diff --git a/.gitignore b/.gitignore index 79be2204..f929377b 100644 --- a/.gitignore +++ b/.gitignore @@ -31,11 +31,6 @@ ui_*.h *.qmlc *.jsc Makefile* -*build-* -*/build/* -stage/* -prime/* -parts/* *cqtdeployer_resource.rc sharedQtWin64/* @@ -63,15 +58,7 @@ sharedQtWin64/ distro/ Distro/ deployTests/ -QIFData/packages/cqtdeployer*/data/ -QIFData/packages/QIF/data/ -staticQt/ -staticQtWin32/ -staticQtWin64/ build -UnitTests/release/* -UnitTests/debug/* -UnitTests/res_qmlcache.qrc # cmake CMakeLists.txt.user @@ -85,3 +72,20 @@ install_manifest.txt compile_commands.json CTestTestfile.cmake _deps + +# cmake configured files +src/Deploy/src/deploy_global.h +src/QtELFReader/src/elfreader_global.h +src/CQtDeployer/Deploy/CQtDeployer.json +src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer/meta/package.xml +src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/package.xml +src/CQtDeployer/Deploy/QIFWTemplate/packages/QIF/meta/package.xml +src/CQtDeployer/Deploy/QIFW/ +src/CQtDeployer/Deploy/CQtDeployerSingle.json +src/CQtDeployer/Deploy/QIFWTemplate/config/config.xml +snap/snapcraft.yaml +src/LibDeploy/src/deploy_global.h +doxygen.conf + +# binaries +testcases/bin/ diff --git a/.gitmodules b/.gitmodules index 99847480..47813c4b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +1,10 @@ -[submodule "QuasarAppLib"] - path = QuasarAppLib +[submodule "submodules/QuasarAppLib"] + path = submodules/QuasarAppLib url = https://github.com/QuasarApp/QuasarAppLib.git -[submodule "qtTools"] - path = qtTools - url = https://github.com/qt/qttools.git -[submodule "pe"] - path = pe +[submodule "submodules/pe-parse"] + path = submodules/pe-parse url = https://github.com/QuasarApp/pe-parse.git -[submodule "QuasarAppScripts"] - path = QuasarAppScripts - url = https://github.com/QuasarApp/QuasarAppScripts.git -[submodule "zip"] - path = zip +[submodule "submodules/zip"] + path = submodules/zip url = https://github.com/QuasarApp/zip.git + diff --git a/CMakeLists.txt b/CMakeLists.txt index be3722e0..3586f761 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,86 @@ # -# Copyright (C) 2018-2021 QuasarApp. -# Distributed under the lgplv3 software license, see the accompanying +# Copyright (C) 2020-2022 QuasarApp. +# Distributed under the GPLv3 software license, see the accompanying # Everyone is permitted to copy and distribute verbatim copies # of this license document, but changing it is not allowed. # -# This is a stub for the cmake build system. +cmake_minimum_required(VERSION 3.18) +project(CQtDeployer LANGUAGES CXX) +if(TARGET ${PROJECT_NAME}) + message("The ${PROJECT_NAME} arledy included in main Project") + return() +endif() +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) -project(CQtDeployer LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(BUILD_SHARED_LIBS ON) + +if (IOS) + set(BUILD_SHARED_LIBS OFF) +endif() + +if (NOT QT_VERSION_MAJOR) + find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Test QUIET) +endif() +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test QUIET) + +include(submodules/QuasarAppLib/CMake/QuasarApp.cmake) + +updateGitVars() + +string(TIMESTAMP TODAY "%Y-%m-%d") +set(CQT_DEPLOYER_VERSION_SHORT_PREFIX "1.6") +set(CQT_DEPLOYER_VERSION "${CQT_DEPLOYER_VERSION_SHORT_PREFIX}.${GIT_COMMIT_COUNT}.${GIT_COMMIT_HASH}") +set(QIFW_VERSION "4.4") + +option(CQT_DEPLOYER_TESTS "This option disables or enables tests of the ${PROJECT_NAME} project" ON) +option(CQT_DEPLOYER_TOOL "This option disables or enables example app of the ${PROJECT_NAME} project" ON) + +if (ANDROID OR IOS OR NOT QT_VERSION_MAJOR OR QA_WASM32) + message(WARNING "CQtDeployer is not availabel for wasm, android and ios platforms") + initAll() + return() +endif() -cmake_minimum_required(VERSION 3.1) -include(QuasarAppLib/CMake/QuasarAppCITargets.cmake) +if (NOT QT_VERSION_MAJOR) + set(CQT_DEPLOYER_TOOL OFF CACHE BOOL "This option force disbled for Not Qt projects" FORCE) +endif() + +if (${QT_VERSION_MAJOR} LESS 6) + message(WARNING "CQtDeployer tests is not available for qt5. Please build cqtdeployer with qt6") + set(CQT_DEPLOYER_TESTS OFF CACHE BOOL "This option force disbled for ANDROID IOS QA_WASM32 and Not Qt projects" FORCE) +endif() + +make_directory(Distro) initAll() +add_subdirectory(submodules/QuasarAppLib) +add_subdirectory(src/QtELFReader) + +option(BUILD_COMMAND_LINE_TOOLS "Build Command Line Tools" OFF) +add_subdirectory(submodules/pe-parse) +add_subdirectory(submodules/zip) + +add_subdirectory(src/Deploy) + +if (DEFINED CQT_DEPLOYER_TOOL) + add_subdirectory(src/CQtDeployer) +endif() + +if (CQT_DEPLOYER_TESTS) + add_subdirectory(testcases) + add_subdirectory(tests) +else() + message("The ${PROJECT_NAME} tests is disabled.") +endif() + +configure_file_in("" "${CMAKE_CURRENT_SOURCE_DIR}/doxygen.conf") + addDoc(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.conf) +addDeployFromCustomFile("CQtDeployer" "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/CQtDeployer.json") diff --git a/CQtDeployer.pro b/CQtDeployer.pro deleted file mode 100644 index da35d8af..00000000 --- a/CQtDeployer.pro +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (C) 2018-2022 QuasarApp. -# Distributed under the lgplv3 software license, see the accompanying -# Everyone is permitted to copy and distribute verbatim copies -# of this license document, but changing it is not allowed. -# - -TEMPLATE = subdirs -CONFIG += ordered - -lessThan(QT_MAJOR_VERSION, 6):lessThan(QT_MINOR_VERSION, 12) { - warning("Tests are only enabled on Qt 5.12.0 or later version. You are using $$[QT_VERSION].") - DEFINES += WITHOUT_TESTS - DEFINES += WITHOUT_TR -} - -unix:gcc { - COMPILER_VERSION = $$system($$QMAKE_CXX " -dumpversion") - COMPILER_MAJOR_VERSION = $$COMPILER_VERSION - lessThan(COMPILER_MAJOR_VERSION, 5): { - warning("The PE parser library is disabled. For build the PE parser library require gcc 5 or later version.") - DEFINES += DISABLE_PE - } - message(Version GCC : $$COMPILER_VERSION) -} - -android: DEFINES += WITHOUT_TESTS - -!android { - SUBDIRS += QuasarAppLib \ - Pe \ - zip \ - Deploy \ - CQtDeployer \ - UnitTests \ - tests/TestOnlyC \ - tests/TestCPPOnly \ - tests/TestQtWidgets \ - tests/TestQMLWidgets \ - tests/virtualkeyboard - - unix:SUBDIRS += tests/quicknanobrowser - unix:SUBDIRS += tests/webui - - contains(DEFINES, DISABLE_PE) { - SUBDIRS -= Pe - DEFINES += WITHOUT_TESTS - } - - contains(DEFINES, WITHOUT_TESTS) { - SUBDIRS -= UnitTests \ - tests/TestOnlyC \ - tests/TestCPPOnly \ - tests/TestQtWidgets \ - tests/TestQMLWidgets \ - tests/quicknanobrowser \ - tests/webui - } - - CQtDeployer.depends=QuasarAppLib - CQtDeployer.depends=Deploy - - QuasarAppLib.file = $$PWD/QuasarAppLib/QuasarApp.pro - Pe.file = $$PWD/pe/pe-parser-library/pe-parser-library.pro - - include('$$PWD/QIFData/installerCQtDeployer.pri') - !contains(QMAKE_HOST.arch, arm.*):{ - include($$PWD/test.pri) - } - - DISTFILES += \ - snap/snapcraft.yaml \ - snap/gui/cqtdeployer.desktop \ - README.md \ - - -} - diff --git a/CQtDeployer/CQtDeployer.pro b/CQtDeployer/CQtDeployer.pro deleted file mode 100644 index d26c4842..00000000 --- a/CQtDeployer/CQtDeployer.pro +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright (C) 2018-2022 QuasarApp. -# Distributed under the lgplv3 software license, see the accompanying -# Everyone is permitted to copy and distribute verbatim copies -# of this license document, but changing it is not allowed. -# - -QT -= gui - -CONFIG += c++17 console -CONFIG -= app_bundle - -# 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 - -CONFIG(release, debug|release): { - DESTDIR="$$PWD/build/release" -} else { - DESTDIR="$$PWD/build/debug" -} - -include('$$PWD/../QuasarAppLib/QuasarLib.pri') -include('$$PWD/../Deploy/Deploy.pri') -include('$$PWD/../zip/zip.pri') - -!contains(DEFINES, DISABLE_PE) { - include('$$PWD/../pe/pe-parser-library/pe-parser-library.pri') -} - -TARGET = cqtdeployer - -SOURCES += \ - main.cpp \ - - -win32: RC_ICONS = $$PWD/../res/icon.ico diff --git a/Deploy/Deploy.pri b/Deploy/Deploy.pri deleted file mode 100644 index 740c1b45..00000000 --- a/Deploy/Deploy.pri +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (C) 2018-2022 QuasarApp. -# Distributed under the lgplv3 software license, see the accompanying -# Everyone is permitted to copy and distribute verbatim copies -# of this license document, but changing it is not allowed. -# - -!isEmpty(DEPLOY_LIB):error("Deploy.pri already included") -DEPLOY_LIB = 1 - -#DEPENDS -CONFIG(release, debug|release): { - DEPLOY_LIB_OUTPUT_DIR="$$PWD/build/release" -} else { - DEPLOY_LIB_OUTPUT_DIR="$$PWD/build/debug" -} - -unix:LIBS += -L$$DEPLOY_LIB_OUTPUT_DIR -lDeploy -win32:LIBS += -L$$DEPLOY_LIB_OUTPUT_DIR -lDeploy1 - - -INCLUDEPATH += "$$PWD/" - - - diff --git a/Deploy/Deploy.pro b/Deploy/Deploy.pro deleted file mode 100644 index 7591bf95..00000000 --- a/Deploy/Deploy.pro +++ /dev/null @@ -1,129 +0,0 @@ -# -# Copyright (C) 2018-2022 QuasarApp. -# Distributed under the lgplv3 software license, see the accompanying -# Everyone is permitted to copy and distribute verbatim copies -# of this license document, but changing it is not allowed. -# - - -#------------------------------------------------- -# -# Project created by QtCreator 2019-01-26T13:55:47 -# -#------------------------------------------------- - -QT -= gui -CONFIG += c++17 -TARGET = Deploy -TEMPLATE = lib - -DEFINES += DEPLOY_LIBRARY - -VERSION = 1.5.4.17 - -DEFINES += APP_VERSION='\\"$$VERSION\\"' - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as 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 - -CONFIG(release, debug|release): { - DESTDIR="$$PWD/build/release" -} else { - DESTDIR="$$PWD/build/debug" -} - -include('$$PWD/../QuasarAppLib/QuasarLib.pri') -!contains(DEFINES, DISABLE_PE) { - include('$$PWD/../pe/pe-parser-library/pe-parser-library.pri') -} -include('$$PWD/../zip/zip.pri') - - -SOURCES += \ - Distributions/deb.cpp \ - Distributions/defaultdistro.cpp \ - Distributions/templateinfo.cpp \ - Distributions/ziparhive.cpp \ - dependencymap.cpp \ - deployconfig.cpp \ - distromodule.cpp \ - distrostruct.cpp \ - configparser.cpp \ - deploy.cpp \ - deploycore.cpp \ - elf_type.cpp \ - envirement.cpp \ - extra.cpp \ - extracter.cpp \ - filemanager.cpp \ - Distributions/idistribution.cpp \ - generalfiles_type.cpp \ - ignorerule.cpp \ - metafilemanager.cpp \ - packagecontrol.cpp \ - packing.cpp \ - pathutils.cpp \ - igetlibinfo.cpp \ - dependenciesscanner.cpp \ - ../qtTools/src/shared/winutils/elfreader.cpp \ - pe_type.cpp \ - pluginsparser.cpp \ - Distributions/qif.cpp \ - qml.cpp \ - libinfo.cpp \ - qtdir.cpp \ - targetdata.cpp \ - targetinfo.cpp \ - zipcompresser.cpp - -HEADERS += \ - Distributions/deb.h \ - Distributions/defaultdistro.h \ - Distributions/templateinfo.h \ - Distributions/ziparhive.h \ - defines.h \ - dependencymap.h \ - deployconfig.h \ - distromodule.h \ - distrostruct.h \ - configparser.h \ - deploy.h \ - deploy_global.h \ - deploycore.h \ - elf_type.h \ - envirement.h \ - extra.h \ - extracter.h \ - filemanager.h \ - Distributions/idistribution.h \ - generalfiles_type.h \ - ignorerule.h \ - metafilemanager.h \ - packagecontrol.h \ - packing.h \ - pathutils.h \ - igetlibinfo.h \ - dependenciesscanner.h \ - ../qtTools/src/shared/winutils/elfreader.h \ - pe_type.h \ - pluginsparser.h \ - Distributions/qif.h \ - qml.h \ - libinfo.h \ - qtdir.h \ - targetdata.h \ - targetinfo.h \ - zipcompresser.h - -STATECHARTS += - -RESOURCES += \ - DeployResources.qrc diff --git a/QIFData/InstallerBase.pri b/QIFData/InstallerBase.pri deleted file mode 100644 index fbd60c63..00000000 --- a/QIFData/InstallerBase.pri +++ /dev/null @@ -1,64 +0,0 @@ - -QT_DIR= $$[QT_HOST_BINS] - -win32:QMAKE_BIN= $$QT_DIR/qmake.exe -win32:LUPDATE = $$QT_DIR/lupdate.exe -win32:LRELEASE = $$QT_DIR/lrelease.exe -win32:DEPLOYER=cqtdeployer - - -contains(QMAKE_HOST.os, Linux):{ - QMAKE_BIN= $$QT_DIR/qmake - LUPDATE = $$QT_DIR/lupdate - LRELEASE = $$QT_DIR/lrelease - DEPLOYER = cqtdeployer -} - -android { - DEPLOYER = $$QT_DIR/androiddeployqt -} - -message( PWD :$$PWD) - -message( Configuration variables :) -message(QT_DIR = $$QT_DIR) -message(QMAKE_BIN = $$QMAKE_BIN) -message(LUPDATE = $$LUPDATE) -message(LRELEASE = $$LRELEASE) -message(DEPLOYER = $$DEPLOYER) - -BINARY_LIST -REPO_LIST - -sopprted_versions = 4.5 4.4 4.3 4.2 4.1 4.0 3.2 3.1 3.0 -for(val, sopprted_versions) { - - exists( $$QT_DIR/../../../Tools/QtInstallerFramework/$$val/bin/ ) { - message( "QtInstallerFramework v$$val: yes" ) - BINARY_LIST += $$QT_DIR/../../../Tools/QtInstallerFramework/$$val/bin/binarycreator - REPO_LIST += $$QT_DIR/../../../Tools/QtInstallerFramework/$$val/bin/repogen - } -} - -isEmpty (BINARY_LIST) { - warning( "QtInstallerFramework not found! use binaries from PATH." ) - EXEC=binarycreator - REPOGEN=repogen - -} else: { - win32:EXEC=$$first(BINARY_LIST).exe - win32:REPOGEN=$$first(REPO_LIST).exe - - contains(QMAKE_HOST.os, Linux):{ - unix:EXEC=$$first(BINARY_LIST) - win32:EXEC=wine $$first(BINARY_LIST).exe - - REPOGEN=$$first(REPO_LIST) - } -} - - - -message( selected $$EXEC and $$REPOGEN) - - diff --git a/QIFData/QIF.pri b/QIFData/QIF.pri deleted file mode 100644 index 6cbeed0f..00000000 --- a/QIFData/QIF.pri +++ /dev/null @@ -1,27 +0,0 @@ -OTHER_FILES += \ - $$PWD/*.md \ - $$PWD/*.sh \ - $$PWD/scripts/*.py \ - $$PWD/packages/QIF/meta/*.xml - -win32:PLATFORM = windows -unix: PLATFORM = linux - -win32:PY = python -unix: PY = python3 - -qif.commands= $$PY $$PWD/scripts/QIF.py $$PLATFORM 4.4 $$PWD/packages/QIF/data -alias.commands= $$PY $$PWD/scripts/alias.py - -!isEmpty( ONLINE ) { - - message(prepare release QIF) - deployOffline.depends += qif - buildSnap.depends += qif -} - -unix:deployOffline.depends += alias - -QMAKE_EXTRA_TARGETS += \ - qif \ - alias diff --git a/QIFData/config/configWin.xml b/QIFData/config/configWin.xml deleted file mode 100644 index adfbc531..00000000 --- a/QIFData/config/configWin.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - 640px - 400px - CQtDeployer - 1.5.4.17 - CQtDeployer - QuasarApp - CQtDeployer - @ApplicationsDir@/CQtDeployer - true - true - controlScript.js - CQtDeployerTool - Modern - style.css - logo.png - - - - http://quasarapp.ddns.net:3030/CQtDeployer/Windows - 1 - QuasarApp - - - diff --git a/QIFData/installerCQtDeployer.pri b/QIFData/installerCQtDeployer.pri deleted file mode 100644 index 1afb1864..00000000 --- a/QIFData/installerCQtDeployer.pri +++ /dev/null @@ -1,163 +0,0 @@ -VERSION = 1.5.4.17 - -include($$PWD/InstallerBase.pri); -mkpath( $$PWD/../Distro) - -message(QMAKE_HOST.arch = $$QMAKE_HOST.arch) - -win32:OUT_FILE = CQtDeployer_'$$VERSION'_Installer_Win'_$$QMAKE_HOST.arch'.exe -unix:OUT_FILE = CQtDeployer_'$$VERSION'_Installer_Linux'_$$QMAKE_HOST.arch'.run - -win32:OUT_FILE_OFF = CQtDeployer_'$$VERSION'_OfflineInstaller_Win'_$$QMAKE_HOST.arch'.exe -unix:OUT_FILE_OFF = CQtDeployer_'$$VERSION'_OfflineInstaller_Linux'_$$QMAKE_HOST.arch'.run - -DEPLOY_TARGET = $$PWD/../CQtDeployer/build/release - -DATA_DIR = $$PWD/packages/cqtdeployer.1_5/data/1.5 -META_DIR = $$PWD/packages/cqtdeployer.1_5/meta/ - -win32:OUT_LIB= -libOut lib -win32:OUT_BIN= -binOut bin - -BASE_DEPLOY_FLAGS = clear -qmake $$QMAKE_BIN -libDir $$PWD/../ -recursiveDepth 4 -ignoreEnv $$DEPLOY_TARGET -extraLibs icu -BASE_DEPLOY_FLAGS_CQT = $$BASE_DEPLOY_FLAGS -targetDir $$DATA_DIR $$OUT_LIB $$OUT_BIN - - -win32:CQT_ICON = -icon $$PWD/config/icon.ico -unix:CQT_ICON = -icon $$PWD/config/logo.png -BASE_DEPLOY_FLAGS_DEB = $$BASE_DEPLOY_FLAGS -targetDir $$PWD/../Distro $$OUT_LIB $$OUT_BIN deb zip -name CQtDeployer -publisher QuasarApp $$CQT_ICON -deployVersion 1.5.4.17 -debOut CQtDeployer_'$$VERSION'_Linux'_$$QMAKE_HOST.arch'.deb -zipOut CQtDeployer_'$$VERSION'_Linux'_$$QMAKE_HOST.arch'.zip - -DEPLOY_TARGET_DEB = $$DEPLOY_TARGET,$$PWD/packages/QIF/data/QIF -deploy_dep.commands += $$DEPLOYER -bin $$DEPLOY_TARGET $$BASE_DEPLOY_FLAGS_CQT -deploy_deb.commands += $$DEPLOYER -bin $$DEPLOY_TARGET_DEB $$BASE_DEPLOY_FLAGS_DEB - -win32:CONFIG_FILE = $$PWD/config/configWin.xml -unix:CONFIG_FILE = $$PWD/config/configLinux.xml - -deployOffline.commands = $$EXEC \ - --offline-only \ - -c $$CONFIG_FILE \ - -p $$PWD/packages \ - $$PWD/../Distro/$$OUT_FILE_OFF - - -!contains(QMAKE_HOST.arch, arm.*):{ - deploy.depends = deploy_dep - deploy.depends += deployOffline - -} - -unix:deploy.depends += deploy_deb - -win32:ONLINE_REPO_DIR = $$ONLINE/CQtDeployer/Windows -unix:ONLINE_REPO_DIR = $$ONLINE/CQtDeployer/Linux - -win32:PY = python -unix: PY = python3 - -create_repo.commands = $$PY $$PWD/../QuasarAppScripts/cp.py $$PWD/packages/ $$PWD/../Repo - -chmodSnap.commands = chmod 777 -R $$DATA_DIR -unix:deploy.depends += chmodSnap - - -message( ONLINE_REPO_DIR $$ONLINE_REPO_DIR) -!isEmpty( ONLINE ) { - - message(online) - - release.depends = create_repo - - deploy.commands = $$EXEC \ - --online-only \ - -c $$CONFIG_FILE \ - -p $$PWD/packages \ - $$PWD/../Distro/$$OUT_FILE -} - -buildSnap.commands = snapcraft -clearSnap.commands = rm parts prime stage *.snap -rdf -clearSnap2.commands = rm parts prime stage -rdf - -deploySnap.commands = rm *.snap -rdf && chmod 777 -R $$PWD/../prime && snapcraft && cp *.snap $$PWD/../Distro/ -releaseSnap.commands = snapcraft push *.snap # bad patern - - - -!isEmpty( ONLINE ) { - - !contains(QMAKE_HOST.arch, arm.*):{ - - message(Snap) - unix:deploy.depends += clearSnap - unix:deploy.depends += buildSnap - unix:deploy.depends += deploySnap - unix:deploy.depends += clearSnap2 - unix:release.depends += releaseSnap - } -} - -OTHER_FILES += \ - $$META_DIR/* \ - $$PWD/config/*.* - -include(QIF.pri) - -QMAKE_EXTRA_TARGETS += \ - deploy_dep \ - deploy_deb \ - deployOffline \ - deploy \ - create_repo \ - release \ - clearSnap \ - clearSnap2 \ - deploySnap \ - releaseSnap \ - buildSnap \ - chmodSnap - - -!contains(DEFINES, WITHOUT_TR) { - - # Translations - SUPPORT_LANGS = ru - - defineReplace(findFiles) { - patern = $$1 - path = $$2 - - all_files = $$files(*$${patern}, true) - win32:all_files ~= s|\\\\|/|g - win32:path ~= s|\\\\|/|g - - for(file, all_files) { - result += $$find(file, $$path) - } - - return($$result) - } - - XML_FILES = $$files(*.xml, true) - - for(LANG, SUPPORT_LANGS) { - for(XML, XML_FILES) { - FILE_PATH = $$dirname(XML) - - JS_FILES = $$findFiles(".js", $$FILE_PATH) - UI_FILES = $$findFiles(".ui", $$FILE_PATH) - - commands += "$$LUPDATE $$JS_FILES $$UI_FILES -ts $$FILE_PATH/$${LANG}.ts" - TS_FILES += $$FILE_PATH/$${LANG}.ts - - } - - for(TS, TS_FILES) { - commands += "$$LRELEASE $$TS" - } - } - - for(command, commands) { - system($$command)|error("Failed to run: $$command") - } -} diff --git a/QIFData/packages/cqtdeployer.1_5/meta/package.xml b/QIFData/packages/cqtdeployer.1_5/meta/package.xml deleted file mode 100644 index 476df750..00000000 --- a/QIFData/packages/cqtdeployer.1_5/meta/package.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - CQtDeployer 1.5 - CQtDeployer 1.5 - 1.5.4.17 - true - false - - 2022-03-03 - 201 - - ru.qm - - diff --git a/QIFData/packages/cqtdeployer.1_5/meta/ru.ts b/QIFData/packages/cqtdeployer.1_5/meta/ru.ts deleted file mode 100644 index 1a671e47..00000000 --- a/QIFData/packages/cqtdeployer.1_5/meta/ru.ts +++ /dev/null @@ -1,53 +0,0 @@ - - - - - installscript - - CQtDeployer 1.3 - CQtDeployer - CQtDeployer - - - This package contains CQtDeployer version 1.3 - This package contains CQtDeployer - Этот пакет содержит CQtDeployer - - - install in system - Установка в систему - - - Installer - Установщик - - - To uninstall cqtdeployer on your system, you need administrator rights!. - Чтобы удалить cqtdeployer в вашей системе, вам нужны права администратора !. - - - To install cqtdeployer on your system, you need administrator rights!. - Чтобы установить cqtdeployer в вашей системе, вам нужны права администратора!. - - - The installation was successful, but cqtdeployer will not be available from the console. - Установка прошла успешно, но cqtdeployer не будет доступен из консоли. - - - To take advantage of this program you will need to enter the full path to it. - Чтобы воспользоваться этой программой, вам нужно будет ввести полный путь к ней. - - - Example: - Пример: - - - CQtDeployer successfully installed on your computer to use the call "cqtdeployer". - CQtDeployer успешно установлен на вашем компьютере, чтобы использоваться введите в консоле "cqtdeployer". - - - The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! - - - - diff --git a/QIFData/packages/cqtdeployer/meta/ru.ts b/QIFData/packages/cqtdeployer/meta/ru.ts deleted file mode 100644 index 6401616d..00000000 --- a/QIFData/packages/cqtdeployer/meta/ru.ts +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/QIFData/scripts/alias.py b/QIFData/scripts/alias.py deleted file mode 100755 index 3d34156e..00000000 --- a/QIFData/scripts/alias.py +++ /dev/null @@ -1,12 +0,0 @@ -import os -import shutil -import subprocess - -dir_path = os.path.dirname(os.path.realpath(__file__)) -dest = dir_path + "/../packages/cqtdeployer.1_5/data/1.5/" -if not os.path.isdir(dest): - os.makedirs(dest) - - -shutil.copyfile(dir_path + "/alias/cqt.sh", dest + "/cqt.sh") -subprocess.run(["chmod", "777", dest + "/cqt.sh"]) diff --git a/QuasarAppLib b/QuasarAppLib deleted file mode 160000 index d69306c1..00000000 --- a/QuasarAppLib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d69306c1210fe6def35cf0ff7323e3e82f9ae8f4 diff --git a/QuasarAppScripts b/QuasarAppScripts deleted file mode 160000 index f680b277..00000000 --- a/QuasarAppScripts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f680b277968f6bbd966a7dcfe2014dbb343fefd2 diff --git a/UnitTests/.gitignore b/UnitTests/.gitignore deleted file mode 100644 index fab7372d..00000000 --- a/UnitTests/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# This file is used to ignore files which are generated -# ---------------------------------------------------------------------------- - -*~ -*.autosave -*.a -*.core -*.moc -*.o -*.obj -*.orig -*.rej -*.so -*.so.* -*_pch.h.cpp -*_resource.rc -*.qm -.#* -*.*# -core -!core/ -tags -.DS_Store -.directory -*.debug -Makefile* -*.prl -*.app -moc_*.cpp -ui_*.h -qrc_*.cpp -Thumbs.db -*.res -*.rc -/.qmake.cache -/.qmake.stash - -# qtcreator generated files -*.pro.user* - -# xemacs temporary files -*.flc - -# Vim temporary files -.*.swp - -# Visual Studio generated files -*.ib_pdb_index -*.idb -*.ilk -*.pdb -*.sln -*.suo -*.vcproj -*vcproj.*.*.user -*.ncb -*.sdf -*.opensdf -*.vcxproj -*vcxproj.* - -# MinGW generated files -*.Debug -*.Release - -# Python byte code -*.pyc - -# Binaries -# -------- -*.dll -*.exe - diff --git a/UnitTests/UnitTests.pro b/UnitTests/UnitTests.pro deleted file mode 100644 index fd44e60b..00000000 --- a/UnitTests/UnitTests.pro +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright (C) 2018-2022 QuasarApp. -# Distributed under the lgplv3 software license, see the accompanying -# Everyone is permitted to copy and distribute verbatim copies -# of this license document, but changing it is not allowed. -# - - -QT += testlib -QT -= gui - -CONFIG(release, debug|release): { - DESTDIR="$$PWD/build/release" -} else { - DESTDIR="$$PWD/build/debug" -} - -include('$$PWD/../QuasarAppLib/QuasarLib.pri') -include('$$PWD/../Deploy/Deploy.pri') -include('$$PWD/../zip/zip.pri') - -include('$$PWD/../pe/pe-parser-library/pe-parser-library.pri') - - -QT_DIR = $$[QT_HOST_BINS]/../ -DEFINES+=QT_BASE_DIR='\\"$$QT_DIR\\"' -DEFINES+=TEST_BIN_DIR='\\"$$PWD/../tests/build/\\"' -DEFINES+=QTEST_FUNCTION_TIMEOUT=900000 - -CONFIG += qt console warn_on depend_includepath testcase -CONFIG -= app_bundle - -TEMPLATE = app - -SOURCES += tst_deploytest.cpp \ - libcreator.cpp \ - modules.cpp \ - modulesqt513.cpp \ - modulesqt514.cpp \ - modulesqt515.cpp \ - modulesqt5152.cpp \ - qmlcreator.cpp \ - testutils.cpp - -RESOURCES += \ - res.qrc - -HEADERS += \ - backward-cpp/backward.hpp \ - libcreator.h \ - modules.h \ - modulesqt513.h \ - modulesqt514.h \ - modulesqt515.h \ - modulesqt5152.h \ - qmlcreator.h \ - testutils.h - diff --git a/UnitTests/tst_deploytest.cpp b/UnitTests/tst_deploytest.cpp deleted file mode 100644 index 37ebdac1..00000000 --- a/UnitTests/tst_deploytest.cpp +++ /dev/null @@ -1,3246 +0,0 @@ -/* - * Copyright (C) 2018-2022 QuasarApp. - * Distributed under the lgplv3 software license, see the accompanying - * Everyone is permitted to copy and distribute verbatim copies - * of this license document, but changing it is not allowed. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include "libcreator.h" -#include "modules.h" -#include "qmlcreator.h" -#include "testutils.h" - -// add necessary includes here - - -static const QString TestBinDir = TEST_BIN_DIR; -static const QString TestQtDir = QT_BASE_DIR; - -class deploytest : public QObject -{ - Q_OBJECT - -private: - QSet filesTree; - - void runTestParams(QStringList list, - QSet *tree = nullptr, - bool noWarnings = false, - bool onlySize = false, - exitCodes exitCode = exitCodes::Good, - const std::function &cb = {}); - - void checkResults(const QSet &tree, - bool noWarnings, - bool onlySize = false); - - void createTree(const QStringList& tree); - -public: - deploytest(); - /** - * @brief generateLib - * @param paath - * @return size of lib - */ - int generateLib(const QString& paath); - void deleteLib(const QString& paath); - - ~deploytest(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - - // old tests (not valid) - void testDeployTarget(); - void testStrip(); - void testExtractLib(); - void testRelativeLink(); - void testCheckQt(); - - void testQmlExtrct(); - void testSetTargetDir(); - - // void mainTests(); - - // end old tests - - // tested flags customScript - - void testZip(); - void costomScript(); - void testDistroStruct(); - - // tested flags clear noOvervrite - void testOverwrite(); - void testOverwriteWithPacking(); - - // tested flags binDir - void testextraData(); - - // tested flags qmlDir qmake - void testQt(); - - - void testWebEngine(); - - // tested flags confFile - void testConfFile(); - - // tested flags targetPackage - void testPackages(); - - // tested clear force clear in clear mode - void testClear(); - - // tested flags ignore - void testIgnore(); - - // tested flags ignore ignoreEnv - void testIgnoreEnv(); - - // tested flags libDir recursiveDepth - void testLibDir(); - - // tested flag extraPlugin - void testExtraPlugins(); - - // tested flag targetDir - void testTargetDir(); - - // tested flag noLibc deploySystem - void testSystemLib(); - - // tested flag qmlOut libOut trOut pluginOut binOut - void testOutDirs(); - - void testMSVC(); - - // qif flags - void testQIF(); - void testQIFMulti(); - void testQIFCustom(); - - // zip flags - void testZIP(); - void testZIPMulti(); - - // deb flags - void testDEB(); - void testDEBMulti(); - void testDEBCustom(); - - // qif and zip flags - void testMultiPacking(); - - // init flags - void testInit(); - - void testDependencyMap(); - - void testQmlScaner(); - - void testPrefix(); - // test configure empty packages - void testallowEmptyPackages(); - // test skip empty packages - void testEmptyPackages(); - - void testRunScripts(); - void testOverridingDefaultTemplateQIF(); - void testOverridingDefaultTemplateDEB(); - - void testDeployGeneralFiles(); - void testTr(); - void testVirtualKeyBoard(); - // Attention! This test only covers 40% of icon functions - void testIcons(); - void testPathUtils(); - void testBinPrefix(); - - void testMd5(); - - void testDisableShortcuts(); - void testDisableRunScripts(); - void testQifOut(); - void testIgnoreEnvWithLibDir(); - - // note: this test checking in manual mode only. - void testInstallDirsOptions(); - - void testQIFResources(); - - void testCustomPlatform(); - void testQifArchiveFormat(); - void testQifBinaryCreator(); - - void customTest(); -}; - -deploytest::deploytest() { - - qputenv("QTEST_FUNCTION_TIMEOUT", "1800000"); - QString qifwPath = qgetenv("PATH") + DeployCore::getEnvSeparator() + TestQtDir + "../../Tools/QtInstallerFramework/4.0/bin/"; - qifwPath += qifwPath + DeployCore::getEnvSeparator() + TestQtDir + "../../Tools/QtInstallerFramework/4.1/bin/"; - qifwPath += qifwPath + DeployCore::getEnvSeparator() + TestQtDir + "../../Tools/QtInstallerFramework/4.2/bin/"; - qifwPath += qifwPath + DeployCore::getEnvSeparator() + TestQtDir + "../../Tools/QtInstallerFramework/4.3/bin/"; - - qputenv("PATH", qifwPath.toLatin1().data()); - TestUtils utils; - - QStringList pathList = QProcessEnvironment::systemEnvironment(). - value("PATH").split(DeployCore::getEnvSeparator()); - - for (const auto& path: qAsConst(pathList)) { - filesTree += utils.getFilesSet(path, 1); - } - - filesTree += utils.getFilesSet(TestQtDir); - -} - -int deploytest::generateLib(const QString &paath) -{ - QDir dir; - dir.mkpath(QFileInfo(paath).absolutePath()); - QFile testLib (paath); - - int size = 0; - - if (testLib.open(QIODevice::ReadWrite| QIODevice::Truncate)) { - QFile resData(":/debugLib"); - if (resData.open(QIODevice::ReadOnly)) { - QByteArray tempData = resData.readAll(); - size = tempData.size(); - testLib.write(tempData.data(), tempData.size()); - resData.close(); - } - - testLib.close(); - } - - return size; -} - -void deploytest::deleteLib(const QString &paath) -{ - QFileInfo info(paath); - if (info.isDir()) { - QFile::remove(info.absoluteFilePath()); - } else { - QDir qt(info.absoluteFilePath()); - qt.removeRecursively(); - } -} - -deploytest::~deploytest(){} - -void deploytest::initTestCase() { - QDir qt; - - QDir("./" + DISTRO_DIR).removeRecursively(); - - qt.mkpath("./test/Qt/5.12/"); - qt.mkpath("./test/extraPath/"); - qt.mkpath("./test/extra/"); - qt.mkpath("./test/warning/"); - qt.mkpath("./test/bins/"); - - QFile f( "./test/Qt/5.12/generalLib.so"); - if (f.open(QIODevice::WriteOnly| QIODevice::Truncate)) { - f.write("lib", 3); - f.close(); - } - - f.setFileName("./test/extraPath/ExtraLib.so"); - if (f.open(QIODevice::WriteOnly| QIODevice::Truncate)) { - f.write("lib", 3); - f.close(); - } - - f.setFileName("./test/extra/ExtraLib.so"); - if (f.open(QIODevice::WriteOnly| QIODevice::Truncate)) { - f.write("lib", 3); - f.close(); - } - - f.setFileName("./test/warning/WarningLib.so"); - if (f.open(QIODevice::WriteOnly| QIODevice::Truncate)) { - f.write("lib", 3); - f.close(); - } - - f.setFileName("./test/bins/execTarget.exe"); - if (f.open(QIODevice::WriteOnly| QIODevice::Truncate)) { - f.write("exec", 3); - f.close(); - } - - f.setFileName("./test/bins/execTarget"); - if (f.open(QIODevice::WriteOnly| QIODevice::Truncate)) { - f.write("exec", 3); - f.close(); - } -} - -void deploytest::cleanupTestCase() { - QDir qt("./test"); - qt.removeRecursively(); - -} - -void deploytest::testDeployTarget() { - - FileManager file; - DependenciesScanner scan; - Packing pac(&file); - PluginsParser _pluginParser; - - ConfigParser *deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - - QStringList targets; - targets << "./test/bins/execTarget.exe"; - QVERIFY(deploy->setTargets(targets)); - delete deploy; - targets.clear(); - - deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - targets << "./test/bins/execTarget"; - QVERIFY(deploy->setTargets(targets)); - delete deploy; - targets.clear(); - - deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - targets << "./test/bins/execTarget.exe" << "./test/bins/execTarget"; - QVERIFY(deploy->setTargets(targets)); - delete deploy; - targets.clear(); - - deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - targets << "./test/bns/execTarget.exe"; - QVERIFY(!deploy->setTargets(targets)); - delete deploy; - targets.clear(); - - deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - targets << "./test/bins/"; - QVERIFY(deploy->setTargets(targets)); - delete deploy; - targets.clear(); - - deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - targets << "./test/bins/" << "./test/warning/"; - QVERIFY(deploy->setTargets(targets)); - - delete deploy; - targets.clear(); -} - -void deploytest::testStrip() { - -#ifdef Q_OS_UNIX - //for one lib - qint64 sizeBefor = generateLib("./test/binTargetDir/debugLib.so"); - qint64 sizeAfter = 0; - - FileManager *deploy = new FileManager(); - QVERIFY(deploy->strip("./test/binTargetDir/debugLib.so")); - - QFile testLib ("./test/binTargetDir/debugLib.so"); - if (testLib.open(QIODevice::ReadOnly)) { - sizeAfter = testLib.size(); - testLib.close(); - } - - deleteLib("./test/binTargetDir"); - delete deploy; - - QVERIFY(sizeBefor > sizeAfter); - - - //for folder - QStringList libList = { - ("./test/binTargetDir/debugLib1.so"), - ("./test/binTargetDir/debugLib2.so.1.2"), - ("./test/binTargetDir/debugLib3.so.1"), - ("./test/binTargetDir/debugLib4.so.1.0.0"), - ("./test/binTargetDir/debugLib.dll"), - ("./test/binTargetDir/debugLib1.dll") - }; - QList sizeBeforList = {}; - - for (const auto & i: libList) { - sizeBeforList.push_back(generateLib(i)); - } - - QList sizeAfterList; - - deploy = new FileManager(); - QVERIFY(deploy->strip("./test/binTargetDir")); - - for(const auto &i: libList) { - QFile testLib (i); - if (testLib.open(QIODevice::ReadOnly)) { - sizeAfterList.push_back(testLib.size()); - testLib.close(); - } - } - - deleteLib("./test/binTargetDir"); - - QVERIFY(sizeBeforList.size() == sizeAfterList.size()); - - for (int i = 0; i < sizeAfterList.size(); ++i) { - QVERIFY2(sizeBeforList[i] > sizeAfterList[i], - QString("index %0, lib: %1 size befor:%2, sizeAfter:%3"). - arg(i).arg(libList[i]).arg(sizeBeforList[i]).arg(sizeAfterList[i]). - toLatin1()); - } - -#endif -} - -void deploytest::testExtractLib() { - LibCreator creator("./"); - auto libs = creator.getLibs(); - auto deb = creator.getLibsDep(); - auto platforms = creator.getLibplatform(); - - DependenciesScanner scaner; - - LibInfo info; - - for (const auto &lib : libs) { - QVERIFY(scaner.fillLibInfo(info, lib)); - QVERIFY(info.getName() == QFileInfo(lib).fileName()); - QVERIFY(info.getPath() == QFileInfo(lib).absolutePath()); - QVERIFY(info.fullPath() == QFileInfo(lib).absoluteFilePath()); - QVERIFY(info.getPlatform() == platforms.value(lib)); - - for (const auto &dep : deb.value(lib)) { - QString depName = dep; - if (info.getPlatform() & Platform::Win) { - depName = dep.toUpper(); - } - - bool test = info.getDependncies().contains(depName); - QVERIFY(test); - } - - } - -} - -void deploytest::testMSVC() { - QString testPath = "./Qt/5.11.2/msvc2017_64/bin/"; - - QDir d; - QDir oldDir("./Qt"); - oldDir.removeRecursively(); - QVERIFY(d.mkpath(testPath)); - - - auto msvc = DeployCore::getMSVC(testPath); - - QVERIFY(msvc & MSVCVersion::MSVC_17); - QVERIFY(msvc & MSVCVersion::MSVC_x64); - - QDir dir("./Qt"); - dir.removeRecursively(); - - -} - -void deploytest::testWebEngine() { -#ifdef Q_OS_UNIX - TestUtils utils; - - QString bin = TestBinDir + "quicknanobrowser"; - QString qmake = TestQtDir + "bin/qmake"; - - auto comapareTree = TestModule.qtWebEngine(); - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-qmlDir", TestBinDir + "/../quicknanobrowser"}, &comapareTree); - - - bin = TestBinDir + "webui"; - qmake = TestQtDir + "bin/qmake"; - - comapareTree = TestModule.qtWebEngineWidgets(); - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake}, &comapareTree); - - -#endif -} - -void deploytest::testQIF() { - TestUtils utils; -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - - QString qmake = TestQtDir + "bin/qmake"; - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/InstallerTestOnlyC.run", - "./" + DISTRO_DIR + "/InstallerTestOnlyC.run.md5", - }); - -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - - QString qmake = TestQtDir + "bin/qmake.exe"; - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/InstallerTestOnlyC.exe", - "./" + DISTRO_DIR + "/InstallerTestOnlyC.exe.md5", - - }); - -#endif - - runTestParams({"-bin", bin, "clear" , - "qif", "qifFromSystem", - "-qifStyle", "quasar", - "-qifBanner", TestBinDir + "/../../res/CQtDeployer_banner_web.png", - "-qifLogo", TestBinDir + "/../../res/CQtDeployer defaultIcon_web.png"}, &comapareTree, true); - -} - -void deploytest::testQIFMulti() { - TestUtils utils; -#ifdef Q_OS_UNIX - QString target1 = TestBinDir + "TestCPPOnly"; - QString target2 = TestBinDir + "TestOnlyC"; - - auto comapareTreeMulti = utils.createTree({ - "./" + DISTRO_DIR + "/InstallerApplication.run", - "./" + DISTRO_DIR + "/InstallerApplication.run.md5", - - }); - -#else - QString target1 = TestBinDir + "TestCPPOnly.exe"; - QString target2 = TestBinDir + "TestOnlyC.exe"; - - auto comapareTreeMulti = utils.createTree({ - "./" + DISTRO_DIR + "/InstallerApplication.exe", - "./" + DISTRO_DIR + "/InstallerApplication.exe.md5", - - }); - -#endif - QString bin = target1; - bin += "," + target2; - - auto packageString = "/package1/;" + QFileInfo(target1).absoluteFilePath() + ",/package2/;" + QFileInfo(target2).absoluteFilePath(); - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", packageString, - "qif", "qifFromSystem"}, &comapareTreeMulti, true); -} - -void deploytest::testQIFCustom() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestCPPOnly" + "," + TestBinDir + "TestOnlyC"; - - QString qmake = TestQtDir + "bin/qmake"; - - auto comapareTreeCustom = utils.createTree({ - "./" + DISTRO_DIR + "/Installerorg.qtproject.ifw.example.stylesheet.run", - "./" + DISTRO_DIR + "/Installerorg.qtproject.ifw.example.stylesheet.run.md5", - - }); -#else - QString bin = TestBinDir + "TestCPPOnly.exe" + "," + TestBinDir + "TestOnlyC.exe"; - - QString qmake = TestQtDir + "bin/qmake.exe"; - auto comapareTreeCustom = utils.createTree({ - "./" + DISTRO_DIR + "/Installerorg.qtproject.ifw.example.stylesheet.exe", - "./" + DISTRO_DIR + "/Installerorg.qtproject.ifw.example.stylesheet.exe.md5", - }); - -#endif - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-qif", TestBinDir + "/../../UnitTests/testRes/QIFCustomTemplate", - "-name", "org.qtproject.ifw.example.stylesheet", - "qifFromSystem"}, &comapareTreeCustom, true); - -} - -void deploytest::testZIP() { - - TestUtils utils; - - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/TestOnlyC.zip", - "./" + DISTRO_DIR + "/TestOnlyC.zip.md5", - }); - - - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; -#else - QString bin = TestBinDir + "TestOnlyC.exe"; -#endif - - runTestParams({"-bin", bin, "clear" , - "zip", "verbose"}, &comapareTree, true); - - // test clear for zip - runTestParams({"clear", "verbose"}, nullptr, true); - -} - -void deploytest::testZIPMulti() { - TestUtils utils; - - auto comapareTreeMulti = utils.createTree({ - "./" + DISTRO_DIR + "/package1.zip", - "./" + DISTRO_DIR + "/package2.zip", - "./" + DISTRO_DIR + "/package1.zip.md5", - "./" + DISTRO_DIR + "/package2.zip.md5", - - }); - -#ifdef Q_OS_UNIX - QString target1 = TestBinDir + "TestCPPOnly"; - QString target2 = TestBinDir + "TestOnlyC"; - -#else - QString target1 = TestBinDir + "TestCPPOnly.exe"; - QString target2 = TestBinDir + "TestOnlyC.exe"; -#endif - QString bin = target1; - bin += "," + target2; - - auto packageString = "/package1/;" + QFileInfo(target1).absoluteFilePath() + ",/package2/;" + QFileInfo(target2).absoluteFilePath(); - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", packageString, - "zip"}, &comapareTreeMulti, true); -} - -void deploytest::testDEB() { - -#ifdef Q_OS_UNIX - TestUtils utils; - - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/TestOnlyC.deb", - "./" + DISTRO_DIR + "/TestOnlyC.deb.md5", - - }); - - QString bin = TestBinDir + "TestOnlyC"; - - runTestParams({"-bin", bin, "clear" , - "deb", "verbose"}, &comapareTree, true); - - // test clear for deb - runTestParams({"clear", "verbose"}, nullptr, true); - -#endif - -} - -void deploytest::testDEBMulti() { -#ifdef Q_OS_UNIX - TestUtils utils; - - auto comapareTreeMulti = utils.createTree({ - "./" + DISTRO_DIR + "/package1.deb", - "./" + DISTRO_DIR + "/package2.deb", - "./" + DISTRO_DIR + "/package1.deb.md5", - "./" + DISTRO_DIR + "/package2.deb.md5", - - }); - - QString target1 = TestBinDir + "TestCPPOnly"; - - QString target2 = TestBinDir + "TestOnlyC"; - - QString bin = target1; - bin += "," + target2; - - auto packageString = "/package1/;" + QFileInfo(target1).absoluteFilePath() + ",/package2/;" + QFileInfo(target2).absoluteFilePath(); - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", packageString, - "deb"}, &comapareTreeMulti, true); -#endif -} - -void deploytest::testDEBCustom() { -#ifdef Q_OS_UNIX - - TestUtils utils; - - QString bin = TestBinDir + "TestOnlyC"; - - auto comapareTreeCustom = utils.createTree({ - "./" + DISTRO_DIR + "/chrome.deb", - "./" + DISTRO_DIR + "/chrome.deb.md5", - - }); - - runTestParams({"-bin", bin, "clear" , - "-deb", TestBinDir + "/../../UnitTests/testRes/DEBCustomTemplate", - "-name", "chrome"}, - &comapareTreeCustom, true); -#endif -} - -void deploytest::testMultiPacking() { - TestUtils utils; - -#ifdef Q_OS_UNIX - - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/TestOnlyC.zip", - "./" + DISTRO_DIR + "/TestOnlyC.deb", - "./" + DISTRO_DIR + "/InstallerTestOnlyC.run", - "./" + DISTRO_DIR + "/InstallerTestOnlyC.run.md5", - "./" + DISTRO_DIR + "/TestOnlyC.zip.md5", - "./" + DISTRO_DIR + "/TestOnlyC.deb.md5", - - }); - - QString bin = TestBinDir + "TestOnlyC"; - - runTestParams({"-bin", bin, "clear" , - "zip", - "qif", "qifFromSystem", - "deb", - "verbose"}, &comapareTree, true); - -#else - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/TestOnlyC.zip", - "./" + DISTRO_DIR + "/InstallerTestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.zip.md5", - "./" + DISTRO_DIR + "/InstallerTestOnlyC.exe.md5", - }); - QString bin = TestBinDir + "TestOnlyC.exe"; - - runTestParams({"-bin", bin, "clear" , - "zip", - "qif", "qifFromSystem", - "verbose"}, &comapareTree, true); - -#endif -} - -void deploytest::testInit() -{ - - TestUtils utils; - - runTestParams({"init"}); - - QVERIFY(QFile(DEFAULT_COFIGURATION_FILE).remove()); - - runTestParams({"-init", "multi"}); - - - QVERIFY(QFile(DEFAULT_COFIGURATION_FILE).remove()); - - runTestParams({"-init", "single"}); - - QVERIFY(QFile(DEFAULT_COFIGURATION_FILE).remove()); - -} - -void deploytest::testDependencyMap() { - DependencyMap dep1, dep2, dep3; - - QVERIFY(dep1.qtModules() == 0); - QVERIFY(dep2.qtModules() == 0); - QVERIFY(dep3.qtModules() == 0); - - QVERIFY(dep1.systemLibs().isEmpty()); - QVERIFY(dep2.systemLibs().isEmpty()); - QVERIFY(dep3.systemLibs().isEmpty()); - - - QVERIFY(dep1.neadedLibs().isEmpty()); - QVERIFY(dep2.neadedLibs().isEmpty()); - QVERIFY(dep3.neadedLibs().isEmpty()); - - dep1.addModule(DeployCore::QtModule::QtGuiModule); - - QVERIFY(dep1.qtModules() == DeployCore::QtModule::QtGuiModule); - dep1.addModule(DeployCore::QtModule::QtHelpModule); - - QVERIFY(dep1.qtModules() == (DeployCore::QtModule::QtGuiModule | - DeployCore::QtModule::QtHelpModule)); - - dep1.removeModule(DeployCore::QtModule::QtGuiModule); - - QVERIFY(dep1.qtModules() == DeployCore::QtModule::QtHelpModule); - - dep2.addModule(DeployCore::QtModule::QtGuiModule); - - dep1 += dep2; - - QVERIFY(dep1.qtModules() == (DeployCore::QtModule::QtGuiModule | - DeployCore::QtModule::QtHelpModule)); - - - -} - -void deploytest::testQmlScaner() { - - // qt5 - auto qmlRoot = QFileInfo(TestQtDir + "/qml").absoluteFilePath(); - QML *scaner = new QML(qmlRoot, QtMajorVersion::Qt5); - auto imports = scaner->extractImportsFromFile(":/qmlFile.qml"); - - scaner->scanQmlTree(qmlRoot); - - QSet results = { - {qmlRoot + "/QtQuick.2/"}, - {qmlRoot + "/QtQuick/Controls.2/"}, - {qmlRoot + "/QtQuick/Controls.2/Material/"}, - {qmlRoot + "/QtQuick/Layouts/"}, - }; - - QVERIFY(results.size() == imports.size()); - - for (const auto &import: qAsConst(imports)) { - auto path = scaner->getPathFromImport(import); - QVERIFY(results.contains(path)); - } - - - scaner->setQtVersion(QtMajorVersion::Qt6); - - // qt6 - - results = { - {qmlRoot + "/QtQuick"}, - {qmlRoot + "/QtQuick/Controls"}, - {qmlRoot + "/QtQuick/Controls/Material"}, - {qmlRoot + "/QtQuick/Layouts"}, - }; - - imports = scaner->extractImportsFromFile(":/qmlFileQt6.qml"); - - QVERIFY(results.size() == imports.size()); - - for (const auto &import: qAsConst(imports)) { - auto path = scaner->getPathFromImport(import); - QVERIFY(results.contains(path)); - } - - imports = scaner->extractImportsFromFile(":/qmlFile.qml"); - - QVERIFY(results.size() == imports.size()); - - for (const auto & import: qAsConst(imports)) { - auto path = scaner->getPathFromImport(import); - QVERIFY(results.contains(path)); - } - - // qt5 - scaner->setQtVersion(QtMajorVersion::Qt5); - - results = { - {qmlRoot + "/QtQuick.2/"}, - {qmlRoot + "/QtQuick/Window.2/"}, - {qmlRoot + "/QtQuick/Layouts/"}, - {qmlRoot + "/Qt/labs/folderlistmodel/"}, - {qmlRoot + "/QtQuick/VirtualKeyboard/Settings/"}, - {qmlRoot + "/QtQuick/VirtualKeyboard/Styles/"}, - }; - - imports = scaner->extractImportsFromQmlModule(":/qmlDir"); - - QVERIFY(results.size() == imports.size()); - - for (const auto &import: qAsConst(imports)) { - auto path = scaner->getPathFromImport(import); - QVERIFY(results.contains(path)); - } - - // qt6 - scaner->setQtVersion(QtMajorVersion::Qt6); - - results = { - {qmlRoot + "/QtQuick"}, - {qmlRoot + "/QtQuick/Window"}, - {qmlRoot + "/QtQuick/Layouts"}, - {qmlRoot + "/Qt/labs/folderlistmodel"}, - {qmlRoot + "/QtQuick/VirtualKeyboard/Settings"}, - {qmlRoot + "/QtQuick/VirtualKeyboard/Styles"}, - }; - - imports = scaner->extractImportsFromQmlModule(":/qmlDir"); - - QVERIFY(results.size() == imports.size()); - - for (const auto &import: qAsConst(imports)) { - auto path = scaner->getPathFromImport(import); - QVERIFY(results.contains(path)); - } - -} - -void deploytest::testPrefix() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QFile f("./" + DISTRO_DIR + "/bin/TestOnlyC"); - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/package/TestOnlyC.sh", - "./" + DISTRO_DIR + "/package/bin/TestOnlyC", - "./" + DISTRO_DIR + "/package/bin/qt.conf" - }); - QString target1 = TestBinDir + "TestOnlyC"; - -#else - QFile f("./" + DISTRO_DIR + "/TestOnlyC.exe"); - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/package/TestOnlyC.exe", - "./" + DISTRO_DIR + "/package/TestOnlyC.bat", - "./" + DISTRO_DIR + "/package/qt.conf"}); - QString target1 = TestBinDir + "TestOnlyC.exe"; - -#endif - QString bin = target1; - - comapareTree = TestModule.replace(comapareTree, {{"package","prefix"}}); - - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", "/package/;TestOn", - "-prefix", "package;prefix"}, &comapareTree); -} - -void deploytest::testallowEmptyPackages() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; -#else - QString bin = TestBinDir + "TestOnlyC.exe"; -#endif - runTestParams({"-bin", bin, "force-clear", - "-prefix", "package;prefix"}, nullptr, false, false, - exitCodes::PrepareError); - - runTestParams({"-bin", bin, "force-clear", - "-prefix", "package;prefix", - "allowEmptyPackages"}); -} - -void deploytest::testEmptyPackages() { - TestUtils utils; - auto comapareTree = TestModule.onlyC(); - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; -#else - QString bin = TestBinDir + "TestOnlyC.exe"; -#endif - - runTestParams({"-bin", bin, "force-clear", - "-prefix", "package;prefix"}, nullptr, false, false, - exitCodes::PrepareError); - - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", "/package/;NONE", - "-libDir", TestQtDir + "bin", - "-prefix", "package;prefix", - "allowEmptyPackages"}, &comapareTree); -} - -void deploytest::testRunScripts() { - TestUtils utils; - auto comapareTree = TestModule.onlyC(); - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - - QFile f(":/testResurces/testRes/customRunScript.sh"); - QVERIFY(f.open(QIODevice::ReadOnly)); - auto etalonData = f.readAll(); - f.close(); - - runTestParams({"-bin", bin, - "force-clear", - "-libOut", "lib", - "-runScript", "TestOnlyC;:/testResurces/testRes/customRunScript.sh"}, &comapareTree); - - f.setFileName(DISTRO_DIR + "/TestOnlyC.sh"); - QVERIFY(f.open(QIODevice::ReadOnly)); - auto deployData = f.readAll(); - - QVERIFY(deployData == etalonData); -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - - QFile f(":/testResurces/testRes/customRunScript.sh"); - QVERIFY(f.open(QIODevice::ReadOnly)); - auto etalonData = f.readAll(); - f.close(); - - runTestParams({"-bin", bin, - "force-clear", - "-libOut", "lib", - "-runScript", "TestOnlyC.exe;:/testResurces/testRes/customRunScript.sh"}, nullptr); - - f.setFileName(DISTRO_DIR + "/TestOnlyC.bat"); - QVERIFY(f.open(QIODevice::ReadOnly)); - auto deployData = f.readAll(); - - QVERIFY(deployData == etalonData); -#endif - -} - -void deploytest::testOverridingDefaultTemplateDEB() -{ - TestUtils utils; - - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC" + "," + TestBinDir + "TestCPPOnly"; - QString qmake = TestQtDir + "bin/qmake"; - - QDir tempalteDir("temaplate"); - if (!tempalteDir.isEmpty()) { - tempalteDir.removeRecursively(); - }; - - auto comapareTree = utils.createTree( - { - "temaplate/defaultDEBTemplate/Test/DEBIAN/control", - "temaplate/defaultDEBTemplate/Test/DEBIAN/postinst", - "temaplate/defaultDEBTemplate/Test/DEBIAN/prerm" - }); - QFile appScript("temaplate/defaultDEBTemplate/Test/DEBIAN/control"); - appScript.remove(); - - runTestParams( - {"force-clear", - "getDefaultTemplate", - "-name", "Test", - "deb", - "-targetDir", "temaplate", - "-targetPackage", "MyApp" - }, &comapareTree); - - comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/Test.deb", - "./" + DISTRO_DIR + "/Test.deb.md5", - - }); - - runTestParams( - {"force-clear", - "-deb", "temaplate/defaultDEBTemplate", - "-targetPackage", "MyApp", - "-name", "Test", - "-qmake", qmake - }, &comapareTree, false, false); - - - QVERIFY(appScript.open(QIODevice::WriteOnly)); - QVERIFY(appScript.write(QByteArray{"ERROR"})); - appScript.close(); - - runTestParams( - {"-bin", bin, - "force-clear", - "-deb", "temaplate/defaultDEBTemplate", - "-targetPackage", "MyApp", - "-name", "Test", - "-qmake", qmake - }, nullptr, false, false, exitCodes::PackingError); -#endif - -} - -void deploytest::testOverridingDefaultTemplateQIF() { - TestUtils utils; - // Prepare bin and qmake values -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC" + "," + TestBinDir + "TestCPPOnly"; - QString qmake = TestQtDir + "bin/qmake"; - -#else - QString bin = TestBinDir + "TestOnlyC.exe" + "," + TestBinDir + "TestCPPOnly.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; - -#endif - QDir tempalteDir("temaplate"); - if (!tempalteDir.isEmpty()) { - tempalteDir.removeRecursively(); - }; - - // QIF case. prepare default template. - auto comapareTree = utils.createTree( - { - "temaplate/defaultQIFWTemplate/config/config.xml", - "temaplate/defaultQIFWTemplate/config/controlScript.qs", - "temaplate/defaultQIFWTemplate/packages/MyApp/meta/installscript.qs", - "temaplate/defaultQIFWTemplate/packages/MyApp/meta/package.xml" - }); - QFile appScript("temaplate/defaultQIFWTemplate/packages/MyApp/meta/installscript.qs"); - appScript.remove(); - - // This command shold be deploy default template in the template folder - runTestParams( - {"-bin", bin, - "force-clear", - "getDefaultTemplate", - "-name", "Test", - "qif", - "-targetDir", "temaplate", - "-targetPackage", "MyApp" - }, &comapareTree); - -#ifdef Q_OS_UNIX - comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/InstallerTest.run", - "./" + DISTRO_DIR + "/InstallerTest.run.md5", - }); - -#else - comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/InstallerTest.exe", - "./" + DISTRO_DIR + "/InstallerTest.exe.md5", - }); - -#endif - - // check deploy application with custom template - runTestParams( - {"-bin", bin, - "force-clear", - "-qif", "temaplate/defaultQIFWTemplate", - "-targetPackage", "MyApp", - "-name", "Test", - "-qmake", qmake, - "qifFromSystem" - }, &comapareTree, false, false); - - QVERIFY(appScript.open(QIODevice::WriteOnly)); - QVERIFY(appScript.write(QByteArray{"ERROR"})); - appScript.close(); - - // Shold be failde because we added error string into template files. - runTestParams( - {"-bin", bin, - "force-clear", - "-qif", "temaplate/defaultQIFWTemplate", - "-targetPackage", "MyApp", - "-name", "Test", - "-qmake", qmake, - "qifFromSystem" - }, nullptr, false, false, exitCodes::PackingError); - - - -} - -void deploytest::testDeployGeneralFiles() { - TestUtils utils; - - QString bin = TestBinDir + "/../../CMakeLists.txt"; - - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/bin/CMakeLists.txt", - "./" + DISTRO_DIR + "/bin/qt.conf", - - }); - - runTestParams( - {"-bin", bin, - "-binOut", "bin", - "force-clear" - }, &comapareTree); -} - -void deploytest::testTr() { - TestUtils utils; -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - -#endif - - runTestParams({"-bin", bin, "clear" , - "-tr", ":/testResurces/testRes/TestTr.qm",}); - - QVERIFY(QFile::exists("./" + DISTRO_DIR + "/translations/TestTr.qm")); - - runTestParams({"-bin", bin, "clear" , - "-tr", ":/testResurces/testRes/"}); - - QVERIFY(QFile::exists("./" + DISTRO_DIR + "/translations/TestTr.qm")); -} - -void deploytest::testVirtualKeyBoard() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "basic"; - QString qmake = TestQtDir + "bin/qmake"; -#else - QString bin = TestBinDir + "basic.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; -#endif - auto comapareTree = TestModule.qmlVirtualKeyBoadrLibs(); - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-qmlDir", TestBinDir + "/../virtualkeyboard"}, &comapareTree); -} - -void deploytest::testIcons() { - TestUtils utils; - - auto initTargets = [](ConfigParser * deploy, const QStringList& params) { - QVERIFY(QuasarAppUtils::Params::parseParams(params)); - - auto bin = QuasarAppUtils::Params::getArg("bin"). - split(DeployCore::getSeparator(0), splitbehavior); - - - QVERIFY(deploy->setTargets(bin)); - - deploy->configureTargets(); - }; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - QStringList binMulti = {TestBinDir + "TestOnlyC" , TestBinDir + "TestCPPOnly"}; - -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - QStringList binMulti = {TestBinDir + "TestOnlyC.exe" , TestBinDir + "TestCPPOnly.exe"}; - -#endif - - FileManager file; - DependenciesScanner scan; - Packing pac(&file); - PluginsParser _pluginParser; - - - // Test default icons - ConfigParser *deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - - initTargets(deploy, {"-bin", bin, - "force-clear", - }); - - auto targetsMap = deploy->_config.getTargetsListByFilter("TestOnlyC"); - auto targetinfo = targetsMap.begin().value(); - QVERIFY(targetinfo->getName().contains("TestOnlyC")); - auto icon = QFileInfo(targetinfo->getIcon()); - -#ifdef Q_OS_UNIX - QVERIFY(icon.fileName() == "Icon.png"); -#else - QVERIFY(icon.fileName() == "Icon.ico"); - -#endif - delete deploy; - - // Test multiple targets icons (sets for all targets on icon) - deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - - initTargets(deploy, {"-bin", binMulti.join(","), - "force-clear", - "-icon", ":/testResurces/testRes/TestIcon.png", - }); - - for (const auto &target : qAsConst(binMulti)) { - QFileInfo tarInfo(target); - - targetsMap = deploy->_config.getTargetsListByFilter(tarInfo.baseName()); - targetinfo = targetsMap.begin().value(); - QVERIFY(targetinfo->getName().contains(tarInfo.baseName())); - icon = QFileInfo(targetinfo->getIcon()); - - QVERIFY(icon.fileName() == "TestIcon.png"); - } - - delete deploy; - - - // Test multiple targets icons (sets only one icon) - deploy = new ConfigParser(&file, &_pluginParser, &scan, &pac); - - initTargets(deploy, {"-bin", binMulti.join(","), - "force-clear", - "-icon", "TestOnlyC;:/testResurces/testRes/TestIcon.png", - }); - - - targetsMap = deploy->_config.getTargetsListByFilter("TestOnlyC"); - targetinfo = targetsMap.begin().value(); - QVERIFY(targetinfo->getName().contains("TestOnlyC")); - icon = QFileInfo(targetinfo->getIcon()); - - QVERIFY(icon.fileName() == "TestIcon.png"); - - - delete deploy; - - // manual tests -#ifdef QT_DEBUG -#ifdef Q_OS_UNIX - bin = TestBinDir + "TestOnlyC," + TestBinDir + "TestCPPOnly"; - - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/InstallerTest.run", - "./" + DISTRO_DIR + "/InstallerTest.run.md5", - }); - -#else - bin = TestBinDir + "TestOnlyC.exe," + TestBinDir + "TestCPPOnly.exe"; - - auto comapareTree = utils.createTree({ - "./" + DISTRO_DIR + "/InstallerTest.exe", - "./" + DISTRO_DIR + "/InstallerTest.exe.md5", - - }); - -#endif - - runTestParams({"-bin", bin, "clear" , - "qif", "qifFromSystem", "-name", "Test", - "-targetPackage", "testPackage;TestOnlyC;TestCPPOnly", - "-icon", "TestOnlyC;:/testResurces/testRes/TestIcon.png,TestCPPOnly;:/testResurces/testRes/TestTr.qm"}, &comapareTree, true); - -#endif -} - -void deploytest::testPathUtils() { - - // test getName - QMap cases = { - {"",""}, - {"test","test"}, - {"t","t"}, - {"/","/"}, - {"/test","test"}, - {"/t","t"}, - {"/test/","test"}, - {"/t/","t"}, - - {"/check/test","test"}, - {"/check/t","t"}, - {"/check/test/","test"}, - {"/check/t/","t"}, - - {"C:\\","C:"}, - {"\\","/"}, - {"\\test","test"}, - {"\\t","t"}, - {"\\test\\","test"}, - {"\\t\\","t"}, - - }; - - for (auto it = cases.begin(); it != cases.end(); ++it) { - if (PathUtils::getName(it.key()) != it.value()) - QVERIFY(false); - } - - struct Result { - QString result; - QString newPath; - }; - - // test popItem - QMap popItemCases = { - {"", {"", ""}}, - {"test", {"test", ""}}, - {"t", {"t", ""}}, - {"/", {"/", ""}}, - {"/test", {"test", "/"}}, - {"/t", {"t", "/"}}, - {"/test/", {"test", "/"}}, - {"/t/", {"t", "/"} }, - - {"/check/test", {"test", "/check/"}}, - {"/check/t", {"t", "/check/"}}, - {"/check/test/", {"test", "/check/"}}, - {"/check/t/", {"t", "/check/"}}, - - {"C:\\", {"C:", ""}}, - {"\\", {"/", ""}}, - {"\\test", {"test", "/"}}, - {"\\t", {"t", "/"}}, - {"\\test\\", {"test", "/"}}, - {"\\t\\", {"t", "/"}}, - - }; - - for (auto it = popItemCases.begin(); it != popItemCases.end(); ++it) { - QString path = it.key(); - QString result = PathUtils::popItem(path); - if (path != it.value().newPath || result != it.value().result) - QVERIFY(false); - } -} - -void deploytest::testBinPrefix() { - TestUtils utils; - -#ifdef Q_OS_UNIX - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.sh", - "./" + DISTRO_DIR + "/bin/TestOnlyC", - "./" + DISTRO_DIR + "/bin/qt.conf" - }); - QString target = TestBinDir + "TestOnlyC"; - QString targetWithoutPrefix = "TestOnlyC"; - -#else - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - "./" + DISTRO_DIR + "/qt.conf"}); - QString target = TestBinDir + "TestOnlyC.exe"; - QString targetWithoutPrefix = "TestOnlyC.exe"; - -#endif - - runTestParams({"-bin", target, "force-clear"}, &comapareTree); - - runTestParams({"-bin", targetWithoutPrefix, - "-binPrefix", TestBinDir, - "force-clear"}, &comapareTree); - -} - -void deploytest::testMd5() { - // This test will check hashes - - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - auto outFile = "./" + DISTRO_DIR + "/InstallerTestOnlyC.run"; - -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - auto outFile = "./" + DISTRO_DIR + "/InstallerTestOnlyC.exe"; - -#endif - - auto comapareTreeqif = utils.createTree( - { - outFile, - outFile + ".md5" - }); - - // Run deploy installer - runTestParams({"-bin", bin, - "force-clear", - "qif", - "qifFromSystem"}, &comapareTreeqif); - - QFile file(outFile); - QVERIFY(file.open(QIODevice::ReadOnly)); - auto binaryData = file.readAll(); - file.close(); - - file.setFileName(outFile + ".md5"); - QVERIFY(file.open(QIODevice::ReadOnly)); - auto hash = file.readAll(); - file.close(); - - // Compare hash sum of the installer with realy hash sum of the object. - QVERIFY(QCryptographicHash::hash(binaryData, QCryptographicHash::Md5).toHex() == hash); - - - comapareTreeqif = utils.createTree( - { - outFile, - }); - - // Check noHashSum option. CQtDeployer must be skip calculating a hash sum of an installer. - runTestParams({"-bin", bin, - "force-clear", - "noHashSum", - "qif", - "qifFromSystem"}, &comapareTreeqif); -} - -void deploytest::testDisableShortcuts() { - - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; -#else - QString bin = TestBinDir + "TestOnlyC.exe"; -#endif - - auto cb = [](const DeployConfig * config){ - const auto list = config->getTargetsListByFilter("TestOnlyC"); - // Check shrtcut option. all targets should be return false. - for (auto target: list) { - QVERIFY(!target->getShortCut()); - } - }; - - // Run deploy installer - runTestParams({"-bin", bin, "clear", - "-disableShortCut", "TestOnlyC", - "qif", "qifFromSystem"}, - nullptr, - false, - false, - exitCodes::Good, - cb); - - - -} - -void deploytest::testDisableRunScripts() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; -#else - QString bin = TestBinDir + "TestOnlyC.exe"; -#endif - - auto comapareTreeqif = TestModule.onlyC(); - comapareTreeqif -= utils.createTree({DISTRO_DIR + "/TestOnlyC.sh", - DISTRO_DIR + "/TestOnlyC.bat"}); - // Run deploy installer - runTestParams({"-bin", bin, "clear", "-libDir", TestQtDir + "/bin", - "-disableRunScript", "TestOnlyC"}, &comapareTreeqif); -} - -void deploytest::testQifOut() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; -#else - QString bin = TestBinDir + "TestOnlyC.exe"; -#endif - -#ifdef Q_OS_UNIX - auto result = utils.createTree({{DISTRO_DIR + "/QIF_OUT.exe"}, {DISTRO_DIR + "/QIF_OUT.exe.md5"}, - {DISTRO_DIR + "/DEB_OUT.deb"}, {DISTRO_DIR + "/DEB_OUT.deb.md5"}, - {DISTRO_DIR + "/ZIP_OUT.zip"}, {DISTRO_DIR + "/ZIP_OUT.zip.md5"}}); - - // Run deploy installer - runTestParams({"-bin", bin, "clear", - "qif", "-qifOut", "QIF_OUT.exe", - "deb", "-debOut", "DEB_OUT.deb", - "zip", "-zipOut", "ZIP_OUT.zip"}, &result); -#else - auto result = utils.createTree({{DISTRO_DIR + "/QIF_OUT.exe"}, {DISTRO_DIR + "/QIF_OUT.exe.md5"}, - {DISTRO_DIR + "/ZIP_OUT.zip"}, {DISTRO_DIR + "/ZIP_OUT.zip.md5"}}); - - // Run deploy installer - runTestParams({"-bin", bin, "clear", - "qif", "-qifOut", "QIF_OUT.exe", - "zip", "-zipOut", "ZIP_OUT.zip"}, &result); -#endif -} - -void deploytest::testIgnoreEnvWithLibDir() { -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; -#else - QString bin = TestBinDir + "TestOnlyC.exe"; -#endif - - QVERIFY(QDir().mkdir("libDirtest")); - - // Run deploy installer - runTestParams({"-bin", bin, "clear", - "-targetDir", "./libDirtest", - "-libDir", "./libDirtest"}, nullptr, false, false, - exitCodes::PrepareError); - - QVERIFY(QDir().rmdir("libDirtest")); -} - -void deploytest::testInstallDirsOptions() { -#ifdef QT_DEBUG -#ifdef Q_OS_UNIX - QStringList binMulti = {TestBinDir + "TestOnlyC" , TestBinDir + "TestCPPOnly"}; - -#else - QStringList binMulti = {TestBinDir + "TestOnlyC.exe" , TestBinDir + "TestCPPOnly.exe"}; - -#endif - - - runTestParams({"-bin", binMulti.join(","), "clear", - "qif", "deb", - "-targetPackage", "pkg;TestCPPOnly", - "-installDirDeb", "pkg;/var", - "-installDirQIFW", "/opt"}); - -#endif -} - -void deploytest::testQIFResources() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = {TestBinDir + "TestOnlyC"}; - - auto result = utils.createTree({{DISTRO_DIR + "/InstallerTestOnlyC.run"}, - {DISTRO_DIR + "/InstallerTestOnlyC.run.md5"}}); -#else - QString bin = {TestBinDir + "TestOnlyC.exe"}; - - auto result = utils.createTree({{DISTRO_DIR + "/InstallerTestOnlyC.exe"}, - {DISTRO_DIR + "/InstallerTestOnlyC.exe.md5"}}); -#endif - - - auto templateDir = TestBinDir + "/../../UnitTests/testRes/QIFCustomTemplate"; - runTestParams({ - "-bin", bin, - "clear", - "qif", - "-qifConfig", templateDir + "/customconfig.xml", - "-qifPackages", templateDir + "/custompackages", - "-qifResources", templateDir + "customRes.qrc" - }, &result - ); - -} - -void deploytest::testCustomPlatform() { - TestUtils utils; - - auto compareTree = TestModule.onlyC(); - -#ifdef Q_OS_UNIX - QString bin = {TestBinDir + "TestOnlyC"}; - QString platform = "linux_x86_64"; - -#else - QString bin = {TestBinDir + "TestOnlyC.exe"}; - QString platform = "win_x86_64"; - - compareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - "./" + DISTRO_DIR + "/qt.conf" - } - ); - -#endif - - runTestParams({ - "-bin", bin, - "clear", - "-platform", platform, - }, &compareTree - ); - - - - runTestParams({ - "-bin", bin, - "clear", - "-platform", "GeneralFile", - }, nullptr, false, false, exitCodes::PrepareError - ); -} - -void deploytest::testQifArchiveFormat() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = {TestBinDir + "TestOnlyC"}; - - auto result = utils.createTree({{DISTRO_DIR + "/InstallerTestOnlyC.run"}, - {DISTRO_DIR + "/InstallerTestOnlyC.run.md5"}}); -#else - QString bin = {TestBinDir + "TestOnlyC.exe"}; - - auto result = utils.createTree({{DISTRO_DIR + "/InstallerTestOnlyC.exe"}, - {DISTRO_DIR + "/InstallerTestOnlyC.exe.md5"}}); -#endif - - - runTestParams({ - "-bin", bin, - "qifFromSystem", - "clear", - "qif", - "-qifArchiveFormat", "zip" - }, &result - ); -} - -void deploytest::testQifBinaryCreator() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = {TestBinDir + "TestOnlyC"}; -#else - QString bin = {TestBinDir + "TestOnlyC.exe"}; -#endif - - { - QuasarAppUtils::Params::parseParams({ - "-bin", bin, - "qifFromSystem", - "clear", - "qif", - "-binarycreator", "test testValue" - }); - Deploy deploy; - QVERIFY(deploy.prepare()); - FileManager fm; - QIF qif(&fm); - - auto command = qif.runCmd(); - QVERIFY(command.size() == 1); - QVERIFY(command.first().command == "test"); - QVERIFY(command.first().arguments.contains("testValue")); - } - - { - QuasarAppUtils::Params::parseParams({ - "-bin", bin, - "qifFromSystem", - "clear", - "qif", - "-binarycreator", "test" - }); - Deploy deploy; - QVERIFY(deploy.prepare()); - FileManager fm; - QIF qif(&fm); - - auto command = qif.runCmd(); - QVERIFY(command.size() == 1); - QVERIFY(command.first().command == "test"); - } - - -} - -void deploytest::customTest() { - //runTestParams({"-confFile", "", - // "qifFromSystem"}); -} - -void deploytest::testQmlExtrct() { - QmlCreator creator("./"); - auto imports = creator.getQmlImports(); - - auto qmlFiles = creator.getCopyedQml(); - - - QML scaner("./", QtMajorVersion::Qt5); - - - for (const auto &file : qAsConst(qmlFiles)) { - - - auto fileImports = scaner.extractImportsFromFile(file); - - for (const auto &fil : imports.value(file)) { - QVERIFY(fileImports.contains(fil, Qt::CaseInsensitive)); - } - - } -} - -void deploytest::testDistroStruct() { - DistroStruct distro; - - auto cases = QList>{ - {"", "/"}, - {"/", "/"}, - {"/res","/../"}, - {"/res/","/../"}, - {"/res/type","/../../"}, - {"/res/type/","/../../"}, - {"res/type","../../"}, - {"res/type/","../../"}, - {"res//type/","../../"}, - {"res////type/","../../"}, - {"//res///type/////","/../../"}, - {"\\", "/"}, - {"\\res","/../"}, - {"\\res\\","/../"}, - {"\\res\\type","/../../"}, - {"\\res\\type\\","/../../"}, - {"res\\type","../../"}, - {"res\\type\\","../../"}, - {"res\\\\type\\","../../"}, - {"res\\\\\\\\type\\","../../"}, - {"\\\\res\\\\\\type\\\\\\\\\\","/../../"}, - }; - - for (const auto &i: qAsConst(cases)) { - if (distro.getRelativePath(i.first) != i.second) - QVERIFY(false); - } - - distro = DistroStruct(); - - distro.setTrOutDir("/tr/"); - QVERIFY(distro.getTrOutDir() == "/tr/"); - - - distro.setTrOutDir("/tr"); - QVERIFY(distro.getTrOutDir() == "/tr/"); - - distro.setTrOutDir("tr"); - QVERIFY(distro.getTrOutDir() == "/tr/"); - - -} - -void deploytest::testRelativeLink() { - auto cases = QList>{ - {"", "", "./"}, - {"/media", "/etc", "./../etc/"}, - {"/media///", "/etc///", "./../etc/"}, - {"/media/etc/usr", "/media/etc", "./../"}, - {"/media/etc", "/media/etc/usr", "./usr/"}, - - {"C:/", "C:/", "./"}, - {"C:\\", "C:/", "./"}, - {"C:/", "C:\\", "./"}, - - {"C:/media", "C:/etc", "./../etc/"}, - {"C:/media//\\", "C:/etc///", "./../etc/"}, - {"C:/media/etc/usr", "C:/media/etc", "./../"}, - {"C:/media\\etc", "C:/media/etc/usr", "./usr/"}, - {"C:/media/etc", "D:/media/etc/usr", "D:/media/etc/usr"}, - -}; - - for (const auto &i: qAsConst(cases)) { - if (PathUtils::getRelativeLink(i[0], i[1]) != i[2]) - QVERIFY(false); - } - - for (int i = 1; i < cases.size() - 1; i++) { - if (!PathUtils::isAbsalutPath(cases[i][0])) - QVERIFY(false); - if (PathUtils::isAbsalutPath(cases[i][2])) - QVERIFY(false); - - } -} - -void deploytest::testCheckQt() { - - Deploy *deployer = new Deploy(); - QuasarAppUtils::Params::parseParams({"-bin", TestBinDir, "clear", - "noCheckRPATH", "noCheckPATH", "noQt"}); - QVERIFY(deployer->prepare()); - - - auto cases = QList>{ - {TestQtDir + "/", QtMajorVersion::NoQt}, - {TestQtDir + "", QtMajorVersion::NoQt}, - {TestQtDir + "/bin/file1", QtMajorVersion::NoQt}, - {TestQtDir + "/lib/file12.so", QtMajorVersion::NoQt}, - {TestQtDir + "/resurces/file13.dll", QtMajorVersion::NoQt}, - {TestQtDir + "/libexec/f", QtMajorVersion::NoQt}, - {TestQtDir + "/mkspecs", QtMajorVersion::NoQt}, - {TestQtDir + "/qml", QtMajorVersion::NoQt}, - {TestQtDir + "/plugins", QtMajorVersion::NoQt}, - {TestQtDir + "/file", QtMajorVersion::NoQt}, - - {TestQtDir + "\\", QtMajorVersion::NoQt}, - {TestQtDir + "", QtMajorVersion::NoQt}, - {TestQtDir + "\\bin\\file1", QtMajorVersion::NoQt}, - {TestQtDir + "\\lib\\file12", QtMajorVersion::NoQt}, - {TestQtDir + "\\resurces\\file13", QtMajorVersion::NoQt}, - {TestQtDir + "\\libexec\\f.so", QtMajorVersion::NoQt}, - {TestQtDir + "\\mkspecs.dll", QtMajorVersion::NoQt}, - {TestQtDir + "\\qml", QtMajorVersion::NoQt}, - {TestQtDir + "\\plugins", QtMajorVersion::NoQt}, - {TestQtDir + "\\file", QtMajorVersion::NoQt}, - - }; - - for (const auto &i: qAsConst(cases)) { - QVERIFY(DeployCore::isQtLib(i.first) == i.second); - } - delete deployer; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestQMLWidgets"; - QString qmake = TestQtDir + "bin/qmake"; - -#else - QString bin = TestBinDir + "TestQMLWidgets.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; -#endif - - deployer = new Deploy(); - QuasarAppUtils::Params::parseParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-qmlDir", TestBinDir + "/../TestQMLWidgets"}); - QVERIFY(deployer->prepare()); - - - cases = QList>{ - {TestQtDir + "/", QtMajorVersion::NoQt}, - {TestQtDir + "", QtMajorVersion::NoQt}, - {TestQtDir + "/bin/file1", QtMajorVersion::NoQt}, - {TestQtDir + "/lib/file12", QtMajorVersion::NoQt}, - {TestQtDir + "/lib/file12", QtMajorVersion::NoQt}, - - {TestQtDir + "/mkspecs", QtMajorVersion::NoQt}, - {TestQtDir + "/qml", QtMajorVersion::NoQt}, - {TestQtDir + "/plugins", QtMajorVersion::NoQt}, - {TestQtDir + "/file", QtMajorVersion::NoQt}, - - {TestQtDir + "\\", QtMajorVersion::NoQt}, - {TestQtDir + "", QtMajorVersion::NoQt}, - {TestQtDir + "\\lib\\file12", QtMajorVersion::NoQt}, - {TestQtDir + "\\libexec\\fQt", QtMajorVersion::NoQt}, - {TestQtDir + "\\mkspecs", QtMajorVersion::NoQt}, - {TestQtDir + "\\qml", QtMajorVersion::NoQt}, - {TestQtDir + "\\plugins", QtMajorVersion::NoQt}, - {TestQtDir + "\\file", QtMajorVersion::NoQt}, - - {TestQtDir + "/bin/file1Qt4.so", QtMajorVersion::Qt4}, - {TestQtDir + "/resources/Qt4file13.so", QtMajorVersion::Qt4}, - {TestQtDir + "/libexec/Qt4f.dll", QtMajorVersion::Qt4}, - {TestQtDir + "\\bin\\Qt4file1.dll", QtMajorVersion::Qt4}, - {TestQtDir + "\\resources\\fileQt413.dll", QtMajorVersion::Qt4}, - - {TestQtDir + "/bin/file1Qt5.so", QtMajorVersion::Qt5}, - {TestQtDir + "/resources/Qt5file13.so", QtMajorVersion::Qt5}, - {TestQtDir + "/libexec/Qt5f.dll", QtMajorVersion::Qt5}, - {TestQtDir + "\\bin\\Qt5file1.dll", QtMajorVersion::Qt5}, - {TestQtDir + "\\resources\\fileQt513.dll", QtMajorVersion::Qt5}, - - {TestQtDir + "/bin/file1Qt6.so", QtMajorVersion::Qt6}, - {TestQtDir + "/resources/Qt6file13.so", QtMajorVersion::Qt6}, - {TestQtDir + "/libexec/Qt6f.dll", QtMajorVersion::Qt6}, - {TestQtDir + "\\bin\\Qt6file1.dll", QtMajorVersion::Qt6}, - {TestQtDir + "\\resources\\fileQt613.dll", QtMajorVersion::Qt6}, - - }; - - for (const auto &i: qAsConst(cases)) { - auto dexription = QString("The isQtLib(%0) function should be return %1").arg( - i.first).arg(i.second); - QVERIFY2(DeployCore::isQtLib(i.first) == i.second, dexription.toLatin1().data()); - } - - delete deployer; -} - -void deploytest::testSetTargetDir() { - - FileManager file; - DependenciesScanner scan; - Packing pac(&file); - PluginsParser _plugins; - ConfigParser dep(&file, &_plugins, &scan, &pac); - - dep.setTargetDir(); - - QVERIFY(dep.config()->getTargetDir() == QFileInfo("./" + DISTRO_DIR + "").absoluteFilePath()); - dep.setTargetDir("./ff"); - QVERIFY(dep.config()->getTargetDir() == QFileInfo("./ff").absoluteFilePath()); - - QStringList argv = {"-targetDir", "./" + DISTRO_DIR + "2"}; - - QuasarAppUtils::Params::parseParams(argv); - - dep.setTargetDir(); - QVERIFY(dep.config()->getTargetDir() == QFileInfo("./" + DISTRO_DIR + "2").absoluteFilePath()); - dep.setTargetDir("./ff"); - QVERIFY(dep.config()->getTargetDir() == QFileInfo("./" + DISTRO_DIR + "2").absoluteFilePath()); - -} - -void deploytest::testZip() { - TestUtils utils; - - ZipCompresser zip; - auto befor = utils.getTree("./test"); - - QVERIFY(zip.compress("./test", "./arr.zip")); - QVERIFY(QDir("./test").removeRecursively()); - QVERIFY(zip.extract("./arr.zip", "./test")); - - auto after = utils.getTree("./test"); - - QVERIFY(utils.compareTree(befor, after).size() == 0); - - -} - -void deploytest::runTestParams(QStringList list, - QSet* tree, - bool noWarnings, bool onlySize, - exitCodes exitCode, - const std::function &cb) { - - QuasarAppUtils::Params::parseParams(list); - - Deploy deploy; - int code = deploy.run(); - if (code != exitCode) { - qDebug() << "Needed exit Code = " << exitCode; - qDebug() << "Exit Code = " << code; - - QVERIFY(false && "exit code not valid"); - } - - if (tree) { - checkResults(*tree, noWarnings, onlySize); - } - - if (cb) - cb(DeployCore::_config); -} - -void deploytest::checkResults(const QSet &tree, - bool noWarnings, - bool onlySize) { - TestUtils utils; - - QVERIFY(DeployCore::_config); - QVERIFY(!DeployCore::_config->getTargetDir().isEmpty()); - - auto resultTree = utils.getTree(DeployCore::_config->getTargetDir()); - -#ifdef Q_OS_WIN - // Remove all API-MS-Win libs, because each OS Windows have a own bundle of this api libs. - // See the https://github.com/QuasarApp/CQtDeployer/issues/481#issuecomment-755156875 post for more information. - resultTree = TestModule.ignoreFilter(resultTree, "API-MS-Win"); - -#endif - - - auto comapre = utils.compareTree(resultTree, tree); - - if (onlySize) { - QVERIFY(resultTree.size() > tree.size()); - return; - } - - if (comapre.size() != 0) { - - bool bug = false; - QJsonObject comapreResult; - - for (auto i = comapre.begin(); i != comapre.end(); ++i) { - - if (i.value() == 1) { - comapreResult[ i.key()] = "Added unnecessary file"; - qCritical() << "added unnecessary file : " + i.key(); - bug = true; - } else if (filesTree.contains(QFileInfo(i.key()).fileName())) { - comapreResult[ i.key()] = "Missing"; - qCritical() << "Missing file : " + i.key(); - bug = true; - } else if (noWarnings) { - comapreResult[ i.key()] = " not exits in qt Dir"; - - qCritical() << "File : " + i.key() + " not exits in qt Dir"; - bug = true; - } else { - comapreResult[ i.key()] = " not exits in qt Dir"; - qWarning() << "File : " + i.key() + " not exits in qt Dir"; - } - } - - if (!bug) { - return; - } - - QJsonObject obj; - for (const auto &i : qAsConst(resultTree)) { - obj[i]; - } - - QJsonDocument doc(obj); - - QFile lasttree("./LastTree.json"); - lasttree.open(QIODevice::WriteOnly| QIODevice::Truncate); - - lasttree.write(doc.toJson()); - lasttree.close(); - - lasttree.setFileName("./CompareTree.json"); - lasttree.open(QIODevice::WriteOnly| QIODevice::Truncate); - - lasttree.write(QJsonDocument(comapreResult).toJson()); - lasttree.close(); - - QVERIFY2(false, "runTestParams fail"); - - - } - -} - -void deploytest::createTree(const QStringList &tree) { - for (const auto& dir : tree) { - QDir().mkpath(dir); - } -} - -void deploytest::costomScript() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QFile f("./" + DISTRO_DIR + "/bin/TestOnlyC"); - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/bin/TestOnlyC", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/TestOnlyC.sh"}); - QString bin = TestBinDir + "TestOnlyC"; - QString scriptPath = "./" + DISTRO_DIR + "/TestOnlyC.sh"; - -#else - QFile f("./" + DISTRO_DIR + "/TestOnlyC.exe"); - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - "./" + DISTRO_DIR + "/qt.conf"}); - QString bin = TestBinDir + "TestOnlyC.exe"; - QString scriptPath = "./" + DISTRO_DIR + "/TestOnlyC.bat"; - - -#endif - - runTestParams({"-bin", bin, "force-clear", "noOverwrite", "-libOut", "lib"}, &comapareTree); - - QFile script(scriptPath); - QVERIFY(script.open(QIODevice::ReadOnly)); - auto scriptText = script.readAll(); - - QVERIFY(!scriptText.contains("Begin Custom Script")); - - script.close(); - - runTestParams({"-bin", bin, "force-clear", "noOverwrite", - "-libOut", "lib", - "-customScript", "echo 'this is test script'"}, &comapareTree); - - QVERIFY(script.open(QIODevice::ReadOnly)); - - scriptText = script.readAll(); - - QVERIFY(scriptText.contains("Begin Custom Script")); - QVERIFY(scriptText.contains("echo 'this is test script'")); - QVERIFY(scriptText.contains("End Custom Script")); - - script.close(); - - - - -} - -void deploytest::testOverwrite() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QFile f("./" + DISTRO_DIR + "/bin/TestOnlyC"); - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/bin/TestOnlyC", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/TestOnlyC.sh"}); - QString bin = TestBinDir + "TestOnlyC"; - -#else - QFile f("./" + DISTRO_DIR + "/TestOnlyC.exe"); - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - "./" + DISTRO_DIR + "/qt.conf"}); - QString bin = TestBinDir + "TestOnlyC.exe"; - -#endif - - runTestParams({"-bin", bin, "force-clear", "noOverwrite"}, &comapareTree); - - QVERIFY(f.open(QIODevice::ReadOnly)); - auto hashBefor = QCryptographicHash::hash(f.readAll(), QCryptographicHash::Md5); - f.close(); - - QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Append)); - f.write(QByteArray(10, '1')); - f.close(); - - QVERIFY(f.open(QIODevice::ReadOnly)); - auto hashAfter = QCryptographicHash::hash(f.readAll(), QCryptographicHash::Md5); - f.close(); - - QVERIFY(hashAfter != hashBefor); - - runTestParams({"-bin", bin, "noOverwrite"}, &comapareTree); - - QVERIFY(f.open(QIODevice::ReadOnly)); - hashAfter = QCryptographicHash::hash(f.readAll(), QCryptographicHash::Md5); - f.close(); - - QVERIFY(hashAfter != hashBefor); - - - runTestParams({"-bin", bin}, &comapareTree); - - QVERIFY(f.open(QIODevice::ReadOnly)); - hashAfter = QCryptographicHash::hash(f.readAll(), QCryptographicHash::Md5); - f.close(); - - QVERIFY(hashAfter == hashBefor); - -} - -void deploytest::testOverwriteWithPacking() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC," + TestBinDir + "TestCPPOnly"; - -#else - QString bin = TestBinDir + "TestOnlyC.exe," + TestBinDir + "TestCPPOnly.exe"; - -#endif -#ifdef Q_OS_UNIX - auto comapareTreeqif = utils.createTree( - { - "./" + DISTRO_DIR + "/InstallerTest.run", - "./" + DISTRO_DIR + "/InstallerTest.run.md5", - }); -#else - auto comapareTreeqif = utils.createTree( - { - "./" + DISTRO_DIR + "/InstallerTest.exe", - "./" + DISTRO_DIR + "/InstallerTest.exe.md5", - - }); - -#endif - - runTestParams({"-bin", bin, - "force-clear", - "noOverwrite", - "qif", - "qifFromSystem", - "-name", "Test"}, &comapareTreeqif); -} - -void deploytest::testextraData() { - TestUtils utils; - - -#ifdef Q_OS_UNIX - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/build/TestOnlyC", - "./" + DISTRO_DIR + "/build/TestCPPOnly", - "./" + DISTRO_DIR + "/build/QtWidgetsProject", - "./" + DISTRO_DIR + "/build/TestQMLWidgets", - "./" + DISTRO_DIR + "/build/basic", - "./" + DISTRO_DIR + "/build/quicknanobrowser", - "./" + DISTRO_DIR + "/build/webui"}); -#else - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/build/TestOnlyC.exe", - "./" + DISTRO_DIR + "/build/TestCPPOnly.exe", - "./" + DISTRO_DIR + "/build/QtWidgetsProject.exe", - "./" + DISTRO_DIR + "/build/TestQMLWidgets.exe", - "./" + DISTRO_DIR + "/build/basic.exe"}); -#endif - - - runTestParams({"-extraData", TestBinDir, "clear", - "noCheckRPATH", "noCheckPATH", "noQt"}, &comapareTree); - - - comapareTree = TestModule.replace(comapareTree, { - {"DistributionKit/build", - "DistributionKit/myExtraData/build"}}); - - runTestParams({"-extraData", TestBinDir, "clear", - "noCheckRPATH", "noCheckPATH", "noQt", - "-extraDataOut", "myExtraData"}, &comapareTree); -} - -void deploytest::testConfFile() { - TestUtils utils; - - - QFile::remove(TestBinDir + "/TestConf.json"); - QFile::remove(TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"); - -#ifdef Q_OS_UNIX - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/bin/TestOnlyC", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/TestOnlyC.sh"}); -#else - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - "./" + DISTRO_DIR + "/qt.conf"}); -#endif - -#ifdef Q_OS_UNIX - runTestParams({"-bin", TestBinDir + "TestOnlyC", "clear" , "noCheckRPATH", "noCheckPATH", "noQt", - "-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); -#else - runTestParams({"-bin", TestBinDir + "TestOnlyC.exe", "clear" , "noCheckRPATH", "noCheckPATH", "noQt", - "-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); -#endif - - - QVERIFY(QFile::exists(TestBinDir + "/TestConf.json")); - QFile::remove(TestBinDir + "/TestConf.json"); - - - -#ifdef Q_OS_UNIX - comapareTree += utils.createTree( - {"./" + DISTRO_DIR + "/bin/TestCPPOnly", - "./" + DISTRO_DIR + "/TestCPPOnly.sh"}); -#else - comapareTree += utils.createTree( - {"./" + DISTRO_DIR + "/TestCPPOnly.exe", - "./" + DISTRO_DIR + "/TestCPPOnly.bat"}); -#endif - -#ifdef Q_OS_UNIX - runTestParams({"-bin", TestBinDir + "TestOnlyC," + TestBinDir + "TestCPPOnly", - "clear", "noCheckRPATH", "noCheckPATH", "noQt", - "-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); -#else - runTestParams({"-bin", TestBinDir + "TestOnlyC.exe," + TestBinDir + "TestCPPOnly.exe", - "clear" , "-libDir", "L:/never/absalut/path", "noCheckPATH", "noQt", - "-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); -#endif - - QFile confFile(TestBinDir + "/TestConf.json"); - QVERIFY(confFile.open(QIODevice::ReadOnly)); - - auto data = confFile.readAll(); - confFile.close(); - - QJsonDocument doc; - doc = doc.fromJson(data); - QVERIFY(!doc.isNull()); - -#ifdef Q_OS_UNIX - - QVERIFY(data.contains("\"bin\": [")); - QVERIFY(data.contains("./TestOnlyC")); - QVERIFY(data.contains("./TestCPPOnly")); - - QVERIFY(data.contains("\"clear\": true")); - - data.insert(data.size() - 2, QString(",\"libDir\": \"/never/absalut/path/\"").toLatin1()); - - QVERIFY(confFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); - confFile.write(data); - confFile.close(); - - runTestParams({"-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); -#else - - QVERIFY(data.contains("\"bin\": [")); - QVERIFY(data.contains("./TestOnlyC.exe")); - QVERIFY(data.contains("./TestCPPOnly.exe")); - QVERIFY(data.contains("\"libDir\": \"L:/never/absalut/path\"")); - - QVERIFY(data.contains("\"clear\": true")); - - runTestParams({"-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); - -#endif - - QVERIFY(QuasarAppUtils::Params::isEndable("clear")); - QVERIFY(QuasarAppUtils::Params::isEndable("bin")); - QVERIFY(QuasarAppUtils::Params::isEndable("libDir")); -#ifdef Q_OS_UNIX - QVERIFY(QuasarAppUtils::Params::getArg("libDir") == "/never/absalut/path/"); -#else - QVERIFY(QuasarAppUtils::Params::getArg("libDir") == "L:/never/absalut/path"); -#endif - QFile::remove(TestBinDir + "/TestConf.json"); - - -#ifdef Q_OS_UNIX - runTestParams({"-bin", TestBinDir + "TestOnlyC," + TestBinDir + "TestCPPOnly", - "clear" , "noCheckRPATH", "noCheckPATH", "noQt", - "-confFile", TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"}, &comapareTree); -#else - runTestParams({"-bin", TestBinDir + "TestOnlyC.exe," + TestBinDir + "TestCPPOnly.exe", - "clear" , "noCheckPATH", "noQt", - "-confFile", TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"}, &comapareTree); -#endif - - confFile.setFileName(TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"); - QVERIFY(confFile.open(QIODevice::ReadOnly)); - - data = confFile.readAll(); - confFile.close(); - - doc = doc.fromJson(data); - QVERIFY(!doc.isNull()); - -#ifdef Q_OS_UNIX - - QVERIFY(data.contains("\"bin\": [")); - QVERIFY(data.contains("./../../../../../build/TestOnlyC")); - QVERIFY(data.contains("./../../../../../build/TestCPPOnly")); - - QVERIFY(data.contains("\"clear\": true")); - QString qmake = TestQtDir + "bin/qmake"; - -#else - - QVERIFY(data.contains("\"bin\": [")); - QVERIFY(data.contains("./../../../../../build/TestOnlyC.exe")); - QVERIFY(data.contains("./../../../../../build/TestCPPOnly.exe")); - - QVERIFY(data.contains("\"clear\": true")); - QString qmake = TestQtDir + "bin/qmake.exe"; - -#endif - runTestParams({"-confFile", TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"}, &comapareTree); - - QVERIFY(QuasarAppUtils::Params::isEndable("clear")); - QVERIFY(QuasarAppUtils::Params::isEndable("bin")); - - QFile::remove(TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"); - - // Test generar string in confFile - comapareTree = TestModule.qtLibs(); - - comapareTree = TestModule.ignoreFilter(comapareTree, "/plugins/p"); -#ifdef Q_OS_UNIX - comapareTree -= utils.createTree( - { - "./" + DISTRO_DIR + "/lib/libQt5EglFSDeviceIntegration.so", - }); - auto bin = TestBinDir + "QtWidgetsProject"; -#else - comapareTree -= utils.createTree( - { - "./" + DISTRO_DIR + "/Qt5DBus.dll" - - }); - auto bin = TestBinDir + "QtWidgetsProject.exe"; -#endif - - runTestParams({"-bin", bin, - "-qmake", qmake, - "clear", - "-ignore", "/plugins/p", - "-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); - - - runTestParams({"-confFile", TestBinDir + "/TestConf.json"}, &comapareTree); - QFile::remove(TestBinDir + "/TestConf.json"); - -#ifdef Q_OS_UNIX - QFile f("./" + DISTRO_DIR + "/bin/TestOnlyC"); - comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/package/TestOnlyC.sh", - "./" + DISTRO_DIR + "/package/bin/TestOnlyC", - "./" + DISTRO_DIR + "/package/bin/qt.conf" - }); - QString target1 = TestBinDir + "TestOnlyC"; - -#else - QFile f("./" + DISTRO_DIR + "/TestOnlyC.exe"); - comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/package/TestOnlyC.exe", - "./" + DISTRO_DIR + "/package/TestOnlyC.bat", - "./" + DISTRO_DIR + "/package/qt.conf"}); - QString target1 = TestBinDir + "TestOnlyC.exe"; - -#endif - bin = target1; - - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", "package;TestOn", - "-confFile", TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"}, &comapareTree); - - runTestParams({"-confFile", TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"}, - &comapareTree); - QFile::remove(TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"); - - auto file = "testCase.json"; -#ifdef Q_OS_UNIX - bin = TestBinDir + "QtWidgetsProject," + TestBinDir + "TestOnlyC"; -#else - bin = TestBinDir + "QtWidgetsProject.exe," + TestBinDir + "TestOnlyC.exe"; -#endif - QVERIFY(utils.deployFile(":/testResurces/testRes/testMultiPackageConfig.json", file, - {{"$BIN_DIR", bin.toLatin1()}})); - - comapareTree = TestModule.onlyC(DISTRO_DIR + "/Dstro1") + - TestModule.qtLibs(DISTRO_DIR + "/Dstro2"); - - - runTestParams({"-confFile", file}, - &comapareTree); - - QFile::remove(TestBinDir + "/TestConf.json"); - QFile::remove(TestBinDir + "/../folder/For/Testing/Deploy/File/TestConf.json"); - -} - -void deploytest::testPackages() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QFile f("./" + DISTRO_DIR + "/bin/TestOnlyC"); - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/package/TestOnlyC.sh", - "./" + DISTRO_DIR + "/package/bin/TestOnlyC", - "./" + DISTRO_DIR + "/package/bin/qt.conf" - }); - QString target1 = TestBinDir + "TestOnlyC"; - -#else - QFile f("./" + DISTRO_DIR + "/TestOnlyC.exe"); - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "/package/TestOnlyC.exe", - "./" + DISTRO_DIR + "/package/TestOnlyC.bat", - "./" + DISTRO_DIR + "/package/qt.conf"}); - QString target1 = TestBinDir + "TestOnlyC.exe"; - -#endif - QString bin = target1; - - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", "/package/;TestOn"}, &comapareTree); - - runTestParams({"-bin", bin, "force-clear", - "-targetPackage", "/package/;" + QFileInfo(target1).absoluteFilePath()}, &comapareTree); - -#ifdef Q_OS_UNIX - QString target2 = TestBinDir + "TestQMLWidgets"; - QString target3 = TestBinDir + "QtWidgetsProject"; - -#else - QString target2 = TestBinDir + "TestQMLWidgets.exe"; - QString target3 = TestBinDir + "QtWidgetsProject.exe"; - -#endif - bin += "," + target2; - bin += "," + target3; - - auto packageString = "package1;" + QFileInfo(target1).absoluteFilePath() + ",package2/ZzZ;" + QFileInfo(target2).absoluteFilePath(); - - comapareTree = TestModule.testDistroLibs(DISTRO_DIR); - - runTestParams({"-bin", bin, "force-clear", - "-binOut", "/lol", - "-libOut", "/lolLib", - "-trOut", "/lolTr", - "-pluginOut", "/p", - "-qmlOut", "package2/ZzZ;/q/and/q,/q", - "-qmlDir", "package2/ZzZ;" + TestBinDir + "/../TestQMLWidgets", - "-targetPackage", packageString}, &comapareTree); - - -#ifdef Q_OS_UNIX - - // test a wrapers source - QFile wraper("./" + DISTRO_DIR + "/package2/ZzZ/TestQMLWidgets.sh"); - - QVERIFY(wraper.open(QIODevice::ReadOnly)); - auto data = wraper.readAll(); - wraper.close(); - - wraper.setFileName(":/testResurces/testRes/TestQMLWidgets.sh"); - QVERIFY(wraper.open(QIODevice::ReadOnly)); - QVERIFY(wraper.readAll() == data); - wraper.close(); -#endif -} - -void deploytest::testQt() { - TestUtils utils; - - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "QtWidgetsProject"; - QString qmake = TestQtDir + "bin/qmake"; - -#else - QString bin = TestBinDir + "QtWidgetsProject.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; - -#endif - - - auto comapareTree = TestModule.qtLibs(); - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake}, &comapareTree); - - // test auto detection of detection qmake from PATH - runTestParams({"-bin", bin, "clear", "noCheckRPATH"}, &comapareTree); - -#ifdef Q_OS_UNIX - // test auto detection of detection qmake from RPATH - runTestParams({"-bin", bin, "clear", "noCheckPATH"}, &comapareTree); -#endif - - - comapareTree = TestModule.qtWithoutTr(); - - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, "noTranslations"}, &comapareTree); - - - comapareTree = TestModule.qmlLibs(); - -#ifdef Q_OS_UNIX - bin = TestBinDir + "TestQMLWidgets"; -#else - bin = TestBinDir + "TestQMLWidgets.exe"; - -#endif - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-qmlDir", TestBinDir + "/../TestQMLWidgets"}, &comapareTree); - - -#ifdef Q_OS_UNIX - - runTestParams({"-bin", bin, "clear" , - "-qmlDir", TestBinDir + "/../TestQMLWidgets"}, &comapareTree); - -#endif - -} - -void deploytest::testClear() { - TestUtils utils; - - - auto compareTree = QSet{}; - - runTestParams({"clear"}, &compareTree); - -} - -void deploytest::testIgnore() { - TestUtils utils; - - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "QtWidgetsProject"; - QString qmake = TestQtDir + "bin/qmake"; - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/QtWidgetsProject.sh", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/bin/QtWidgetsProject", - }); - -#else - QString bin = TestBinDir + "QtWidgetsProject.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; - - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/qt.conf", - "./" + DISTRO_DIR + "/QtWidgetsProject.exe", - "./" + DISTRO_DIR + "/QtWidgetsProject.bat", - #if defined(Q_OS_WIN64) - "./" + DISTRO_DIR + "/libgcc_s_seh-1.dll", - #else - "./" + DISTRO_DIR + "/libgcc_s_dw2-1.dll", - #endif - "./" + DISTRO_DIR + "/libstdc++-6.dll", - "./" + DISTRO_DIR + "/libwinpthread-1.dll" - - }); - -#endif - - - if (!TestQtDir.contains("Qt5")) { - -#ifdef Q_OS_UNIX - bin = TestBinDir + "QtWidgetsProject"; - qmake = TestQtDir + "bin/qmake"; - -#else - bin = TestBinDir + "QtWidgetsProject.exe"; - qmake = TestQtDir + "bin/qmake.exe"; - -#endif - } - - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-ignore", "Qt5"}, &comapareTree); - - - -#ifdef Q_OS_UNIX - auto removeTree = utils.createTree({ - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/libqtvirtualkeyboard_hangul.so", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/libqtvirtualkeyboard_openwnn.so", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/libqtvirtualkeyboard_pinyin.so", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/libqtvirtualkeyboard_tcime.so", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/libqtvirtualkeyboard_thai.so", - "./" + DISTRO_DIR + "/plugins/platforminputcontexts/libqtvirtualkeyboardplugin.so", - "./" + DISTRO_DIR + "/lib/libQt5VirtualKeyboard.so", - - }); -#else - auto removeTree = utils.createTree({ - "./" + DISTRO_DIR + "/Qt5VirtualKeyboard.dll", - "./" + DISTRO_DIR + "/plugins/platforminputcontexts/qtvirtualkeyboardplugin.dll", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/qtvirtualkeyboard_hangul.dll", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/qtvirtualkeyboard_openwnn.dll", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/qtvirtualkeyboard_pinyin.dll", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/qtvirtualkeyboard_tcime.dll", - "./" + DISTRO_DIR + "/plugins/virtualkeyboard/qtvirtualkeyboard_thai.dll" - }); - -#endif - - comapareTree = TestModule.qtLibs() - removeTree; - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-ignore", "VirtualKeyboard"}, &comapareTree); - -} - -void deploytest::testIgnoreEnv() { - - - - Envirement env; - QDir("./testTree").removeRecursively(); - - QStringList ignoreTree = { - "./testTree/test", - "./testTree/", - "./testTree/test1/1", - "./testTree/test2/1/", - }; - - QStringList testTree = { - "./testTree/test/z", - "./testTree/z", - "./testTree/test1/1z", - "./testTree/test2/1/z", - }; - - createTree(ignoreTree); - createTree(testTree); - - env.setIgnoreEnvList(ignoreTree); - env.addEnv(ignoreTree); - - // must be empty becouse all pathes is ignored - QVERIFY(env.size() == 0); - - env.addEnv(testTree); - - // must be equals 4 becouse all pathes is not ignored - QVERIFY(env.size() == 4); - - // try add dublicate - env.addEnv(testTree); - - // must be equals 4 becouse all dublicates must be ignored - QVERIFY(env.size() == 4); - - QVERIFY(QDir("./testTree").removeRecursively()); -} - -void deploytest::testLibDir() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - QString extraPath = "/usr/lib,/lib"; - - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.sh", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/bin/TestOnlyC" - }); - -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - QString extraPath = TestQtDir; - - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/qt.conf", - "./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - - }); - -#endif - - - - - runTestParams({"-bin", bin, "clear" , - "-libDir", extraPath, - }, &comapareTree); - - -#ifdef Q_OS_UNIX - comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.sh", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/bin/TestOnlyC", - "./" + DISTRO_DIR + "/lib/libstdc++.so", - "./" + DISTRO_DIR + "/lib/libgcc_s.so", - "./" + DISTRO_DIR + "/lib/ld-linux-x86-64.so", - "./" + DISTRO_DIR + "/lib/libc.so", - "./" + DISTRO_DIR + "/lib/libm.so", - }); - - auto comapareTreeExtraLib = utils.createTree( - { - "./" + DISTRO_DIR + "2/TestOnlyC.sh", - "./" + DISTRO_DIR + "2/bin/qt.conf", - "./" + DISTRO_DIR + "2/bin/TestOnlyC", - "./" + DISTRO_DIR + "2/lib/libstdc++.so", - "./" + DISTRO_DIR + "2/lib/libgcc_s.so" - }); - -#else - comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/qt.conf", - "./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - #if defined(Q_OS_WIN64) - "./" + DISTRO_DIR + "/libgcc_s_seh-1.dll", - #else - "./" + DISTRO_DIR + "/libgcc_s_dw2-1.dll", - #endif - "./" + DISTRO_DIR + "/libwinpthread-1.dll", - "./" + DISTRO_DIR + "/libstdc++-6.dll", - - }); - - auto comapareTreeExtraLib = utils.createTree( - { - "./" + DISTRO_DIR + "2/qt.conf", - "./" + DISTRO_DIR + "2/TestOnlyC.exe", - "./" + DISTRO_DIR + "2/TestOnlyC.bat", - #if defined(Q_OS_WIN64) - "./" + DISTRO_DIR + "2/libgcc_s_seh-1.dll", - #else - "./" + DISTRO_DIR + "2/libgcc_s_dw2-1.dll", - #endif - "./" + DISTRO_DIR + "2/libstdc++-6.dll", - - }); - -#endif - - - runTestParams({"-bin", bin, "clear" , - "-libDir", extraPath, - "-recursiveDepth", "5", - "noCheckRPATH, noCheckPATH", "noQt"}, &comapareTree, true); - - runTestParams({"-bin", bin, "clear" , - "-targetDir", "./" + DISTRO_DIR + "2", - "-extraLibs", "stdc,gcc", - "noCheckRPATH, noCheckPATH", "noQt"}, &comapareTreeExtraLib, true); - - //task #258 - //https://github.com/QuasarApp/CQtDeployer/issues/258 - - -#ifdef Q_OS_UNIX - comapareTreeExtraLib = utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.sh", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/bin/TestOnlyC", - "./" + DISTRO_DIR + "/lib/libstdc++.so", - "./" + DISTRO_DIR + "/lib/libgcc_s.so" - }); - extraPath = "./" + DISTRO_DIR + "2/lib"; - - -#else - - comapareTreeExtraLib = utils.createTree( - { - "./" + DISTRO_DIR + "/qt.conf", - "./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - #if defined(Q_OS_WIN64) - "./" + DISTRO_DIR + "/libgcc_s_seh-1.dll", - #else - "./" + DISTRO_DIR + "/libgcc_s_dw2-1.dll", - #endif - "./" + DISTRO_DIR + "/libstdc++-6.dll", - - }); - extraPath = "./" + DISTRO_DIR + "2"; - -#endif - runTestParams({"-bin", bin, "clear" , - "-libDir", extraPath, - "noCheckRPATH, noCheckPATH", "noQt"}, &comapareTreeExtraLib, true); - - QDir(extraPath).removeRecursively(); - -} - -void deploytest::testExtraPlugins() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "QtWidgetsProject"; - QString qmake = TestQtDir + "bin/qmake"; - - auto pluginTree = utils.createTree( - { - "./" + DISTRO_DIR + "/plugins/sqldrivers/libqsqlodbc.so", - "./" + DISTRO_DIR + "/plugins/sqldrivers/libqsqlpsql.so", - "./" + DISTRO_DIR + "/plugins/sqldrivers/libqsqlite.so", - "./" + DISTRO_DIR + "/lib/libQt5Sql.so", - "./" + DISTRO_DIR + "/lib/libpq.so", - "./" + DISTRO_DIR + "/lib/libcrypto.so", - "./" + DISTRO_DIR + "/lib/libssl.so", - - }); -#else - QString bin = TestBinDir + "QtWidgetsProject.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; - - auto pluginTree = utils.createTree( - { - "./" + DISTRO_DIR + "/plugins/sqldrivers/qsqlmysql.dll", - "./" + DISTRO_DIR + "/plugins/sqldrivers/qsqlodbc.dll", - "./" + DISTRO_DIR + "/plugins/sqldrivers/qsqlite.dll", - "./" + DISTRO_DIR + "/plugins/sqldrivers/qsqlpsql.dll", - "./" + DISTRO_DIR + "/Qt5Sql.dll", - "./" + DISTRO_DIR + "/libpq.dll", - - }); -#endif - - auto comapareTree = TestModule.qtLibs(); - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - }, &comapareTree); - - - comapareTree = comapareTree + pluginTree; - - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-enablePlugins", "sqldrivers"}, &comapareTree); - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-extraPlugin", TestQtDir + "/plugins/sqldrivers"}, &comapareTree); - - comapareTree -= pluginTree; - comapareTree -= utils.createTree( - { - "./" + DISTRO_DIR + "/plugins/platforms/libqxcb.so", - "./" + DISTRO_DIR + "/lib/libxcb-xinerama.so.0", - "./" + DISTRO_DIR + "/plugins/xcbglintegrations/libqxcb-egl-integration.so", - "./" + DISTRO_DIR + "/plugins/xcbglintegrations/libqxcb-glx-integration.so", - "./" + DISTRO_DIR + "/lib/libQt5XcbQpa.so", - - }); - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "-disablePlugins", "qxcb,xcbglintegrations"}, &comapareTree); -} - -void deploytest::testTargetDir() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "Z/bin/TestOnlyC", - "./" + DISTRO_DIR + "Z/bin/qt.conf", - "./" + DISTRO_DIR + "Z/TestOnlyC.sh"}); -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - - auto comapareTree = utils.createTree( - {"./" + DISTRO_DIR + "Z/TestOnlyC.exe", - "./" + DISTRO_DIR + "Z/TestOnlyC.bat", - "./" + DISTRO_DIR + "Z/qt.conf"}); -#endif - - runTestParams({"-bin", bin, "clear" , - "-targetDir", "./" + DISTRO_DIR + "Z" - }, &comapareTree); -} - -void deploytest::testSystemLib() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestOnlyC"; - QString qmake = TestQtDir + "bin/qmake"; - - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.sh", - "./" + DISTRO_DIR + "/bin/qt.conf", - "./" + DISTRO_DIR + "/bin/TestOnlyC", - "./" + DISTRO_DIR + "/lib/systemLibs/libgcc_s.so", - "./" + DISTRO_DIR + "/lib/systemLibs/libstdc++.so" - }); - -#else - QString bin = TestBinDir + "TestOnlyC.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; - - auto comapareTree = utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - #if defined(Q_OS_WIN64) - "./" + DISTRO_DIR + "/systemLibs/libgcc_s_seh-1.dll", - #else - "./" + DISTRO_DIR + "/systemLibs/libgcc_s_dw2-1.dll", - #endif - "./" + DISTRO_DIR + "/systemLibs/libstdc++-6.dll", - "./" + DISTRO_DIR + "/systemLibs/libwinpthread-1.dll", - "./" + DISTRO_DIR + "/systemLibs/msvcrt.dll", - "./" + DISTRO_DIR + "/qt.conf" - }); - -#endif - - runTestParams({"-bin", bin, "clear" , - "deploySystem", - "-qmake", qmake, - }, &comapareTree); - -#ifdef Q_OS_WIN - bin = TestBinDir + "QtWidgetsProject.exe"; - - comapareTree += TestModule.qtLibs(); - - comapareTree -= utils.createTree( - { - "./" + DISTRO_DIR + "/TestOnlyC.exe", - "./" + DISTRO_DIR + "/TestOnlyC.bat", - #if defined(Q_OS_WIN64) - "./" + DISTRO_DIR + "/systemLibs/libgcc_s_seh-1.dll", - #else - "./" + DISTRO_DIR + "/systemLibs/libgcc_s_dw2-1.dll", - #endif - "./" + DISTRO_DIR + "/systemLibs/libstdc++-6.dll", - "./" + DISTRO_DIR + "/systemLibs/libwinpthread-1.dll", - - }); - - comapareTree += utils.createTree( - { - "./" + DISTRO_DIR + "/systemLibs/msvcrt.dll", - "./" + DISTRO_DIR + "/qt.conf", - "./" + DISTRO_DIR + "/systemLibs/mpr.dll", - "./" + DISTRO_DIR + "/systemLibs/profapi.dll", - "./" + DISTRO_DIR + "/systemLibs/rpcrt4.dll", - "./" + DISTRO_DIR + "/systemLibs/shell32.dll", - "./" + DISTRO_DIR + "/systemLibs/userenv.dll", - "./" + DISTRO_DIR + "/systemLibs/uxtheme.dll", - "./" + DISTRO_DIR + "/systemLibs/version.dll", - "./" + DISTRO_DIR + "/systemLibs/ucrtbase.dll", - "./" + DISTRO_DIR + "/systemLibs/oleaut32.dll", - "./" + DISTRO_DIR + "/systemLibs/bcryptprimitives.dll", - "./" + DISTRO_DIR + "/systemLibs/msvcp_win.dll", - "./" + DISTRO_DIR + "/systemLibs/wtsapi32.dll", - "./" + DISTRO_DIR + "/systemLibs/combase.dll", - #if !defined(Q_OS_WIN64) - "./" + DISTRO_DIR + "/systemLibs/sspicli.dll", - "./" + DISTRO_DIR + "/systemLibs/cryptbase.dll", - #endif - - }); - - -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - comapareTree += utils.createTree( - { - "./" + DISTRO_DIR + "/systemLibs/d3d11.dll", - "./" + DISTRO_DIR + "/systemLibs/dxgi.dll", - "./" + DISTRO_DIR + "/systemLibs/win32u.dll", - }); -#endif - - - runTestParams({"-bin", bin, "clear" , - "-qmake", qmake, - "deploySystem" - }, &comapareTree); - - -#endif -} - -void deploytest::testOutDirs() { - TestUtils utils; - -#ifdef Q_OS_UNIX - QString bin = TestBinDir + "TestQMLWidgets"; - QString qmake = TestQtDir + "bin/qmake"; - -#else - QString bin = TestBinDir + "TestQMLWidgets.exe"; - QString qmake = TestQtDir + "bin/qmake.exe"; - - -#endif - - auto comapareTree = TestModule.testOutLibs(); - - runTestParams({"-bin", bin, "clear" , - "-binOut", "/lol", - "-libOut", "/lolLib", - "-trOut", "/lolTr", - "-pluginOut", "/p", - "-qmlOut", "/q", - "-qmake", qmake, - "-qmlDir", TestBinDir + "/../TestQMLWidgets" - }, &comapareTree); - - QFile file; - - file.setFileName("./" + DISTRO_DIR + "/lol/qt.conf"); - - QVERIFY(file.open(QIODevice::ReadOnly)); - - auto runScript = file.readAll(); - file.close(); - - QVERIFY(runScript.contains("Prefix= ./../")); - QVERIFY(runScript.contains("Libraries= ./lolLib/")); - QVERIFY(runScript.contains("Plugins= ./p/")); - QVERIFY(runScript.contains("Imports= ./q/")); - QVERIFY(runScript.contains("Translations= ./lolTr/")); - QVERIFY(runScript.contains("Qml2Imports= ./q/")); - -#ifdef Q_OS_WIN - - - runTestParams({"-bin", bin, "clear" , - "-binOut", "/lol", - "-libOut", "/lolLib", - "-trOut", "/lolTr", - "-pluginOut", "/p", - "-qmlOut", "/q", - "-qmake", qmake, - "-qmlDir", TestBinDir + "/../TestQMLWidgets" - }, &comapareTree); - - - - file.setFileName( "./" + DISTRO_DIR + "/TestQMLWidgets.bat"); - - QVERIFY(file.open(QIODevice::ReadOnly)); - - runScript = file.readAll(); - file.close(); - - qDebug() << "runScript =" << runScript; - - QVERIFY(runScript.contains("SET BASE_DIR=%~dp0")); - QVERIFY(runScript.contains("SET PATH=%BASE_DIR%\\lol\\;%BASE_DIR%\\lolLib\\;%PATH%")); - QVERIFY(runScript.contains("start \"TestQMLWidgets\" /B \"%BASE_DIR%\\lol\\TestQMLWidgets.exe\" %*")); - - runTestParams({"-bin", TestBinDir + "TestOnlyC.exe", "clear", - }, nullptr); - - file.setFileName( "./" + DISTRO_DIR + "/TestOnlyC.bat"); - - QVERIFY(file.open(QIODevice::ReadOnly)); - - runScript = file.readAll(); - file.close(); - - qDebug() << "runScript =" << runScript; - - QVERIFY(runScript.contains("call \"%BASE_DIR%\\TestOnlyC.exe\" %*")); - -#endif - -} - -QTEST_APPLESS_MAIN(deploytest) - -#include "tst_deploytest.moc" diff --git a/_config.yml b/_config.yml deleted file mode 100644 index ddeb671b..00000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-time-machine \ No newline at end of file diff --git a/doxygen.conf b/doxygen.conf.in similarity index 99% rename from doxygen.conf rename to doxygen.conf.in index 2d9a0e49..a48d573e 100644 --- a/doxygen.conf +++ b/doxygen.conf.in @@ -32,25 +32,28 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = CQtDeployer official documentation page +PROJECT_NAME = CQtDeployer + # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = @CQT_DEPLOYER_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = +PROJECT_BRIEF = CQtDeployer helps you to extract all libraries your executable depends on and to create a launch script for your application. + # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. -PROJECT_LOGO = "res/CQtDeployer logo_web.png" +PROJECT_LOGO = res/CQtDeployer logo_installer.png + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If @@ -701,7 +704,7 @@ FILE_VERSION_FILTER = # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. -LAYOUT_FILE = QuasarAppLib/CMake/DoxyStyle/DoxygenLayout.xml +LAYOUT_FILE = submodules/CMake/DoxyStyle/DoxygenLayout.xml # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib @@ -788,10 +791,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = ./md \ - - - +INPUT = ./md # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -874,7 +874,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = ./submodules # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -927,7 +927,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = ./res +IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -983,7 +983,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = md/README.md +USE_MDFILE_AS_MAINPAGE = ./md/README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1193,7 +1193,7 @@ HTML_STYLESHEET = # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = QuasarAppLib/CMake/DoxyStyle/doxygenStyles.css +HTML_EXTRA_STYLESHEET = submodules/CMake/DoxyStyle/doxygenStyles.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1392,7 +1392,7 @@ QCH_FILE = # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_NAMESPACE = QuasarApp +QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual @@ -1496,7 +1496,7 @@ ENUM_VALUES_PER_LINE = 4 # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. -TREEVIEW_WIDTH = 300 +TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. @@ -1605,7 +1605,7 @@ SEARCHENGINE = YES # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. -SERVER_BASED_SEARCH = NO +SERVER_BASED_SEARCH = YES # When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file diff --git a/examples/TestQMLWidgets/.qmake.stash b/examples/TestQMLWidgets/.qmake.stash deleted file mode 100644 index 17a7f337..00000000 --- a/examples/TestQMLWidgets/.qmake.stash +++ /dev/null @@ -1,24 +0,0 @@ -QMAKE_CXX.INCDIRS = \ - /usr/include/c++/7 \ - /usr/include/x86_64-linux-gnu/c++/7 \ - /usr/include/c++/7/backward \ - /usr/lib/gcc/x86_64-linux-gnu/7/include \ - /usr/local/include \ - /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed \ - /usr/include/x86_64-linux-gnu \ - /usr/include -QMAKE_CXX.LIBDIRS = \ - /usr/lib/gcc/x86_64-linux-gnu/7 \ - /usr/lib/x86_64-linux-gnu \ - /usr/lib \ - /lib/x86_64-linux-gnu \ - /lib -QMAKE_CXX.QT_COMPILER_STDCXX = 201402L -QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 7 -QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 3 -QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 0 -QMAKE_CXX.COMPILER_MACROS = \ - QT_COMPILER_STDCXX \ - QMAKE_GCC_MAJOR_VERSION \ - QMAKE_GCC_MINOR_VERSION \ - QMAKE_GCC_PATCH_VERSION diff --git a/examples/TestQMLWidgets/HomeForm.ui.qml b/examples/TestQMLWidgets/HomeForm.ui.qml deleted file mode 100644 index 6474fad0..00000000 --- a/examples/TestQMLWidgets/HomeForm.ui.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.10 -import QtQuick.Controls 2.3 - -Page { - width: 600 - height: 400 - - title: qsTr("Home") - - Label { - text: qsTr("You are on the home page.") - anchors.centerIn: parent - } -} diff --git a/examples/TestQMLWidgets/Page1Form.ui.qml b/examples/TestQMLWidgets/Page1Form.ui.qml deleted file mode 100644 index a25e78ae..00000000 --- a/examples/TestQMLWidgets/Page1Form.ui.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.10 -import QtQuick.Controls 2.3 - -Page { - width: 600 - height: 400 - - title: qsTr("Page 1") - - Label { - text: qsTr("You are on Page 1.") - anchors.centerIn: parent - } -} diff --git a/examples/TestQMLWidgets/Page2Form.ui.qml b/examples/TestQMLWidgets/Page2Form.ui.qml deleted file mode 100644 index c34bb984..00000000 --- a/examples/TestQMLWidgets/Page2Form.ui.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.10 -import QtQuick.Controls 2.3 - -Page { - width: 600 - height: 400 - - title: qsTr("Page 2") - - Label { - text: qsTr("You are on Page 2.") - anchors.centerIn: parent - } -} diff --git a/examples/TestQMLWidgets/README.md b/examples/TestQMLWidgets/README.md deleted file mode 100644 index 9c1b75f4..00000000 --- a/examples/TestQMLWidgets/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# This example for packing apps to snap -You need to build your project with your own Qt version. - -1. cd ~/ # go to home dir -2. snap install cqtdeployer # install cqtdeployer from snap store -3. git clone https://github.com/QuasarApp/CQtDeployer.git # clone this project -4. cd Console-QtDeployer/examples/TestQMLWidgets # go to folder with example -5. /path/to/your/qmake/bin/qmake TestQMLWidgets.pro # run your qmake for this example -6. make # build example -7. cqtdeployer -bin ./build/TestQMLWidgets -qmake /path/to/your/qmake/bin/qmake -qmlDir ./ -targetDir ./distro - # run cqtdeployer for deploy example project -8. snapcraft # create snapcraft build -9. snap install cqtdeployerexample_0.1_amd64.snap --dangerous # install this example -10. cqtdeployerexample # check - -Done! diff --git a/examples/TestQMLWidgets/TestQMLWidgets.pro b/examples/TestQMLWidgets/TestQMLWidgets.pro deleted file mode 100644 index 762b55dd..00000000 --- a/examples/TestQMLWidgets/TestQMLWidgets.pro +++ /dev/null @@ -1,27 +0,0 @@ -QT += quick -CONFIG += c++11 - -# The following define makes your compiler emit warnings if you use -# any Qt feature that has been marked deprecated (the exact warnings -# depend on your compiler). Refer to the documentation for the -# deprecated API to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if it uses 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 = - -DESTDIR="$$PWD/build" - diff --git a/examples/TestQMLWidgets/main.cpp b/examples/TestQMLWidgets/main.cpp deleted file mode 100644 index 6333b85c..00000000 --- a/examples/TestQMLWidgets/main.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#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/examples/TestQMLWidgets/qtquickcontrols2.conf b/examples/TestQMLWidgets/qtquickcontrols2.conf deleted file mode 100644 index 08109fee..00000000 --- a/examples/TestQMLWidgets/qtquickcontrols2.conf +++ /dev/null @@ -1,6 +0,0 @@ -; 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=Imagine diff --git a/examples/TestQMLWidgets/snap/snapcraft.yaml b/examples/TestQMLWidgets/snap/snapcraft.yaml deleted file mode 100644 index 078e1247..00000000 --- a/examples/TestQMLWidgets/snap/snapcraft.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: cqtdeployerexample # you probably want to 'snapcraft register ' -base: core18 # the base snap is the execution environment for this snap -version: '0.1' # just for humans, typically '1.2+git' or '1.3.2' -summary: simple example for packing with cqtdeployer # 79 char long summary -description: | - simple example for packing with cqtdeployer - -grade: stable # must be 'stable' to release into candidate/stable channels -confinement: strict # use 'strict' once you have the right plugs and slots - - -apps: - cqtdeployerexample: - command: desktop-launch $SNAP/TestQMLWidgets.sh - - plugs: [desktop, unity7, home, opengl, x11, wayland] - - -parts: - cqtdeployerexample: - # See 'snapcraft plugins' - plugin: dump - source: distro - after: [wrapper, libsgl] - - wrapper: - plugin: dump - source: wrapper - - libsgl: - plugin: nil - stage-packages: - # Here for the plugins-- they're not linked in automatically. - - libx11-xcb1 - - libglu1-mesa - - libxrender1 - - libxi6 - - libegl1-mesa - - fontconfig - - libgl1-mesa-dri - - libxkbcommon0 - - ttf-ubuntu-font-family - - dmz-cursor-theme - - adwaita-icon-theme - - gnome-themes-standard - - shared-mime-info - - libgdk-pixbuf2.0-0 - - libgtk2.0-0 - - xdg-user-dirs - - libxrandr2 - - libwayland-cursor0 - - libwayland-egl1 - - libpq5 diff --git a/examples/TestQMLWidgets/wrapper/bin/desktop-launch b/examples/TestQMLWidgets/wrapper/bin/desktop-launch deleted file mode 100755 index 2a6d60ca..00000000 --- a/examples/TestQMLWidgets/wrapper/bin/desktop-launch +++ /dev/null @@ -1,442 +0,0 @@ -#!/bin/bash -################# -# Launcher init # -################# - -START=$(date +%s.%N) - -# On Fedora $SNAP is under /var and there is some magic to map it to /snap. -# # We need to handle that case and reset $SNAP -SNAP=`echo $SNAP | sed -e "s|/var/lib/snapd||g"` - -needs_update=true - -. $SNAP_USER_DATA/.last_revision 2>/dev/null || true -if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_REVISION" ]; then - needs_update=false -fi - -# Set $REALHOME to the users real home directory -REALHOME=`getent passwd $UID | cut -d ':' -f 6` - -# If the user has modified their user-dirs settings, force an update -if [[ -f $HOME/.config/user-dirs.dirs.md5sum && -f $HOME/.config/user-dirs.locale.md5sum ]]; then - if [[ "$(md5sum < $REALHOME/.config/user-dirs.dirs)" != "$(cat $HOME/.config/user-dirs.dirs.md5sum)" || - "$(md5sum < $REALHOME/.config/user-dirs.locale)" != "$(cat $HOME/.config/user-dirs.locale.md5sum)" ]]; then - needs_update=true - fi -fi - -if [ "$SNAP_ARCH" == "amd64" ]; then - ARCH="x86_64-linux-gnu" -elif [ "$SNAP_ARCH" == "armhf" ]; then - ARCH="arm-linux-gnueabihf" -elif [ "$SNAP_ARCH" == "arm64" ]; then - ARCH="aarch64-linux-gnu" -else - ARCH="$SNAP_ARCH-linux-gnu" -fi - -export SNAP_LAUNCHER_ARCH_TRIPLET=$ARCH - -# Don't LD_PRELOAD bindtextdomain for classic snaps -if ! grep -qs "^\s*confinement:\s*classic\s*" $SNAP/meta/snap.yaml; then - if [ -f $SNAP/lib/bindtextdomain.so ]; then - export LD_PRELOAD=$LD_PRELOAD:$SNAP/lib/bindtextdomain.so - fi -fi -############################################### -# Launcher common exports for any desktop app # -############################################### - -function prepend_dir() { - local var="$1" - local dir="$2" - if [ -d "$dir" ]; then - eval "export $var=\"\$dir\${$var:+:\$$var}\"" - fi -} - -function append_dir() { - local var="$1" - local dir="$2" - if [ -d "$dir" ]; then - eval "export $var=\"\${$var:+\$$var:}\$dir\"" - fi -} - -function can_open_file() { - return `head -c0 "$1" &> /dev/null`; -} - -WITH_RUNTIME=no -if [ -z "$RUNTIME" ]; then - RUNTIME=$SNAP -else - # add general paths not added by snapcraft due to runtime snap - append_dir LD_LIBRARY_PATH $RUNTIME/lib/$ARCH - append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH - append_dir PATH $RUNTIME/usr/bin - WITH_RUNTIME=yes -fi - -# XKB config -export XKB_CONFIG_ROOT=$RUNTIME/usr/share/X11/xkb - -# Give XOpenIM a chance to locate locale data. -# This is required for text input to work in SDL2 games. -export XLOCALEDIR=$RUNTIME/usr/share/X11/locale - -# Set XCursors path -export XCURSOR_PATH=$RUNTIME/usr/share/icons - -# Mesa Libs for OpenGL support -append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/mesa -append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/mesa-egl - -# Tell libGL where to find the drivers -export LIBGL_DRIVERS_PATH=$RUNTIME/usr/lib/$ARCH/dri -append_dir LD_LIBRARY_PATH $LIBGL_DRIVERS_PATH - -# Workaround in snapd for proprietary nVidia drivers mounts the drivers in -# /var/lib/snapd/lib/gl that needs to be in LD_LIBRARY_PATH -# Without that OpenGL using apps do not work with the nVidia drivers. -# Ref.: https://bugs.launchpad.net/snappy/+bug/1588192 -append_dir LD_LIBRARY_PATH /var/lib/snapd/lib/gl - -# Unity7 export (workaround for https://launchpad.net/bugs/1638405) -append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/libunity - -# Pulseaudio export -append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/pulseaudio - -# EGL vendor files on glvnd enabled systems -[ -d /var/lib/snapd/lib/glvnd/egl_vendor.d ] && \ - append_dir __EGL_VENDOR_LIBRARY_DIRS /var/lib/snapd/lib/glvnd/egl_vendor.d - -# Tell GStreamer where to find its plugins -export GST_PLUGIN_PATH=$SNAP/usr/lib/$ARCH/gstreamer-1.0 -export GST_PLUGIN_SYSTEM_PATH=$RUNTIME/usr/lib/$ARCH/gstreamer-1.0 -# gst plugin scanner doesn't install in the correct path: https://github.com/ubuntu/snapcraft-desktop-helpers/issues/43 -export GST_PLUGIN_SCANNER=$RUNTIME/usr/lib/$ARCH/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner - -# XDG Config -[ "$WITH_RUNTIME" = yes ] && prepend_dir XDG_CONFIG_DIRS $RUNTIME/etc/xdg -prepend_dir XDG_CONFIG_DIRS $SNAP/etc/xdg - -# Define snaps' own data dir -[ "$WITH_RUNTIME" = yes ] && prepend_dir XDG_DATA_DIRS $RUNTIME/usr/share -prepend_dir XDG_DATA_DIRS $SNAP/usr/share -prepend_dir XDG_DATA_DIRS $SNAP/share -prepend_dir XDG_DATA_DIRS $SNAP/data-dir -prepend_dir XDG_DATA_DIRS $SNAP_USER_DATA - -# Set XDG_DATA_HOME to local path -export XDG_DATA_HOME=$SNAP_USER_DATA/.local/share -mkdir -p $XDG_DATA_HOME - -# Workaround for GLib < 2.53.2 not searching for schemas in $XDG_DATA_HOME: -# https://bugzilla.gnome.org/show_bug.cgi?id=741335 -prepend_dir XDG_DATA_DIRS $XDG_DATA_HOME - -# Set cache folder to local path -export XDG_CACHE_HOME=$SNAP_USER_COMMON/.cache -if [[ -d $SNAP_USER_DATA/.cache && ! -e $XDG_CACHE_HOME ]]; then - # the .cache directory used to be stored under $SNAP_USER_DATA, migrate it - mv $SNAP_USER_DATA/.cache $SNAP_USER_COMMON/ -fi -mkdir -p $XDG_CACHE_HOME - -# Set config folder to local path -export XDG_CONFIG_HOME=$SNAP_USER_DATA/.config -mkdir -p $XDG_CONFIG_HOME - -# Create $XDG_RUNTIME_DIR if not exists (to be removed when LP: #1656340 is fixed) -[ -n "$XDG_RUNTIME_DIR" ] && mkdir -p $XDG_RUNTIME_DIR -m 700 - -# Ensure the app finds locale definitions (requires locales-all to be installed) -append_dir LOCPATH $RUNTIME/usr/lib/locale - -# If any, keep track of where XDG dirs were so we can potentially migrate the content later -test -f ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs && . ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs -for d in DOCUMENTS DESKTOP DOWNLOAD MUSIC PICTURES VIDEOS PUBLICSHARE TEMPLATES; do - eval $(echo "OLD_XDG_${d}_DIR")=`eval "$(echo "echo \\$XDG_${d}_DIR")"` -done - -# Setup user-dirs.* or run xdg-user-dirs-update if needed -needs_xdg_update=false -needs_xdg_links=false -if can_open_file "$REALHOME/.config/user-dirs.dirs" && can_open_file "$REALHOME/.config/user-dirs.locale"; then - mkdir -p $HOME/.config -m 700 - sed /^#/!s#\$HOME#${REALHOME}#g $REALHOME/.config/user-dirs.dirs > $HOME/.config/user-dirs.dirs - cp -a $REALHOME/.config/user-dirs.locale $HOME/.config/ - for f in user-dirs.dirs user-dirs.locale; do - md5sum < $REALHOME/.config/$f > $HOME/.config/$f.md5sum - done -else - needs_xdg_update=true - needs_xdg_links=true -fi - -# Check if we can actually read the contents of each xdg dir -test -f ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs && . ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs -XDG_SPECIAL_DIRS=($XDG_DOCUMENTS_DIR $XDG_DESKTOP_DIR $XDG_DOWNLOAD_DIR $XDG_MUSIC_DIR $XDG_PICTURES_DIR $XDG_VIDEOS_DIR $XDG_PUBLIC_DIR $XDG_TEMPLATES_DIR) -for d in ${XDG_SPECIAL_DIRS[@]}; do - if ! can_open_file $d; then - needs_xdg_update=true - fi -done - -# If needs XDG update and xdg-user-dirs-update exists in $PATH, run it -if [ $needs_xdg_update = true ] && command -v xdg-user-dirs-update >/dev/null; then - xdg-user-dirs-update -fi - -# Create links for user-dirs.dirs -if [ $needs_xdg_links = true ]; then - test -f ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs && . ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs - XDG_SPECIAL_DIRS=($XDG_DOCUMENTS_DIR $XDG_DESKTOP_DIR $XDG_DOWNLOAD_DIR $XDG_MUSIC_DIR $XDG_PICTURES_DIR $XDG_VIDEOS_DIR $XDG_PUBLIC_DIR $XDG_TEMPLATES_DIR) - for d in ${XDG_SPECIAL_DIRS[@]}; do - b=$(realpath "$d" --relative-to="$REALHOME") - if [ -e $REALHOME/$b ] && [ ! -e $HOME/$b ]; then - ln -s $REALHOME/$b $HOME/$b - fi - done -else - # If we aren't creating new links, check if we have content saved in old locations and move it - for d in DOCUMENTS DESKTOP DOWNLOAD MUSIC PICTURES VIDEOS PUBLICSHARE TEMPLATES; do - old=`eval "$(echo "echo \\$OLD_XDG_${d}_DIR")"` - new=`eval "$(echo "echo \\$XDG_${d}_DIR")"` - if [ -L "$old" ] && [ -d "$new" ] && [ `readlink "$old"` != "$new" ]; then - mv "$old"/* "$new"/ 2>/dev/null - elif [ -d "$old" ] && [ -d "$new" ] && [ "$old" != "$new" ]; then - mv "$old"/* "$new"/ 2>/dev/null - fi - done -fi - -# If detect wayland server socket, then set environment so applications prefer -# wayland, and setup compat symlink (until we use user mounts. Remember, -# XDG_RUNTIME_DIR is /run/user//snap.$SNAP so look in the parent directory -# for the socket. For details: -# https://forum.snapcraft.io/t/wayland-dconf-and-xdg-runtime-dir/186/10 -# Applications that don't support wayland natively may define DISABLE_WAYLAND -# (to any non-empty value) to skip that logic entirely. -wayland_available=false -if [[ -n "$XDG_RUNTIME_DIR" && -z "$DISABLE_WAYLAND" ]]; then - wdisplay="wayland-0" - if [ -n "$WAYLAND_DISPLAY" ]; then - wdisplay="$WAYLAND_DISPLAY" - fi - wayland_sockpath="$XDG_RUNTIME_DIR/../$wdisplay" - wayland_snappath="$XDG_RUNTIME_DIR/$wdisplay" - if [ -S "$wayland_sockpath" ]; then - # if running under wayland, use it - #export WAYLAND_DEBUG=1 - wayland_available=true - # create the compat symlink for now - if [ ! -e "$wayland_snappath" ]; then - ln -s "$wayland_sockpath" "$wayland_snappath" - fi - fi -fi - -# Make PulseAudio socket available inside the snap-specific $XDG_RUNTIME_DIR -if [ -n "$XDG_RUNTIME_DIR" ]; then - pulsenative="pulse/native" - pulseaudio_sockpath="$XDG_RUNTIME_DIR/../$pulsenative" - if [ -S "$pulseaudio_sockpath" ]; then - export PULSE_SERVER="unix:${pulseaudio_sockpath}" - fi -fi - -# GI repository -[ "$WITH_RUNTIME" = yes ] && prepend_dir GI_TYPELIB_PATH $RUNTIME/usr/lib/$ARCH/girepository-1.0 -[ "$WITH_RUNTIME" = yes ] && prepend_dir GI_TYPELIB_PATH $RUNTIME/usr/lib/girepository-1.0 -prepend_dir GI_TYPELIB_PATH $SNAP/usr/lib/$ARCH/girepository-1.0 -prepend_dir GI_TYPELIB_PATH $SNAP/usr/lib/girepository-1.0 -prepend_dir GI_TYPELIB_PATH $SNAP/usr/lib/gjs/girepository-1.0 - -# Keep an array of data dirs, for looping through them -IFS=':' read -r -a data_dirs_array <<< "$XDG_DATA_DIRS" - -# Font Config and themes -export FONTCONFIG_PATH=$RUNTIME/etc/fonts -export FONTCONFIG_FILE=$RUNTIME/etc/fonts/fonts.conf - -function make_user_fontconfig { - echo "" - if [ -d $REALHOME/.local/share/fonts ]; then - echo " $REALHOME/.local/share/fonts" - fi - if [ -d $REALHOME/.fonts ]; then - echo " $REALHOME/.fonts" - fi - for d in "${data_dirs_array[@]}"; do - if [ -d "$d/fonts" ]; then - echo " $d/fonts" - fi - done - echo ' conf.d' - # We need to include this default cachedir first so that caching - # works: without it, fontconfig will try to write to the real user home - # cachedir and be blocked by AppArmor. - echo ' fontconfig' - if [ -d $REALHOME/.cache/fontconfig ]; then - echo " $REALHOME/.cache/fontconfig" - fi - echo "" -} - -if [ $needs_update = true ]; then - rm -rf $XDG_DATA_HOME/{fontconfig,fonts,fonts-*,themes,.themes} - - # This fontconfig fragment is installed in a location that is - # included by the system fontconfig configuration: namely the - # etc/fonts/conf.d/50-user.conf file. - mkdir -p $XDG_CONFIG_HOME/fontconfig - make_user_fontconfig > $XDG_CONFIG_HOME/fontconfig/fonts.conf - - # the themes symlink are needed for GTK 3.18 when the prefix isn't changed - # GTK 3.20 looks into XDG_DATA_DIR which has connected themes. - ln -sf $RUNTIME/usr/share/themes $XDG_DATA_HOME - ln -sfn $RUNTIME/usr/share/themes $SNAP_USER_DATA/.themes -fi - -# Build mime.cache -# needed for gtk and qt icon -if [ $needs_update = true ]; then - rm -rf $XDG_DATA_HOME/mime - if [ ! -f $RUNTIME/usr/share/mime/mime.cache ]; then - if command -v update-mime-database >/dev/null; then - cp --preserve=timestamps -dR $RUNTIME/usr/share/mime $XDG_DATA_HOME - update-mime-database $XDG_DATA_HOME/mime - fi - fi -fi - -# Gio modules and cache (including gsettings module) -export GIO_MODULE_DIR=$XDG_CACHE_HOME/gio-modules -function compile_giomodules { - if [ -f $1/glib-2.0/gio-querymodules ]; then - rm -rf $GIO_MODULE_DIR - mkdir -p $GIO_MODULE_DIR - ln -s $1/gio/modules/*.so $GIO_MODULE_DIR - $1/glib-2.0/gio-querymodules $GIO_MODULE_DIR - fi -} -if [ $needs_update = true ]; then - compile_giomodules $RUNTIME/usr/lib/$ARCH -fi - -# Setup compiled gsettings schema -GS_SCHEMA_DIR=$XDG_DATA_HOME/glib-2.0/schemas -function compile_schemas { - if [ -f "$1" ]; then - rm -rf $GS_SCHEMA_DIR - mkdir -p $GS_SCHEMA_DIR - for d in "${data_dirs_array[@]}"; do - schema_dir=$d/glib-2.0/schemas - if [ -f "$schema_dir/gschemas.compiled" ]; then - # This directory already has compiled schemas - continue - fi - if [ -n "$(ls -A $schema_dir/*.xml 2>/dev/null)" ]; then - ln -s $schema_dir/*.xml $GS_SCHEMA_DIR - fi - if [ -n "$(ls -A $schema_dir/*.override 2>/dev/null)" ]; then - ln -s $schema_dir/*.override $GS_SCHEMA_DIR - fi - done - # Only compile schemas if we copied anyting - if [ -n "$(ls -A $GS_SCHEMA_DIR/*.xml $GS_SCHEMA_DIR/*.override 2>/dev/null)" ]; then - "$1" $GS_SCHEMA_DIR - fi - fi -} -if [ $needs_update = true ]; then - compile_schemas $RUNTIME/usr/lib/$ARCH/glib-2.0/glib-compile-schemas -fi - -# Enable gsettings user changes -# symlink the dconf file if home plug is connected for read -DCONF_DEST_USER_DIR=$SNAP_USER_DATA/.config/dconf -if [ ! -f $DCONF_DEST_USER_DIR/user ]; then - if [ -f $REALHOME/.config/dconf/user ]; then - mkdir -p $DCONF_DEST_USER_DIR - ln -s $REALHOME/.config/dconf/user $DCONF_DEST_USER_DIR - fi -fi - -# Testability support -append_dir LD_LIBRARY_PATH $SNAP/testability -append_dir LD_LIBRARY_PATH $SNAP/testability/$ARCH -append_dir LD_LIBRARY_PATH $SNAP/testability/$ARCH/mesa - -# Gdk-pixbuf loaders -export GDK_PIXBUF_MODULE_FILE=$XDG_CACHE_HOME/gdk-pixbuf-loaders.cache -export GDK_PIXBUF_MODULEDIR=$RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders -if [ $needs_update = true ]; then - rm -f $GDK_PIXBUF_MODULE_FILE - if [ -f $RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders ]; then - $RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders > $GDK_PIXBUF_MODULE_FILE - fi -fi - -# Icon themes cache -if [ $needs_update = true ]; then - rm -rf $XDG_DATA_HOME/icons - mkdir -p $XDG_DATA_HOME/icons - for d in "${data_dirs_array[@]}"; do - for i in $d/icons/*; do - if [ -f "$i/index.theme" -a ! -f "$i/icon-theme.cache" ]; then - theme_dir=$XDG_DATA_HOME/icons/$(basename "$i") - if [ ! -d "$theme_dir" ]; then - mkdir -p "$theme_dir" - ln -s $i/* "$theme_dir" - if [ -f $RUNTIME/usr/sbin/update-icon-caches ]; then - $RUNTIME/usr/sbin/update-icon-caches "$theme_dir" - elif [ -f $RUNTIME/usr/sbin/update-icon-cache.gtk2 ]; then - $RUNTIME/usr/sbin/update-icon-cache.gtk2 "$theme_dir" - fi - fi - fi - done - done -fi - -# GTK theme and behavior modifier -# Those can impact the theme engine used by Qt as well -gtk_configs=(.config/gtk-3.0/settings.ini .config/gtk-3.0/bookmarks .config/gtk-2.0/gtkfilechooser.ini) -for f in ${gtk_configs[@]}; do - dest="$SNAP_USER_DATA/$f" - if [ ! -L "$dest" ] - then - mkdir -p `dirname $dest` - ln -s $REALHOME/$f $dest - fi -done - -# create symbolic link to ibus socket path for ibus to look up its socket files -# (see comments #3 and #6 on https://launchpad.net/bugs/1580463) -IBUS_CONFIG_PATH=$XDG_CONFIG_HOME/ibus -mkdir -p $IBUS_CONFIG_PATH -[ -d $IBUS_CONFIG_PATH/bus ] && rm -rf $IBUS_CONFIG_PATH/bus -ln -sfn $REALHOME/.config/ibus/bus $IBUS_CONFIG_PATH - -############################## -# Glib minimum specific part # -############################## - -############################### -# Mark update and exec binary # -############################### - -[ $needs_update = true ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_REVISION" > $SNAP_USER_DATA/.last_revision - -if [ -n "$SNAP_DESKTOP_DEBUG" ]; then - echo "desktop-launch elapsed time: " $(date +%s.%N --date="$START seconds ago") - echo "Now running: exec $@" -fi - -exec "$@" diff --git a/pe b/pe deleted file mode 160000 index f681c21b..00000000 --- a/pe +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f681c21b7b2c6232b3252a4025a4b94c8d960d65 diff --git a/qtTools b/qtTools deleted file mode 160000 index cc52debd..00000000 --- a/qtTools +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cc52debd905e0ed061290d6fd00a5f1ab67478a5 diff --git a/snap/gui/icon.png b/snap/gui/icon.png old mode 100644 new mode 100755 diff --git a/src/CQtDeployer/CMakeLists.txt b/src/CQtDeployer/CMakeLists.txt new file mode 100644 index 00000000..a22e26cf --- /dev/null +++ b/src/CQtDeployer/CMakeLists.txt @@ -0,0 +1,117 @@ +# +# Copyright (C) 2021-2022 QuasarApp. +# Distributed under the GPLv3 software license, see the accompanying +# Everyone is permitted to copy and distribute verbatim copies +# of this license document, but changing it is not allowed. +# + +cmake_minimum_required(VERSION 3.18) + +get_filename_component(CURRENT_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(CURRENT_PROJECT "${PROJECT_NAME}") +option(SIGN_APP "This option enable od disabled sign apk and aab files" ON) + +file(GLOB_RECURSE SOURCE_CPP + "*.cpp" "*.h" +) + +if (${QT_VERSION_MAJOR}) + file(GLOB_RECURSE SOURCE_QRC + "*.qrc" + ) +endif() + +set(ALL_SOURCES ${SOURCE_CPP} ${SOURCE_QRC}) + +set(PUBLIC_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + +set(PRIVATE_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Private") + + +if (${QT_VERSION_MAJOR} EQUAL 6) + + qt_add_executable(${CURRENT_PROJECT} MANUAL_FINALIZATION ${ALL_SOURCES}) + +else() + if (ANDROID) + add_library(${CURRENT_PROJECT} ${ALL_SOURCES}) + else () + add_executable(${CURRENT_PROJECT} ${ALL_SOURCES} ) + endif() + +endif() + +target_link_libraries(${CURRENT_PROJECT} PUBLIC Deploy) + +target_include_directories(${CURRENT_PROJECT} PUBLIC ${PUBLIC_INCUDE_DIR}) +target_include_directories(${CURRENT_PROJECT} PRIVATE ${PRIVATE_INCUDE_DIR}) + +SET(TARGET_DIR "${CMAKE_SOURCE_DIR}/Distro") +file(MAKE_DIRECTORY ${TARGET_DIR}) + +if(QT_VERSION_MAJOR EQUAL 6) + # Add This line if your project use the Quick module + # qt_import_qml_plugins(${CURRENT_PROJECT}) + qt_finalize_executable(${CURRENT_PROJECT}) +endif() + + +set(LANGS ${CMAKE_CURRENT_SOURCE_DIR}/languages/en.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/ru.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/uk.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/ja.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/tr.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/zh.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/de.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/fr.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/es.ts + ${CMAKE_CURRENT_SOURCE_DIR}/languages/pl.ts) + +prepareQM(${CURRENT_PROJECT} ${CMAKE_CURRENT_SOURCE_DIR}/../ "${LANGS}") + +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/CQtDeployer.json") +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/CQtDeployerSingle.json") + +# qifw installer +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFWTemplate/packages/CQtDeployer/meta/package.xml") +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/package.xml") +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFWTemplate/packages/QIF/meta/package.xml") + +# snap +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Deploy/snapcraft.yaml.in" "${CMAKE_SOURCE_DIR}/snap/snapcraft.yaml" @ONLY) +add_custom_target(${name}Templates ALL + SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/snapcraft.yaml.in" +) + +# sets qifw variable +set(HomeDir "@HomeDir@") +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFWTemplate/config/config.xml") + + +addDeployFromCustomFile(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/CQtDeployer.json") + +set(QIFW_PLATFORM linux) +if (WIN32) + set(QIFW_PLATFORM windows) +endif() + +ADD_CUSTOM_TARGET( + downloadQIFW + SOURCES ${${name}files} + COMMAND python "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFW.py" ${QIFW_PLATFORM} ${QIFW_VERSION} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFW" + COMMENT python "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFW.py" ${QIFW_PLATFORM} ${QIFW_VERSION} "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/QIFW" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) +add_dependencies(deploy${CURRENT_PROJECT} downloadQIFW) + +addDeployFromCustomFile(${CURRENT_PROJECT}Single "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/CQtDeployerSingle.json") + +addDeploySnap(${CURRENT_PROJECT} "${CMAKE_SOURCE_DIR}/Distro/") + +if(TARGET snapcraft${CURRENT_PROJECT}) + message("snap is depends of single deploy") + add_dependencies(snapcraft${CURRENT_PROJECT} "deploy${CURRENT_PROJECT}Single") +endif() + +addReleaseSnap(${CURRENT_PROJECT}) diff --git a/src/CQtDeployer/Deploy/CQtDeployer.json.in b/src/CQtDeployer/Deploy/CQtDeployer.json.in new file mode 100644 index 00000000..0d336bad --- /dev/null +++ b/src/CQtDeployer/Deploy/CQtDeployer.json.in @@ -0,0 +1,84 @@ +{ + + "qmake": "@QT_QMAKE_EXECUTABLE@", + "allowEmptyPackages": true, + "targetPackage": [ + ["CQtDeployer.1_6", "CQtDeployer"], + ["CQtDeployer.1_6", "cqt"] + + ], + + "icon": [ + ["CQtDeployer", "./QIFWTemplate/res/icon.png"], + ["CQtDeployer.exe", "./QIFWTemplate/res/icon.ico"] + ], + + "extraData": [ + ["QIF", "./QIFW/QIF"], + ["CQtDeployer", "./../../../LICENSE"] + ], + + "extraDataOut": [ + ["QIF", ""], + ["CQtDeployer", ""] + ], + + "bin": [ + "src/CQtDeployer/CQtDeployer", + "src/CQtDeployer/CQtDeployer.exe" + ], + "clear": false, + "binPrefix": "@CMAKE_BINARY_DIR@", + "libDir": [ + "@CMAKE_SOURCE_DIR@", + "@CMAKE_PREFIX_PATH@", + "@CMAKE_BINARY_DIR@" + ], + + "prefix": [ + ["CQtDeployer.1_6", "1.6"], + ["QIF", "/"], + ["CQtDeployer", "/"] + + ], + + "publisher": [ + ["QIF", "Qt corporation"], + ["CQtDeployer", "QuasarApp group"], + ["CQtDeployer.1_6", "QuasarApp group"] + + ], + + "releaseDate": [ + ["QIF", "@TODAY@"], + ["CQtDeployer", "@TODAY@"], + ["CQtDeployer.1_6", "@TODAY@"] + + ], + + "name": [ + ["QIF", "QtInstallerFramework"], + ["CQtDeployer", "CQtDeployer"], + ["CQtDeployer.1_6", "CQtDeployer 1.6"] + ], + + "deployVersion": [ + ["QIF", "@QIFW_VERSION@"], + ["CQtDeployer", "@CQT_DEPLOYER_VERSION_SHORT_PREFIX@"], + ["CQtDeployer.1_6", "@CQT_DEPLOYER_VERSION@"] + + ], + + "recursiveDepth": "10", + "deploySystem": false, + "deb": false, + "qif": "./QIFWTemplate", + "qifOut": "CQtDeployer_@CQT_DEPLOYER_VERSION@_@CMAKE_SYSTEM_NAME@_@CMAKE_SYSTEM_PROCESSOR@", + "zip": false, + "ignoreEnv": [ + "@CMAKE_SOURCE_DIR@/Distro" + ], + "targetDir": "@CMAKE_SOURCE_DIR@/Distro" + +} + diff --git a/src/CQtDeployer/Deploy/CQtDeployerSingle.json.in b/src/CQtDeployer/Deploy/CQtDeployerSingle.json.in new file mode 100644 index 00000000..945f65ce --- /dev/null +++ b/src/CQtDeployer/Deploy/CQtDeployerSingle.json.in @@ -0,0 +1,36 @@ +{ + "extraData": "./QIFW/QIF", + "bin": [ + "src/CQtDeployer/CQtDeployer", + "src/CQtDeployer/CQtDeployer.exe" + ], + + "clear": false, + "binPrefix": "@CMAKE_BINARY_DIR@", + "libDir": [ + "@CMAKE_SOURCE_DIR@", + "@CMAKE_PREFIX_PATH@", + "@CMAKE_BINARY_DIR@" + ], + + "publisher": "QuasarApp group", + "releaseDate": "@TODAY@", + + "name": "CQtDeployer", + "deployVersion": "@CQT_DEPLOYER_VERSION@", + + "recursiveDepth": "10", + "deploySystem": false, + "deb": true, + "qif": false, + "zip": true, + "debOut": "CQtDeployer_@CQT_DEPLOYER_VERSION@_@CMAKE_SYSTEM_NAME@_@CMAKE_SYSTEM_PROCESSOR@.deb", + "zipOut": "CQtDeployer_@CQT_DEPLOYER_VERSION@_@CMAKE_SYSTEM_NAME@_@CMAKE_SYSTEM_PROCESSOR@.zip", + + "ignoreEnv": [ + "@CMAKE_SOURCE_DIR@/Distro" + ], + "targetDir": "@CMAKE_SOURCE_DIR@/Distro" + +} + diff --git a/QIFData/scripts/QIF.py b/src/CQtDeployer/Deploy/QIFW.py similarity index 68% rename from QIFData/scripts/QIF.py rename to src/CQtDeployer/Deploy/QIFW.py index 8908651e..96aa4a8a 100755 --- a/QIFData/scripts/QIF.py +++ b/src/CQtDeployer/Deploy/QIFW.py @@ -2,6 +2,7 @@ import os import subprocess import shutil +from glob import glob PLATFORM = sys.argv[1] VERSION = sys.argv[2] @@ -19,20 +20,27 @@ # Command Example : aqt tool linux tools_ifw 4.0 qt.tools.ifw.40 command = ["aqt", - "tool", -# "-b", -# "https://mirrors.ocf.berkeley.edu/qt/", + "install-tool", "--outputdir", PATHQIF, PLATFORM, + "desktop", "tools_ifw", - VERSION, "qt.tools.ifw." + VERSION.replace('.', '')] print("command=" + " ".join(command)) subprocess.call(command) +BASEPATHQIF = PATHQIF + "/Tools/QtInstallerFramework/" + VERSION[0:3] + +for file in glob(BASEPATHQIF + "/bin/repogen*"): + os.remove(file) +for file in glob(BASEPATHQIF + "/bin/archivegen*"): + os.remove(file) +for file in glob(BASEPATHQIF + "/bin/devtool*"): + os.remove(file) + os.rename(PATHQIF + "/Tools/QtInstallerFramework/" + VERSION[0:3] + "/bin/", PATHQIF + "/QIF") shutil.rmtree(PATHQIF + "/Tools") diff --git a/QIFData/config/banner.png b/src/CQtDeployer/Deploy/QIFWTemplate/config/banner.png similarity index 100% rename from QIFData/config/banner.png rename to src/CQtDeployer/Deploy/QIFWTemplate/config/banner.png diff --git a/QIFData/config/configLinux.xml b/src/CQtDeployer/Deploy/QIFWTemplate/config/config.xml.in similarity index 60% rename from QIFData/config/configLinux.xml rename to src/CQtDeployer/Deploy/QIFWTemplate/config/config.xml.in index a114868b..3203b47e 100644 --- a/QIFData/config/configLinux.xml +++ b/src/CQtDeployer/Deploy/QIFWTemplate/config/config.xml.in @@ -1,9 +1,9 @@ - 640px - 400px + 980px + 540px CQtDeployer - 1.5.4.17 + @CQT_DEPLOYER_VERSION@ CQtDeployer QuasarApp CQtDeployer @@ -15,12 +15,4 @@ Modern style.css logo.png - - - - http://quasarapp.ddns.net:3030/CQtDeployer/Linux - 1 - QuasarApp - - diff --git a/QIFData/config/controlScript.js b/src/CQtDeployer/Deploy/QIFWTemplate/config/controlScript.js similarity index 96% rename from QIFData/config/controlScript.js rename to src/CQtDeployer/Deploy/QIFWTemplate/config/controlScript.js index a09553a0..ba627e10 100644 --- a/QIFData/config/controlScript.js +++ b/src/CQtDeployer/Deploy/QIFWTemplate/config/controlScript.js @@ -6,7 +6,6 @@ function Controller() installer.uninstallationFinished.connect(this, Controller.prototype.uninstallationFinished); installer.installationFinished.connect(this, Controller.prototype.installationFinished); - } Controller.prototype.ComponentSelectionPageCallback = function() @@ -14,7 +13,7 @@ Controller.prototype.ComponentSelectionPageCallback = function() var widget = gui.currentPageWidget(); // get the current wizard page if (widget !== null && installer.isInstaller()) { widget.deselectAll(); - widget.selectComponent('cqtdeployer.1_5'); + widget.selectComponent('CQtDeployer.1_6'); widget.selectComponent('QIF'); } diff --git a/QIFData/config/icon.ico b/src/CQtDeployer/Deploy/QIFWTemplate/config/icon.ico similarity index 100% rename from QIFData/config/icon.ico rename to src/CQtDeployer/Deploy/QIFWTemplate/config/icon.ico diff --git a/QIFData/config/logo.png b/src/CQtDeployer/Deploy/QIFWTemplate/config/logo.png similarity index 100% rename from QIFData/config/logo.png rename to src/CQtDeployer/Deploy/QIFWTemplate/config/logo.png diff --git a/QIFData/config/ru.ts b/src/CQtDeployer/Deploy/QIFWTemplate/config/ru.ts similarity index 100% rename from QIFData/config/ru.ts rename to src/CQtDeployer/Deploy/QIFWTemplate/config/ru.ts diff --git a/QIFData/config/style.css b/src/CQtDeployer/Deploy/QIFWTemplate/config/style.css similarity index 100% rename from QIFData/config/style.css rename to src/CQtDeployer/Deploy/QIFWTemplate/config/style.css diff --git a/QIFData/packages/cqtdeployer.1_5/meta/installscript.js b/src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/installscript.js similarity index 96% rename from QIFData/packages/cqtdeployer.1_5/meta/installscript.js rename to src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/installscript.js index cbc7df46..da7e0f06 100644 --- a/QIFData/packages/cqtdeployer.1_5/meta/installscript.js +++ b/src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/installscript.js @@ -1,4 +1,4 @@ -const VERSION = "1.5" +const VERSION = "1.6" function Component() { @@ -88,7 +88,7 @@ function systemIntegration() { if (systemInfo.kernelType === "winnt") { - component.addOperation('Execute', ["SETX", "cqtdeployer", targetDir + "\\" + VERSION + "\\cqtdeployer.bat"], + component.addOperation('Execute', ["SETX", "cqtdeployer", targetDir + "\\" + VERSION + "\\CQtDeployer.bat"], "UNDOEXECUTE", ["SETX", "cqtdeployer", ""]) component.addOperation('Execute', ["SETX", "cqtDir", targetDir + "\\" + VERSION + "\\"], "UNDOEXECUTE", ["SETX", "cqtDir", ""]) @@ -133,15 +133,15 @@ function systemIntegration() { } } - component.addOperation('Execute', ["ln", "-sf", targetDir + "/" + VERSION + "/cqtdeployer.sh", + component.addOperation('Execute', ["ln", "-sf", targetDir + "/" + VERSION + "/CQtDeployer.sh", homeDir + "/.local/bin/cqtdeployer"], "UNDOEXECUTE", ["rm", "-f", homeDir + "/.local/bin/cqtdeployer"] ) - component.addOperation('Execute', ["ln", "-sf", targetDir + "/" + VERSION + "/cqt.sh", + component.addOperation('Execute', ["ln", "-sf", targetDir + "/" + VERSION + "/bin/cqt.sh", homeDir + "/.local/bin/cqt"], "UNDOEXECUTE", ["rm", "-f", homeDir + "/.local/bin/cqt"] ) - component.addOperation('Execute', ["ln", "-sf", targetDir + "/" + VERSION + "/cqt.sh", + component.addOperation('Execute', ["ln", "-sf", targetDir + "/" + VERSION + "/bin/cqt.sh", homeDir + "/.local/bin/cqtdeployer.cqt"], "UNDOEXECUTE", ["rm", "-f", homeDir + "/.local/bin/cqtdeployer.cqt"] ) diff --git a/src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/package.xml.in b/src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/package.xml.in new file mode 100644 index 00000000..7d3372c8 --- /dev/null +++ b/src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer.1_6/meta/package.xml.in @@ -0,0 +1,11 @@ + + + CQtDeployer @CQT_DEPLOYER_VERSION_SHORT_PREFIX@ + CQtDeployer @CQT_DEPLOYER_VERSION_SHORT_PREFIX@ + @CQT_DEPLOYER_VERSION@ + true + false + + @TODAY@ + 201 + diff --git a/QIFData/packages/cqtdeployer/meta/package.xml b/src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer/meta/package.xml.in similarity index 71% rename from QIFData/packages/cqtdeployer/meta/package.xml rename to src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer/meta/package.xml.in index 35d0c064..5a05b4c0 100644 --- a/QIFData/packages/cqtdeployer/meta/package.xml +++ b/src/CQtDeployer/Deploy/QIFWTemplate/packages/CQtDeployer/meta/package.xml.in @@ -2,9 +2,9 @@ CQtDeployer CQtDeployer - 1.5 + @CQT_DEPLOYER_VERSION_SHORT_PREFIX@ true false - 2021-05-25 + @TODAY@ 100 diff --git a/QIFData/packages/QIF/meta/package.xml b/src/CQtDeployer/Deploy/QIFWTemplate/packages/QIF/meta/package.xml.in similarity index 73% rename from QIFData/packages/QIF/meta/package.xml rename to src/CQtDeployer/Deploy/QIFWTemplate/packages/QIF/meta/package.xml.in index f3b3f058..7114500e 100644 --- a/QIFData/packages/QIF/meta/package.xml +++ b/src/CQtDeployer/Deploy/QIFWTemplate/packages/QIF/meta/package.xml.in @@ -2,7 +2,7 @@ Qt Installer Framework Qt Installer Framework for CQtDeployer - 4.4.0.0 - 2022-07-25 + @QIFW_VERSION@ + @TODAY@ true diff --git a/QIFData/scripts/alias/cqt.sh b/src/CQtDeployer/Deploy/QIFWTemplate/res/cqt.sh similarity index 100% rename from QIFData/scripts/alias/cqt.sh rename to src/CQtDeployer/Deploy/QIFWTemplate/res/cqt.sh diff --git a/src/CQtDeployer/Deploy/QIFWTemplate/res/icon.ico b/src/CQtDeployer/Deploy/QIFWTemplate/res/icon.ico new file mode 100644 index 00000000..e39643da Binary files /dev/null and b/src/CQtDeployer/Deploy/QIFWTemplate/res/icon.ico differ diff --git a/QIFData/packages/cqtdeployer.1_5/data/1.5/icon.png b/src/CQtDeployer/Deploy/QIFWTemplate/res/icon.png similarity index 100% rename from QIFData/packages/cqtdeployer.1_5/data/1.5/icon.png rename to src/CQtDeployer/Deploy/QIFWTemplate/res/icon.png diff --git a/src/CQtDeployer/Deploy/snap/cqt.sh b/src/CQtDeployer/Deploy/snap/cqt.sh new file mode 100644 index 00000000..42903fd5 --- /dev/null +++ b/src/CQtDeployer/Deploy/snap/cqt.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +function join_by { local IFS="$1"; shift; echo "$*"; } + +var=$(join_by , $@) +$SNAP/CQtDeployer.sh $var -bin $var + diff --git a/snap/snapcraft.yaml b/src/CQtDeployer/Deploy/snapcraft.yaml.in similarity index 57% rename from snap/snapcraft.yaml rename to src/CQtDeployer/Deploy/snapcraft.yaml.in index d519e450..aab72287 100644 --- a/snap/snapcraft.yaml +++ b/src/CQtDeployer/Deploy/snapcraft.yaml.in @@ -6,8 +6,8 @@ # name: cqtdeployer # you probably want to 'snapcraft register ' -version: '1.5.4.17' # just for humans, typically '1.2+git' or '1.3.2' -summary: deploy your qt projects # 79 char long summary +version: '@CQT_DEPLOYER_VERSION@' +summary: deploy your qt or c/c++ projects # 79 char long summary description: | Console app for deploy qt libs. Key differences of this program @@ -16,15 +16,15 @@ description: | grade: stable # must be 'stable' to release into candidate/stable channels confinement: strict # use 'strict' once you have the right plugs and slots -base: core18 +base: core22 icon: snap/gui/icon.png apps: cqtdeployer: - command: bash $SNAP/cqtdeployer.sh + command: bin/bash $SNAP/CQtDeployer.sh plugs: [home, removable-media, process-control, system-backup] cqt: - command: bash $SNAP/cqt.sh + command: bin/bash $SNAP/cqt.sh plugs: [home, removable-media, process-control, system-backup] parts: @@ -32,9 +32,10 @@ parts: # See 'snapcraft plugins' plugin: dump - source: QIFData/packages/cqtdeployer.1_5/data/1.5 + source: Distro/CQtDeployer_@CQT_DEPLOYER_VERSION@_@CMAKE_SYSTEM_NAME@_@CMAKE_SYSTEM_PROCESSOR@.zip stage-packages: + - bash - libfreetype6 - libpng16-16 - dpkg @@ -44,13 +45,38 @@ parts: - libxcb-keysyms1 - libxcb-render-util0 - libxcb-xinerama0 + - libfontconfig1 + - libxcb-glx0 + - libx11-xcb1 + - libxcb-randr0 + - libxcb-shape0 + - libxcb-sync1 + - libxcb-xfixes0 + - libxcb-xkb1 + - libxext6 + - libx11-6 + - libxkbcommon-x11-0 + - libxkbcommon0 + - libgl1-mesa-glx - qif: + after: [ cqt-meta ] + + override-stage: | + snapcraftctl stage + chmod 777 -R "$SNAPCRAFT_STAGE" + + cqt-meta: plugin: dump - source: QIFData/packages/QIF/data/ + source: src/CQtDeployer/Deploy/snap/ override-stage: | snapcraftctl stage - chmod 777 -R "$SNAPCRAFT_STAGE/QIF" + chmod 777 -R "$SNAPCRAFT_STAGE" +# cqt-qifw: +# plugin: dump +# source: src/CQtDeployer/Deploy/QIFW/ +# override-stage: | +# snapcraftctl stage +# chmod 777 -R "$SNAPCRAFT_STAGE" diff --git a/src/CQtDeployer/languages/de.ts b/src/CQtDeployer/languages/de.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/de.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/en.ts b/src/CQtDeployer/languages/en.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/en.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/es.ts b/src/CQtDeployer/languages/es.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/es.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/fr.ts b/src/CQtDeployer/languages/fr.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/fr.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/ja.ts b/src/CQtDeployer/languages/ja.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/ja.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/pl.ts b/src/CQtDeployer/languages/pl.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/pl.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/ru.ts b/src/CQtDeployer/languages/ru.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/ru.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/tr.ts b/src/CQtDeployer/languages/tr.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/tr.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/uk.ts b/src/CQtDeployer/languages/uk.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/uk.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/src/CQtDeployer/languages/zh.ts b/src/CQtDeployer/languages/zh.ts new file mode 100644 index 00000000..713fd788 --- /dev/null +++ b/src/CQtDeployer/languages/zh.ts @@ -0,0 +1,46 @@ + + + + + controlScript + + CQtDeployer + + + + Install CQtDeployer + + + + install in system + + + + Installer + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer". + + + + CQtDeployer successfully installed on your computer to use the call "cqtdeployer", cqt or cqtdeployer.cqt. + + + + + installscript + + install in system + + + + Installer + + + + The "~/local/bin" folder was not initialized, you may need to reboot to work correctly! + + + + diff --git a/CQtDeployer/main.cpp b/src/CQtDeployer/main.cpp similarity index 95% rename from CQtDeployer/main.cpp rename to src/CQtDeployer/main.cpp index cc2425aa..b5179ef3 100644 --- a/CQtDeployer/main.cpp +++ b/src/CQtDeployer/main.cpp @@ -5,8 +5,6 @@ * of this license document, but changing it is not allowed. */ -#include "extracter.h" -#include "quasarapp.h" #include "deploycore.h" #include #include diff --git a/src/Deploy/CMakeLists.txt b/src/Deploy/CMakeLists.txt new file mode 100644 index 00000000..eae2542b --- /dev/null +++ b/src/Deploy/CMakeLists.txt @@ -0,0 +1,46 @@ +# +# Copyright (C) 2020-2022 QuasarApp. +# Distributed under the GPLv3 software license, see the accompanying +# Everyone is permitted to copy and distribute verbatim copies +# of this license document, but changing it is not allowed. +# + +cmake_minimum_required(VERSION 3.18) + +get_filename_component(CURRENT_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(CURRENT_PROJECT "${CURRENT_PROJECT_DIR}") +add_definitions(-DCQT_DEPLOYER_LIBRARY) + + +file(GLOB_RECURSE SOURCE_CPP + "src/*.cpp" + "src/*.h" + + "src/Distributions/*.cpp" + "src/Distributions/*.h" + +) + +file(GLOB_RECURSE SOURCE_QRC + "*.qrc" + "src/*.qrc" +) + +set(PUBLIC_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") + + +add_library(${CURRENT_PROJECT} ${SOURCE_CPP} ${SOURCE_QRC}) + +target_link_libraries(${CURRENT_PROJECT} PUBLIC QuasarApp QtELFReader pe-parse zip) + +target_include_directories(${CURRENT_PROJECT} PUBLIC ${PUBLIC_INCUDE_DIR}) + +set(LANGS ${CMAKE_CURRENT_SOURCE_DIR}/languages/en.ts) + + +prepareQM(${CURRENT_PROJECT} ${CMAKE_CURRENT_SOURCE_DIR} "${LANGS}") + +set(QML_IMPORT_PATH ${QML_IMPORT_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/src" CACHE STRING "" FORCE) + +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/src/deploy_global.h") diff --git a/src/Deploy/CQtDeployer.qrc b/src/Deploy/CQtDeployer.qrc new file mode 100644 index 00000000..ef011b79 --- /dev/null +++ b/src/Deploy/CQtDeployer.qrc @@ -0,0 +1,5 @@ + + + languages/en.qm + + diff --git a/QIFData/packages/QIF/meta/ru.ts b/src/Deploy/languages/en.ts similarity index 100% rename from QIFData/packages/QIF/meta/ru.ts rename to src/Deploy/languages/en.ts diff --git a/Deploy/DeployResources.qrc b/src/Deploy/src/DeployResources.qrc similarity index 100% rename from Deploy/DeployResources.qrc rename to src/Deploy/src/DeployResources.qrc diff --git a/Deploy/Distributions/Templates/Icon.ico b/src/Deploy/src/Distributions/Templates/Icon.ico similarity index 100% rename from Deploy/Distributions/Templates/Icon.ico rename to src/Deploy/src/Distributions/Templates/Icon.ico diff --git a/Deploy/Distributions/Templates/Icon.png b/src/Deploy/src/Distributions/Templates/Icon.png similarity index 100% rename from Deploy/Distributions/Templates/Icon.png rename to src/Deploy/src/Distributions/Templates/Icon.png diff --git a/Deploy/Distributions/Templates/deb/DEBIAN/control b/src/Deploy/src/Distributions/Templates/deb/DEBIAN/control similarity index 100% rename from Deploy/Distributions/Templates/deb/DEBIAN/control rename to src/Deploy/src/Distributions/Templates/deb/DEBIAN/control diff --git a/Deploy/Distributions/Templates/deb/DEBIAN/postinst b/src/Deploy/src/Distributions/Templates/deb/DEBIAN/postinst similarity index 100% rename from Deploy/Distributions/Templates/deb/DEBIAN/postinst rename to src/Deploy/src/Distributions/Templates/deb/DEBIAN/postinst diff --git a/Deploy/Distributions/Templates/deb/DEBIAN/prerm b/src/Deploy/src/Distributions/Templates/deb/DEBIAN/prerm similarity index 100% rename from Deploy/Distributions/Templates/deb/DEBIAN/prerm rename to src/Deploy/src/Distributions/Templates/deb/DEBIAN/prerm diff --git a/Deploy/Distributions/Templates/qif/Styles/quasar.css b/src/Deploy/src/Distributions/Templates/qif/Styles/quasar.css similarity index 100% rename from Deploy/Distributions/Templates/qif/Styles/quasar.css rename to src/Deploy/src/Distributions/Templates/qif/Styles/quasar.css diff --git a/Deploy/Distributions/Templates/qif/Styles/quasarDark.css b/src/Deploy/src/Distributions/Templates/qif/Styles/quasarDark.css similarity index 100% rename from Deploy/Distributions/Templates/qif/Styles/quasarDark.css rename to src/Deploy/src/Distributions/Templates/qif/Styles/quasarDark.css diff --git a/Deploy/Distributions/Templates/qif/config custom designe/config.xml b/src/Deploy/src/Distributions/Templates/qif/config custom designe/config.xml similarity index 100% rename from Deploy/Distributions/Templates/qif/config custom designe/config.xml rename to src/Deploy/src/Distributions/Templates/qif/config custom designe/config.xml diff --git a/Deploy/Distributions/Templates/qif/config custom designe/controlScript.qs b/src/Deploy/src/Distributions/Templates/qif/config custom designe/controlScript.qs similarity index 100% rename from Deploy/Distributions/Templates/qif/config custom designe/controlScript.qs rename to src/Deploy/src/Distributions/Templates/qif/config custom designe/controlScript.qs diff --git a/Deploy/Distributions/Templates/qif/config custom designe/style.css b/src/Deploy/src/Distributions/Templates/qif/config custom designe/style.css similarity index 100% rename from Deploy/Distributions/Templates/qif/config custom designe/style.css rename to src/Deploy/src/Distributions/Templates/qif/config custom designe/style.css diff --git a/Deploy/Distributions/Templates/qif/config/config.xml b/src/Deploy/src/Distributions/Templates/qif/config/config.xml similarity index 100% rename from Deploy/Distributions/Templates/qif/config/config.xml rename to src/Deploy/src/Distributions/Templates/qif/config/config.xml diff --git a/Deploy/Distributions/Templates/qif/config/controlScript.qs b/src/Deploy/src/Distributions/Templates/qif/config/controlScript.qs similarity index 100% rename from Deploy/Distributions/Templates/qif/config/controlScript.qs rename to src/Deploy/src/Distributions/Templates/qif/config/controlScript.qs diff --git a/Deploy/Distributions/Templates/qif/packages/default/meta/installscript.qs b/src/Deploy/src/Distributions/Templates/qif/packages/default/meta/installscript.qs similarity index 100% rename from Deploy/Distributions/Templates/qif/packages/default/meta/installscript.qs rename to src/Deploy/src/Distributions/Templates/qif/packages/default/meta/installscript.qs diff --git a/Deploy/Distributions/Templates/qif/packages/default/meta/package.xml b/src/Deploy/src/Distributions/Templates/qif/packages/default/meta/package.xml similarity index 100% rename from Deploy/Distributions/Templates/qif/packages/default/meta/package.xml rename to src/Deploy/src/Distributions/Templates/qif/packages/default/meta/package.xml diff --git a/Deploy/Distributions/configures/Init multiPackage configuration.json b/src/Deploy/src/Distributions/configures/Init multiPackage configuration.json similarity index 100% rename from Deploy/Distributions/configures/Init multiPackage configuration.json rename to src/Deploy/src/Distributions/configures/Init multiPackage configuration.json diff --git a/Deploy/Distributions/configures/Init single configuration.json b/src/Deploy/src/Distributions/configures/Init single configuration.json similarity index 100% rename from Deploy/Distributions/configures/Init single configuration.json rename to src/Deploy/src/Distributions/configures/Init single configuration.json diff --git a/Deploy/Distributions/configures/Init.json b/src/Deploy/src/Distributions/configures/Init.json similarity index 100% rename from Deploy/Distributions/configures/Init.json rename to src/Deploy/src/Distributions/configures/Init.json diff --git a/Deploy/Distributions/deb.cpp b/src/Deploy/src/Distributions/deb.cpp similarity index 100% rename from Deploy/Distributions/deb.cpp rename to src/Deploy/src/Distributions/deb.cpp diff --git a/Deploy/Distributions/deb.h b/src/Deploy/src/Distributions/deb.h similarity index 100% rename from Deploy/Distributions/deb.h rename to src/Deploy/src/Distributions/deb.h diff --git a/Deploy/Distributions/defaultdistro.cpp b/src/Deploy/src/Distributions/defaultdistro.cpp similarity index 100% rename from Deploy/Distributions/defaultdistro.cpp rename to src/Deploy/src/Distributions/defaultdistro.cpp diff --git a/Deploy/Distributions/defaultdistro.h b/src/Deploy/src/Distributions/defaultdistro.h similarity index 100% rename from Deploy/Distributions/defaultdistro.h rename to src/Deploy/src/Distributions/defaultdistro.h diff --git a/Deploy/Distributions/idistribution.cpp b/src/Deploy/src/Distributions/idistribution.cpp similarity index 98% rename from Deploy/Distributions/idistribution.cpp rename to src/Deploy/src/Distributions/idistribution.cpp index 33b6377b..2c29b2ca 100644 --- a/Deploy/Distributions/idistribution.cpp +++ b/src/Deploy/src/Distributions/idistribution.cpp @@ -9,7 +9,10 @@ #include "pathutils.h" #include #include +#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0) #include +#endif + #include #include #include @@ -82,7 +85,11 @@ bool iDistribution::unpackFile(const QFileInfo &resource, } QTextStream stream(&file); +#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0) stream.setCodec(QTextCodec::codecForName("UTF-8")); +#else + stream.setEncoding(QStringConverter::Utf8); +#endif stream << inputText; } else { file.write(inputData); diff --git a/Deploy/Distributions/idistribution.h b/src/Deploy/src/Distributions/idistribution.h similarity index 100% rename from Deploy/Distributions/idistribution.h rename to src/Deploy/src/Distributions/idistribution.h diff --git a/Deploy/Distributions/qif.cpp b/src/Deploy/src/Distributions/qif.cpp similarity index 99% rename from Deploy/Distributions/qif.cpp rename to src/Deploy/src/Distributions/qif.cpp index f53df585..947d9cdc 100644 --- a/Deploy/Distributions/qif.cpp +++ b/src/Deploy/src/Distributions/qif.cpp @@ -1,5 +1,4 @@ #include "qif.h" -#include "quasarapp.h" #include "deploycore.h" #include "deployconfig.h" @@ -78,8 +77,7 @@ QList QIF::runCmd() { "-c", QuasarAppUtils::Params::getArg("qifConfig", location + "/config/config.xml"), "-p", - QuasarAppUtils::Params::getArg("qifPackages", location + "/packages/"), - "-v" + QuasarAppUtils::Params::getArg("qifPackages", location + "/packages/") }; QString resources = QuasarAppUtils::Params::getArg("qifResources"); @@ -96,6 +94,8 @@ QList QIF::runCmd() { cmd.arguments.push_back(customFormat); } + cmd.arguments += "-v"; + return {cmd}; } diff --git a/Deploy/Distributions/qif.h b/src/Deploy/src/Distributions/qif.h similarity index 100% rename from Deploy/Distributions/qif.h rename to src/Deploy/src/Distributions/qif.h diff --git a/Deploy/Distributions/templateinfo.cpp b/src/Deploy/src/Distributions/templateinfo.cpp similarity index 100% rename from Deploy/Distributions/templateinfo.cpp rename to src/Deploy/src/Distributions/templateinfo.cpp diff --git a/Deploy/Distributions/templateinfo.h b/src/Deploy/src/Distributions/templateinfo.h similarity index 100% rename from Deploy/Distributions/templateinfo.h rename to src/Deploy/src/Distributions/templateinfo.h diff --git a/Deploy/Distributions/ziparhive.cpp b/src/Deploy/src/Distributions/ziparhive.cpp similarity index 100% rename from Deploy/Distributions/ziparhive.cpp rename to src/Deploy/src/Distributions/ziparhive.cpp diff --git a/Deploy/Distributions/ziparhive.h b/src/Deploy/src/Distributions/ziparhive.h similarity index 100% rename from Deploy/Distributions/ziparhive.h rename to src/Deploy/src/Distributions/ziparhive.h diff --git a/Deploy/ScriptsTemplates/linux.sh b/src/Deploy/src/ScriptsTemplates/linux.sh similarity index 100% rename from Deploy/ScriptsTemplates/linux.sh rename to src/Deploy/src/ScriptsTemplates/linux.sh diff --git a/Deploy/ScriptsTemplates/windows.bat b/src/Deploy/src/ScriptsTemplates/windows.bat similarity index 100% rename from Deploy/ScriptsTemplates/windows.bat rename to src/Deploy/src/ScriptsTemplates/windows.bat diff --git a/Deploy/configparser.cpp b/src/Deploy/src/configparser.cpp similarity index 97% rename from Deploy/configparser.cpp rename to src/Deploy/src/configparser.cpp index bf371d4a..6b3b1191 100644 --- a/Deploy/configparser.cpp +++ b/src/Deploy/src/configparser.cpp @@ -16,10 +16,9 @@ #include "packing.h" #include "pathutils.h" #include "pluginsparser.h" -#include "quasarapp.h" - +#include "defines.h" #include - +#include #include #include #include @@ -547,7 +546,7 @@ bool ConfigParser::initDistroStruct() { return false; } - if (trData.size() && !parsePackagesPrivate(mainDistro, trData, &DistroModule::addTr)) { + if (trData.size() && !parsePackagesPrivate(mainDistro, trData, &DistroModule::addTranslation)) { packagesErrorLog("tr"); return false; } @@ -841,12 +840,12 @@ bool ConfigParser::parseClearMode() { return true; } -QSet ConfigParser::getQtPathesFromTargets() { - QSet res; +QString ConfigParser::getRPathFromTargets() { + QString res; for (const auto &i: _config.targets()) { - if (i.isValid() && !i.getQtPath().isEmpty()) { - res.insert(i.getQtPath()); + if (i.isValid()) { + res += i.getRPath() + DeployCore::getEnvSeparator(); } } @@ -1176,9 +1175,9 @@ bool ConfigParser::initQmake() { if (!info.isFile() || (info.baseName() != "qmake")) { - auto qtList = getQtPathesFromTargets(); + QString qmakeFromRPath = DeployCore::findProcess(getRPathFromTargets(), "qmake"); - if (qtList.isEmpty()) { + if (qmakeFromRPath.isEmpty()) { if (!QuasarAppUtils::Params::isEndable("noCheckPATH")) { auto env = QProcessEnvironment::systemEnvironment(); @@ -1191,6 +1190,14 @@ bool ConfigParser::initQmake() { return false; } + + QuasarAppUtils::Params::log(QString("The qmake was found in the PATH variable. qmake : %0" + " If you want to disable search qmake executable in PATH variable," + " use the noCheckPATH option"). + arg(proc), + QuasarAppUtils::Info); + + return initQmakePrivate(proc); } @@ -1204,21 +1211,15 @@ bool ConfigParser::initQmake() { } - if (qtList.size() > 1) { - QuasarAppUtils::Params::log("Your deployment targets were compiled by different qmakes, " - "auto-capture of the Qt libraries is not possible. " - "Please use the -qmake flag to solve this problem.", - QuasarAppUtils::Error); - return false; - } - auto qt = *qtList.begin(); + QuasarAppUtils::Params::log(QString("The qmake was found in the RPATH variable. qmake : %0" + " If you want to disable search qmake executable in RPATH variable," + " use the noCheckRPATH option"). + arg(qmakeFromRPath), + QuasarAppUtils::Info); - if (qt.rightRef(3).compare(QString("lib"), Qt::CaseInsensitive)) { - return initQmakePrivate(QFileInfo(qt + "/../bin/qmake").absoluteFilePath()); - } + return initQmakePrivate(qmakeFromRPath); - return initQmakePrivate(QFileInfo(qt + "/qmake").absoluteFilePath()); } return initQmakePrivate(qmake); @@ -1240,9 +1241,9 @@ bool ConfigParser::setQmake(const QString &value) { proc.setArguments({"-query"}); proc.start(); - if (!proc.waitForFinished(1000)) { - QuasarAppUtils::Params::log("run qmake fail!"); + if (!(proc.waitForStarted(1000) && proc.waitForFinished(1000))) { + QuasarAppUtils::Params::log("Run qmake fail! " + proc.errorString(), QuasarAppUtils::Warning); return false; } @@ -1646,7 +1647,7 @@ bool ConfigParser::smartMoveTargets() { } - _config.targetsEdit() = temp; + _config.targetsEdit() = QHash{temp.begin(), temp.end()}; return result && configureTargets(); } diff --git a/Deploy/configparser.h b/src/Deploy/src/configparser.h similarity index 96% rename from Deploy/configparser.h rename to src/Deploy/src/configparser.h index 8abf05ad..51b51a02 100644 --- a/Deploy/configparser.h +++ b/src/Deploy/src/configparser.h @@ -9,10 +9,6 @@ #define CQT_H #include "deployconfig.h" #include "distrostruct.h" -#include "envirement.h" -#include "ignorerule.h" -#include "targetdata.h" -#include "targetinfo.h" #include #include @@ -21,6 +17,7 @@ #include #include #include "deploy_global.h" +#include "targetdata.h" class FileManager; class DependenciesScanner; @@ -36,7 +33,9 @@ class DEPLOYSHARED_EXPORT ConfigParser bool smartMoveTargets(); const DeployConfig* config() const; - friend class deploytest; + friend class DeployTargetTest; + friend class IconsTest; + friend class SetTargetDirTest; private: @@ -63,7 +62,7 @@ class DEPLOYSHARED_EXPORT ConfigParser bool parseClearMode(); - QSet getQtPathesFromTargets(); + QString getRPathFromTargets(); void setTargetDir(const QString &target = ""); bool setTargets(const QStringList &value); diff --git a/Deploy/defines.h b/src/Deploy/src/defines.h similarity index 100% rename from Deploy/defines.h rename to src/Deploy/src/defines.h diff --git a/Deploy/dependenciesscanner.cpp b/src/Deploy/src/dependenciesscanner.cpp similarity index 98% rename from Deploy/dependenciesscanner.cpp rename to src/Deploy/src/dependenciesscanner.cpp index 996276fe..21521fad 100644 --- a/Deploy/dependenciesscanner.cpp +++ b/src/Deploy/src/dependenciesscanner.cpp @@ -6,13 +6,12 @@ */ #include "dependenciesscanner.h" +#include "deployconfig.h" #include "deploycore.h" -#include "quasarapp.h" -#include "configparser.h" +#include "qaglobalutils.h" #include #include #include -#include "pathutils.h" DependenciesScanner::DependenciesScanner() { diff --git a/Deploy/dependenciesscanner.h b/src/Deploy/src/dependenciesscanner.h similarity index 100% rename from Deploy/dependenciesscanner.h rename to src/Deploy/src/dependenciesscanner.h diff --git a/Deploy/dependencymap.cpp b/src/Deploy/src/dependencymap.cpp similarity index 99% rename from Deploy/dependencymap.cpp rename to src/Deploy/src/dependencymap.cpp index 5e13506f..6c4f117e 100644 --- a/Deploy/dependencymap.cpp +++ b/src/Deploy/src/dependencymap.cpp @@ -7,7 +7,7 @@ #include "dependencymap.h" #include "deploycore.h" -#include "quasarapp.h" +#include "qaglobalutils.h" DependencyMap::DependencyMap() { _qtModules = DeployCore::QtModule::NONE; diff --git a/Deploy/dependencymap.h b/src/Deploy/src/dependencymap.h similarity index 100% rename from Deploy/dependencymap.h rename to src/Deploy/src/dependencymap.h diff --git a/Deploy/deploy.cpp b/src/Deploy/src/deploy.cpp similarity index 95% rename from Deploy/deploy.cpp rename to src/Deploy/src/deploy.cpp index 02698997..c19ae4c3 100644 --- a/Deploy/deploy.cpp +++ b/src/Deploy/src/deploy.cpp @@ -25,6 +25,8 @@ Deploy::Deploy() { int Deploy::run() { + QuasarAppUtils::Settings::initService(); + if (!prepare()) { return PrepareError; } @@ -41,6 +43,8 @@ int Deploy::run() { } _fileManager->saveDeploymendFiles(_paramsParser->config()->getTargetDir()); + QuasarAppUtils::Settings::deinitService(); + return Good; } diff --git a/Deploy/deploy.h b/src/Deploy/src/deploy.h similarity index 95% rename from Deploy/deploy.h rename to src/Deploy/src/deploy.h index 96ab3b51..8a2c41cf 100644 --- a/Deploy/deploy.h +++ b/src/Deploy/src/deploy.h @@ -63,6 +63,8 @@ class DEPLOYSHARED_EXPORT Deploy */ static QString codeString(int code); friend class deploytest; + friend class CheckQtTest; + friend class QIFWBinaryCreatorTest; }; #endif // DEPLOY_H diff --git a/Deploy/deploy_global.h b/src/Deploy/src/deploy_global.h.in similarity index 87% rename from Deploy/deploy_global.h rename to src/Deploy/src/deploy_global.h.in index c3cb5276..feac3fb9 100644 --- a/Deploy/deploy_global.h +++ b/src/Deploy/src/deploy_global.h.in @@ -12,9 +12,10 @@ #define DEFAULT_COFIGURATION_FILE QString("CQtDeployer.json") #define DISTRO_DIR QString("DistributionKit") +#define CQT_DEPLOYER_VERSION "@CQT_DEPLOYER_VERSION@" -#if defined(DEPLOY_LIBRARY) +#if defined(CQT_DEPLOYER_LIBRARY) # define DEPLOYSHARED_EXPORT Q_DECL_EXPORT #else # define DEPLOYSHARED_EXPORT Q_DECL_IMPORT diff --git a/Deploy/deployconfig.cpp b/src/Deploy/src/deployconfig.cpp similarity index 99% rename from Deploy/deployconfig.cpp rename to src/Deploy/src/deployconfig.cpp index 948dcb0c..7d9407ae 100644 --- a/Deploy/deployconfig.cpp +++ b/src/Deploy/src/deployconfig.cpp @@ -6,7 +6,7 @@ */ #include "deployconfig.h" -#include "quasarapp.h" +#include "qaglobalutils.h" void DeployConfig::reset() { *this = DeployConfig{}; diff --git a/Deploy/deployconfig.h b/src/Deploy/src/deployconfig.h similarity index 100% rename from Deploy/deployconfig.h rename to src/Deploy/src/deployconfig.h diff --git a/Deploy/deploycore.cpp b/src/Deploy/src/deploycore.cpp similarity index 98% rename from Deploy/deploycore.cpp rename to src/Deploy/src/deploycore.cpp index b13c063b..d4e65ccf 100644 --- a/Deploy/deploycore.cpp +++ b/src/Deploy/src/deploycore.cpp @@ -5,9 +5,8 @@ * of this license document, but changing it is not allowed. */ -#include "extracter.h" #include "deploycore.h" -#include "pathutils.h" +#include "defines.h" #include "pluginsparser.h" #include @@ -156,7 +155,7 @@ LibPriority DeployCore::getLibPriority(const QString &lib) { } bool DeployCore::containsModule(const QString& moduleLibrary, const QString& lib) { - QRegExp erfexp(QString(moduleLibrary).replace("QtX", "Qt[4,5,6]")); + QRegularExpression erfexp(QString(moduleLibrary).replace("QtX", "Qt[4,5,6]")); return lib.contains(erfexp); } @@ -600,11 +599,11 @@ QStringList DeployCore::extractTranslation(const QSet &libs) { } QString DeployCore::getAppVersion() { - return APP_VERSION; + return CQT_DEPLOYER_VERSION; } QString DeployCore::getAppVersionName() { - return "*** Binary Box ***"; + return "*** Cool Core ***"; } QString DeployCore::getQtVersion() { @@ -755,13 +754,13 @@ QString DeployCore::getVCredist(const QString &_qtbinDir) { } QString DeployCore::getMSVCName(MSVCVersion msvc) { - if (msvc | MSVCVersion::MSVC_13) { + if (msvc & MSVCVersion::MSVC_13) { return "msvc2013"; - } else if (msvc | MSVCVersion::MSVC_15) { + } else if (msvc & MSVCVersion::MSVC_15) { return "msvc2015"; - } else if (msvc | MSVCVersion::MSVC_17) { + } else if (msvc & MSVCVersion::MSVC_17) { return "msvc2017"; - } else if (msvc | MSVCVersion::MSVC_19) { + } else if (msvc & MSVCVersion::MSVC_19) { return "msvc2019"; } @@ -769,9 +768,9 @@ QString DeployCore::getMSVCName(MSVCVersion msvc) { } QString DeployCore::getMSVCVersion(MSVCVersion msvc) { - if (msvc | MSVCVersion::MSVC_x32) { + if (msvc & MSVCVersion::MSVC_x32) { return "x86"; - } else if (msvc | MSVCVersion::MSVC_x64) { + } else if (msvc & MSVCVersion::MSVC_x64) { return "x64"; } @@ -812,8 +811,7 @@ QtMajorVersion DeployCore::isQtLibName(const QString &lib) { isQt = QtMajorVersion::Qt6; } - if (isQt && QuasarAppUtils::Params::isEndable("noQt") && - !QuasarAppUtils::Params::isEndable("qmake")) { + if (isQt && QuasarAppUtils::Params::isEndable("noQt")) { return QtMajorVersion::NoQt; } @@ -986,7 +984,7 @@ QString DeployCore::transportPathToSnapRoot(const QString &path) { return path; } - if (path.size() && path[0] != "/") { + if (path.size() && path[0] != QString("/")) { auto absalutPath = QProcessEnvironment::systemEnvironment().value("PWD") + "/" + path; if (!absalutPath.contains(DeployCore::snapRootFS())) { return snapRootFS() + "/" + absalutPath; diff --git a/Deploy/deploycore.h b/src/Deploy/src/deploycore.h similarity index 99% rename from Deploy/deploycore.h rename to src/Deploy/src/deploycore.h index d0fd2eaf..79cb8720 100644 --- a/Deploy/deploycore.h +++ b/src/Deploy/src/deploycore.h @@ -12,8 +12,7 @@ #include #include #include "deploy_global.h" -#include "defines.h" -#include "quasarapp.h" +#include enum MSVCVersion: int { MSVC_Unknown = 0x0, diff --git a/Deploy/distromodule.cpp b/src/Deploy/src/distromodule.cpp similarity index 96% rename from Deploy/distromodule.cpp rename to src/Deploy/src/distromodule.cpp index a85573b0..a34e106d 100644 --- a/Deploy/distromodule.cpp +++ b/src/Deploy/src/distromodule.cpp @@ -175,15 +175,15 @@ void DistroModule::setInstallDirDEB(const QString &newInstallDir) { _installDirDEB = newInstallDir; } -QSet DistroModule::tr() const { +QSet DistroModule::translation() const { return _tr; } -void DistroModule::setTr(const QSet &tr) { +void DistroModule::setTranslation(const QSet &tr) { _tr = tr; } -void DistroModule::addTr(const QString &tr) { +void DistroModule::addTranslation(const QString &tr) { _tr += tr; } diff --git a/Deploy/distromodule.h b/src/Deploy/src/distromodule.h similarity index 96% rename from Deploy/distromodule.h rename to src/Deploy/src/distromodule.h index 84aa6a6a..9b8ebe07 100644 --- a/Deploy/distromodule.h +++ b/src/Deploy/src/distromodule.h @@ -70,9 +70,9 @@ class DEPLOYSHARED_EXPORT DistroModule: public DistroStruct void setExtraData(const QSet &extraFiles); void addExtraData(const QString &extraFile); - QSet tr() const; - void setTr(const QSet &tr); - void addTr(const QString &tr); + QSet translation() const; + void setTranslation(const QSet &tr); + void addTranslation(const QString &tr); QString installDirDEB() const; void setInstallDirDEB(const QString &newInstallDir); diff --git a/Deploy/distrostruct.cpp b/src/Deploy/src/distrostruct.cpp similarity index 100% rename from Deploy/distrostruct.cpp rename to src/Deploy/src/distrostruct.cpp diff --git a/Deploy/distrostruct.h b/src/Deploy/src/distrostruct.h similarity index 97% rename from Deploy/distrostruct.h rename to src/Deploy/src/distrostruct.h index 782c7daa..73ba4fb6 100644 --- a/Deploy/distrostruct.h +++ b/src/Deploy/src/distrostruct.h @@ -54,6 +54,7 @@ class DEPLOYSHARED_EXPORT DistroStruct bool isEmpty(); friend class deploytest; + friend class DistroStructTest; }; diff --git a/Deploy/elf_type.cpp b/src/Deploy/src/elf_type.cpp similarity index 78% rename from Deploy/elf_type.cpp rename to src/Deploy/src/elf_type.cpp index cb2829af..50dfe614 100644 --- a/Deploy/elf_type.cpp +++ b/src/Deploy/src/elf_type.cpp @@ -50,6 +50,37 @@ int ELF::getVersionOfTag(const QByteArray& tag, QByteArray& source) const { return ver; } +QString ELF::extractRPath(ElfReader& reader) const { + + QString result; + if (!QuasarAppUtils::Params::isEndable("noCheckRPATH")) { + auto dynStr = getDynamicString(reader); + + for (auto i = dynStr.rbegin(); i != dynStr.rend(); ++i) { + + if (i->contains("end_")) { + return result; + } + + const auto pathes = i->split(DeployCore::getEnvSeparator()); + for (const auto &path: pathes) { + if (path.contains("/")) { + if (result.size()) { + result += DeployCore::getEnvSeparator() + DeployCore::transportPathToSnapRoot(path); + } else { + result += DeployCore::transportPathToSnapRoot(path); + } + } + } + + if (result.size()) + return result; + } + } + + return result; +} + bool ELF::getLibInfo(const QString &lib, LibInfo &info) const { ElfReader reader(lib); @@ -82,25 +113,10 @@ bool ELF::getLibInfo(const QString &lib, LibInfo &info) const { return false; } - if (!QuasarAppUtils::Params::isEndable("noCheckRPATH")) { - auto dynStr = getDynamicString(reader); - - for (auto i = dynStr.rbegin(); i != dynStr.rend(); ++i) { - - if (i->contains("end_")) { - break; - } - - if (QFileInfo(*i).isDir()) { - info.setQtPath(DeployCore::transportPathToSnapRoot(*i)); - } - - } - } - QFileInfo infolib(lib); info.setName(infolib.fileName()); info.setPath(infolib.absolutePath()); + info.setRPath(extractRPath(reader)); auto dep = reader.dependencies(); for (const auto &i : dep) { diff --git a/Deploy/elf_type.h b/src/Deploy/src/elf_type.h similarity index 88% rename from Deploy/elf_type.h rename to src/Deploy/src/elf_type.h index 217861f2..f2138fd7 100644 --- a/Deploy/elf_type.h +++ b/src/Deploy/src/elf_type.h @@ -7,22 +7,25 @@ #ifndef ELF_H #define ELF_H -#include "../qtTools/src/shared/winutils/elfreader.h" +#include "elfreader.h" #include "igetlibinfo.h" class ELF : public IGetLibInfo { +public: + ELF(); + + bool getLibInfo(const QString &lib, LibInfo &info) const override; + + private: QByteArrayList getDynamicString(ElfReader &reader) const; int getVersionOfTag(const QByteArray &tag, QByteArray &source) const; -public: - ELF(); - - bool getLibInfo(const QString &lib, LibInfo &info) const override; + QString extractRPath(ElfReader &reader) const; }; #endif // ELF_H diff --git a/Deploy/envirement.cpp b/src/Deploy/src/envirement.cpp similarity index 100% rename from Deploy/envirement.cpp rename to src/Deploy/src/envirement.cpp diff --git a/Deploy/envirement.h b/src/Deploy/src/envirement.h similarity index 100% rename from Deploy/envirement.h rename to src/Deploy/src/envirement.h diff --git a/Deploy/extra.cpp b/src/Deploy/src/extra.cpp similarity index 100% rename from Deploy/extra.cpp rename to src/Deploy/src/extra.cpp diff --git a/Deploy/extra.h b/src/Deploy/src/extra.h similarity index 100% rename from Deploy/extra.h rename to src/Deploy/src/extra.h diff --git a/Deploy/extracter.cpp b/src/Deploy/src/extracter.cpp similarity index 95% rename from Deploy/extracter.cpp rename to src/Deploy/src/extracter.cpp index ac617101..cffa61f9 100644 --- a/Deploy/extracter.cpp +++ b/src/Deploy/src/extracter.cpp @@ -20,7 +20,7 @@ #include #include #include - +#include #include #include @@ -266,7 +266,7 @@ bool Extracter::copyTr() { QuasarAppUtils::Warning); } - const auto trFiles = i->tr(); + const auto trFiles = i->translation(); for (const auto &tr: trFiles) { QFileInfo info(tr); @@ -473,10 +473,23 @@ bool Extracter::extractQml() { } } + + QStringList toCopyQmlFiles; + for (const auto& plugin: qAsConst(plugins)) { + const auto qmlFiles = QDir(plugin).entryInfoList(QDir::Files); + for (const auto& qmlFile: qmlFiles) { + toCopyQmlFiles.push_back(qmlFile.absoluteFilePath()); + } + } + + // This function works very slow because use list mask + // solution: use the QSet and restriction comparese of the pathes for the mask argument. + // to-do optimise this function if (!_fileManager->copyFolder(cnf->qtDir.getQmls(), targetPath + distro.getQmlOutDir(), DeployCore::debugExtensions() , - &listItems, &plugins)) { + &listItems, + &toCopyQmlFiles)) { return false; } diff --git a/Deploy/extracter.h b/src/Deploy/src/extracter.h similarity index 100% rename from Deploy/extracter.h rename to src/Deploy/src/extracter.h diff --git a/Deploy/filemanager.cpp b/src/Deploy/src/filemanager.cpp similarity index 97% rename from Deploy/filemanager.cpp rename to src/Deploy/src/filemanager.cpp index b2992c70..0c0cba43 100644 --- a/Deploy/filemanager.cpp +++ b/src/Deploy/src/filemanager.cpp @@ -10,12 +10,15 @@ #include "filemanager.h" #include #include -#include "configparser.h" +#include "defines.h" +#include "deployconfig.h" #include "deploycore.h" #include #include #include #include "pathutils.h" +#include +#include #ifdef Q_OS_WIN #include "windows.h" @@ -435,7 +438,7 @@ void FileManager::clear(const QString& targetDir, bool force) { for (auto it = sortedOldData.end(); it != sortedOldData.begin(); --it) { - auto index = it - 1; + auto index = std::prev(it); if (!index.value().exists()) { continue; @@ -469,9 +472,10 @@ bool FileManager::copyFile(const QString &file, const QString &target, QString FileManager::changeDistanation(const QString& absalutePath, QString basePath, int depch) { - - auto prefixes = absalutePath.split(QRegExp("[\\/]"), splitbehavior); - depch = std::min(depch, prefixes.size()); + QRegularExpression _matcher; + _matcher.setPattern("[\\/]"); + auto prefixes = absalutePath.split(_matcher, splitbehavior); + depch = std::min(static_cast(depch), static_cast(prefixes.size())); while (depch) { auto index = prefixes.size() - depch; if (index >= 0) { diff --git a/Deploy/filemanager.h b/src/Deploy/src/filemanager.h similarity index 100% rename from Deploy/filemanager.h rename to src/Deploy/src/filemanager.h diff --git a/Deploy/generalfiles_type.cpp b/src/Deploy/src/generalfiles_type.cpp similarity index 100% rename from Deploy/generalfiles_type.cpp rename to src/Deploy/src/generalfiles_type.cpp diff --git a/Deploy/generalfiles_type.h b/src/Deploy/src/generalfiles_type.h similarity index 100% rename from Deploy/generalfiles_type.h rename to src/Deploy/src/generalfiles_type.h diff --git a/Deploy/igetlibinfo.cpp b/src/Deploy/src/igetlibinfo.cpp similarity index 100% rename from Deploy/igetlibinfo.cpp rename to src/Deploy/src/igetlibinfo.cpp diff --git a/Deploy/igetlibinfo.h b/src/Deploy/src/igetlibinfo.h similarity index 100% rename from Deploy/igetlibinfo.h rename to src/Deploy/src/igetlibinfo.h diff --git a/Deploy/ignorerule.cpp b/src/Deploy/src/ignorerule.cpp similarity index 100% rename from Deploy/ignorerule.cpp rename to src/Deploy/src/ignorerule.cpp diff --git a/Deploy/ignorerule.h b/src/Deploy/src/ignorerule.h similarity index 100% rename from Deploy/ignorerule.h rename to src/Deploy/src/ignorerule.h diff --git a/Deploy/libinfo.cpp b/src/Deploy/src/libinfo.cpp similarity index 95% rename from Deploy/libinfo.cpp rename to src/Deploy/src/libinfo.cpp index 4f52289b..6d494f04 100644 --- a/Deploy/libinfo.cpp +++ b/src/Deploy/src/libinfo.cpp @@ -84,14 +84,14 @@ void LibInfo::setPriority(const LibPriority &value) { _priority = value; } -QString LibInfo::getQtPath() const +const QString &LibInfo::getRPath() const { - return _qtPath; + return _rpath; } -void LibInfo::setQtPath(const QString &value) +void LibInfo::setRPath(const QString &value) { - _qtPath = value; + _rpath = value; } WinAPI LibInfo::getWinApi() const { @@ -124,7 +124,7 @@ QString LibInfo::toString() const { return QString("LibInfo: path: '%0', name: '%1', qtPath: '%2', platform: '%3', dependencies: '%4'"). arg(_path, _name, - _qtPath, + _rpath, DeployCore::platformToString(_platform), dependenciesList.join(", ")); } @@ -136,7 +136,7 @@ QString LibInfo::fullPath() const { void LibInfo::clear() { _path = ""; _name = ""; - _qtPath = ""; + _rpath = ""; _platform = Platform::UnknownPlatform; _dependncies.clear(); _allDep.clear(); diff --git a/Deploy/libinfo.h b/src/Deploy/src/libinfo.h similarity index 95% rename from Deploy/libinfo.h rename to src/Deploy/src/libinfo.h index edbf1d89..976f40f8 100644 --- a/Deploy/libinfo.h +++ b/src/Deploy/src/libinfo.h @@ -42,8 +42,8 @@ class DEPLOYSHARED_EXPORT LibInfo { LibPriority getPriority() const; void setPriority(const LibPriority &value); - QString getQtPath() const; - void setQtPath(const QString &value); + const QString& getRPath() const; + void setRPath(const QString &value); WinAPI getWinApi() const; void setWinApi(WinAPI winApi); QtMajorVersion isDependetOfQt() const; @@ -60,7 +60,7 @@ class DEPLOYSHARED_EXPORT LibInfo { QString _path; QSet _dependncies; bool _dependsOfGui; - QString _qtPath; + QString _rpath; LibPriority _priority = NotFile; WinAPI _winApi = WinAPI::NoWinAPI; diff --git a/Deploy/metafilemanager.cpp b/src/Deploy/src/metafilemanager.cpp similarity index 100% rename from Deploy/metafilemanager.cpp rename to src/Deploy/src/metafilemanager.cpp diff --git a/Deploy/metafilemanager.h b/src/Deploy/src/metafilemanager.h similarity index 100% rename from Deploy/metafilemanager.h rename to src/Deploy/src/metafilemanager.h diff --git a/Deploy/packagecontrol.cpp b/src/Deploy/src/packagecontrol.cpp similarity index 100% rename from Deploy/packagecontrol.cpp rename to src/Deploy/src/packagecontrol.cpp diff --git a/Deploy/packagecontrol.h b/src/Deploy/src/packagecontrol.h similarity index 100% rename from Deploy/packagecontrol.h rename to src/Deploy/src/packagecontrol.h diff --git a/Deploy/packing.cpp b/src/Deploy/src/packing.cpp similarity index 100% rename from Deploy/packing.cpp rename to src/Deploy/src/packing.cpp diff --git a/Deploy/packing.h b/src/Deploy/src/packing.h similarity index 99% rename from Deploy/packing.h rename to src/Deploy/src/packing.h index 0b7d78c0..7aea55f6 100644 --- a/Deploy/packing.h +++ b/src/Deploy/src/packing.h @@ -8,6 +8,7 @@ #ifndef PACKING_H #define PACKING_H +#include #include #include #include "deploy_global.h" diff --git a/Deploy/pathutils.cpp b/src/Deploy/src/pathutils.cpp similarity index 88% rename from Deploy/pathutils.cpp rename to src/Deploy/src/pathutils.cpp index ab44240f..a191a67d 100644 --- a/Deploy/pathutils.cpp +++ b/src/Deploy/src/pathutils.cpp @@ -89,12 +89,12 @@ QChar PathUtils::getDrive(QString path) { return path[0]; } - return 0; + return {}; } bool PathUtils::isAbsalutPath(const QString &path) { if (getDrive(path).isNull()) { - return path.size() && (path.at(0) == "/" || path.at(0) == "\\"); + return path.size() && (path.at(0) == QString("/") || path.at(0) == QString("\\")); } return true; @@ -117,9 +117,11 @@ QString PathUtils::getName(const QString &path) { if (fixedPath == "/") { return fixedPath; } + QRegularExpression _matche; - short endIndex = fixedPath.lastIndexOf(QRegularExpression("[/\\\\]")); - short beginIndex = fixedPath.lastIndexOf(QRegularExpression("[/\\\\]"), endIndex - 1) + 1; + _matche.setPattern("[/\\\\]"); + short endIndex = fixedPath.lastIndexOf(_matche); + short beginIndex = fixedPath.lastIndexOf(_matche, endIndex - 1) + 1; return fixedPath.mid(beginIndex, endIndex - beginIndex); } @@ -134,9 +136,11 @@ QString PathUtils::popItem(QString &path) { path = ""; return fixedPath; } + QRegularExpression _matche; - short endIndex = fixedPath.lastIndexOf(QRegularExpression("[/\\\\]")); - short beginIndex = fixedPath.lastIndexOf(QRegularExpression("[/\\\\]"), endIndex - 1) + 1; + _matche.setPattern("[/\\\\]"); + short endIndex = fixedPath.lastIndexOf(_matche); + short beginIndex = fixedPath.lastIndexOf(_matche, endIndex - 1) + 1; path = fixedPath.left(beginIndex); diff --git a/Deploy/pathutils.h b/src/Deploy/src/pathutils.h similarity index 100% rename from Deploy/pathutils.h rename to src/Deploy/src/pathutils.h diff --git a/Deploy/pe_type.cpp b/src/Deploy/src/pe_type.cpp similarity index 100% rename from Deploy/pe_type.cpp rename to src/Deploy/src/pe_type.cpp diff --git a/Deploy/pe_type.h b/src/Deploy/src/pe_type.h similarity index 100% rename from Deploy/pe_type.h rename to src/Deploy/src/pe_type.h diff --git a/Deploy/pluginsparser.cpp b/src/Deploy/src/pluginsparser.cpp similarity index 99% rename from Deploy/pluginsparser.cpp rename to src/Deploy/src/pluginsparser.cpp index 3e3562d5..e5e5f915 100644 --- a/Deploy/pluginsparser.cpp +++ b/src/Deploy/src/pluginsparser.cpp @@ -9,7 +9,7 @@ #include "pluginsparser.h" #include #include -#include +#include PluginsParser::PluginsParser(){ } diff --git a/Deploy/pluginsparser.h b/src/Deploy/src/pluginsparser.h similarity index 100% rename from Deploy/pluginsparser.h rename to src/Deploy/src/pluginsparser.h diff --git a/Deploy/qml.cpp b/src/Deploy/src/qml.cpp similarity index 90% rename from Deploy/qml.cpp rename to src/Deploy/src/qml.cpp index c0fbb92f..f9beb90c 100644 --- a/Deploy/qml.cpp +++ b/src/Deploy/src/qml.cpp @@ -9,9 +9,9 @@ #include #include -#include "quasarapp.h" +#include "defines.h" #include "deploycore.h" -#include "deployconfig.h" +#include "qregularexpression.h" QStringList QML::extractImportLine(const QString& line) const { QStringList result; @@ -24,7 +24,7 @@ QStringList QML::extractImportLine(const QString& line) const { return result; } // qt5 - result << (list[2][0] + "#" + list[1].replace(".", "/")); + result << (list[2][0] + QString("#") + list[1].replace(".", "/")); } else if (list.count() == 2 || (list.count() == 4 && list[2] == "as")) { // qt6 result << (list[1].replace(".", "/")); @@ -39,8 +39,18 @@ QStringList QML::extractImportsFromFile(const QString &filepath) const { if (!F.open(QIODevice::ReadOnly)) return QStringList(); QString content = F.readAll(); - content.remove(QRegExp("\\{(.*)\\}")); - content.remove(QRegExp("/\\*(.*)\\*/")); + QRegularExpression matcher; + + matcher.setPattern("\\{(.*)\\}"); + content.remove(matcher); + + matcher.setPattern("/\\*(.*)\\*/"); + content.remove(matcher); + + // Replace optional imports to restrict option, because before Qt 6.3 The Qml app needee of optional qml packas. + content.replace("optional import", "import"); + + const auto list = content.split("\n"); for (const QString &line : list) for (QString &word : line.split(";", splitbehavior)) @@ -72,18 +82,19 @@ bool QML::extractImportsFromDir(const QString &path, bool recursive) { for (const auto &import : qAsConst(imports)) { if (!_imports.contains(import)) { _imports.insert(import); - extractImportsFromDir(getPathFromImport(import), recursive); + extractImportsFromDir(getPathFromImport(import), false); } } } for (const auto& module: qAsConst(qmlmodule)) { QStringList imports = extractImportsFromQmlModule(module.absoluteFilePath()); + imports += extractImportsFromFile(module.absoluteFilePath()); for (const auto &import : qAsConst(imports)) { if (!_imports.contains(import)) { _imports.insert(import); - extractImportsFromDir(getPathFromImport(import), recursive); + extractImportsFromDir(getPathFromImport(import), false); } } } @@ -94,7 +105,7 @@ bool QML::extractImportsFromDir(const QString &path, bool recursive) { auto importQtQml = "QtQml"; if (!_imports.contains(importQtQml)) { _imports.insert(importQtQml); - extractImportsFromDir(getPathFromImport(importQtQml), recursive); + extractImportsFromDir(getPathFromImport(importQtQml), false); } } @@ -125,8 +136,9 @@ QString QML::getPathFromImport(const QString &import, bool checkVersions) { } else { return ""; } - - auto words = importData.value(index).split(QRegExp("[/\\\\]")); + QRegularExpression matcher; + matcher.setPattern("[/\\\\]"); + auto words = importData.value(index).split(matcher); const bool isSecond = importData.first() == "2" && checkVersions; bool secondVersion = isSecond; diff --git a/Deploy/qml.h b/src/Deploy/src/qml.h similarity index 95% rename from Deploy/qml.h rename to src/Deploy/src/qml.h index 31d3a0bb..eac9dbac 100644 --- a/Deploy/qml.h +++ b/src/Deploy/src/qml.h @@ -39,6 +39,8 @@ class DEPLOYSHARED_EXPORT QML { void setQtVersion(const QtMajorVersion &qtVersion); friend class deploytest; + friend class QmlScanerTest; + friend class QMLExtractTest; }; #endif // QML_DEPLY_H diff --git a/Deploy/qtdir.cpp b/src/Deploy/src/qtdir.cpp similarity index 100% rename from Deploy/qtdir.cpp rename to src/Deploy/src/qtdir.cpp diff --git a/Deploy/qtdir.h b/src/Deploy/src/qtdir.h similarity index 100% rename from Deploy/qtdir.h rename to src/Deploy/src/qtdir.h diff --git a/Deploy/targetdata.cpp b/src/Deploy/src/targetdata.cpp similarity index 100% rename from Deploy/targetdata.cpp rename to src/Deploy/src/targetdata.cpp diff --git a/Deploy/targetdata.h b/src/Deploy/src/targetdata.h similarity index 100% rename from Deploy/targetdata.h rename to src/Deploy/src/targetdata.h diff --git a/Deploy/targetinfo.cpp b/src/Deploy/src/targetinfo.cpp similarity index 100% rename from Deploy/targetinfo.cpp rename to src/Deploy/src/targetinfo.cpp diff --git a/Deploy/targetinfo.h b/src/Deploy/src/targetinfo.h similarity index 100% rename from Deploy/targetinfo.h rename to src/Deploy/src/targetinfo.h diff --git a/Deploy/zipcompresser.cpp b/src/Deploy/src/zipcompresser.cpp similarity index 99% rename from Deploy/zipcompresser.cpp rename to src/Deploy/src/zipcompresser.cpp index 1bfbaf40..eb0f8ef3 100644 --- a/Deploy/zipcompresser.cpp +++ b/src/Deploy/src/zipcompresser.cpp @@ -8,7 +8,7 @@ #include "zipcompresser.h" #include -#include "zip.h" +#include ZipCompresser::ZipCompresser() { diff --git a/Deploy/zipcompresser.h b/src/Deploy/src/zipcompresser.h similarity index 100% rename from Deploy/zipcompresser.h rename to src/Deploy/src/zipcompresser.h diff --git a/src/QtELFReader/CMakeLists.txt b/src/QtELFReader/CMakeLists.txt new file mode 100644 index 00000000..86051c50 --- /dev/null +++ b/src/QtELFReader/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# Copyright (C) 2020-2022 QuasarApp. +# Distributed under the GPLv3 software license, see the accompanying +# Everyone is permitted to copy and distribute verbatim copies +# of this license document, but changing it is not allowed. +# + +cmake_minimum_required(VERSION 3.18) + +get_filename_component(CURRENT_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +set(CURRENT_PROJECT "${CURRENT_PROJECT_DIR}") +add_definitions(-DQT_ELFREADER_LIBRARY) + + +file(GLOB_RECURSE SOURCE_CPP + "src/*.cpp" + "src/*.h" +) + +set(PUBLIC_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") + +if (NOT QT_VERSION_MAJOR) + find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +endif() + +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) + +add_library(${CURRENT_PROJECT} ${SOURCE_CPP}) + +target_link_libraries(${CURRENT_PROJECT} PUBLIC Qt::Core ) + +target_include_directories(${CURRENT_PROJECT} PUBLIC ${PUBLIC_INCUDE_DIR}) + + +configure_file_in(${CURRENT_PROJECT} "${CMAKE_CURRENT_SOURCE_DIR}/src/elfreader_global.h") diff --git a/src/QtELFReader/src/elfreader.cpp b/src/QtELFReader/src/elfreader.cpp new file mode 100644 index 00000000..ab224261 --- /dev/null +++ b/src/QtELFReader/src/elfreader.cpp @@ -0,0 +1,440 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "elfreader.h" + +#include + +QT_BEGIN_NAMESPACE + +/* This is a copy of the ELF reader contained in Qt Creator (src/libs/utils), + * extended by the dependencies() function to read out the dependencies of a dynamic executable. */ + +quint16 getHalfWord(const unsigned char *&s, const ElfData &context) +{ + quint16 res; + if (context.endian == Elf_ELFDATA2MSB) + res = qFromBigEndian(s); + else + res = qFromLittleEndian(s); + s += 2; + return res; +} + +quint32 getWord(const unsigned char *&s, const ElfData &context) +{ + quint32 res; + if (context.endian == Elf_ELFDATA2MSB) + res = qFromBigEndian(s); + else + res = qFromLittleEndian(s); + s += 4; + return res; +} + +quint64 getAddress(const unsigned char *&s, const ElfData &context) +{ + quint64 res; + if (context.elfclass == Elf_ELFCLASS32) { + if (context.endian == Elf_ELFDATA2MSB) + res = qFromBigEndian(s); + else + res = qFromLittleEndian(s); + s += 4; + } else { + if (context.endian == Elf_ELFDATA2MSB) + res = qFromBigEndian(s); + else + res = qFromLittleEndian(s); + s += 8; + } + return res; +} + +quint64 getOffset(const unsigned char *&s, const ElfData &context) +{ + return getAddress(s, context); +} + +static void parseSectionHeader(const uchar *s, ElfSectionHeader *sh, const ElfData &context) +{ + sh->index = getWord(s, context); + sh->type = getWord(s, context); + sh->flags = quint32(getOffset(s, context)); + sh->addr = getAddress(s, context); + sh->offset = getOffset(s, context); + sh->size = getOffset(s, context); +} + +static void parseProgramHeader(const uchar *s, ElfProgramHeader *sh, const ElfData &context) +{ + sh->type = getWord(s, context); + sh->offset = getOffset(s, context); + /* p_vaddr = */ getAddress(s, context); + /* p_paddr = */ getAddress(s, context); + sh->filesz = getWord(s, context); + sh->memsz = getWord(s, context); +} + +class ElfMapper +{ +public: + ElfMapper(const ElfReader *reader) : file(reader->m_binary) {} + + bool map() + { + if (!file.open(QIODevice::ReadOnly)) + return false; + + fdlen = quint64(file.size()); + ustart = file.map(0, qint64(fdlen)); + if (ustart == 0) { + // Try reading the data into memory instead. + raw = file.readAll(); + start = raw.constData(); + fdlen = quint64(raw.size()); + } + return true; + } + +public: + QFile file; + QByteArray raw; + union { const char *start; const uchar *ustart; }; + quint64 fdlen; +}; + +ElfReader::ElfReader(const QString &binary) + : m_binary(binary) +{ +} + +ElfData ElfReader::readHeaders() +{ + readIt(); + return m_elfData; +} + +static inline QString msgInvalidElfObject(const QString &binary, const QString &why) +{ + return QStringLiteral("'%1' is an invalid ELF object (%2)") + .arg(QDir::toNativeSeparators(binary), why); +} + +ElfReader::Result ElfReader::readIt() +{ + if (!m_elfData.sectionHeaders.isEmpty()) + return Ok; + if (!m_elfData.programHeaders.isEmpty()) + return Ok; + + ElfMapper mapper(this); + if (!mapper.map()) + return Corrupt; + + const quint64 fdlen = mapper.fdlen; + + if (fdlen < 64) { + m_errorString = QStringLiteral("'%1' is not an ELF object (file too small)").arg(QDir::toNativeSeparators(m_binary)); + return NotElf; + } + + if (strncmp(mapper.start, "\177ELF", 4) != 0) { + m_errorString = QStringLiteral("'%1' is not an ELF object").arg(QDir::toNativeSeparators(m_binary)); + return NotElf; + } + + // 32 or 64 bit + m_elfData.elfclass = ElfClass(mapper.start[4]); + const bool is64Bit = m_elfData.elfclass == Elf_ELFCLASS64; + if (m_elfData.elfclass != Elf_ELFCLASS32 && m_elfData.elfclass != Elf_ELFCLASS64) { + m_errorString = msgInvalidElfObject(m_binary, QStringLiteral("odd cpu architecture")); + return Corrupt; + } + + // int bits = (data[4] << 5); + // If you remove this check to read ELF objects of a different arch, + // please make sure you modify the typedefs + // to match the _plugin_ architecture. + // if ((sizeof(void*) == 4 && bits != 32) + // || (sizeof(void*) == 8 && bits != 64)) { + // if (errorString) + // *errorString = QLibrary::QStringLiteral("'%1' is an invalid ELF object (%2)") + // .arg(m_binary).arg(QLatin1String("wrong cpu architecture")); + // return Corrupt; + // } + + // Read Endianhness. + m_elfData.endian = ElfEndian(mapper.ustart[5]); + if (m_elfData.endian != Elf_ELFDATA2LSB && m_elfData.endian != Elf_ELFDATA2MSB) { + m_errorString = msgInvalidElfObject(m_binary, QStringLiteral("odd endianness")); + return Corrupt; + } + + const uchar *data = mapper.ustart + 16; // e_ident + m_elfData.elftype = ElfType(getHalfWord(data, m_elfData)); + m_elfData.elfmachine = ElfMachine(getHalfWord(data, m_elfData)); + /* e_version = */ getWord(data, m_elfData); + m_elfData.entryPoint = getAddress(data, m_elfData); + + quint64 e_phoff = getOffset(data, m_elfData); + quint64 e_shoff = getOffset(data, m_elfData); + /* e_flags = */ getWord(data, m_elfData); + + quint32 e_shsize = getHalfWord(data, m_elfData); + + if (e_shsize > fdlen) { + m_errorString = msgInvalidElfObject(m_binary, QStringLiteral("unexpected e_shsize")); + return Corrupt; + } + + quint32 e_phentsize = getHalfWord(data, m_elfData); + if (e_phentsize != (is64Bit ? 56 : 32)) { + m_errorString = msgInvalidElfObject(m_binary, QStringLiteral("invalid structure")); + return ElfReader::Corrupt; + } + quint32 e_phnum = getHalfWord(data, m_elfData); + + quint32 e_shentsize = getHalfWord(data, m_elfData); + + if (e_shentsize % 4) { + m_errorString = msgInvalidElfObject(m_binary, QStringLiteral("unexpected e_shentsize")); + return Corrupt; + } + + quint32 e_shnum = getHalfWord(data, m_elfData); + quint32 e_shtrndx = getHalfWord(data, m_elfData); + if (data != mapper.ustart + (is64Bit ? 64 : 52)) { + m_errorString = msgInvalidElfObject(m_binary, QStringLiteral("unexpected e_phentsize")); + return ElfReader::Corrupt; + } + + if (quint64(e_shnum) * e_shentsize > fdlen) { + const QString reason = QStringLiteral("announced %1 sections, each %2 bytes, exceed file size").arg(e_shnum).arg(e_shentsize); + m_errorString = msgInvalidElfObject(m_binary, reason); + return Corrupt; + } + + quint64 soff = e_shoff + e_shentsize * e_shtrndx; + +// if ((soff + e_shentsize) > fdlen || soff % 4 || soff == 0) { +// m_errorString = QLibrary::QStringLiteral("'%1' is an invalid ELF object (%2)") +// .arg(m_binary) +// .arg(QLatin1String("shstrtab section header seems to be at %1")) +// .arg(QString::number(soff, 16)); +// return Corrupt; +// } + + if (e_shoff) { + ElfSectionHeader strtab; + parseSectionHeader(mapper.ustart + soff, &strtab, m_elfData); + const quint64 stringTableFileOffset = strtab.offset; + if (quint32(stringTableFileOffset + e_shentsize) >= fdlen + || stringTableFileOffset == 0) { + const QString reason = QStringLiteral("string table seems to be at 0x%1").arg(soff, 0, 16); + m_errorString = msgInvalidElfObject(m_binary, reason); + return Corrupt; + } + + for (quint32 i = 0; i < e_shnum; ++i) { + const uchar *s = mapper.ustart + e_shoff + i * e_shentsize; + ElfSectionHeader sh; + parseSectionHeader(s, &sh, m_elfData); + + if (stringTableFileOffset + sh.index > fdlen) { + const QString reason = QStringLiteral("section name %1 of %2 behind end of file") + .arg(i).arg(e_shnum); + m_errorString = msgInvalidElfObject(m_binary, reason); + return Corrupt; + } + + sh.name = mapper.start + stringTableFileOffset + sh.index; + if (sh.name == ".gdb_index") { + m_elfData.symbolsType = FastSymbols; + } else if (sh.name == ".debug_info") { + m_elfData.symbolsType = PlainSymbols; + } else if (sh.name == ".gnu_debuglink") { + m_elfData.debugLink = QByteArray(mapper.start + sh.offset); + m_elfData.symbolsType = LinkedSymbols; + } else if (sh.name == ".note.gnu.build-id") { + m_elfData.symbolsType = BuildIdSymbols; + if (sh.size > 16) + m_elfData.buildId = QByteArray(mapper.start + sh.offset + 16, + int(sh.size) - 16).toHex(); + } + m_elfData.sectionHeaders.append(sh); + } + } + + if (e_phoff) { + for (quint32 i = 0; i < e_phnum; ++i) { + const uchar *s = mapper.ustart + e_phoff + i * e_phentsize; + ElfProgramHeader ph; + parseProgramHeader(s, &ph, m_elfData); + m_elfData.programHeaders.append(ph); + } + } + return Ok; +} + +QByteArray ElfReader::readSection(const QByteArray &name) +{ + readIt(); + int i = m_elfData.indexOf(name); + if (i == -1) + return QByteArray(); + + ElfMapper mapper(this); + if (!mapper.map()) + return QByteArray(); + + const ElfSectionHeader §ion = m_elfData.sectionHeaders.at(i); + return QByteArray(mapper.start + section.offset, int(section.size)); +} + +static QByteArray cutout(const char *s) +{ + QByteArray res(s, 80); + const int pos = res.indexOf('\0'); + if (pos != -1) + res.resize(pos - 1); + return res; +} + +QByteArray ElfReader::readCoreName(bool *isCore) +{ + *isCore = false; + + readIt(); + + ElfMapper mapper(this); + if (!mapper.map()) + return QByteArray(); + + if (m_elfData.elftype != Elf_ET_CORE) + return QByteArray(); + + *isCore = true; + + for (int i = 0, n = m_elfData.sectionHeaders.size(); i != n; ++i) + if (m_elfData.sectionHeaders.at(i).type == Elf_SHT_NOTE) { + const ElfSectionHeader &header = m_elfData.sectionHeaders.at(i); + return cutout(mapper.start + header.offset + 0x40); + } + + for (int i = 0, n = m_elfData.programHeaders.size(); i != n; ++i) + if (m_elfData.programHeaders.at(i).type == Elf_PT_NOTE) { + const ElfProgramHeader &header = m_elfData.programHeaders.at(i); + return cutout(mapper.start + header.offset + 0xec); + } + + return QByteArray(); +} + +int ElfData::indexOf(const QByteArray &name) const +{ + for (int i = 0, n = sectionHeaders.size(); i != n; ++i) + if (sectionHeaders.at(i).name == name) + return i; + return -1; +} + +/* Helpers for reading out the .dynamic section containing the dependencies. + * The ".dynamic" section is an array of + * typedef struct { + * Elf32_Sword d_tag; + * union { + * Elf32_Word d_val; + * dElf32_Addr d_ptr; + * } d_un; + * } Elf32_Dyn + * with entries where a tag DT_NEEDED indicates that m_val is an offset into + * the string table ".dynstr". The documentation states that entries with the + * tag DT_STRTAB contain an offset for the string table to be used, but that + * has been found not to contain valid entries. */ + +enum DynamicSectionTags { + DT_NULL = 0, + DT_NEEDED = 1, + DT_STRTAB = 5, + DT_SONAME = 14, + DT_RPATH = 15 +}; + +QList ElfReader::dependencies() +{ + QList result; + + ElfMapper mapper(this); + if (!mapper.map()) { + m_errorString = QStringLiteral("Mapper failure"); + return result; + } + quint64 dynStrOffset = 0; + quint64 dynamicOffset = 0; + quint64 dynamicSize = 0; + + const QVector &headers = readHeaders().sectionHeaders; + for (const ElfSectionHeader &eh : headers) { + if (eh.name == QByteArrayLiteral(".dynstr")) { + dynStrOffset = eh.offset; + } else if (eh.name == QByteArrayLiteral(".dynamic")) { + dynamicOffset = eh.offset; + dynamicSize = eh.size; + } + if (dynStrOffset && dynamicOffset) + break; + } + + if (!dynStrOffset || !dynamicOffset) { + m_errorString = QStringLiteral("Not a dynamically linked executable."); + return result; + } + + const unsigned char *dynamicData = mapper.ustart + dynamicOffset; + const unsigned char *dynamicDataEnd = dynamicData + dynamicSize; + while (dynamicData < dynamicDataEnd) { + const quint32 tag = getWord(dynamicData, m_elfData); + if (tag == DT_NULL) + break; + if (m_elfData.elfclass == Elf_ELFCLASS64) + dynamicData += sizeof(quint32); // padding to d_val/d_ptr. + if (tag == DT_NEEDED) { + const quint32 offset = getWord(dynamicData, m_elfData); + if (m_elfData.elfclass == Elf_ELFCLASS64) + dynamicData += sizeof(quint32); // past d_ptr. + const char *name = mapper.start + dynStrOffset + offset; + result.push_back(name); + } else { + dynamicData += m_elfData.elfclass == Elf_ELFCLASS64 ? 8 : 4; + } + } + return result; +} + +QT_END_NAMESPACE diff --git a/src/QtELFReader/src/elfreader.h b/src/QtELFReader/src/elfreader.h new file mode 100644 index 00000000..3beb2f94 --- /dev/null +++ b/src/QtELFReader/src/elfreader.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ELFREADER_H +#define ELFREADER_H + +#include +#include +#include +#include "elfreader_global.h" + +QT_BEGIN_NAMESPACE + +enum ELFREADER_SHARED_EXPORT ElfProgramHeaderType +{ + Elf_PT_NULL = 0, + Elf_PT_LOAD = 1, + Elf_PT_DYNAMIC = 2, + Elf_PT_INTERP = 3, + Elf_PT_NOTE = 4, + Elf_PT_SHLIB = 5, + Elf_PT_PHDR = 6, + Elf_PT_TLS = 7, + Elf_PT_NUM = 8 +}; + +enum ELFREADER_SHARED_EXPORT ElfSectionHeaderType +{ + Elf_SHT_NULL = 0, + Elf_SHT_PROGBITS = 1, + Elf_SHT_SYMTAB = 2, + Elf_SHT_STRTAB = 3, + Elf_SHT_RELA = 4, + Elf_SHT_HASH = 5, + Elf_SHT_DYNAMIC = 6, + Elf_SHT_NOTE = 7, + Elf_SHT_NOBITS = 8, + Elf_SHT_REL = 9, + Elf_SHT_SHLIB = 10, + Elf_SHT_DYNSYM = 11, + Elf_SHT_INIT_ARRAY = 14, + Elf_SHT_FINI_ARRAY = 15, + Elf_SHT_PREINIT_ARRAY = 16, + Elf_SHT_GROUP = 17, + Elf_SHT_SYMTAB_SHNDX = 18 +}; + +enum ELFREADER_SHARED_EXPORT ElfEndian +{ + Elf_ELFDATANONE = 0, + Elf_ELFDATA2LSB = 1, + Elf_ELFDATA2MSB = 2, + Elf_ELFDATANUM = 3 +}; + +enum ELFREADER_SHARED_EXPORT ElfClass +{ + Elf_ELFCLASS32 = 1, + Elf_ELFCLASS64 = 2 +}; + +enum ELFREADER_SHARED_EXPORT ElfType +{ + Elf_ET_NONE = 0, + Elf_ET_REL = 1, + Elf_ET_EXEC = 2, + Elf_ET_DYN = 3, + Elf_ET_CORE = 4 +}; + +enum ELFREADER_SHARED_EXPORT ElfMachine +{ + Elf_EM_386 = 3, + Elf_EM_ARM = 40, + Elf_EM_X86_64 = 62 +}; + +enum ELFREADER_SHARED_EXPORT DebugSymbolsType +{ + UnknownSymbols = 0, // Unknown. + NoSymbols = 1, // No usable symbols. + LinkedSymbols = 2, // Link to symols available. + BuildIdSymbols = 4, // BuildId available. + PlainSymbols = 8, // Ordinary symbols available. + FastSymbols = 16 // Dwarf index available. +}; + +class ELFREADER_SHARED_EXPORT ElfSectionHeader +{ +public: + QByteArray name; + quint32 index; + quint32 type; + quint32 flags; + quint64 offset; + quint64 size; + quint64 addr; +}; + +class ELFREADER_SHARED_EXPORT ElfProgramHeader +{ +public: + quint32 name; + quint32 type; + quint64 offset; + quint64 filesz; + quint64 memsz; +}; + +class ELFREADER_SHARED_EXPORT ElfData +{ +public: + ElfData() : symbolsType(UnknownSymbols) {} + int indexOf(const QByteArray &name) const; + +public: + ElfEndian endian; + ElfType elftype; + ElfMachine elfmachine; + ElfClass elfclass; + quint64 entryPoint; + QByteArray debugLink; + QByteArray buildId; + DebugSymbolsType symbolsType; + QVector sectionHeaders; + QVector programHeaders; +}; + +class ELFREADER_SHARED_EXPORT ElfReader +{ +public: + explicit ElfReader(const QString &binary); + enum Result { Ok, NotElf, Corrupt }; + + ElfData readHeaders(); + QByteArray readSection(const QByteArray §ionName); + QString errorString() const { return m_errorString; } + QByteArray readCoreName(bool *isCore); + QList dependencies(); + +private: + friend class ElfMapper; + Result readIt(); + + QString m_binary; + QString m_errorString; + ElfData m_elfData; +}; + +QT_END_NAMESPACE + +#endif // ELFREADER_H diff --git a/src/QtELFReader/src/elfreader_global.h.in b/src/QtELFReader/src/elfreader_global.h.in new file mode 100644 index 00000000..dd9e07f6 --- /dev/null +++ b/src/QtELFReader/src/elfreader_global.h.in @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2018-2022 QuasarApp. + * Distributed under the lgplv3 software license, see the accompanying + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +#ifndef ELF_READER_GLOBAL_H +#define ELF_READER_GLOBAL_H + +#include + +#if defined(QT_ELFREADER_LIBRARY) +# define ELFREADER_SHARED_EXPORT Q_DECL_EXPORT +#else +# define ELFREADER_SHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // ELF_READER_GLOBAL_H diff --git a/submodules/QuasarAppLib b/submodules/QuasarAppLib new file mode 160000 index 00000000..cac23de9 --- /dev/null +++ b/submodules/QuasarAppLib @@ -0,0 +1 @@ +Subproject commit cac23de9573eed9efe5e924f34e75325c9c049d5 diff --git a/submodules/pe-parse b/submodules/pe-parse new file mode 160000 index 00000000..29220c94 --- /dev/null +++ b/submodules/pe-parse @@ -0,0 +1 @@ +Subproject commit 29220c9435d6e5b7ce08f237350d1d221390c59b diff --git a/submodules/zip b/submodules/zip new file mode 160000 index 00000000..114d9d46 --- /dev/null +++ b/submodules/zip @@ -0,0 +1 @@ +Subproject commit 114d9d46fdbdad55b37705190a8625f4ab5fa81a diff --git a/test.pri b/test.pri deleted file mode 100644 index 09d2f56f..00000000 --- a/test.pri +++ /dev/null @@ -1,30 +0,0 @@ -unix:exec = $$PWD/UnitTests/build/release/UnitTests -win32:exec = $$PWD/UnitTests/build/release/UnitTests.exe - -QT_DIR= $$[QT_HOST_BINS] -win32:QMAKE_BIN= $$QT_DIR/qmake.exe -contains(QMAKE_HOST.os, Linux):{ - QMAKE_BIN= $$QT_DIR/qmake -} - -DEPLOYER=cqtdeployer - -test.commands = -deployTest.commands = $$DEPLOYER -bin $$exec clear -qmake $$QMAKE_BIN -targetDir $$PWD/deployTests -libDir $$PWD -recursiveDepth 4 - -!contains(DEFINES, WITHOUT_TESTS) { - test.depends = deployTest - unix:test.commands = $$PWD/deployTests/UnitTests.sh -maxwarnings 100000 - win32:test.commands = $$PWD/deployTests/UnitTests.exe -maxwarnings 100000 -o buildLog.log -} - -contains(QMAKE_HOST.os, Linux):{ - win32:test.commands = -} - - -QMAKE_EXTRA_TARGETS += \ - deployTest \ - test - - diff --git a/testcases/CMakeLists.txt b/testcases/CMakeLists.txt new file mode 100644 index 00000000..c18948b1 --- /dev/null +++ b/testcases/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# Copyright (C) 2020-2022 QuasarApp. +# Distributed under the GPLv3 software license, see the accompanying +# Everyone is permitted to copy and distribute verbatim copies +# of this license document, but changing it is not allowed. +# + +cmake_minimum_required(VERSION 3.16) + +set(CMAKE_AUTOMOC ON) +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin) + +add_subdirectory(quicknanobrowser) +add_subdirectory(TestCPPOnly) +add_subdirectory(TestOnlyC) +add_subdirectory(TestQMLWidgets) +add_subdirectory(TestQtWidgets) +add_subdirectory(virtualkeyboard) +add_subdirectory(webui) diff --git a/testcases/TestCPPOnly/CMakeLists.txt b/testcases/TestCPPOnly/CMakeLists.txt new file mode 100644 index 00000000..f6cb98c8 --- /dev/null +++ b/testcases/TestCPPOnly/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) +project(TestCPPOnly LANGUAGES CXX) + + +add_executable(TestCPPOnly + main.cpp +) + diff --git a/tests/TestCPPOnly/main.cpp b/testcases/TestCPPOnly/main.cpp similarity index 100% rename from tests/TestCPPOnly/main.cpp rename to testcases/TestCPPOnly/main.cpp diff --git a/testcases/TestOnlyC/CMakeLists.txt b/testcases/TestOnlyC/CMakeLists.txt new file mode 100644 index 00000000..4d3a789b --- /dev/null +++ b/testcases/TestOnlyC/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) +project(TestOnlyC LANGUAGES C) + + +add_executable(TestOnlyC + main.cpp +) + diff --git a/testcases/TestOnlyC/main.cpp b/testcases/TestOnlyC/main.cpp new file mode 100644 index 00000000..768dc1ec --- /dev/null +++ b/testcases/TestOnlyC/main.cpp @@ -0,0 +1,7 @@ +#include + +int main() +{ + printf("TEST DONE (ONLY_C)"); + return 0; +} diff --git a/testcases/TestQMLWidgets/CMakeLists.txt b/testcases/TestQMLWidgets/CMakeLists.txt new file mode 100644 index 00000000..68206d90 --- /dev/null +++ b/testcases/TestQMLWidgets/CMakeLists.txt @@ -0,0 +1,39 @@ +# +# Copyright (C) 2021-2022 QuasarApp. +# Distributed under the GPLv3 software license, see the accompanying +# Everyone is permitted to copy and distribute verbatim copies +# of this license document, but changing it is not allowed. +# + +cmake_minimum_required(VERSION 3.18) + +set(CMAKE_AUTOMOC ON) + +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Qml Quick) +set(CURRENT_PROJECT "TestQMLWidgets") + +# needed for test RPATH functions +get_filename_component(QT_QT_ROOT "${Qt${QT_VERSION_MAJOR}Core_DIR}/../../.." ABSOLUTE) +set(CMAKE_BUILD_RPATH ${QT_QT_ROOT}/bin) + +file(GLOB_RECURSE SOURCE_CPP + "*.cpp" "*.h" +) + +file(GLOB_RECURSE SOURCE_QRC + "*.qrc" +) + +set(ALL_SOURCES ${SOURCE_CPP} ${SOURCE_QRC}) +set(PUBLIC_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + +add_executable(${CURRENT_PROJECT} ${ALL_SOURCES} ) + +target_link_libraries(${CURRENT_PROJECT} PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +target_include_directories(${CURRENT_PROJECT} PUBLIC ${PUBLIC_INCUDE_DIR}) diff --git a/tests/TestQMLWidgets/HomeForm.ui.qml b/testcases/TestQMLWidgets/HomeForm.ui.qml similarity index 90% rename from tests/TestQMLWidgets/HomeForm.ui.qml rename to testcases/TestQMLWidgets/HomeForm.ui.qml index 6474fad0..ecdde7c0 100644 --- a/tests/TestQMLWidgets/HomeForm.ui.qml +++ b/testcases/TestQMLWidgets/HomeForm.ui.qml @@ -1,4 +1,3 @@ -import QtQuick 2.10 import QtQuick.Controls 2.3 Page { diff --git a/tests/TestQMLWidgets/Page1Form.ui.qml b/testcases/TestQMLWidgets/Page1Form.ui.qml similarity index 90% rename from tests/TestQMLWidgets/Page1Form.ui.qml rename to testcases/TestQMLWidgets/Page1Form.ui.qml index a25e78ae..5c9adb84 100644 --- a/tests/TestQMLWidgets/Page1Form.ui.qml +++ b/testcases/TestQMLWidgets/Page1Form.ui.qml @@ -1,4 +1,3 @@ -import QtQuick 2.10 import QtQuick.Controls 2.3 Page { diff --git a/tests/TestQMLWidgets/Page2Form.ui.qml b/testcases/TestQMLWidgets/Page2Form.ui.qml similarity index 90% rename from tests/TestQMLWidgets/Page2Form.ui.qml rename to testcases/TestQMLWidgets/Page2Form.ui.qml index c34bb984..31cf90e7 100644 --- a/tests/TestQMLWidgets/Page2Form.ui.qml +++ b/testcases/TestQMLWidgets/Page2Form.ui.qml @@ -1,4 +1,3 @@ -import QtQuick 2.10 import QtQuick.Controls 2.3 Page { diff --git a/tests/TestQMLWidgets/main.cpp b/testcases/TestQMLWidgets/main.cpp similarity index 85% rename from tests/TestQMLWidgets/main.cpp rename to testcases/TestQMLWidgets/main.cpp index b532603f..38c8a2fa 100644 --- a/tests/TestQMLWidgets/main.cpp +++ b/testcases/TestQMLWidgets/main.cpp @@ -4,8 +4,6 @@ int main(int argc, char *argv[]) { - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QGuiApplication app(argc, argv); QQmlApplicationEngine engine; diff --git a/examples/TestQMLWidgets/main.qml b/testcases/TestQMLWidgets/main.qml similarity index 100% rename from examples/TestQMLWidgets/main.qml rename to testcases/TestQMLWidgets/main.qml diff --git a/examples/TestQMLWidgets/qml.qrc b/testcases/TestQMLWidgets/qml.qrc similarity index 82% rename from examples/TestQMLWidgets/qml.qrc rename to testcases/TestQMLWidgets/qml.qrc index 77259896..2e09c089 100644 --- a/examples/TestQMLWidgets/qml.qrc +++ b/testcases/TestQMLWidgets/qml.qrc @@ -4,6 +4,5 @@ HomeForm.ui.qml Page1Form.ui.qml Page2Form.ui.qml - qtquickcontrols2.conf diff --git a/testcases/TestQtWidgets/CMakeLists.txt b/testcases/TestQtWidgets/CMakeLists.txt new file mode 100644 index 00000000..40f4289f --- /dev/null +++ b/testcases/TestQtWidgets/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright (C) 2021-2022 QuasarApp. +# Distributed under the GPLv3 software license, see the accompanying +# Everyone is permitted to copy and distribute verbatim copies +# of this license document, but changing it is not allowed. +# + +cmake_minimum_required(VERSION 3.18) + +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widgets) + +# needed for test RPATH functions +get_filename_component(QT_QT_ROOT "${Qt${QT_VERSION_MAJOR}Core_DIR}/../../.." ABSOLUTE) +set(CMAKE_BUILD_RPATH ${QT_QT_ROOT}/bin) + + +set(CURRENT_PROJECT "QtWidgetsProject") + +file(GLOB_RECURSE SOURCE_CPP + "*.cpp" "*.h" +) + +file(GLOB_RECURSE SOURCE_QRC + "*.qrc" +) + +set(ALL_SOURCES ${SOURCE_CPP} ${SOURCE_QRC}) +set(PUBLIC_INCUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + +add_executable(${CURRENT_PROJECT} ${ALL_SOURCES} ) + +target_link_libraries(${CURRENT_PROJECT} PUBLIC Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets) +target_include_directories(${CURRENT_PROJECT} PUBLIC ${PUBLIC_INCUDE_DIR}) diff --git a/tests/TestQtWidgets/main.cpp b/testcases/TestQtWidgets/main.cpp similarity index 100% rename from tests/TestQtWidgets/main.cpp rename to testcases/TestQtWidgets/main.cpp diff --git a/tests/TestQtWidgets/mainwindow.cpp b/testcases/TestQtWidgets/mainwindow.cpp similarity index 100% rename from tests/TestQtWidgets/mainwindow.cpp rename to testcases/TestQtWidgets/mainwindow.cpp diff --git a/tests/TestQtWidgets/mainwindow.h b/testcases/TestQtWidgets/mainwindow.h similarity index 100% rename from tests/TestQtWidgets/mainwindow.h rename to testcases/TestQtWidgets/mainwindow.h diff --git a/tests/TestQtWidgets/mainwindow.ui b/testcases/TestQtWidgets/mainwindow.ui similarity index 100% rename from tests/TestQtWidgets/mainwindow.ui rename to testcases/TestQtWidgets/mainwindow.ui diff --git a/tests/quicknanobrowser/ApplicationRoot.qml b/testcases/quicknanobrowser/ApplicationRoot.qml similarity index 94% rename from tests/quicknanobrowser/ApplicationRoot.qml rename to testcases/quicknanobrowser/ApplicationRoot.qml index adae6f5f..cd40a7fd 100644 --- a/tests/quicknanobrowser/ApplicationRoot.qml +++ b/testcases/quicknanobrowser/ApplicationRoot.qml @@ -1,89 +1,87 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine 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$ -** -****************************************************************************/ - -import QtQuick 2.1 -import QtWebEngine 1.9 - -QtObject { - id: root - - property QtObject defaultProfile: WebEngineProfile { - storageName: "Profile" - offTheRecord: false - useForGlobalCertificateVerification: true - } - - property QtObject otrProfile: WebEngineProfile { - offTheRecord: true - } - - property Component browserWindowComponent: BrowserWindow { - applicationRoot: root - onClosing: destroy() - } - property Component browserDialogComponent: BrowserDialog { - onClosing: destroy() - } - function createWindow(profile) { - var newWindow = browserWindowComponent.createObject(root); - newWindow.currentWebView.profile = profile; - profile.downloadRequested.connect(newWindow.onDownloadRequested); - return newWindow; - } - function createDialog(profile) { - var newDialog = browserDialogComponent.createObject(root); - newDialog.currentWebView.profile = profile; - return newDialog; - } - function load(url) { - var browserWindow = createWindow(defaultProfile); - browserWindow.currentWebView.url = url; - } -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine 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$ +** +****************************************************************************/ + +import QtQuick +import QtWebEngine + +QtObject { + id: root + + property QtObject defaultProfile: WebEngineProfile { + storageName: "Profile" + offTheRecord: false + } + + property QtObject otrProfile: WebEngineProfile { + offTheRecord: true + } + + property Component browserWindowComponent: BrowserWindow { + applicationRoot: root + } + property Component browserDialogComponent: BrowserDialog { + onClosing: destroy() + } + function createWindow(profile) { + var newWindow = browserWindowComponent.createObject(root); + newWindow.currentWebView.profile = profile; + profile.downloadRequested.connect(newWindow.onDownloadRequested); + return newWindow; + } + function createDialog(profile) { + var newDialog = browserDialogComponent.createObject(root); + newDialog.currentWebView.profile = profile; + return newDialog; + } + function load(url) { + var browserWindow = createWindow(defaultProfile); + browserWindow.currentWebView.url = url; + } +} diff --git a/tests/quicknanobrowser/BrowserDialog.qml b/testcases/quicknanobrowser/BrowserDialog.qml similarity index 95% rename from tests/quicknanobrowser/BrowserDialog.qml rename to testcases/quicknanobrowser/BrowserDialog.qml index c2b6737c..281f4490 100644 --- a/tests/quicknanobrowser/BrowserDialog.qml +++ b/testcases/quicknanobrowser/BrowserDialog.qml @@ -1,74 +1,74 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine 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$ -** -****************************************************************************/ - -import QtQuick 2.1 -import QtQuick.Window 2.2 -import QtWebEngine 1.9 - -Window { - id: window - property alias currentWebView: webView - flags: Qt.Dialog | Qt.WindowStaysOnTopHint - width: 800 - height: 600 - visible: true - onClosing: destroy() - WebEngineView { - id: webView - anchors.fill: parent - - onGeometryChangeRequested: function(geometry) { - window.x = geometry.x - window.y = geometry.y - window.width = geometry.width - window.height = geometry.height - } - } -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine 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$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Window +import QtWebEngine + +Window { + id: window + property alias currentWebView: webView + flags: Qt.Dialog | Qt.WindowStaysOnTopHint + width: 800 + height: 600 + visible: true + onClosing: destroy() + WebEngineView { + id: webView + anchors.fill: parent + + onGeometryChangeRequested: function(geometry) { + window.x = geometry.x + window.y = geometry.y + window.width = geometry.width + window.height = geometry.height + } + } +} diff --git a/testcases/quicknanobrowser/BrowserWindow.qml b/testcases/quicknanobrowser/BrowserWindow.qml new file mode 100644 index 00000000..0da1bc04 --- /dev/null +++ b/testcases/quicknanobrowser/BrowserWindow.qml @@ -0,0 +1,801 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine 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$ +** +****************************************************************************/ + +import Qt.labs.settings +import QtQml +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window +import QtWebEngine + +ApplicationWindow { + id: browserWindow + property QtObject applicationRoot + property Item currentWebView: tabBar.currentIndex < tabBar.count ? tabLayout.children[tabBar.currentIndex] : null + property int previousVisibility: Window.Windowed + property int createdTabs: 0 + + width: 1300 + height: 900 + visible: true + title: currentWebView && currentWebView.title + + // Make sure the Qt.WindowFullscreenButtonHint is set on OS X. + Component.onCompleted: flags = flags | Qt.WindowFullscreenButtonHint + + onCurrentWebViewChanged: { + findBar.reset(); + } + + // When using style "mac", ToolButtons are not supposed to accept focus. + property bool platformIsMac: Qt.platform.os == "osx" + + Settings { + id : appSettings + property alias autoLoadImages: loadImages.checked + property alias javaScriptEnabled: javaScriptEnabled.checked + property alias errorPageEnabled: errorPageEnabled.checked + property alias pluginsEnabled: pluginsEnabled.checked + property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked + property alias autoLoadIconsForPage: autoLoadIconsForPage.checked + property alias touchIconsEnabled: touchIconsEnabled.checked + property alias webRTCPublicInterfacesOnly : webRTCPublicInterfacesOnly.checked + property alias devToolsEnabled: devToolsEnabled.checked + property alias pdfViewerEnabled: pdfViewerEnabled.checked + } + + Action { + shortcut: "Ctrl+D" + onTriggered: { + downloadView.visible = !downloadView.visible; + } + } + Action { + id: focus + shortcut: "Ctrl+L" + onTriggered: { + addressBar.forceActiveFocus(); + addressBar.selectAll(); + } + } + Action { + shortcut: StandardKey.Refresh + onTriggered: { + if (currentWebView) + currentWebView.reload(); + } + } + Action { + shortcut: StandardKey.AddTab + onTriggered: { + tabBar.createTab(tabBar.count != 0 ? currentWebView.profile : defaultProfile); + addressBar.forceActiveFocus(); + addressBar.selectAll(); + } + } + Action { + shortcut: StandardKey.Close + onTriggered: { + currentWebView.triggerWebAction(WebEngineView.RequestClose); + } + } + Action { + shortcut: StandardKey.Quit + onTriggered: browserWindow.close() + } + Action { + shortcut: "Escape" + onTriggered: { + if (currentWebView.state == "FullScreen") { + browserWindow.visibility = browserWindow.previousVisibility; + fullScreenNotification.hide(); + currentWebView.triggerWebAction(WebEngineView.ExitFullScreen); + } + + if (findBar.visible) + findBar.visible = false; + } + } + Action { + shortcut: "Ctrl+0" + onTriggered: currentWebView.zoomFactor = 1.0 + } + Action { + shortcut: StandardKey.ZoomOut + onTriggered: currentWebView.zoomFactor -= 0.1 + } + Action { + shortcut: StandardKey.ZoomIn + onTriggered: currentWebView.zoomFactor += 0.1 + } + + Action { + shortcut: StandardKey.Copy + onTriggered: currentWebView.triggerWebAction(WebEngineView.Copy) + } + Action { + shortcut: StandardKey.Cut + onTriggered: currentWebView.triggerWebAction(WebEngineView.Cut) + } + Action { + shortcut: StandardKey.Paste + onTriggered: currentWebView.triggerWebAction(WebEngineView.Paste) + } + Action { + shortcut: "Shift+"+StandardKey.Paste + onTriggered: currentWebView.triggerWebAction(WebEngineView.PasteAndMatchStyle) + } + Action { + shortcut: StandardKey.SelectAll + onTriggered: currentWebView.triggerWebAction(WebEngineView.SelectAll) + } + Action { + shortcut: StandardKey.Undo + onTriggered: currentWebView.triggerWebAction(WebEngineView.Undo) + } + Action { + shortcut: StandardKey.Redo + onTriggered: currentWebView.triggerWebAction(WebEngineView.Redo) + } + Action { + shortcut: StandardKey.Back + onTriggered: currentWebView.triggerWebAction(WebEngineView.Back) + } + Action { + shortcut: StandardKey.Forward + onTriggered: currentWebView.triggerWebAction(WebEngineView.Forward) + } + Action { + shortcut: StandardKey.Find + onTriggered: { + if (!findBar.visible) + findBar.visible = true; + } + } + Action { + shortcut: StandardKey.FindNext + onTriggered: findBar.findNext() + } + Action { + shortcut: StandardKey.FindPrevious + onTriggered: findBar.findPrevious() + } + + menuBar: ToolBar { + id: navigationBar + RowLayout { + anchors.fill: parent + ToolButton { + enabled: currentWebView && (currentWebView.canGoBack || currentWebView.canGoForward) + onClicked: historyMenu.open() + text: qsTr("▼") + Menu { + id: historyMenu + Instantiator { + model: currentWebView && currentWebView.history.items + MenuItem { + text: model.title + onTriggered: currentWebView.goBackOrForward(model.offset) + checkable: !enabled + checked: !enabled + enabled: model.offset + } + + onObjectAdded: function(index, object) { + historyMenu.insertItem(index, object) + } + onObjectRemoved: function(index, object) { + historyMenu.removeItem(object) + } + } + } + } + + ToolButton { + id: backButton + icon.source: "qrc:/icons/go-previous.png" + onClicked: currentWebView.goBack() + enabled: currentWebView && currentWebView.canGoBack + activeFocusOnTab: !browserWindow.platformIsMac + } + ToolButton { + id: forwardButton + icon.source: "qrc:/icons/go-next.png" + onClicked: currentWebView.goForward() + enabled: currentWebView && currentWebView.canGoForward + activeFocusOnTab: !browserWindow.platformIsMac + } + ToolButton { + id: reloadButton + icon.source: currentWebView && currentWebView.loading ? "qrc:/icons/process-stop.png" : "qrc:/icons/view-refresh.png" + onClicked: currentWebView && currentWebView.loading ? currentWebView.stop() : currentWebView.reload() + activeFocusOnTab: !browserWindow.platformIsMac + } + TextField { + id: addressBar + Image { + anchors.verticalCenter: addressBar.verticalCenter; + x: 5 + z: 2 + id: faviconImage + width: 16; height: 16 + sourceSize: Qt.size(width, height) + source: currentWebView && currentWebView.icon ? currentWebView.icon : '' + } + MouseArea { + id: textFieldMouseArea + acceptedButtons: Qt.RightButton + anchors.fill: parent + onClicked: { + var textSelectionStartPos = addressBar.selectionStart; + var textSelectionEndPos = addressBar.selectionEnd; + textFieldContextMenu.open(); + addressBar.select(textSelectionStartPos, textSelectionEndPos); + } + Menu { + id: textFieldContextMenu + x: textFieldMouseArea.mouseX + y: textFieldMouseArea.mouseY + MenuItem { + text: qsTr("Cut") + onTriggered: addressBar.cut() + enabled: addressBar.selectedText.length > 0 + } + MenuItem { + text: qsTr("Copy") + onTriggered: addressBar.copy() + enabled: addressBar.selectedText.length > 0 + } + MenuItem { + text: qsTr("Paste") + onTriggered: addressBar.paste() + enabled: addressBar.canPaste + } + MenuItem { + text: qsTr("Delete") + onTriggered: addressBar.text = qsTr("") + enabled: addressBar.selectedText.length > 0 + } + MenuSeparator {} + MenuItem { + text: qsTr("Select All") + onTriggered: addressBar.selectAll() + enabled: addressBar.text.length > 0 + } + } + } + leftPadding: 26 + focus: true + Layout.fillWidth: true + Binding on text { + when: currentWebView + value: currentWebView.url + } + onAccepted: currentWebView.url = utils.fromUserInput(text) + selectByMouse: true + } + ToolButton { + id: settingsMenuButton + text: qsTr("⋮") + onClicked: settingsMenu.open() + Menu { + id: settingsMenu + y: settingsMenuButton.height + MenuItem { + id: loadImages + text: "Autoload images" + checkable: true + checked: WebEngine.settings.autoLoadImages + } + MenuItem { + id: javaScriptEnabled + text: "JavaScript On" + checkable: true + checked: WebEngine.settings.javascriptEnabled + } + MenuItem { + id: errorPageEnabled + text: "ErrorPage On" + checkable: true + checked: WebEngine.settings.errorPageEnabled + } + MenuItem { + id: pluginsEnabled + text: "Plugins On" + checkable: true + checked: true + } + MenuItem { + id: fullScreenSupportEnabled + text: "FullScreen On" + checkable: true + checked: WebEngine.settings.fullScreenSupportEnabled + } + MenuItem { + id: offTheRecordEnabled + text: "Off The Record" + checkable: true + checked: currentWebView && currentWebView.profile === otrProfile + onToggled: function(checked) { + if (currentWebView) { + currentWebView.profile = checked ? otrProfile : defaultProfile; + } + } + } + MenuItem { + id: httpDiskCacheEnabled + text: "HTTP Disk Cache" + checkable: currentWebView && !currentWebView.profile.offTheRecord + checked: currentWebView && (currentWebView.profile.httpCacheType === WebEngineProfile.DiskHttpCache) + onToggled: function(checked) { + if (currentWebView) { + currentWebView.profile.httpCacheType = checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache; + } + } + } + MenuItem { + id: autoLoadIconsForPage + text: "Icons On" + checkable: true + checked: WebEngine.settings.autoLoadIconsForPage + } + MenuItem { + id: touchIconsEnabled + text: "Touch Icons On" + checkable: true + checked: WebEngine.settings.touchIconsEnabled + enabled: autoLoadIconsForPage.checked + } + MenuItem { + id: webRTCPublicInterfacesOnly + text: "WebRTC Public Interfaces Only" + checkable: true + checked: WebEngine.settings.webRTCPublicInterfacesOnly + } + MenuItem { + id: devToolsEnabled + text: "Open DevTools" + checkable: true + checked: false + } + MenuItem { + id: pdfViewerEnabled + text: "PDF viewer enabled" + checkable: true + checked: WebEngine.settings.pdfViewerEnabled + } + } + } + } + ProgressBar { + id: progressBar + height: 3 + anchors { + left: parent.left + top: parent.bottom + right: parent.right + leftMargin: parent.leftMargin + rightMargin: parent.rightMargin + } + background: Item {} + z: -2 + from: 0 + to: 100 + value: (currentWebView && currentWebView.loadProgress < 100) ? currentWebView.loadProgress : 0 + } + } + + StackLayout { + id: tabLayout + currentIndex: tabBar.currentIndex + + anchors.top: tabBar.bottom + anchors.bottom: devToolsView.top + anchors.left: parent.left + anchors.right: parent.right + } + + Component { + id: tabButtonComponent + + TabButton { + property color frameColor: "#999" + property color fillColor: "#eee" + property color nonSelectedColor: "#ddd" + property string tabTitle: "New Tab" + + id: tabButton + contentItem: Rectangle { + id: tabRectangle + color: tabButton.down ? fillColor : nonSelectedColor + border.width: 1 + border.color: frameColor + implicitWidth: Math.max(text.width + 30, 80) + implicitHeight: Math.max(text.height + 10, 20) + Rectangle { height: 1 ; width: parent.width ; color: frameColor} + Rectangle { height: parent.height ; width: 1; color: frameColor} + Rectangle { x: parent.width - 2; height: parent.height ; width: 1; color: frameColor} + Text { + id: text + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 6 + text: tabButton.tabTitle + elide: Text.ElideRight + color: tabButton.down ? "black" : frameColor + width: parent.width - button.background.width + } + Button { + id: button + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.rightMargin: 4 + height: 12 + background: Rectangle { + implicitWidth: 12 + implicitHeight: 12 + color: button.hovered ? "#ccc" : tabRectangle.color + Text {text: "x"; anchors.centerIn: parent; color: "gray"} + } + onClicked: tabButton.closeTab() + } + } + + onClicked: addressBar.text = tabLayout.itemAt(TabBar.index).url; + function closeTab() { + tabBar.removeView(TabBar.index); + } + } + } + + TabBar { + id: tabBar + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + Component.onCompleted: createTab(defaultProfile) + + function createTab(profile, focusOnNewTab = true, url = undefined) { + var webview = tabComponent.createObject(tabLayout, {profile: profile}); + var newTabButton = tabButtonComponent.createObject(tabBar, {tabTitle: Qt.binding(function () { return webview.title; })}); + tabBar.addItem(newTabButton); + if (focusOnNewTab) { + tabBar.setCurrentIndex(tabBar.count - 1); + } + if (url !== undefined) { + webview.url = url; + } + return webview; + } + + function removeView(index) { + tabBar.removeItem(index); + if (tabBar.count > 1) { + tabBar.removeItem(tabBar.itemAt(index)); + tabLayout.children[index].destroy(); + } else { + browserWindow.close(); + } + } + + Component { + id: tabComponent + WebEngineView { + id: webEngineView + focus: true + + onLinkHovered: function(hoveredUrl) { + if (hoveredUrl == "") + hideStatusText.start(); + else { + statusText.text = hoveredUrl; + statusBubble.visible = true; + hideStatusText.stop(); + } + } + + states: [ + State { + name: "FullScreen" + PropertyChanges { + target: tabBar + visible: false + height: 0 + } + PropertyChanges { + target: navigationBar + visible: false + } + } + ] + settings.autoLoadImages: appSettings.autoLoadImages + settings.javascriptEnabled: appSettings.javaScriptEnabled + settings.errorPageEnabled: appSettings.errorPageEnabled + settings.pluginsEnabled: appSettings.pluginsEnabled + settings.fullScreenSupportEnabled: appSettings.fullScreenSupportEnabled + settings.autoLoadIconsForPage: appSettings.autoLoadIconsForPage + settings.touchIconsEnabled: appSettings.touchIconsEnabled + settings.webRTCPublicInterfacesOnly: appSettings.webRTCPublicInterfacesOnly + settings.pdfViewerEnabled: appSettings.pdfViewerEnabled + + onCertificateError: function(error) { + error.defer(); + sslDialog.enqueue(error); + } + + onNewWindowRequested: function(request) { + if (!request.userInitiated) + console.warn("Blocked a popup window."); + else if (request.destination === WebEngineNewWindowRequest.InNewTab) { + var tab = tabBar.createTab(currentWebView.profile, true, request.requestedUrl); + tab.acceptAsNewWindow(request); + } else if (request.destination === WebEngineNewWindowRequest.InNewBackgroundTab) { + var backgroundTab = tabBar.createTab(currentWebView.profile, false); + backgroundTab.acceptAsNewWindow(request); + } else if (request.destination === WebEngineNewWindowRequest.InNewDialog) { + var dialog = applicationRoot.createDialog(currentWebView.profile); + dialog.currentWebView.acceptAsNewWindow(request); + } else { + var window = applicationRoot.createWindow(currentWebView.profile); + window.currentWebView.acceptAsNewWindow(request); + } + } + + onFullScreenRequested: function(request) { + if (request.toggleOn) { + webEngineView.state = "FullScreen"; + browserWindow.previousVisibility = browserWindow.visibility; + browserWindow.showFullScreen(); + fullScreenNotification.show(); + } else { + webEngineView.state = ""; + browserWindow.visibility = browserWindow.previousVisibility; + fullScreenNotification.hide(); + } + request.accept(); + } + + onQuotaRequested: function(request) { + if (request.requestedSize <= 5 * 1024 * 1024) + request.accept(); + else + request.reject(); + } + + onRegisterProtocolHandlerRequested: function(request) { + console.log("accepting registerProtocolHandler request for " + + request.scheme + " from " + request.origin); + request.accept(); + } + + onRenderProcessTerminated: function(terminationStatus, exitCode) { + var status = ""; + switch (terminationStatus) { + case WebEngineView.NormalTerminationStatus: + status = "(normal exit)"; + break; + case WebEngineView.AbnormalTerminationStatus: + status = "(abnormal exit)"; + break; + case WebEngineView.CrashedTerminationStatus: + status = "(crashed)"; + break; + case WebEngineView.KilledTerminationStatus: + status = "(killed)"; + break; + } + + print("Render process exited with code " + exitCode + " " + status); + reloadTimer.running = true; + } + + onSelectClientCertificate: function(selection) { + selection.certificates[0].select(); + } + + onFindTextFinished: function(result) { + if (!findBar.visible) + findBar.visible = true; + + findBar.numberOfMatches = result.numberOfMatches; + findBar.activeMatch = result.activeMatch; + } + + onLoadingChanged: function(loadRequest) { + if (loadRequest.status == WebEngineView.LoadStartedStatus) + findBar.reset(); + } + + Timer { + id: reloadTimer + interval: 0 + running: false + repeat: false + onTriggered: currentWebView.reload() + } + } + } + } + WebEngineView { + id: devToolsView + visible: devToolsEnabled.checked + height: visible ? 400 : 0 + inspectedView: visible && tabBar.currentIndex < tabBar.count ? tabLayout.children[tabBar.currentIndex] : null + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + onNewWindowRequested: function(request) { + var tab = tabBar.createTab(currentWebView.profile); + request.openIn(tab); + } + + Timer { + id: hideTimer + interval: 0 + running: false + repeat: false + onTriggered: devToolsEnabled.checked = false + } + onWindowCloseRequested: function(request) { + // Delay hiding for keep the inspectedView set to receive the ACK message of close. + hideTimer.running = true; + } + } + Dialog { + id: sslDialog + anchors.centerIn: parent + contentWidth: Math.max(mainText.width, detailedText.width) + contentHeight: mainText.height + detailedText.height + property var certErrors: [] + // fixme: icon! + // icon: StandardIcon.Warning + standardButtons: Dialog.No | Dialog.Yes + title: "Server's certificate not trusted" + contentItem: Item { + id: textContentItem + Label { + id: mainText + text: "Do you wish to continue?" + } + Text { + id: detailedText + anchors.top: mainText.bottom + text: "If you wish so, you may continue with an unverified certificate.\n" + + "Accepting an unverified certificate means\n" + + "you may not be connected with the host you tried to connect to.\n" + + "Do you wish to override the security check and continue?" + } + } + + onAccepted: { + certErrors.shift().acceptCertificate(); + presentError(); + } + onRejected: reject() + + function reject(){ + certErrors.shift().rejectCertificate(); + presentError(); + } + function enqueue(error){ + certErrors.push(error); + presentError(); + } + function presentError(){ + visible = certErrors.length > 0 + } + } + + FullScreenNotification { + id: fullScreenNotification + } + + DownloadView { + id: downloadView + visible: false + anchors.fill: parent + } + + function onDownloadRequested(download) { + downloadView.visible = true; + downloadView.append(download); + download.accept(); + } + + FindBar { + id: findBar + visible: false + anchors.right: parent.right + anchors.rightMargin: 10 + anchors.top: parent.top + + onFindNext: { + if (text) + currentWebView && currentWebView.findText(text); + else if (!visible) + visible = true; + } + onFindPrevious: { + if (text) + currentWebView && currentWebView.findText(text, WebEngineView.FindBackward); + else if (!visible) + visible = true; + } + } + + + Rectangle { + id: statusBubble + color: "oldlace" + property int padding: 8 + visible: false + + anchors.left: parent.left + anchors.bottom: parent.bottom + width: statusText.paintedWidth + padding + height: statusText.paintedHeight + padding + + Text { + id: statusText + anchors.centerIn: statusBubble + elide: Qt.ElideMiddle + + Timer { + id: hideStatusText + interval: 750 + onTriggered: { + statusText.text = ""; + statusBubble.visible = false; + } + } + } + } +} diff --git a/testcases/quicknanobrowser/CMakeLists.txt b/testcases/quicknanobrowser/CMakeLists.txt new file mode 100644 index 00000000..aefcae84 --- /dev/null +++ b/testcases/quicknanobrowser/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.16) + +set(CMAKE_AUTOMOC ON) + +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Qml Quick WebEngineQuick) + +# Resources: +file(GLOB_RECURSE SOURCE_QRC + "*.qrc" +) + +add_executable(quicknanobrowser + main.cpp + utils.h + ${SOURCE_QRC} +) + +set_target_properties(quicknanobrowser PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(quicknanobrowser PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick + Qt::WebEngineQuick +) diff --git a/tests/quicknanobrowser/DownloadView.qml b/testcases/quicknanobrowser/DownloadView.qml similarity index 93% rename from tests/quicknanobrowser/DownloadView.qml rename to testcases/quicknanobrowser/DownloadView.qml index 545a502a..ea7e0b53 100644 --- a/tests/quicknanobrowser/DownloadView.qml +++ b/testcases/quicknanobrowser/DownloadView.qml @@ -1,175 +1,174 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine 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$ -** -****************************************************************************/ - -import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Controls.Styles 1.0 -import QtWebEngine 1.9 -import QtQuick.Layouts 1.0 - -Rectangle { - id: downloadView - color: "lightgray" - - ListModel { - id: downloadModel - property var downloads: [] - } - - function append(download) { - downloadModel.append(download); - downloadModel.downloads.push(download); - } - - Component { - id: downloadItemDelegate - - Rectangle { - width: listView.width - height: childrenRect.height - anchors.margins: 10 - radius: 3 - color: "transparent" - border.color: "black" - Rectangle { - id: progressBar - - property real progress: downloadModel.downloads[index] - ? downloadModel.downloads[index].receivedBytes / downloadModel.downloads[index].totalBytes : 0 - - radius: 3 - color: width == listView.width ? "green" : "#2b74c7" - width: listView.width * progress - height: cancelButton.height - - Behavior on width { - SmoothedAnimation { duration: 100 } - } - } - Rectangle { - anchors { - left: parent.left - right: parent.right - leftMargin: 20 - } - Label { - id: label - text: path - anchors { - verticalCenter: cancelButton.verticalCenter - left: parent.left - right: cancelButton.left - } - } - Button { - id: cancelButton - anchors.right: parent.right - iconSource: "icons/process-stop.png" - onClicked: { - var download = downloadModel.downloads[index]; - - download.cancel(); - - downloadModel.downloads = downloadModel.downloads.filter(function (el) { - return el.id !== download.id; - }); - downloadModel.remove(index); - } - } - } - } - - } - ListView { - id: listView - anchors { - topMargin: 10 - top: parent.top - bottom: parent.bottom - horizontalCenter: parent.horizontalCenter - } - width: parent.width - 20 - spacing: 5 - - model: downloadModel - delegate: downloadItemDelegate - - Text { - visible: !listView.count - horizontalAlignment: Text.AlignHCenter - height: 30 - anchors { - top: parent.top - left: parent.left - right: parent.right - } - font.pixelSize: 20 - text: "No active downloads." - } - - Rectangle { - color: "gray" - anchors { - bottom: parent.bottom - left: parent.left - right: parent.right - } - height: 30 - Button { - id: okButton - text: "OK" - anchors.centerIn: parent - onClicked: { - downloadView.visible = false; - } - } - } - } -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine 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$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtWebEngine +import QtQuick.Layouts + +Rectangle { + id: downloadView + color: "lightgray" + + ListModel { + id: downloadModel + property var downloads: [] + } + + function append(download) { + downloadModel.append(download); + downloadModel.downloads.push(download); + } + + Component { + id: downloadItemDelegate + + Rectangle { + width: listView.width + height: childrenRect.height + anchors.margins: 10 + radius: 3 + color: "transparent" + border.color: "black" + Rectangle { + id: progressBar + + property real progress: downloadModel.downloads[index] + ? downloadModel.downloads[index].receivedBytes / downloadModel.downloads[index].totalBytes : 0 + + radius: 3 + color: width == listView.width ? "green" : "#2b74c7" + width: listView.width * progress + height: cancelButton.height + + Behavior on width { + SmoothedAnimation { duration: 100 } + } + } + Rectangle { + anchors { + left: parent.left + right: parent.right + leftMargin: 20 + } + Label { + id: label + text: downloadModel.downloads[index] ? downloadModel.downloads[index].downloadDirectory + "/" + downloadModel.downloads[index].downloadFileName : qsTr("") + anchors { + verticalCenter: cancelButton.verticalCenter + left: parent.left + right: cancelButton.left + } + } + Button { + id: cancelButton + anchors.right: parent.right + icon.source: "qrc:/icons/process-stop.png" + onClicked: { + var download = downloadModel.downloads[index]; + + download.cancel(); + + downloadModel.downloads = downloadModel.downloads.filter(function (el) { + return el.id !== download.id; + }); + downloadModel.remove(index); + } + } + } + } + + } + ListView { + id: listView + anchors { + topMargin: 10 + top: parent.top + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + width: parent.width - 20 + spacing: 5 + + model: downloadModel + delegate: downloadItemDelegate + + Text { + visible: !listView.count + horizontalAlignment: Text.AlignHCenter + height: 30 + anchors { + top: parent.top + left: parent.left + right: parent.right + } + font.pixelSize: 20 + text: "No active downloads." + } + + Rectangle { + color: "gray" + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + } + height: 30 + Button { + id: okButton + text: "OK" + anchors.centerIn: parent + onClicked: { + downloadView.visible = false; + } + } + } + } +} diff --git a/testcases/quicknanobrowser/FindBar.qml b/testcases/quicknanobrowser/FindBar.qml new file mode 100644 index 00000000..738a38c8 --- /dev/null +++ b/testcases/quicknanobrowser/FindBar.qml @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine 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$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Rectangle { + id: root + + property int numberOfMatches: 0 + property int activeMatch: 0 + property alias text: findTextField.text + + function reset() { + numberOfMatches = 0; + activeMatch = 0; + visible = false; + } + + signal findNext() + signal findPrevious() + + width: 250 + height: 35 + radius: 2 + + border.width: 1 + border.color: "black" + color: "white" + + onVisibleChanged: { + if (visible) + findTextField.forceActiveFocus(); + } + + + RowLayout { + anchors.fill: parent + anchors.topMargin: 5 + anchors.bottomMargin: 5 + anchors.leftMargin: 10 + anchors.rightMargin: 10 + + spacing: 5 + + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + + TextField { + id: findTextField + anchors.fill: parent + background: Rectangle { + color: "transparent" + } + + onAccepted: root.findNext() + onTextChanged: root.findNext() + onActiveFocusChanged: activeFocus ? selectAll() : deselect() + } + } + + Label { + text: activeMatch + "/" + numberOfMatches + visible: findTextField.text != "" + } + + Rectangle { + border.width: 1 + border.color: "#ddd" + width: 2 + height: parent.height + anchors.topMargin: 5 + anchors.bottomMargin: 5 + } + + ToolButton { + text: "<" + enabled: numberOfMatches > 0 + onClicked: root.findPrevious() + } + + ToolButton { + text: ">" + enabled: numberOfMatches > 0 + onClicked: root.findNext() + } + + ToolButton { + text: "x" + onClicked: root.visible = false + } + } +} diff --git a/tests/quicknanobrowser/FullScreenNotification.qml b/testcases/quicknanobrowser/FullScreenNotification.qml similarity index 96% rename from tests/quicknanobrowser/FullScreenNotification.qml rename to testcases/quicknanobrowser/FullScreenNotification.qml index 55f5f00e..c5f891db 100644 --- a/tests/quicknanobrowser/FullScreenNotification.qml +++ b/testcases/quicknanobrowser/FullScreenNotification.qml @@ -1,109 +1,109 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -import QtQuick 2.5 - -Rectangle { - id: fullScreenNotification - width: 500 - height: 40 - color: "white" - radius: 7 - - visible: false - opacity: 0 - - function show() { - visible = true; - opacity = 1; - reset.start(); - } - - function hide() { - reset.stop(); - opacity = 0; - } - - Behavior on opacity { - NumberAnimation { - duration: 750 - onStopped: { - if (opacity == 0) - visible = false; - } - } - } - - Timer { - id: reset - interval: 5000 - onTriggered: hide() - } - - anchors.horizontalCenter: parent.horizontalCenter - y: 125 - - Text { - id: message - width: parent.width - - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - - wrapMode: Text.WordWrap - elide: Text.ElideNone - clip: true - - text: qsTr("You are now in fullscreen mode. Press ESC to quit!") - } -} +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples 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$ +** +****************************************************************************/ + +import QtQuick + +Rectangle { + id: fullScreenNotification + width: 500 + height: 40 + color: "white" + radius: 7 + + visible: false + opacity: 0 + + function show() { + visible = true; + opacity = 1; + reset.start(); + } + + function hide() { + reset.stop(); + opacity = 0; + } + + Behavior on opacity { + NumberAnimation { + duration: 750 + onStopped: { + if (opacity == 0) + visible = false; + } + } + } + + Timer { + id: reset + interval: 5000 + onTriggered: hide() + } + + anchors.horizontalCenter: parent.horizontalCenter + y: 125 + + Text { + id: message + width: parent.width + + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + wrapMode: Text.WordWrap + elide: Text.ElideNone + clip: true + + text: qsTr("You are now in fullscreen mode. Press ESC to quit!") + } +} diff --git a/tests/quicknanobrowser/doc/images/quicknanobrowser-demo.jpg b/testcases/quicknanobrowser/doc/images/quicknanobrowser-demo.jpg similarity index 100% rename from tests/quicknanobrowser/doc/images/quicknanobrowser-demo.jpg rename to testcases/quicknanobrowser/doc/images/quicknanobrowser-demo.jpg diff --git a/tests/quicknanobrowser/doc/src/quicknanobrowser.qdoc b/testcases/quicknanobrowser/doc/src/quicknanobrowser.qdoc similarity index 81% rename from tests/quicknanobrowser/doc/src/quicknanobrowser.qdoc rename to testcases/quicknanobrowser/doc/src/quicknanobrowser.qdoc index 48a63c79..3b9af68b 100644 --- a/tests/quicknanobrowser/doc/src/quicknanobrowser.qdoc +++ b/testcases/quicknanobrowser/doc/src/quicknanobrowser.qdoc @@ -1,149 +1,153 @@ -/**************************************************************************** -** -** 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:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and 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. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example webengine/quicknanobrowser - \title WebEngine Quick Nano Browser - \ingroup webengine-examples - \brief A web browser implemented using the WebEngineView QML type. - - \image quicknanobrowser-demo.jpg - - \e {Quick Nano Browser} demonstrates how to use the \l{Qt WebEngine QML Types} - {Qt WebEngine QML types} to develop a small web browser application that consists of a browser - window with a title bar, toolbar, tab view, and status bar. The web content is loaded in a web - engine view within the tab view. If certificate errors occur, users are prompted for action in a - message dialog. The status bar pops up to display the URL of a hovered link. - - A web page can issue a request for being displayed in fullscreen mode. Users can allow full - screen mode by using a toolbar button. They can leave fullscreen mode by using a keyboard - shortcut. Additional toolbar buttons enable moving backwards and forwards in the browser - history, reloading tab content, and opening a settings menu for enabling the following features: - JavaScript, plugins, fullscreen mode, off the record, HTTP disk cache, autoloading images, and - ignoring certificate errors. - - \include examples-run.qdocinc - - \section1 Creating the Main Browser Window - - When the browser main window is loaded, it creates an empty tab using the default profile. Each - tab is a web engine view that fills the main window. - - We create the main window in the \e BrowserWindow.qml file using the ApplicationWindow type: - - \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml - \skipto ApplicationWindow - \printuntil currentWebView - \dots - \skipto width - \printuntil title - - We use the TabView Qt Quick control to create an empty tab view that fills the main window. We - set the tab active first, to make sure that the tab item is immediately instantiated: - - \skipto TabView - \printuntil Component.onCompleted - - The tab contains a web engine view that loads web content: - - \printuntil focus - - We use the \l Action type to create new tabs: - - \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml - \skipto reload - \skipto Action - \printuntil } - - We use the \l TextField Qt Quick Control within a \l ToolBar to create an address bar that - shows the current URL and where users can enter another URL: - - \skipto toolBar - \printuntil anchors.fill - \dots - \skipto TextField - \printuntil addressBar - \dots - \skipto focus - \printuntil /^\ {16}\}/ - - \section1 Handling Certificate Errors - - If the certificate of the site being loaded triggers a certificate error, we call the - \l{WebEngineCertificateError::}{defer()} QML method to pause the URL request and wait for user - input: - - \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml - \skipto onCertificateError - \printuntil } - - We use the MessageDialog type to prompt users to continue or cancel the loading of the web page. - If users select \uicontrol Yes, we call the - \l{WebEngineCertificateError::}{ignoreCertificateError()} method to ignore the error and - continue loading content from the URL. If users select \uicontrol No, we call the - \l{WebEngineCertificateError::}{rejectCertificate()} method to reject the request and stop - loading content from the URL: - - \skipto MessageDialog - \printuntil /^\ {4}\}/ - - \section1 Entering and Leaving Fullscreen Mode - - We create a menu item for allowing fullscreen mode in a settings menu that we place on the tool - bar. Also, we create an action for leaving fullscreen mode by using a keyboard shortcut. - We call the \l{FullScreenRequest::}{accept()} method to accept the fullscreen request. - The methdod sets the \l{WebEngineView::}{isFullScreen} property to be equal to the - \l{FullScreenRequest::}{toggleOn} property. - - \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml - \skipto onFullScreenRequested - \printuntil /^\ {16}\}/ - - When entering fullscreen mode, we display a notification using the FullScreenNotification custom - type that we create in \e FullScreenNotification.qml. - - We use the \l Action type in the settings menu to create a shortcut for leaving fullscreen mode - by pressing the escape key: - - \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml - \skipto Settings - \printuntil appSettings - \skipto fullScreenSupportEnabled - \printuntil Action - \skipto Escape - \printuntil /^\ {4}\}/ - - \section1 Files and Attributions - - The example uses icons from the Tango Icon Library: - - \table - \row - \li \l{quicknanobrowser-tango}{Tango Icon Library} - \li Public Domain - \endtable -*/ +/**************************************************************************** +** +** 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:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and 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. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example webenginequick/quicknanobrowser + \title WebEngine Quick Nano Browser + \ingroup webengine-examples + \brief A web browser implemented using the WebEngineView QML type. + + \image quicknanobrowser-demo.jpg + + \e {Quick Nano Browser} demonstrates how to use the \l{Qt WebEngine QML Types} + {Qt WebEngine QML types} to develop a small web browser application that consists of a browser + window with a title bar, toolbar, tab view, and status bar. The web content is loaded in a web + engine view within the tab view. If certificate errors occur, users are prompted for action in a + message dialog. The status bar pops up to display the URL of a hovered link. + + A web page can issue a request for being displayed in fullscreen mode. Users can allow full + screen mode by using a toolbar button. They can leave fullscreen mode by using a keyboard + shortcut. Additional toolbar buttons enable moving backwards and forwards in the browser + history, reloading tab content, and opening a settings menu for enabling the following features: + JavaScript, plugins, fullscreen mode, off the record, HTTP disk cache, autoloading images, and + ignoring certificate errors. + + \include examples-run.qdocinc + + \section1 Creating the Main Browser Window + + When the browser main window is loaded, it creates an empty tab using the default profile. Each + tab is a web engine view that fills the main window. + + We create the main window in the \e BrowserWindow.qml file using the ApplicationWindow type: + + \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml + \skipto ApplicationWindow + \printuntil currentWebView + \dots + \skipto width + \printuntil title + + We use the TabBar Qt Quick control to create a tab bar anchored to the top of the window, and + create a new, empty tab: + + \skipto TabBar { + \printuntil return webview + \printuntil } + + The tab contains a web engine view that loads web content: + + \skipto Component { + \printuntil currentWebView.reload + \printuntil /^\ {8}\}/ + + We use the \l Action type to create new tabs: + + \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml + \skipto reload + \skipto Action + \printuntil } + + We use the \l TextField Qt Quick Control within a \l ToolBar to create an address bar that + shows the current URL and where users can enter another URL: + + \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml + \skipto menuBar: ToolBar + \printuntil anchors.fill + \dots + \skipto TextField + \printuntil addressBar + \dots + \skipto focus + \printuntil /^\ {12}\}/ + + \section1 Handling Certificate Errors + + If the certificate of the site being loaded triggers a certificate error, we call the + \l{WebEngineCertificateError::}{defer()} QML method to pause the URL request and wait for user + input: + + \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml + \skipto onCertificateError + \printuntil } + + We use the Dialog type to prompt users to continue or cancel the loading of the web page. + If users select \uicontrol Yes, we call the + \l{WebEngineCertificateError::}{acceptCertificate()} method to continue loading content from + the URL. If users select \uicontrol No, we call the + \l{WebEngineCertificateError::}{rejectCertificate()} method to reject the request and stop + loading content from the URL: + + \skipto Dialog { + \printuntil /^\ {4}\}/ + + \section1 Entering and Leaving Fullscreen Mode + + We create a menu item for allowing fullscreen mode in a settings menu that we place on the tool + bar. Also, we create an action for leaving fullscreen mode by using a keyboard shortcut. + We call the \l{FullScreenRequest::}{accept()} method to accept the fullscreen request. + The methdod sets the \l{WebEngineView::}{isFullScreen} property to be equal to the + \l{FullScreenRequest::}{toggleOn} property. + + \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml + \skipto onFullScreenRequested + \printuntil /^\ {16}\}/ + + When entering fullscreen mode, we display a notification using the FullScreenNotification custom + type that we create in \e FullScreenNotification.qml. + + We use the \l Action type in the settings menu to create a shortcut for leaving fullscreen mode + by pressing the escape key: + + \quotefromfile webenginequick/quicknanobrowser/BrowserWindow.qml + \skipto Settings + \printuntil appSettings + \skipto fullScreenSupportEnabled + \printuntil Action + \skipto Escape + \printuntil /^\ {4}\}/ + + \section1 Files and Attributions + + The example uses icons from the Tango Icon Library: + + \table + \row + \li \l{quicknanobrowser-tango}{Tango Icon Library} + \li Public Domain + \endtable +*/ diff --git a/tests/quicknanobrowser/icons/3rdparty/COPYING b/testcases/quicknanobrowser/icons/3rdparty/COPYING similarity index 98% rename from tests/quicknanobrowser/icons/3rdparty/COPYING rename to testcases/quicknanobrowser/icons/3rdparty/COPYING index 95490508..220881da 100644 --- a/tests/quicknanobrowser/icons/3rdparty/COPYING +++ b/testcases/quicknanobrowser/icons/3rdparty/COPYING @@ -1 +1 @@ -The icons in this repository are herefore released into the Public Domain. +The icons in this repository are herefore released into the Public Domain. diff --git a/tests/quicknanobrowser/icons/3rdparty/go-next.png b/testcases/quicknanobrowser/icons/3rdparty/go-next.png similarity index 100% rename from tests/quicknanobrowser/icons/3rdparty/go-next.png rename to testcases/quicknanobrowser/icons/3rdparty/go-next.png diff --git a/tests/quicknanobrowser/icons/3rdparty/go-previous.png b/testcases/quicknanobrowser/icons/3rdparty/go-previous.png similarity index 100% rename from tests/quicknanobrowser/icons/3rdparty/go-previous.png rename to testcases/quicknanobrowser/icons/3rdparty/go-previous.png diff --git a/tests/quicknanobrowser/icons/3rdparty/process-stop.png b/testcases/quicknanobrowser/icons/3rdparty/process-stop.png similarity index 100% rename from tests/quicknanobrowser/icons/3rdparty/process-stop.png rename to testcases/quicknanobrowser/icons/3rdparty/process-stop.png diff --git a/tests/quicknanobrowser/icons/3rdparty/qt_attribution.json b/testcases/quicknanobrowser/icons/3rdparty/qt_attribution.json similarity index 92% rename from tests/quicknanobrowser/icons/3rdparty/qt_attribution.json rename to testcases/quicknanobrowser/icons/3rdparty/qt_attribution.json index a3d55637..681223b1 100644 --- a/tests/quicknanobrowser/icons/3rdparty/qt_attribution.json +++ b/testcases/quicknanobrowser/icons/3rdparty/qt_attribution.json @@ -1,24 +1,24 @@ -{ - "Id": "quicknanobrowser-tango", - "Name": "Tango Icon Library", - "QDocModule": "qtwebengine", - "QtUsage": "Used in WebEngine Quick Nano Browser example.", - - "QtParts": [ "examples" ], - "Description": "Selected icons from the Tango Icon Library", - "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library", - "Version": "0.8.90", - "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz", - "LicenseId": "DocumentRef-PublicDomain", - "License": "Public Domain", - "LicenseFile": "COPYING", - "Copyright": "Ulisse Perusin -Steven Garrity -Lapo Calamandrei -Ryan Collier -Rodney Dawes -Andreas Nilsson -Tuomas Kuosmanen -Garrett LeSage -Jakub Steiner " -} +{ + "Id": "quicknanobrowser-tango", + "Name": "Tango Icon Library", + "QDocModule": "qtwebengine", + "QtUsage": "Used in WebEngine Quick Nano Browser example.", + + "QtParts": [ "examples" ], + "Description": "Selected icons from the Tango Icon Library", + "Homepage": "http://tango.freedesktop.org/Tango_Icon_Library", + "Version": "0.8.90", + "DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz", + "LicenseId": "urn:dje:license:public-domain", + "License": "Public Domain", + "LicenseFile": "COPYING", + "Copyright": "Ulisse Perusin +Steven Garrity +Lapo Calamandrei +Ryan Collier +Rodney Dawes +Andreas Nilsson +Tuomas Kuosmanen +Garrett LeSage +Jakub Steiner " +} diff --git a/tests/quicknanobrowser/icons/3rdparty/view-refresh.png b/testcases/quicknanobrowser/icons/3rdparty/view-refresh.png similarity index 100% rename from tests/quicknanobrowser/icons/3rdparty/view-refresh.png rename to testcases/quicknanobrowser/icons/3rdparty/view-refresh.png diff --git a/tests/quicknanobrowser/main.cpp b/testcases/quicknanobrowser/main.cpp similarity index 89% rename from tests/quicknanobrowser/main.cpp rename to testcases/quicknanobrowser/main.cpp index 343882f4..f21b0362 100644 --- a/tests/quicknanobrowser/main.cpp +++ b/testcases/quicknanobrowser/main.cpp @@ -1,98 +1,90 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine 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 "utils.h" - -#ifndef QT_NO_WIDGETS -#include -typedef QApplication Application; -#else -#include -typedef QGuiApplication Application; -#endif -#include -#include -#include - -static QUrl startupUrl() -{ - QUrl ret; - QStringList args(qApp->arguments()); - args.takeFirst(); - for (const QString &arg : qAsConst(args)) { - if (arg.startsWith(QLatin1Char('-'))) - continue; - ret = Utils::fromUserInput(arg); - if (ret.isValid()) - return ret; - } - return QUrl(QStringLiteral("https://www.qt.io")); -} - -int main(int argc, char **argv) -{ - QCoreApplication::setOrganizationName("QtExamples"); - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - - Application app(argc, argv); - - QtWebEngine::initialize(); - - QQmlApplicationEngine appEngine; - Utils utils; - appEngine.rootContext()->setContextProperty("utils", &utils); - appEngine.load(QUrl("qrc:/ApplicationRoot.qml")); - if (!appEngine.rootObjects().isEmpty()) - QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl())); - else - qFatal("Failed to load sources"); - - return app.exec(); -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine 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 "utils.h" + +#include +#include +#include +#include + +static QUrl startupUrl() +{ + QUrl ret; + QStringList args(qApp->arguments()); + args.takeFirst(); + for (const QString &arg : qAsConst(args)) { + if (arg.startsWith(QLatin1Char('-'))) + continue; + ret = Utils::fromUserInput(arg); + if (ret.isValid()) + return ret; + } + return QUrl(QStringLiteral("https://www.qt.io")); +} + +int main(int argc, char **argv) +{ + QCoreApplication::setOrganizationName("QtExamples"); + QtWebEngineQuick::initialize(); + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine appEngine; + Utils utils; + appEngine.rootContext()->setContextProperty("utils", &utils); + appEngine.load(QUrl("qrc:/ApplicationRoot.qml")); + if (!appEngine.rootObjects().isEmpty()) + QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl())); + else + qFatal("Failed to load sources"); + + return app.exec(); +} diff --git a/tests/quicknanobrowser/resources.qrc b/testcases/quicknanobrowser/resources.qrc similarity index 87% rename from tests/quicknanobrowser/resources.qrc rename to testcases/quicknanobrowser/resources.qrc index af52c47e..9d1f927d 100644 --- a/tests/quicknanobrowser/resources.qrc +++ b/testcases/quicknanobrowser/resources.qrc @@ -1,15 +1,16 @@ - - - ApplicationRoot.qml - BrowserDialog.qml - BrowserWindow.qml - DownloadView.qml - FullScreenNotification.qml - - - icons/3rdparty/go-next.png - icons/3rdparty/go-previous.png - icons/3rdparty/process-stop.png - icons/3rdparty/view-refresh.png - - + + + ApplicationRoot.qml + BrowserDialog.qml + BrowserWindow.qml + DownloadView.qml + FindBar.qml + FullScreenNotification.qml + + + icons/3rdparty/go-next.png + icons/3rdparty/go-previous.png + icons/3rdparty/process-stop.png + icons/3rdparty/view-refresh.png + + diff --git a/tests/quicknanobrowser/utils.h b/testcases/quicknanobrowser/utils.h similarity index 97% rename from tests/quicknanobrowser/utils.h rename to testcases/quicknanobrowser/utils.h index 260a0c93..79aa38cc 100644 --- a/tests/quicknanobrowser/utils.h +++ b/testcases/quicknanobrowser/utils.h @@ -1,70 +1,70 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine 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 UTILS_H -#define UTILS_H - -#include -#include - -class Utils : public QObject { - Q_OBJECT -public: - Q_INVOKABLE static QUrl fromUserInput(const QString& userInput); -}; - -inline QUrl Utils::fromUserInput(const QString& userInput) -{ - QFileInfo fileInfo(userInput); - if (fileInfo.exists()) - return QUrl::fromLocalFile(fileInfo.absoluteFilePath()); - return QUrl::fromUserInput(userInput); -} - -#endif // UTILS_H +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine 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 UTILS_H +#define UTILS_H + +#include +#include + +class Utils : public QObject { + Q_OBJECT +public: + Q_INVOKABLE static QUrl fromUserInput(const QString& userInput); +}; + +inline QUrl Utils::fromUserInput(const QString& userInput) +{ + QFileInfo fileInfo(userInput); + if (fileInfo.exists()) + return QUrl::fromLocalFile(fileInfo.absoluteFilePath()); + return QUrl::fromUserInput(userInput); +} + +#endif // UTILS_H diff --git a/testcases/virtualkeyboard/.prev_CMakeLists.txt b/testcases/virtualkeyboard/.prev_CMakeLists.txt new file mode 100644 index 00000000..cc153191 --- /dev/null +++ b/testcases/virtualkeyboard/.prev_CMakeLists.txt @@ -0,0 +1,80 @@ +# Generated from basic.pro. + +cmake_minimum_required(VERSION 3.14) +project(basic LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/virtualkeyboard/basic") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Qml) +find_package(Qt6 COMPONENTS Quick) + +qt_add_executable(basic + main.cpp +) +set_target_properties(basic PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(basic PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + + +# Resources: +set(demo_resource_files + "Basic.qml" + "basic-b2qt.qml" + "content/AutoScroller.qml" + "content/FloatingButton_Active.svg" + "content/FloatingButton_Available.svg" + "content/FloatingButton_Unavailable.svg" + "content/HandwritingModeButton.qml" + "content/TextArea.qml" + "content/TextField.qml" +) + +qt6_add_resources(basic "demo" + PREFIX + "/" + FILES + ${demo_resource_files} +) + +if(NOT QT_BUILD_SHARED_LIBS) + target_link_libraries(basic PUBLIC + Qt::Svg + ) +endif() + +if(NOT QT_FEATURE_vkb_desktop) + target_compile_definitions(basic PUBLIC + MAIN_QML=\\\"basic-b2qt.qml\\\" + ) +endif() + +if(QT_FEATURE_vkb_desktop) + target_compile_definitions(basic PUBLIC + MAIN_QML=\\\"Basic.qml\\\" + ) +endif() + +install(TARGETS basic + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/virtualkeyboard/basic/Basic.qml b/testcases/virtualkeyboard/Basic.qml similarity index 94% rename from tests/virtualkeyboard/basic/Basic.qml rename to testcases/virtualkeyboard/Basic.qml index 465b7837..2fb42197 100644 --- a/tests/virtualkeyboard/basic/Basic.qml +++ b/testcases/virtualkeyboard/Basic.qml @@ -1,146 +1,146 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.10 -import QtQuick.Controls 2.3 -import QtQuick.VirtualKeyboard 2.1 -import "content" - -Rectangle { - width: 1280 - height: 720 - color: "#F6F6F6" - - // Only set with CONFIG+=disable-desktop. - property bool handwritingInputPanelActive: false - - Flickable { - id: flickable - anchors.fill: parent - contentWidth: content.width - contentHeight: content.height - interactive: contentHeight > height - flickableDirection: Flickable.VerticalFlick - - property real scrollMarginVertical: 20 - - ScrollBar.vertical: ScrollBar {} - - MouseArea { - id: content - width: flickable.width - height: textEditors.height + 24 - - onClicked: focus = true - - Column { - id: textEditors - spacing: 15 - x: 12 - y: 12 - width: parent.width - 26 - - Label { - color: "#565758" - text: "Tap fields to enter text" - anchors.horizontalCenter: parent.horizontalCenter - font.pixelSize: 22 - } - TextField { - width: parent.width - placeholderText: "One line field" - enterKeyAction: EnterKeyAction.Next - onAccepted: passwordField.focus = true - } - TextField { - id: passwordField - width: parent.width - echoMode: TextInput.Password - placeholderText: "Password field" - inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText - enterKeyAction: EnterKeyAction.Next - onAccepted: upperCaseField.focus = true - } - TextField { - id: upperCaseField - width: parent.width - placeholderText: "Upper case field" - inputMethodHints: Qt.ImhUppercaseOnly - enterKeyAction: EnterKeyAction.Next - onAccepted: lowerCaseField.focus = true - } - TextField { - id: lowerCaseField - width: parent.width - placeholderText: "Lower case field" - inputMethodHints: Qt.ImhLowercaseOnly - enterKeyAction: EnterKeyAction.Next - onAccepted: phoneNumberField.focus = true - } - TextField { - id: phoneNumberField - validator: RegExpValidator { regExp: /^[0-9\+\-\#\*\ ]{6,}$/ } - width: parent.width - placeholderText: "Phone number field" - inputMethodHints: Qt.ImhDialableCharactersOnly - enterKeyAction: EnterKeyAction.Next - onAccepted: formattedNumberField.focus = true - } - TextField { - id: formattedNumberField - width: parent.width - placeholderText: "Formatted number field" - inputMethodHints: Qt.ImhFormattedNumbersOnly - enterKeyAction: EnterKeyAction.Next - onAccepted: digitsField.focus = true - } - TextField { - id: digitsField - width: parent.width - placeholderText: "Digits only field" - inputMethodHints: Qt.ImhDigitsOnly - enterKeyAction: EnterKeyAction.Next - onAccepted: textArea.focus = true - } - TextArea { - id: textArea - width: parent.width - placeholderText: "Multiple line field" - height: Math.max(206, implicitHeight) - } - } - } - } - - // Hide the text fields' cursors when fullscreen handwriting is active. - MouseArea { - anchors.fill: parent - visible: handwritingInputPanelActive - } -} +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.VirtualKeyboard +import "content" + +Rectangle { + width: 1280 + height: 720 + color: "#F6F6F6" + + // Only set with CONFIG+=disable-desktop. + property bool handwritingInputPanelActive: false + + Flickable { + id: flickable + anchors.fill: parent + contentWidth: content.width + contentHeight: content.height + interactive: contentHeight > height + flickableDirection: Flickable.VerticalFlick + + property real scrollMarginVertical: 20 + + ScrollBar.vertical: ScrollBar {} + + MouseArea { + id: content + width: flickable.width + height: textEditors.height + 24 + + onClicked: focus = true + + Column { + id: textEditors + spacing: 15 + x: 12 + y: 12 + width: parent.width - 26 + + Label { + color: "#565758" + text: "Tap fields to enter text" + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 22 + } + TextField { + width: parent.width + placeholderText: "One line field" + enterKeyAction: EnterKeyAction.Next + onAccepted: passwordField.focus = true + } + TextField { + id: passwordField + width: parent.width + echoMode: TextInput.Password + placeholderText: "Password field" + inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText + enterKeyAction: EnterKeyAction.Next + onAccepted: upperCaseField.focus = true + } + TextField { + id: upperCaseField + width: parent.width + placeholderText: "Upper case field" + inputMethodHints: Qt.ImhUppercaseOnly + enterKeyAction: EnterKeyAction.Next + onAccepted: lowerCaseField.focus = true + } + TextField { + id: lowerCaseField + width: parent.width + placeholderText: "Lower case field" + inputMethodHints: Qt.ImhLowercaseOnly + enterKeyAction: EnterKeyAction.Next + onAccepted: phoneNumberField.focus = true + } + TextField { + id: phoneNumberField + validator: RegularExpressionValidator { regularExpression: /^[0-9\+\-\#\*\ ]{6,}$/ } + width: parent.width + placeholderText: "Phone number field" + inputMethodHints: Qt.ImhDialableCharactersOnly + enterKeyAction: EnterKeyAction.Next + onAccepted: formattedNumberField.focus = true + } + TextField { + id: formattedNumberField + width: parent.width + placeholderText: "Formatted number field" + inputMethodHints: Qt.ImhFormattedNumbersOnly + enterKeyAction: EnterKeyAction.Next + onAccepted: digitsField.focus = true + } + TextField { + id: digitsField + width: parent.width + placeholderText: "Digits only field" + inputMethodHints: Qt.ImhDigitsOnly + enterKeyAction: EnterKeyAction.Next + onAccepted: textArea.focus = true + } + TextArea { + id: textArea + width: parent.width + placeholderText: "Multiple line field" + height: Math.max(206, implicitHeight) + } + } + } + } + + // Hide the text fields' cursors when fullscreen handwriting is active. + MouseArea { + anchors.fill: parent + visible: handwritingInputPanelActive + } +} diff --git a/testcases/virtualkeyboard/CMakeLists.txt b/testcases/virtualkeyboard/CMakeLists.txt new file mode 100644 index 00000000..9782c007 --- /dev/null +++ b/testcases/virtualkeyboard/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.16) +project(basic LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick) + +qt_add_executable(basic + main.cpp +) + +set_target_properties(basic PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(basic PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +# Resources: +set(demo_resource_files + "Basic.qml" + "basic-b2qt.qml" + "content/AutoScroller.qml" + "content/FloatingButton_Active.svg" + "content/FloatingButton_Available.svg" + "content/FloatingButton_Unavailable.svg" + "content/HandwritingModeButton.qml" + "content/TextArea.qml" + "content/TextField.qml" +) + +qt6_add_resources(basic "demo" + PREFIX + "/" + FILES + ${demo_resource_files} +) + +if(QT_FEATURE_static) + find_package(Qt6 REQUIRED COMPONENTS Svg) + target_link_libraries(basic PUBLIC + Qt::Svg + ) +endif() + +if(NOT QT_FEATURE_vkb_desktop) + target_compile_definitions(basic PUBLIC + MAIN_QML="basic-b2qt.qml" + ) +endif() + +if(QT_FEATURE_vkb_desktop) + target_compile_definitions(basic PUBLIC + MAIN_QML="Basic.qml" + ) +endif() diff --git a/tests/virtualkeyboard/basic/basic-b2qt.qml b/testcases/virtualkeyboard/basic-b2qt.qml similarity index 94% rename from tests/virtualkeyboard/basic/basic-b2qt.qml rename to testcases/virtualkeyboard/basic-b2qt.qml index b189416e..274599cb 100644 --- a/tests/virtualkeyboard/basic/basic-b2qt.qml +++ b/testcases/virtualkeyboard/basic-b2qt.qml @@ -1,174 +1,172 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. -import QtQml 2.14 -import QtQuick.Window 2.2 -import QtQuick.VirtualKeyboard 2.2 -import QtQuick.VirtualKeyboard.Settings 2.2 -import "content" - -Item { - width: 1280 - height: 720 - - Item { - id: appContainer - width: Screen.orientation === Qt.LandscapeOrientation ? parent.width : parent.height - height: Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width - anchors.centerIn: parent - Basic { - id: virtualKeyboard - anchors.left: parent.left - anchors.top: parent.top - anchors.right: parent.right - anchors.bottom: parent.bottom - handwritingInputPanelActive: handwritingInputPanel.available && handwritingInputPanel.active - } - - /* Handwriting input panel for full screen handwriting input. - - This component is an optional add-on for the InputPanel component, that - is, its use does not affect the operation of the InputPanel component, - but it also can not be used as a standalone component. - - The handwriting input panel is positioned to cover the entire area of - application. The panel itself is transparent, but once it is active the - user can draw handwriting on it. - */ - HandwritingInputPanel { - z: 79 - id: handwritingInputPanel - anchors.fill: parent - inputPanel: inputPanel - Rectangle { - z: -1 - anchors.fill: parent - color: "black" - opacity: 0.10 - } - } - - /* Container area for the handwriting mode button. - - Handwriting mode button can be moved freely within the container area. - In this example, a single click changes the handwriting mode and a - double-click changes the availability of the full screen handwriting input. - */ - Item { - z: 99 - visible: handwritingInputPanel.enabled && Qt.inputMethod.visible - anchors { left: parent.left; top: parent.top; right: parent.right; bottom: inputPanel.top; } - HandwritingModeButton { - id: handwritingModeButton - anchors.top: parent.top - anchors.right: parent.right - anchors.margins: 10 - floating: true - flipable: true - width: 76 - height: width - state: handwritingInputPanel.state - onClicked: handwritingInputPanel.active = !handwritingInputPanel.active - onDoubleClicked: handwritingInputPanel.available = !handwritingInputPanel.available - } - } - - /* Keyboard input panel. - - The keyboard is anchored to the bottom of the application. - */ - InputPanel { - id: inputPanel - z: 89 - y: yPositionWhenHidden - x: Screen.orientation === Qt.LandscapeOrientation ? 0 : (parent.width-parent.height) / 2 - width: Screen.orientation === Qt.LandscapeOrientation ? parent.width : parent.height - - keyboard.shadowInputControl.height: (Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width) - keyboard.height - - property real yPositionWhenHidden: Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width + (parent.height-parent.width) / 2 - - states: State { - name: "visible" - /* The visibility of the InputPanel can be bound to the Qt.inputMethod.visible property, - but then the handwriting input panel and the keyboard input panel can be visible - at the same time. Here the visibility is bound to InputPanel.active property instead, - which allows the handwriting panel to control the visibility when necessary. - */ - when: inputPanel.active - PropertyChanges { - target: inputPanel - y: inputPanel.yPositionWhenHidden - inputPanel.height - } - } - transitions: Transition { - id: inputPanelTransition - from: "" - to: "visible" - reversible: true - enabled: !VirtualKeyboardSettings.fullScreenMode - ParallelAnimation { - NumberAnimation { - properties: "y" - duration: 250 - easing.type: Easing.InOutQuad - } - } - } - Binding { - target: InputContext - property: "animating" - value: inputPanelTransition.running - restoreMode: Binding.RestoreBinding - - } - AutoScroller {} - } - - Binding { - target: VirtualKeyboardSettings - property: "fullScreenMode" - value: appContainer.height > 0 && (appContainer.width / appContainer.height) > (16.0 / 9.0) - restoreMode: Binding.RestoreBinding - } - - } - - property bool inLandscapeOrientation: Screen.orientation === Qt.LandscapeOrientation - - Screen.orientationUpdateMask: Qt.LandscapeOrientation | Qt.PortraitOrientation - - Binding { - target: appContainer.Window.window !== null ? appContainer.Window.window.contentItem : null - property: "rotation" - value: inLandscapeOrientation ? 0 : 90 - } -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6. +import QtQml +import QtQuick.Window +import QtQuick.VirtualKeyboard +import QtQuick.VirtualKeyboard.Settings +import "content" + +Item { + width: 1280 + height: 720 + + Item { + id: appContainer + width: Screen.orientation === Qt.LandscapeOrientation ? parent.width : parent.height + height: Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width + anchors.centerIn: parent + Basic { + id: virtualKeyboard + anchors.left: parent.left + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.bottom + handwritingInputPanelActive: handwritingInputPanel.available && handwritingInputPanel.active + } + + /* Handwriting input panel for full screen handwriting input. + + This component is an optional add-on for the InputPanel component, that + is, its use does not affect the operation of the InputPanel component, + but it also can not be used as a standalone component. + + The handwriting input panel is positioned to cover the entire area of + application. The panel itself is transparent, but once it is active the + user can draw handwriting on it. + */ + HandwritingInputPanel { + z: 79 + id: handwritingInputPanel + anchors.fill: parent + inputPanel: inputPanel + Rectangle { + z: -1 + anchors.fill: parent + color: "black" + opacity: 0.10 + } + } + + /* Container area for the handwriting mode button. + + Handwriting mode button can be moved freely within the container area. + In this example, a single click changes the handwriting mode and a + double-click changes the availability of the full screen handwriting input. + */ + Item { + z: 99 + visible: handwritingInputPanel.enabled && Qt.inputMethod.visible + anchors { left: parent.left; top: parent.top; right: parent.right; bottom: inputPanel.top; } + HandwritingModeButton { + id: handwritingModeButton + anchors.top: parent.top + anchors.right: parent.right + anchors.margins: 10 + floating: true + flipable: true + width: 76 + height: width + state: handwritingInputPanel.state + onClicked: handwritingInputPanel.active = !handwritingInputPanel.active + onDoubleClicked: handwritingInputPanel.available = !handwritingInputPanel.available + } + } + + /* Keyboard input panel. + + The keyboard is anchored to the bottom of the application. + */ + InputPanel { + id: inputPanel + z: 89 + y: yPositionWhenHidden + x: Screen.orientation === Qt.LandscapeOrientation ? 0 : (parent.width-parent.height) / 2 + width: Screen.orientation === Qt.LandscapeOrientation ? parent.width : parent.height + + keyboard.shadowInputControl.height: (Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width) - keyboard.height + + property real yPositionWhenHidden: Screen.orientation === Qt.LandscapeOrientation ? parent.height : parent.width + (parent.height-parent.width) / 2 + + states: State { + name: "visible" + /* The visibility of the InputPanel can be bound to the Qt.inputMethod.visible property, + but then the handwriting input panel and the keyboard input panel can be visible + at the same time. Here the visibility is bound to InputPanel.active property instead, + which allows the handwriting panel to control the visibility when necessary. + */ + when: inputPanel.active + PropertyChanges { + target: inputPanel + y: inputPanel.yPositionWhenHidden - inputPanel.height + } + } + transitions: Transition { + id: inputPanelTransition + from: "" + to: "visible" + reversible: true + enabled: !VirtualKeyboardSettings.fullScreenMode + ParallelAnimation { + NumberAnimation { + properties: "y" + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + Binding { + target: InputContext + property: "animating" + value: inputPanelTransition.running + restoreMode: Binding.RestoreBinding + + } + AutoScroller {} + } + + Binding { + target: VirtualKeyboardSettings + property: "fullScreenMode" + value: appContainer.height > 0 && (appContainer.width / appContainer.height) > (16.0 / 9.0) + restoreMode: Binding.RestoreBinding + } + + } + + property bool inLandscapeOrientation: Screen.orientation === Qt.LandscapeOrientation + + Binding { + target: appContainer.Window.window !== null ? appContainer.Window.window.contentItem : null + property: "rotation" + value: inLandscapeOrientation ? 0 : 90 + } +} diff --git a/tests/virtualkeyboard/basic/basic.pro b/testcases/virtualkeyboard/basic.pro similarity index 66% rename from tests/virtualkeyboard/basic/basic.pro rename to testcases/virtualkeyboard/basic.pro index 5a2e9201..ed471dbb 100644 --- a/tests/virtualkeyboard/basic/basic.pro +++ b/testcases/virtualkeyboard/basic.pro @@ -1,35 +1,32 @@ -TEMPLATE = app -TARGET = basic -QT += qml quick -SOURCES += main.cpp -CONFIG += link_pkgconfig -static { - QT += svg - QTPLUGIN += qtvirtualkeyboardplugin -} - -target.path = $$[QT_INSTALL_EXAMPLES]/virtualkeyboard/basic -INSTALLS += target - -RESOURCES += \ - demo.qrc - -OTHER_FILES += \ - Basic.qml \ - basic-b2qt.qml \ - content/AutoScroller.qml \ - content/HandwritingModeButton.qml \ - content/TextArea.qml \ - content/TextField.qml \ - -disable-xcb { - message("The disable-xcb option has been deprecated. Please use disable-desktop instead.") - CONFIG += disable-desktop -} - -disable-desktop|android-embedded|!isEmpty(CROSS_COMPILE)|qnx { - DEFINES += MAIN_QML=\\\"basic-b2qt.qml\\\" -} else { - DEFINES += MAIN_QML=\\\"Basic.qml\\\" -} -DESTDIR="$$PWD/../../build" +TEMPLATE = app +TARGET = basic +QT += qml quick + +QT_FOR_CONFIG += virtualkeyboard + +SOURCES += main.cpp +CONFIG += link_pkgconfig +contains(CONFIG, static) { + QT += svg + QTPLUGIN += qtvirtualkeyboardplugin +} + +target.path = $$[QT_INSTALL_EXAMPLES]/virtualkeyboard/basic +INSTALLS += target + +RESOURCES += \ + demo.qrc + +OTHER_FILES += \ + Basic.qml \ + basic-b2qt.qml \ + content/AutoScroller.qml \ + content/HandwritingModeButton.qml \ + content/TextArea.qml \ + content/TextField.qml \ + +!qtConfig(vkb-desktop) { + DEFINES += MAIN_QML=\\\"basic-b2qt.qml\\\" +} else { + DEFINES += MAIN_QML=\\\"Basic.qml\\\" +} diff --git a/tests/virtualkeyboard/basic/content/AutoScroller.qml b/testcases/virtualkeyboard/content/AutoScroller.qml similarity index 97% rename from tests/virtualkeyboard/basic/content/AutoScroller.qml rename to testcases/virtualkeyboard/content/AutoScroller.qml index 9e837ba5..529791d1 100644 --- a/tests/virtualkeyboard/basic/content/AutoScroller.qml +++ b/testcases/virtualkeyboard/content/AutoScroller.qml @@ -1,104 +1,104 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import QtQuick.VirtualKeyboard 2.1 - -Item { - - property var innerFlickable - property var outerFlickable - property var inputItem: InputContext.priv.inputItem - - onInputItemChanged: { - innerFlickable = null - outerFlickable = null - if (inputItem !== null) { - var parent_ = inputItem.parent - while (parent_) { - if (parent_.maximumFlickVelocity) { - if (innerFlickable) { - outerFlickable = parent_ - break - } else { - innerFlickable = parent_ - } - } - parent_ = parent_.parent - } - delayedLoading.restart() - } - } - - function ensureVisible(flickable) { - if (Qt.inputMethod.visible && inputItem && flickable && flickable.visible && flickable.interactive) { - - var verticallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.VerticalFlick - || (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentHeight > flickable.height)) - var horizontallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.HorizontalFlick - || (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentWidth > flickable.width)) - - if ((!verticallyFlickable && !horizontallyFlickable) || !inputItem.hasOwnProperty("cursorRectangle")) - return - - var cursorRectangle = flickable.contentItem.mapFromItem(inputItem, inputItem.cursorRectangle.x, inputItem.cursorRectangle.y) - - var oldContentY = flickable.contentY - if (verticallyFlickable) { - var scrollMarginVertical = (flickable && flickable.scrollMarginVertical) ? flickable.scrollMarginVertical : 10 - if (flickable.contentY >= cursorRectangle.y - scrollMarginVertical) - flickable.contentY = Math.max(0, cursorRectangle.y - scrollMarginVertical) - else if (flickable.contentY + flickable.height <= cursorRectangle.y + inputItem.cursorRectangle.height + scrollMarginVertical) - flickable.contentY = Math.min(flickable.contentHeight - flickable.height, cursorRectangle.y + inputItem.cursorRectangle.height - flickable.height + scrollMarginVertical) - } - if (horizontallyFlickable) { - var scrollMarginHorizontal = (flickable && flickable.scrollMarginHorizontal) ? flickable.scrollMarginHorizontal : 10 - if (flickable.contentX >= cursorRectangle.x - scrollMarginHorizontal) - flickable.contentX = Math.max(0, cursorRectangle.x - scrollMarginHorizontal) - else if (flickable.contentX + flickable.width <= cursorRectangle.x + inputItem.cursorRectangle.width + scrollMarginHorizontal) - flickable.contentX = Math.min(flickable.contentWidth - flickable.width, cursorRectangle.x + inputItem.cursorRectangle.width - flickable.width + scrollMarginHorizontal) - } - } - } - Timer { - id: delayedLoading - interval: 10 - onTriggered: { - ensureVisible(innerFlickable) - ensureVisible(outerFlickable) - } - } - Connections { - ignoreUnknownSignals: true - target: Qt.inputMethod - function onAnimatingChanged() { if (inputItem && !Qt.inputMethod.animating) delayedLoading.restart() } - function onKeyboardRectangleChanged() { if (inputItem) delayedLoading.restart() } - function onCursorRectangleChanged() { if (inputItem && inputItem.activeFocus) delayedLoading.restart() } - } -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.VirtualKeyboard + +Item { + + property var innerFlickable + property var outerFlickable + property var inputItem: InputContext.priv.inputItem + + onInputItemChanged: { + innerFlickable = null + outerFlickable = null + if (inputItem !== null) { + var parent_ = inputItem.parent + while (parent_) { + if (parent_.maximumFlickVelocity) { + if (innerFlickable) { + outerFlickable = parent_ + break + } else { + innerFlickable = parent_ + } + } + parent_ = parent_.parent + } + delayedLoading.restart() + } + } + + function ensureVisible(flickable) { + if (Qt.inputMethod.visible && inputItem && flickable && flickable.visible && flickable.interactive) { + + var verticallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.VerticalFlick + || (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentHeight > flickable.height)) + var horizontallyFlickable = (flickable.flickableDirection === Flickable.HorizontalAndVerticalFlick || flickable.flickableDirection === Flickable.HorizontalFlick + || (flickable.flickableDirection === Flickable.AutoFlickDirection && flickable.contentWidth > flickable.width)) + + if ((!verticallyFlickable && !horizontallyFlickable) || !inputItem.hasOwnProperty("cursorRectangle")) + return + + var cursorRectangle = flickable.contentItem.mapFromItem(inputItem, inputItem.cursorRectangle.x, inputItem.cursorRectangle.y) + + var oldContentY = flickable.contentY + if (verticallyFlickable) { + var scrollMarginVertical = (flickable && flickable.scrollMarginVertical) ? flickable.scrollMarginVertical : 10 + if (flickable.contentY >= cursorRectangle.y - scrollMarginVertical) + flickable.contentY = Math.max(0, cursorRectangle.y - scrollMarginVertical) + else if (flickable.contentY + flickable.height <= cursorRectangle.y + inputItem.cursorRectangle.height + scrollMarginVertical) + flickable.contentY = Math.min(flickable.contentHeight - flickable.height, cursorRectangle.y + inputItem.cursorRectangle.height - flickable.height + scrollMarginVertical) + } + if (horizontallyFlickable) { + var scrollMarginHorizontal = (flickable && flickable.scrollMarginHorizontal) ? flickable.scrollMarginHorizontal : 10 + if (flickable.contentX >= cursorRectangle.x - scrollMarginHorizontal) + flickable.contentX = Math.max(0, cursorRectangle.x - scrollMarginHorizontal) + else if (flickable.contentX + flickable.width <= cursorRectangle.x + inputItem.cursorRectangle.width + scrollMarginHorizontal) + flickable.contentX = Math.min(flickable.contentWidth - flickable.width, cursorRectangle.x + inputItem.cursorRectangle.width - flickable.width + scrollMarginHorizontal) + } + } + } + Timer { + id: delayedLoading + interval: 10 + onTriggered: { + ensureVisible(innerFlickable) + ensureVisible(outerFlickable) + } + } + Connections { + ignoreUnknownSignals: true + target: Qt.inputMethod + function onAnimatingChanged() { if (inputItem && !Qt.inputMethod.animating) delayedLoading.restart() } + function onKeyboardRectangleChanged() { if (inputItem) delayedLoading.restart() } + function onCursorRectangleChanged() { if (inputItem && inputItem.activeFocus) delayedLoading.restart() } + } +} diff --git a/tests/virtualkeyboard/basic/content/FloatingButton_Active.svg b/testcases/virtualkeyboard/content/FloatingButton_Active.svg similarity index 98% rename from tests/virtualkeyboard/basic/content/FloatingButton_Active.svg rename to testcases/virtualkeyboard/content/FloatingButton_Active.svg index c9c234e6..ef108358 100644 --- a/tests/virtualkeyboard/basic/content/FloatingButton_Active.svg +++ b/testcases/virtualkeyboard/content/FloatingButton_Active.svg @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/virtualkeyboard/basic/content/FloatingButton_Available.svg b/testcases/virtualkeyboard/content/FloatingButton_Available.svg similarity index 98% rename from tests/virtualkeyboard/basic/content/FloatingButton_Available.svg rename to testcases/virtualkeyboard/content/FloatingButton_Available.svg index d5edc3c1..1178c8c6 100644 --- a/tests/virtualkeyboard/basic/content/FloatingButton_Available.svg +++ b/testcases/virtualkeyboard/content/FloatingButton_Available.svg @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/virtualkeyboard/basic/content/FloatingButton_Unavailable.svg b/testcases/virtualkeyboard/content/FloatingButton_Unavailable.svg similarity index 98% rename from tests/virtualkeyboard/basic/content/FloatingButton_Unavailable.svg rename to testcases/virtualkeyboard/content/FloatingButton_Unavailable.svg index 4ce6b3aa..d8149b53 100644 --- a/tests/virtualkeyboard/basic/content/FloatingButton_Unavailable.svg +++ b/testcases/virtualkeyboard/content/FloatingButton_Unavailable.svg @@ -1,39 +1,39 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/virtualkeyboard/basic/content/HandwritingModeButton.qml b/testcases/virtualkeyboard/content/HandwritingModeButton.qml similarity index 96% rename from tests/virtualkeyboard/basic/content/HandwritingModeButton.qml rename to testcases/virtualkeyboard/content/HandwritingModeButton.qml index d2a543b3..21ac3444 100644 --- a/tests/virtualkeyboard/basic/content/HandwritingModeButton.qml +++ b/testcases/virtualkeyboard/content/HandwritingModeButton.qml @@ -1,165 +1,165 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - id: handwritingModeButton - state: "unavailable" - property bool floating - property bool flipable - readonly property real __minWidthHeight: Math.min(width, height) - - signal clicked() - signal doubleClicked() - - Flipable { - id: flipableImage - anchors.fill: parent - - property bool flipped - - front: Image { - sourceSize.width: handwritingModeButton.__minWidthHeight - sourceSize.height: handwritingModeButton.__minWidthHeight - smooth: false - source: "qrc:/content/FloatingButton_Unavailable.svg" - } - - back: Image { - id: buttonImage - sourceSize.width: handwritingModeButton.__minWidthHeight - sourceSize.height: handwritingModeButton.__minWidthHeight - smooth: false - source: "qrc:/content/FloatingButton_Available.svg" - } - - states: State { - PropertyChanges { target: rotation; angle: 180 } - when: flipableImage.flipped - } - - transform: Rotation { - id: rotation - origin.x: flipableImage.width / 2 - origin.y: flipableImage.height / 2 - axis { x: 0; y: 1; z: 0 } - angle: 0 - } - - transitions: Transition { - enabled: handwritingModeButton.flipable - NumberAnimation { target: rotation; property: "angle"; duration: 400 } - } - } - - states: [ - State { - name: "available" - PropertyChanges { target: flipableImage; flipped: true } - }, - State { - name: "active" - PropertyChanges { target: flipableImage; flipped: true } - PropertyChanges { target: buttonImage; source: "qrc:/content/FloatingButton_Active.svg" } - } - ] - - function snapHorizontal() { - if (!floating) - return - if (mouseArea.drag.maximumX > mouseArea.drag.minimumX) { - if (x + 20 >= mouseArea.drag.maximumX) { - anchors.left = undefined - anchors.right = parent.right - } else if (x - 20 <= mouseArea.drag.minimumX) { - anchors.right = undefined - anchors.left = parent.left - } - } - } - - function snapVertical() { - if (!floating) - return - if (mouseArea.drag.maximumY > mouseArea.drag.minimumY) { - if (y + 20 >= mouseArea.drag.maximumY) { - anchors.top = undefined - anchors.bottom = parent.bottom - } else if (y - 20 <= mouseArea.drag.minimumY) { - anchors.bottom = undefined - anchors.top = parent.top - } - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - drag { - target: handwritingModeButton.floating ? handwritingModeButton : undefined - axis: Drag.XAxis | Drag.YAxis - minimumX: 0 - maximumX: handwritingModeButton.parent.width - handwritingModeButton.width - onMaximumXChanged: !mouseArea.drag.active && handwritingModeButton.snapHorizontal() - minimumY: 0 - maximumY: handwritingModeButton.parent.height - handwritingModeButton.height - onMaximumYChanged: !mouseArea.drag.active && handwritingModeButton.snapVertical() - } - onPressed: { - if (!handwritingModeButton.floating) - return - handwritingModeButton.anchors.left = undefined - handwritingModeButton.anchors.top = undefined - handwritingModeButton.anchors.right = undefined - handwritingModeButton.anchors.bottom = undefined - } - onReleased: { - handwritingModeButton.snapHorizontal() - handwritingModeButton.snapVertical() - } - onClicked: { - handwritingModeButton.snapHorizontal() - handwritingModeButton.snapVertical() - clickTimer.restart() - } - onDoubleClicked: { - clickTimer.stop() - handwritingModeButton.snapHorizontal() - handwritingModeButton.snapVertical() - handwritingModeButton.doubleClicked() - } - Timer { - id: clickTimer - interval: Qt.styleHints ? Qt.styleHints.mouseDoubleClickInterval / 3 : 0 - repeat: false - onTriggered: handwritingModeButton.clicked() - } - } -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick + +Item { + id: handwritingModeButton + state: "unavailable" + property bool floating + property bool flipable + readonly property real __minWidthHeight: Math.min(width, height) + + signal clicked() + signal doubleClicked() + + Flipable { + id: flipableImage + anchors.fill: parent + + property bool flipped + + front: Image { + sourceSize.width: handwritingModeButton.__minWidthHeight + sourceSize.height: handwritingModeButton.__minWidthHeight + smooth: false + source: "qrc:/content/FloatingButton_Unavailable.svg" + } + + back: Image { + id: buttonImage + sourceSize.width: handwritingModeButton.__minWidthHeight + sourceSize.height: handwritingModeButton.__minWidthHeight + smooth: false + source: "qrc:/content/FloatingButton_Available.svg" + } + + states: State { + PropertyChanges { target: rotation; angle: 180 } + when: flipableImage.flipped + } + + transform: Rotation { + id: rotation + origin.x: flipableImage.width / 2 + origin.y: flipableImage.height / 2 + axis { x: 0; y: 1; z: 0 } + angle: 0 + } + + transitions: Transition { + enabled: handwritingModeButton.flipable + NumberAnimation { target: rotation; property: "angle"; duration: 400 } + } + } + + states: [ + State { + name: "available" + PropertyChanges { target: flipableImage; flipped: true } + }, + State { + name: "active" + PropertyChanges { target: flipableImage; flipped: true } + PropertyChanges { target: buttonImage; source: "qrc:/content/FloatingButton_Active.svg" } + } + ] + + function snapHorizontal() { + if (!floating) + return + if (mouseArea.drag.maximumX > mouseArea.drag.minimumX) { + if (x + 20 >= mouseArea.drag.maximumX) { + anchors.left = undefined + anchors.right = parent.right + } else if (x - 20 <= mouseArea.drag.minimumX) { + anchors.right = undefined + anchors.left = parent.left + } + } + } + + function snapVertical() { + if (!floating) + return + if (mouseArea.drag.maximumY > mouseArea.drag.minimumY) { + if (y + 20 >= mouseArea.drag.maximumY) { + anchors.top = undefined + anchors.bottom = parent.bottom + } else if (y - 20 <= mouseArea.drag.minimumY) { + anchors.bottom = undefined + anchors.top = parent.top + } + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + drag { + target: handwritingModeButton.floating ? handwritingModeButton : undefined + axis: Drag.XAxis | Drag.YAxis + minimumX: 0 + maximumX: handwritingModeButton.parent.width - handwritingModeButton.width + onMaximumXChanged: !mouseArea.drag.active && handwritingModeButton.snapHorizontal() + minimumY: 0 + maximumY: handwritingModeButton.parent.height - handwritingModeButton.height + onMaximumYChanged: !mouseArea.drag.active && handwritingModeButton.snapVertical() + } + onPressed: { + if (!handwritingModeButton.floating) + return + handwritingModeButton.anchors.left = undefined + handwritingModeButton.anchors.top = undefined + handwritingModeButton.anchors.right = undefined + handwritingModeButton.anchors.bottom = undefined + } + onReleased: { + handwritingModeButton.snapHorizontal() + handwritingModeButton.snapVertical() + } + onClicked: { + handwritingModeButton.snapHorizontal() + handwritingModeButton.snapVertical() + clickTimer.restart() + } + onDoubleClicked: { + clickTimer.stop() + handwritingModeButton.snapHorizontal() + handwritingModeButton.snapVertical() + handwritingModeButton.doubleClicked() + } + Timer { + id: clickTimer + interval: Qt.styleHints ? Qt.styleHints.mouseDoubleClickInterval / 3 : 0 + repeat: false + onTriggered: handwritingModeButton.clicked() + } + } +} diff --git a/tests/virtualkeyboard/basic/content/TextArea.qml b/testcases/virtualkeyboard/content/TextArea.qml similarity index 93% rename from tests/virtualkeyboard/basic/content/TextArea.qml rename to testcases/virtualkeyboard/content/TextArea.qml index 9fed65a6..bc83310f 100644 --- a/tests/virtualkeyboard/basic/content/TextArea.qml +++ b/testcases/virtualkeyboard/content/TextArea.qml @@ -1,53 +1,53 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.10 -import QtQuick.Controls 2.3 as Controls -import QtQuick.VirtualKeyboard 2.3 - -Controls.TextArea { - id: control - color: "#2B2C2E" - selectionColor: Qt.rgba(0.0, 0.0, 0.0, 0.15) - selectedTextColor: color - selectByMouse: true - font.pixelSize: Qt.application.font.pixelSize * 2 - - property int enterKeyAction: EnterKeyAction.None - readonly property bool enterKeyEnabled: enterKeyAction === EnterKeyAction.None || text.length > 0 || inputMethodComposing - - EnterKeyAction.actionId: control.enterKeyAction - EnterKeyAction.enabled: control.enterKeyEnabled - - background: Rectangle { - color: "#FFFFFF" - border.width: 1 - border.color: control.activeFocus ? "#5CAA15" : "#BDBEBF" - } -} +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as Controls +import QtQuick.VirtualKeyboard + +Controls.TextArea { + id: control + color: "#2B2C2E" + selectionColor: Qt.rgba(0.0, 0.0, 0.0, 0.15) + selectedTextColor: color + selectByMouse: true + font.pixelSize: Qt.application.font.pixelSize * 2 + + property int enterKeyAction: EnterKeyAction.None + readonly property bool enterKeyEnabled: enterKeyAction === EnterKeyAction.None || text.length > 0 || inputMethodComposing + + EnterKeyAction.actionId: control.enterKeyAction + EnterKeyAction.enabled: control.enterKeyEnabled + + background: Rectangle { + color: "#FFFFFF" + border.width: 1 + border.color: control.activeFocus ? "#5CAA15" : "#BDBEBF" + } +} diff --git a/tests/virtualkeyboard/basic/content/TextField.qml b/testcases/virtualkeyboard/content/TextField.qml similarity index 93% rename from tests/virtualkeyboard/basic/content/TextField.qml rename to testcases/virtualkeyboard/content/TextField.qml index 960afcaf..16ed0cdd 100644 --- a/tests/virtualkeyboard/basic/content/TextField.qml +++ b/testcases/virtualkeyboard/content/TextField.qml @@ -1,53 +1,53 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.10 -import QtQuick.Controls 2.3 as Controls -import QtQuick.VirtualKeyboard 2.3 - -Controls.TextField { - id: control - color: "#2B2C2E" - selectionColor: Qt.rgba(0.0, 0.0, 0.0, 0.15) - selectedTextColor: color - selectByMouse: true - font.pixelSize: Qt.application.font.pixelSize * 2 - - property int enterKeyAction: EnterKeyAction.None - readonly property bool enterKeyEnabled: enterKeyAction === EnterKeyAction.None || acceptableInput || inputMethodComposing - - EnterKeyAction.actionId: control.enterKeyAction - EnterKeyAction.enabled: control.enterKeyEnabled - - background: Rectangle { - color: "#FFFFFF" - border.width: 1 - border.color: control.activeFocus ? "#5CAA15" : "#BDBEBF" - } -} +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls as Controls +import QtQuick.VirtualKeyboard + +Controls.TextField { + id: control + color: "#2B2C2E" + selectionColor: Qt.rgba(0.0, 0.0, 0.0, 0.15) + selectedTextColor: color + selectByMouse: true + font.pixelSize: Qt.application.font.pixelSize * 2 + + property int enterKeyAction: EnterKeyAction.None + readonly property bool enterKeyEnabled: enterKeyAction === EnterKeyAction.None || acceptableInput || inputMethodComposing + + EnterKeyAction.actionId: control.enterKeyAction + EnterKeyAction.enabled: control.enterKeyEnabled + + background: Rectangle { + color: "#FFFFFF" + border.width: 1 + border.color: control.activeFocus ? "#5CAA15" : "#BDBEBF" + } +} diff --git a/tests/virtualkeyboard/basic/demo.qrc b/testcases/virtualkeyboard/demo.qrc similarity index 97% rename from tests/virtualkeyboard/basic/demo.qrc rename to testcases/virtualkeyboard/demo.qrc index 8b71cb3e..52706522 100644 --- a/tests/virtualkeyboard/basic/demo.qrc +++ b/testcases/virtualkeyboard/demo.qrc @@ -1,13 +1,13 @@ - - - content/AutoScroller.qml - content/TextArea.qml - content/TextField.qml - content/HandwritingModeButton.qml - content/FloatingButton_Active.svg - content/FloatingButton_Available.svg - content/FloatingButton_Unavailable.svg - Basic.qml - basic-b2qt.qml - - + + + content/AutoScroller.qml + content/TextArea.qml + content/TextField.qml + content/HandwritingModeButton.qml + content/FloatingButton_Active.svg + content/FloatingButton_Available.svg + content/FloatingButton_Unavailable.svg + Basic.qml + basic-b2qt.qml + + diff --git a/tests/virtualkeyboard/basic/main.cpp b/testcases/virtualkeyboard/main.cpp similarity index 97% rename from tests/virtualkeyboard/basic/main.cpp rename to testcases/virtualkeyboard/main.cpp index 34802fd1..883808b8 100644 --- a/tests/virtualkeyboard/basic/main.cpp +++ b/testcases/virtualkeyboard/main.cpp @@ -1,47 +1,47 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -int main(int argc, char *argv[]) -{ - qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); - - QGuiApplication app(argc, argv); - QQuickView view(QString("qrc:/%2").arg(MAIN_QML)); - if (view.status() == QQuickView::Error) - return -1; - view.setResizeMode(QQuickView::SizeRootObjectToView); - - view.show(); - - return app.exec(); -} +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); + + QGuiApplication app(argc, argv); + QQuickView view(QString("qrc:/%2").arg(MAIN_QML)); + if (view.status() == QQuickView::Error) + return -1; + view.setResizeMode(QQuickView::SizeRootObjectToView); + + view.show(); + + return app.exec(); +} diff --git a/testcases/webui/CMakeLists.txt b/testcases/webui/CMakeLists.txt new file mode 100644 index 00000000..fc27a140 --- /dev/null +++ b/testcases/webui/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.16) +project(webui LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + + +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui WebEngineWidgets) + +# needed for test RPATH functions +get_filename_component(QT_QT_ROOT "${Qt${QT_VERSION_MAJOR}Core_DIR}/../../.." ABSOLUTE) +set(CMAKE_BUILD_RPATH ${QT_QT_ROOT}/bin) + +# Resources: +file(GLOB_RECURSE SOURCE_QRC + "*.qrc" +) + +add_executable(webui + main.cpp + webuihandler.cpp webuihandler.h + ${SOURCE_QRC} + +) + +set_target_properties(webui PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(webui PUBLIC + Qt::Core + Qt::Gui + Qt::WebEngineWidgets +) diff --git a/tests/webui/about.html b/testcases/webui/about.html similarity index 96% rename from tests/webui/about.html rename to testcases/webui/about.html index 475b5668..7b5a5896 100644 --- a/tests/webui/about.html +++ b/testcases/webui/about.html @@ -1,129 +1,129 @@ - - - - Qt WebEngine WebUI Example - - - -
- -

WebEngine Widgets
WebUI Example

-
-
-

- Aside from the built-in schemes, such as http and - qrc, Qt WebEngine may be extended with custom - schemes by creating custom scheme handlers. -

- -

- This is a simple HTML page loaded from a custom scheme and - displayed by a QWebEngineView. Even the Quit button - below is a standard HTML <button> element. -

- -

- Read the documentation to find out -

-
    -
  • -

    - How to create a custom scheme handler which serves HTML - and handles HTML form submissions. -

    -
  • -
  • -

    - How to prevent ordinary web content from accessing the - custom scheme. -

    -
  • -
  • -

    - How to prevent any other scheme from submitting HTML - form data. -

    -
  • -
-
-
-
- -
-
- - + + + + Qt WebEngine WebUI Example + + + +
+ +

WebEngine Widgets
WebUI Example

+
+
+

+ Aside from the built-in schemes, such as http and + qrc, Qt WebEngine may be extended with custom + schemes by creating custom scheme handlers. +

+ +

+ This is a simple HTML page loaded from a custom scheme and + displayed by a QWebEngineView. Even the Quit button + below is a standard HTML <button> element. +

+ +

+ Read the documentation to find out +

+
    +
  • +

    + How to create a custom scheme handler which serves HTML + and handles HTML form submissions. +

    +
  • +
  • +

    + How to prevent ordinary web content from accessing the + custom scheme. +

    +
  • +
  • +

    + How to prevent any other scheme from submitting HTML + form data. +

    +
  • +
+
+
+
+ +
+
+ + diff --git a/tests/webui/doc/images/webui-example.png b/testcases/webui/doc/images/webui-example.png similarity index 100% rename from tests/webui/doc/images/webui-example.png rename to testcases/webui/doc/images/webui-example.png diff --git a/testcases/webui/doc/src/webui.qdoc b/testcases/webui/doc/src/webui.qdoc new file mode 100644 index 00000000..949b358a --- /dev/null +++ b/testcases/webui/doc/src/webui.qdoc @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and 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. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example webenginewidgets/webui + \title WebEngine Widgets WebUI Example + \ingroup webengine-widgetexamples + \brief Displays HTML over a custom scheme. + + \image webui-example.png + + \e {WebUI} demonstrates how to implement a custom scheme in a secure way. + + Aside from the built-in URL schemes, such as \c {http} and \c {qrc}, + \QWE may be extended with \e {custom schemes} by creating \e {custom + scheme handlers}. This example shows: + + \list + \li How to create a custom scheme handler which serves HTML and handles + HTML form submissions. + \li How to prevent ordinary web content from accessing the custom scheme. + \li How to prevent any other scheme from submitting HTML form data. + \endlist + + \include examples-run.qdocinc + + \section1 Overview + + The example program consists of a single \l {QWebEngineView} showing a + simple HTML page loaded from the URL \c {webui:about}, over our custom + scheme. Pressing the button at the bottom of the page will trigger an HTML + form submission via POST to the same URL, at which point our custom scheme + handler will cause the application to exit. + + The program is divided into two parts, the \c {main} function for setting + everything up, and the \c {WebUiHandler} class for implementing our custom + scheme handler. The \c {main} function is quite short: + + \quotefromfile webenginewidgets/webui/main.cpp + \skipto int main + \printuntil /^\}/ + + Aside from the relatively standard setup of widgets, two points are + noteworthy. First, we call the static method \c + {WebUiHandler::registerUrlScheme()} to register our custom scheme with the + web engine. Second, we create and install our custom scheme handler \c + {WebUiHandler} using \l + {QWebEngineProfile::installUrlSchemeHandler()}{installUrlSchemeHandler()}. + The following sections describe these aspects in more detail. + + \section1 Registering the Scheme + + As custom schemes are integrated directly into the web engine, they do not + necessarily need to follow the standard security rules which apply to + ordinary web content. Depending on the chosen configuration, content served + over a custom scheme may be given access to local resources, be set to + ignore Content-Security-Policy rules, or conversely, be denied access to any + other content entirely. + + In order to take advantage of these possibilities, the custom scheme must + first be registered. This means creating and configuring a \l + {QWebEngineUrlScheme} object and then handing it over to \l + {QWebEngineUrlScheme::registerScheme()}. The example program does exactly this in + the static method \c {WebUiHandler::registerUrlScheme()}: + + \quotefromfile webenginewidgets/webui/webuihandler.cpp + \skipto void WebUiHandler::registerUrlScheme + \printuntil /^\}/ + + A custom scheme needs a name, which can be set by passing it to + the constructor of \c {QWebEngineUrlScheme} or by calling \l + {QWebEngineUrlScheme::setName}. In the above, the name \c {webui} is set + through the constructor. Additionally, we activate the flags \l + {QWebEngineUrlScheme::SecureScheme}{SecureScheme}, \l + {QWebEngineUrlScheme::LocalScheme}{LocalScheme} and \l + {QWebEngineUrlScheme::LocalAccessAllowed}{LocalAccessAllowed}. Since our + custom scheme handler will not deliver resources received from insecure + network connections, we can safely mark it as a \c {SecureScheme}. The \c {LocalScheme} + flag prevents content from non-local schemes (such as \c {http}) from + interacting with our custom scheme. Without this flag it would be possible, + for example, to embed the \c {webui:about} page in an \c