Automatic crash reports.
This commit is contained in:
parent
fb15284483
commit
33a5939c18
42
.cirrus.yml
42
.cirrus.yml
|
@ -125,10 +125,12 @@ linux_qt5_qbs_task_template: &LINUX_QT5_QBS_TASK_TEMPLATE
|
|||
appimage_task_template: &APPIMAGE_TASK_TEMPLATE
|
||||
pip_cache:
|
||||
folder: ${PIP_CACHE_DIR}
|
||||
conan_cache:
|
||||
folder: "~/.conan/data"
|
||||
install_script:
|
||||
- bash -c "$PACKAGE_MANAGER_INSTALL qt515base qt515svg qt515tools qt515xmlpatterns qt515translations qt515doc qt515imageformats poppler-utils git xvfb ccache build-essential libgl1-mesa-dev libicu-dev python3-pip"
|
||||
- python3 --version
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0'
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0
|
||||
build_script:
|
||||
- uname -a
|
||||
- mkdir -pm 0700 $XDG_RUNTIME_DIR
|
||||
|
@ -143,12 +145,25 @@ appimage_task_template: &APPIMAGE_TASK_TEMPLATE
|
|||
- ${COMPILER} --version
|
||||
- qmake --version
|
||||
- qbs --version
|
||||
- conan profile new valentina
|
||||
- conan profile update settings.build_type=Release valentina
|
||||
- conan profile update settings.os=Linux valentina
|
||||
- conan profile update settings.compiler=gcc valentina
|
||||
- conan profile update settings.compiler.cppstd=17 valentina
|
||||
- conan profile update settings.compiler.libcxx=libstdc++11 valentina
|
||||
- conan profile update settings.compiler.version=9 valentina
|
||||
- qbs setup-toolchains /usr/bin/${COMPILER} ${COMPILER}
|
||||
- qbs setup-qt /opt/qt515/bin/qmake qt5
|
||||
- qbs config defaultProfile qt5
|
||||
- qbs config profiles.qt5.baseProfile ${COMPILER}
|
||||
- qbs build -f valentina.qbs -d $CIRRUS_WORKING_DIR/build --jobs $(nproc) profile:qt5 config:release modules.buildconfig.enableCcache:${ENABLE_CCACHE} qbs.installRoot:$CIRRUS_WORKING_DIR/build/AppDir modules.buildconfig.enableAppImage:true modules.buildconfig.enableRPath:false
|
||||
- conan install . -s os=Linux --build=missing -o with_crash_reporting=True -pr valentina -g virtualrunenv
|
||||
- qbs build -f valentina.qbs -d $CIRRUS_WORKING_DIR/build --jobs $(nproc) profile:qt5 config:release modules.buildconfig.enableCcache:${ENABLE_CCACHE} qbs.installRoot:$CIRRUS_WORKING_DIR/build/AppDir modules.buildconfig.enableAppImage:true modules.buildconfig.enableRPath:false project.conanWithCrashReporting:true project.enableConan:true
|
||||
- qbs -p autotest-runner -d build profile:qt5 config:release
|
||||
- export CRASH_QT_VERSION=$(/opt/qt515/bin/qmake -query QT_VERSION | awk -F. '{print $1 "_" $2}')
|
||||
- export CRASH_SHORT_SHA=$(git log --pretty=format:%h -n 1)
|
||||
- source activate_run.sh
|
||||
- python3 scripts/symupload.py $CIRRUS_WORKING_DIR/build/AppDir $VALENTINA_VERSION $CRASH_SHORT_SHA $CRASH_QT_VERSION --clean
|
||||
- source deactivate_run.sh
|
||||
- appimage-builder --recipe dist/AppImage/AppImageBuilder.yml --appdir $CIRRUS_WORKING_DIR/build/AppDir --skip-test
|
||||
- ccache -s
|
||||
deploy_script:
|
||||
|
@ -228,6 +243,7 @@ linux_task:
|
|||
QT_VERSION: Qt6
|
||||
ARCH: x86_64
|
||||
TARGET_PLATFORM: "Linux"
|
||||
VALENTINA_VERSION: 0_7_52
|
||||
container:
|
||||
cpu: 4
|
||||
memory: 8G # Set to 8GB to avoid OOM. https://cirrus-ci.org/guide/linux/#linux-container
|
||||
|
@ -350,16 +366,11 @@ macos_task_template: &MACOS_TASK_TEMPLATE
|
|||
- chmod -R 755 /opt/homebrew/opt/poppler/*
|
||||
- chmod -R 755 /opt/homebrew/opt/xerces-c/*
|
||||
- python3 --version
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0'
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0
|
||||
- ccache --set-config sloppiness=pch_defines,time_macros max_size="$CCACHE_SIZE"
|
||||
- qmake --version
|
||||
- which qmake
|
||||
- qbs --version
|
||||
# Patch Qbs. Remove after Qbs 2.2.1+.
|
||||
- curl https://gist.githubusercontent.com/dismine/43f3c51e05f3317c5d4fe16cd3c4b6d8/raw/2d297bcb53c2c022f740509923adf1eb1796afe2/qbs-pkg-config-probe.patch --output $HOME/qbs-pkg-config-probe.patch --silent
|
||||
- patch -N -d $(brew --prefix qbs)/ -p1 < $HOME/qbs-pkg-config-probe.patch || true
|
||||
- rm -f $(brew --prefix qbs)/share/qbs/imports/qbs/Probes/qbs-pkg-config-probe.js.rej
|
||||
- rm $HOME/qbs-pkg-config-probe.patch
|
||||
build_script:
|
||||
- echo $PATH
|
||||
- export PATH="${HOME}/.local/bin:`python3 -m site --user-base`/bin:$PATH"
|
||||
|
@ -373,12 +384,26 @@ macos_task_template: &MACOS_TASK_TEMPLATE
|
|||
- unzip ${HOME}/macdeployqt-main.zip -d ${HOME}
|
||||
- cmake ${HOME}/macdeployqt-main -GNinja -S ${HOME}/macdeployqt-main -B ${HOME}/macdeployqt-build-dir -DCMAKE_INSTALL_PREFIX=${HOME}/macdeployqt-install-dir -DCMAKE_BUILD_TYPE=Release
|
||||
- cmake --build ${HOME}/macdeployqt-build-dir --target install
|
||||
- conan profile new valentina
|
||||
- conan profile update settings.build_type=Release valentina
|
||||
- conan profile update settings.os=Macos valentina
|
||||
- conan profile update settings.os.Macos.sdk_version=${MACOS_DEPLOYMENT_TARGET} valentina
|
||||
- conan profile update settings.compiler=clang valentina
|
||||
- conan profile update settings.compiler.cppstd=17 valentina
|
||||
- conan profile update settings.compiler.libcxx=libstdc++11 valentina
|
||||
- conan profile update settings.compiler.version=14 valentina
|
||||
- qbs setup-toolchains --detect
|
||||
- qbs config --list profiles
|
||||
- qbs setup-qt /opt/homebrew/opt/qt6/bin/qmake qt6
|
||||
- qbs config defaultProfile qt6
|
||||
- qbs config profiles.qt6.baseProfile clang
|
||||
- conan install . -s os=Macos --build=missing -o with_crash_reporting=True -pr valentina -g virtualrunenv
|
||||
- qbs build -f valentina.qbs -d $CIRRUS_WORKING_DIR/build --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:$CIRRUS_WORKING_DIR/build/install-root profile:qt6 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:${ENABLE_CCACHE} moduleProviders.qbspkgconfig.extraPaths:$(brew --prefix xerces-c)/lib/pkgconfig,$(brew --prefix qt6)/lib/pkgconfig,$(brew --prefix openssl@1.1)/lib/pkgconfig "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:$(brew --prefix qt6)/lib,$(brew --prefix poppler)/lib modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir
|
||||
- export CRASH_QT_VERSION=$(/opt/homebrew/opt/qt6/bin/qmake -query QT_VERSION | awk -F. '{print $1 "_" $2}')
|
||||
- export CRASH_SHORT_SHA=$(git log --pretty=format:%h -n 1)
|
||||
- source activate_run.sh
|
||||
- python3 scripts/symupload.py $CIRRUS_WORKING_DIR/build/install-root $VALENTINA_VERSION $CRASH_SHORT_SHA $CRASH_QT_VERSION --clean
|
||||
- source deactivate_run.sh
|
||||
- qbs build -f valentina.qbs -d $CIRRUS_WORKING_DIR/build -p 'Valentina DMG' --force-probe-execution --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:$CIRRUS_WORKING_DIR/build/install-root profile:qt6 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:${ENABLE_CCACHE} moduleProviders.qbspkgconfig.extraPaths:$(brew --prefix xerces-c)/lib/pkgconfig,$(brew --prefix qt6)/lib/pkgconfig,$(brew --prefix openssl@1.1)/lib/pkgconfig "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:$(brew --prefix qt6)/lib,$(brew --prefix poppler)/lib modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir
|
||||
# Store the notarization credentials so that we can prevent a UI password dialog
|
||||
# from blocking the CI
|
||||
|
@ -412,6 +437,7 @@ macos_task:
|
|||
TARGET_PLATFORM: "macOS_12.4+"
|
||||
MACOS_DEPLOYMENT_TARGET: 12.0
|
||||
ENABLE_CCACHE: true
|
||||
VALENTINA_VERSION: 0_7_52
|
||||
matrix:
|
||||
- name: 'macOS Monterey 12 [signle bundle, no tests]'
|
||||
env:
|
||||
|
|
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -73,7 +73,6 @@ cov-int/
|
|||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
*.lo
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
|
@ -117,7 +116,6 @@ Makefile*
|
|||
*.xcodeproj
|
||||
|
||||
# OSX specific
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
|
@ -173,3 +171,14 @@ __pycache__
|
|||
# Sonar Cloud
|
||||
.scannerwork
|
||||
bw-output
|
||||
|
||||
# Conan
|
||||
/activate_run.ps1
|
||||
/activate_run.sh
|
||||
/conanbuildinfo.txt
|
||||
/conaninfo.txt
|
||||
/deactivate_run.ps1
|
||||
/deactivate_run.sh
|
||||
/environment_run.ps1.env
|
||||
/environment_run.sh.env
|
||||
/graph_info.json
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
- Fold line.
|
||||
- Minimal Qt version increased to Qt 5.15. Minimal C++ standard to C++17.
|
||||
- Updated Windows installer.
|
||||
- Automatic crash reports.
|
||||
|
||||
# Valentina 0.7.52 September 12, 2022
|
||||
- Fix crash when default locale is ru.
|
||||
|
|
63
appveyor.yml
63
appveyor.yml
|
@ -40,6 +40,7 @@ environment:
|
|||
ACCESS_TOKEN:
|
||||
secure: RUhnEHqaR8KhalOMWwZZOoO342Ja50QV4KpEWdm9g3pG+jG7i6aJqUmeKF1l5VN6dzksk1u+yN6pOLnU8oGcaVQ6v+1dpKK1oZvF0tyHhNE=
|
||||
APPVEYOR_SAVE_CACHE_ON_ERROR: "true"
|
||||
VALENTINA_VERSION: 0_7_52
|
||||
|
||||
matrix:
|
||||
- job_name: Windows_Qt_6_5_(MSVC_x64)
|
||||
|
@ -398,15 +399,26 @@ for:
|
|||
|
||||
build_script:
|
||||
- conan profile list
|
||||
- conan install . -s os=Windows --build=missing -pr valentina
|
||||
- qbs build -f valentina.qbs -d %APPVEYOR_BUILD_FOLDER%\build --jobs %NUMBER_OF_PROCESSORS% config:release qbs.installRoot:%APPVEYOR_BUILD_FOLDER%\build\install-root\valentina profile:qt6 project.enableConan:true modules.buildconfig.enableCcache:false project.conanProfiles:valentina modules.buildconfig.enablePCH:%ENABLE_PCH% modules.windeployqt.windeployqtProgramBinPath:%WINDEPLOYQT_BIN_PATH% modules.windeployqt.compilerRuntime:%WINDEPLOYQT_COMPILER_RUNTIME% modules.windeployqt.noCompilerRuntime:%WINDEPLOYQT_NO_COMPILER_RUNTIME%
|
||||
- conan install . -s os=Windows --build=missing -o with_crash_reporting=True -o with_xerces=True -pr valentina -g virtualrunenv
|
||||
- qbs build -f valentina.qbs -d %APPVEYOR_BUILD_FOLDER%\build --jobs %NUMBER_OF_PROCESSORS% config:release qbs.installRoot:%APPVEYOR_BUILD_FOLDER%\build\install-root\valentina profile:qt6 project.enableConan:true project.conanWithCrashReporting:true project.conanWithXerces:true modules.buildconfig.enableCcache:false project.conanProfiles:valentina modules.buildconfig.enablePCH:%ENABLE_PCH% modules.windeployqt.windeployqtProgramBinPath:%WINDEPLOYQT_BIN_PATH% modules.windeployqt.compilerRuntime:%WINDEPLOYQT_COMPILER_RUNTIME% modules.windeployqt.noCompilerRuntime:%WINDEPLOYQT_NO_COMPILER_RUNTIME%
|
||||
|
||||
test_script:
|
||||
- path
|
||||
- if "%RUN_TESTS%" == "true" (qbs -p autotest-runner -d %APPVEYOR_BUILD_FOLDER%\build profile:qt6 config:release)
|
||||
|
||||
deploy_script:
|
||||
- if "%DEPLOY%" == "true" (qbs build -f valentina.qbs -d %APPVEYOR_BUILD_FOLDER%\build -p ValentinaSetup --jobs %NUMBER_OF_PROCESSORS% config:release qbs.installRoot:%APPVEYOR_BUILD_FOLDER%\build\install-root\valentina profile:qt6 project.enableConan:true modules.buildconfig.enableCcache:false project.conanProfiles:valentina modules.buildconfig.enablePCH:%ENABLE_PCH% modules.windeployqt.windeployqtProgramBinPath:%WINDEPLOYQT_BIN_PATH% modules.windeployqt.compilerRuntime:%WINDEPLOYQT_COMPILER_RUNTIME% modules.windeployqt.noCompilerRuntime:%WINDEPLOYQT_NO_COMPILER_RUNTIME%)
|
||||
- ps: |
|
||||
if ($env:DEPLOY -eq "true") {
|
||||
$qmakeOutput = %QTDIR%\bin\%QMAKE% -query QT_VERSION
|
||||
$majorMinorVersion = $qmakeOutput -replace '\D+(\d+)\.(\d+).*', '$1_$2'
|
||||
$env:CRASH_QT_VERSION = $majorMinorVersion
|
||||
|
||||
$env:CRASH_SHORT_SHA = git log --pretty=format:%h -n 1
|
||||
}
|
||||
- ps: activate_run.ps1
|
||||
- if "%DEPLOY%" == "true" (python3 scripts/symupload.py %APPVEYOR_BUILD_FOLDER%\build\install-root\valentina $VALENTINA_VERSION $CRASH_SHORT_SHA $CRASH_QT_VERSION --clean)
|
||||
- ps: deactivate_run.ps1
|
||||
- if "%DEPLOY%" == "true" (qbs build -f valentina.qbs -d %APPVEYOR_BUILD_FOLDER%\build -p ValentinaSetup --jobs %NUMBER_OF_PROCESSORS% config:release qbs.installRoot:%APPVEYOR_BUILD_FOLDER%\build\install-root\valentina profile:qt6 project.enableConan:true project.conanWithCrashReporting:true project.conanWithXerces:true modules.buildconfig.enableCcache:false project.conanProfiles:valentina modules.buildconfig.enablePCH:%ENABLE_PCH% modules.windeployqt.windeployqtProgramBinPath:%WINDEPLOYQT_BIN_PATH% modules.windeployqt.compilerRuntime:%WINDEPLOYQT_COMPILER_RUNTIME% modules.windeployqt.noCompilerRuntime:%WINDEPLOYQT_NO_COMPILER_RUNTIME%)
|
||||
- ps: scripts/appveyor-deploy.ps1
|
||||
|
||||
on_finish:
|
||||
|
@ -537,7 +549,7 @@ for:
|
|||
secure: B8yHPBym+BTDPK5ZCg7WlSnUCHLbcim8WqLTC6/PSNs=
|
||||
|
||||
cache:
|
||||
#- /Users/appveyor/.conan/data -> conanfile.py
|
||||
- /Users/appveyor/.conan/data -> conanfile.py
|
||||
- $HOME/brew_cache_dir
|
||||
|
||||
init:
|
||||
|
@ -643,7 +655,7 @@ for:
|
|||
|
||||
fi
|
||||
- sudo python3 -m pip install --upgrade pip
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0'
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0
|
||||
- export QTDIR=`$(brew --prefix qt6)`
|
||||
- export PATH="$PATH:`python3 -m site --user-base`/bin:$QTDIR/bin"
|
||||
- echo $PATH
|
||||
|
@ -663,13 +675,28 @@ for:
|
|||
|
||||
build_script:
|
||||
- pwd
|
||||
- git describe --always HEAD
|
||||
- conan profile new valentina
|
||||
- conan profile update settings.build_type=Release valentina
|
||||
- conan profile update settings.os=Macos valentina
|
||||
- conan profile update settings.os.Macos.sdk_version=${MACOS_DEPLOYMENT_TARGET} valentina
|
||||
- conan profile update settings.compiler=clang valentina
|
||||
- conan profile update settings.compiler.cppstd=17 valentina
|
||||
- conan profile update settings.compiler.libcxx=libstdc++11 valentina
|
||||
- conan profile update settings.compiler.version=15 valentina
|
||||
- qbs setup-toolchains --detect
|
||||
- qbs config --list profiles
|
||||
- qbs setup-qt $(brew --prefix qt6)/bin/qmake qt6
|
||||
- qbs config defaultProfile qt6
|
||||
- qbs config profiles.qt6.baseProfile clang
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt6 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true moduleProviders.qbspkgconfig.extraPaths:$(brew --prefix xerces-c)/lib/pkgconfig,$(brew --prefix qt6)/lib/pkgconfig,$(brew --prefix openssl@1.1)/lib/pkgconfig "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:$(brew --prefix qt6)/lib,$(brew --prefix poppler)/lib modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build -p 'Valentina DMG' --force-probe-execution --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt6 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true moduleProviders.qbspkgconfig.extraPaths:$(brew --prefix xerces-c)/lib/pkgconfig,$(brew --prefix qt6)/lib/pkgconfig,$(brew --prefix openssl@1.1)/lib/pkgconfig "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:$(brew --prefix qt6)/lib,$(brew --prefix poppler)/lib modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir
|
||||
- conan install . -s os=Macos --build=missing -o with_crash_reporting=True -pr valentina -g virtualrunenv
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt6 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true moduleProviders.qbspkgconfig.extraPaths:$(brew --prefix xerces-c)/lib/pkgconfig,$(brew --prefix qt6)/lib/pkgconfig,$(brew --prefix openssl@1.1)/lib/pkgconfig "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:$(brew --prefix qt6)/lib,$(brew --prefix poppler)/lib modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir project.enableConan:true project.conanWithCrashReporting:true
|
||||
- export CRASH_QT_VERSION=$($QTDIR/bin/qmake -query QT_VERSION | awk -F. '{print $1 "_" $2}')
|
||||
- export CRASH_SHORT_SHA=$(git log --pretty=format:%h -n 1)
|
||||
- source activate_run.sh
|
||||
- python3 scripts/symupload.py ${APPVEYOR_BUILD_FOLDER}/build/install-root $VALENTINA_VERSION $CRASH_SHORT_SHA $CRASH_QT_VERSION --clean
|
||||
- source deactivate_run.sh
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build -p 'Valentina DMG' --force-probe-execution --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt6 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true moduleProviders.qbspkgconfig.extraPaths:$(brew --prefix xerces-c)/lib/pkgconfig,$(brew --prefix qt6)/lib/pkgconfig,$(brew --prefix openssl@1.1)/lib/pkgconfig "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:$(brew --prefix qt6)/lib,$(brew --prefix poppler)/lib modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir project.enableConan:true project.conanWithCrashReporting:true
|
||||
# Store the notarization credentials so that we can prevent a UI password dialog
|
||||
# from blocking the CI
|
||||
- echo "Create keychain profile"
|
||||
|
@ -720,7 +747,7 @@ for:
|
|||
secure: B8yHPBym+BTDPK5ZCg7WlSnUCHLbcim8WqLTC6/PSNs=
|
||||
|
||||
cache:
|
||||
#- /Users/appveyor/.conan/data -> conanfile.py
|
||||
- /Users/appveyor/.conan/data -> conanfile.py
|
||||
- $HOME/brew_cache_dir
|
||||
|
||||
init:
|
||||
|
@ -827,7 +854,7 @@ for:
|
|||
|
||||
fi
|
||||
- sudo python3 -m pip install --upgrade pip
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0'
|
||||
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0
|
||||
- export PATH="`brew --prefix qbs`/bin:$PATH"
|
||||
- echo $PATH
|
||||
- clang --version
|
||||
|
@ -846,13 +873,27 @@ for:
|
|||
|
||||
build_script:
|
||||
- pwd
|
||||
- conan profile new valentina
|
||||
- conan profile update settings.build_type=Release valentina
|
||||
- conan profile update settings.os=Macos valentina
|
||||
- conan profile update settings.os.Macos.sdk_version=${MACOS_DEPLOYMENT_TARGET} valentina
|
||||
- conan profile update settings.compiler=clang valentina
|
||||
- conan profile update settings.compiler.cppstd=17 valentina
|
||||
- conan profile update settings.compiler.libcxx=libstdc++11 valentina
|
||||
- conan profile update settings.compiler.version=14 valentina
|
||||
- qbs setup-toolchains --detect
|
||||
- qbs config --list profiles
|
||||
- qbs setup-qt ${QTDIR}/bin/qmake qt5
|
||||
- qbs config defaultProfile qt5
|
||||
- qbs config profiles.qt5.baseProfile clang
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt5 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:${QTDIR}/lib modules.macdeployqt.pluginspath:${QTDIR}/plugins modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build -p 'Valentina DMG' --force-probe-execution --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt5 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:${QTDIR}/lib modules.macdeployqt.pluginspath:${QTDIR}/plugins modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir
|
||||
- conan install . -s os=Macos --build=missing -o with_crash_reporting=True -pr valentina -g virtualrunenv
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt5 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:${QTDIR}/lib modules.macdeployqt.pluginspath:${QTDIR}/plugins modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir project.enableConan:true project.conanWithCrashReporting:true
|
||||
- export CRASH_QT_VERSION=$($QTDIR/bin/qmake -query QT_VERSION | awk -F. '{print $1 "_" $2}')
|
||||
- export CRASH_SHORT_SHA=$(git log --pretty=format:%h -n 1)
|
||||
- source activate_run.sh
|
||||
- python3 scripts/symupload.py ${APPVEYOR_BUILD_FOLDER}/build/install-root $VALENTINA_VERSION $CRASH_SHORT_SHA $CRASH_QT_VERSION --clean
|
||||
- source deactivate_run.sh
|
||||
- qbs build -f valentina.qbs -d ${APPVEYOR_BUILD_FOLDER}/build -p 'Valentina DMG' --force-probe-execution --jobs $(nproc) config:release modules.buildconfig.enableUnitTests:false modules.buildconfig.enableMultiBundle:${MULTI_BUNDLE} qbs.installRoot:${APPVEYOR_BUILD_FOLDER}/build/install-root profile:qt5 project.minimumMacosVersion:${MACOS_DEPLOYMENT_TARGET} modules.buildconfig.enableCcache:true "modules.buildconfig.signingIdentity:$MACOS_CERTIFICATE_NAME" modules.macdeployqt.libpath:${QTDIR}/lib modules.macdeployqt.pluginspath:${QTDIR}/plugins modules.macdeployqt.macdeployqtProgramBinPath:${HOME}/macdeployqt-install-dir project.enableConan:true project.conanWithCrashReporting:true
|
||||
# Store the notarization credentials so that we can prevent a UI password dialog
|
||||
# from blocking the CI
|
||||
- echo "Create keychain profile"
|
||||
|
|
20
conanfile.py
20
conanfile.py
|
@ -4,8 +4,16 @@ from conan import ConanFile
|
|||
|
||||
class Recipe(ConanFile):
|
||||
settings = "os"
|
||||
requires = "xerces-c/[~3.2]"
|
||||
default_options = {"xerces-c/*:shared": True}
|
||||
requires = "xerces-c/[~3.2]", "crashpad/cci.20220219", "breakpad/cci.20210521"
|
||||
options = {
|
||||
"with_xerces": [True, False],
|
||||
"with_crash_reporting": [True, False]
|
||||
}
|
||||
default_options = {
|
||||
"xerces-c/*:shared": True,
|
||||
"with_xerces": False,
|
||||
"with_crash_reporting": False
|
||||
}
|
||||
|
||||
def configure(self):
|
||||
if self.settings.os == "Linux":
|
||||
|
@ -13,3 +21,11 @@ class Recipe(ConanFile):
|
|||
|
||||
if self.settings.os == "Macos" and "MACOS_DEPLOYMENT_TARGET" in os.environ:
|
||||
self.settings.os.version = os.environ["MACOS_DEPLOYMENT_TARGET"]
|
||||
|
||||
def requirements(self):
|
||||
if not self.options.with_xerces:
|
||||
del self.requires["xerces-c"]
|
||||
|
||||
if not self.options.with_crash_reporting:
|
||||
del self.requires["crashpad/cci.20220219"]
|
||||
del self.requires["breakpad/cci.20210521"]
|
||||
|
|
|
@ -44,4 +44,9 @@ VLib {
|
|||
install: true
|
||||
installDir: buildconfig.installLibraryPath
|
||||
}
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
qbs.debugInformation: true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,11 @@ VApp {
|
|||
cpp.dynamicLibraries: ["icudata", "icui18n", "icuuc"]
|
||||
}
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
qbs.debugInformation: true
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "Translations"
|
||||
condition: product.primaryApp || (qbs.targetOS.contains("macos") && (!bundle.isBundle || (bundle.isBundle && buildconfig.enableMultiBundle)))
|
||||
|
|
|
@ -2,6 +2,8 @@ import qbs.File
|
|||
import qbs.FileInfo
|
||||
import qbs.TextFile
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
ModuleProvider {
|
||||
relativeSearchPaths: {
|
||||
var conanPackageDir = FileInfo.cleanPath(FileInfo.joinPaths(outputBaseDir, "../../..", "genconan"));
|
||||
|
@ -25,8 +27,6 @@ ModuleProvider {
|
|||
|
||||
file.close();
|
||||
|
||||
console.info(JSON.stringify(fileContent));
|
||||
|
||||
var deps = fileContent.dependencies;
|
||||
|
||||
for(i in deps){
|
||||
|
@ -48,11 +48,11 @@ ModuleProvider {
|
|||
|
||||
// module name can be invalid for Javascrip. Search for alternative names for cmake.
|
||||
var moduleName = deps[i].name;
|
||||
if (deps[i].hasOwnProperty("names"))
|
||||
if (!Utils.isValidAttributeName(moduleName) && deps[i].hasOwnProperty("names"))
|
||||
{
|
||||
if (deps[i].names.hasOwnProperty("cmake_find_package"))
|
||||
moduleName = deps[i].names.cmake_find_package;
|
||||
else if (deps.names.hasOwnProperty("cmake_find_package_multi"))
|
||||
else if (deps[i].names.hasOwnProperty("cmake_find_package_multi"))
|
||||
moduleName = deps[i].names.cmake_find_package_multi;
|
||||
}
|
||||
|
||||
|
@ -63,15 +63,18 @@ ModuleProvider {
|
|||
var moduleFile = new TextFile(FileInfo.joinPaths(moduleDir, moduleName + ".qbs"), TextFile.WriteOnly);
|
||||
|
||||
var shared = false;
|
||||
if (fileContent.options[deps[i].name].hasOwnProperty("shared"))
|
||||
if (fileContent.options.hasOwnProperty(deps[i].name) && fileContent.options[deps[i].name].hasOwnProperty("shared"))
|
||||
{
|
||||
shared = (fileContent.options[deps[i].name].shared === 'True');
|
||||
}
|
||||
|
||||
var cppLibraries = shared ? "\tcpp.dynamicLibraries: " : "\tcpp.staticLibraries: ";
|
||||
var cppLibrariesTag = shared ? "dynamiclibrary" : "staticlibrary";
|
||||
var cppLibrarySuffix = shared ? "cpp.dynamicLibrarySuffix" : "cpp.staticLibrarySuffix";
|
||||
|
||||
moduleFile.write("import qbs\n" +
|
||||
"Module {\n" +
|
||||
"\tDepends { name: \"cpp\" }\n\n" +
|
||||
"\tproperty bool installBin: false\n" +
|
||||
"\tproperty bool installLib: false\n" +
|
||||
"\tproperty bool installRes: false\n" +
|
||||
|
@ -81,10 +84,9 @@ ModuleProvider {
|
|||
"\tproperty string resInstallDir: \"res\"\n" +
|
||||
"\tproperty string includeInstallDir: \"include\"\n" +
|
||||
"\tproperty stringList binFilePatterns: [\"**/*\"]\n" +
|
||||
"\tproperty stringList libFilePatterns: [\"**/*\"]\n" +
|
||||
"\tproperty stringList libFilePatterns: [\"**/*\" + " + cppLibrarySuffix + "]\n" +
|
||||
"\tproperty stringList resFilePatterns: [\"**/*\"]\n" +
|
||||
"\tproperty stringList includeFilePatterns: [\"**/*\"]\n\n" +
|
||||
"\tDepends { name: \"cpp\" }\n\n" +
|
||||
"\tcpp.includePaths: " + JSON.stringify(deps[i].include_paths) + "\n" +
|
||||
"\tcpp.systemIncludePaths: " + JSON.stringify(deps[i].include_paths) + "\n" +
|
||||
"\tcpp.libraryPaths: " + JSON.stringify(deps[i].lib_paths) + "\n" +
|
||||
|
@ -94,9 +96,9 @@ ModuleProvider {
|
|||
function writeGroups(file, moduleName, prefix, pathList, install) {
|
||||
for(j in pathList) {
|
||||
file.write("\tGroup {\n" +
|
||||
"\t\tname: \"" + prefix + (j > 0 ? j : "") + "\"\n" +
|
||||
"\t\tprefix: \"" + FileInfo.fromNativeSeparators(pathList[j]) + "/\"\n" +
|
||||
"\t\tfilesAreTargets: true\n");
|
||||
"\t\tname: \"" + prefix + (j > 0 ? j : "") + "\"\n" +
|
||||
"\t\tprefix: \"" + FileInfo.fromNativeSeparators(pathList[j]) + "/\"\n" +
|
||||
"\t\tfilesAreTargets: true\n");
|
||||
|
||||
if (install)
|
||||
file.write("\t\tqbs.install: product.conan." + moduleName + ".install" + (prefix.charAt(0).toUpperCase() + prefix.substring(1)) + "\n" +
|
||||
|
@ -104,15 +106,19 @@ ModuleProvider {
|
|||
"\t\tqbs.installDir: product.conan." + moduleName + "." + prefix + "InstallDir\n" +
|
||||
"\t\tqbs.installSourceBase: \"" + FileInfo.fromNativeSeparators(pathList[j]) + "\"\n");
|
||||
|
||||
file.write("\t\tfiles: product.conan." + moduleName + "." + prefix + "FilePatterns\n" +
|
||||
"\t}\n");
|
||||
file.write("\t\tfiles: product.conan." + moduleName + "." + prefix + "FilePatterns\n");
|
||||
|
||||
if (prefix === "lib")
|
||||
file.write("\t\tfileTags: [\"" + cppLibrariesTag + "\"]\n");
|
||||
|
||||
file.write("\t}\n");
|
||||
}
|
||||
}
|
||||
|
||||
writeGroups(moduleFile, moduleName, "bin", deps[i].bin_paths, true);
|
||||
writeGroups(moduleFile, moduleName, "lib", deps[i].lib_paths, shared);
|
||||
writeGroups(moduleFile, moduleName, "res", deps[i].res_paths, true);
|
||||
writeGroups(moduleFile, moduleName, "include", deps[i].include_paths, shared);
|
||||
writeGroups(moduleFile, moduleName, "include", Utils.filterUniqueRootPaths(deps[i].include_paths), shared);
|
||||
|
||||
moduleFile.writeLine("}");
|
||||
moduleFile.close();
|
||||
|
|
65
qbs/module-providers/conan/utils.js
Normal file
65
qbs/module-providers/conan/utils.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
var FileInfo = require("qbs.FileInfo");
|
||||
|
||||
function isValidAttributeName(name) {
|
||||
// Check if the name starts with a letter, underscore, or dollar sign
|
||||
if (!/^[a-zA-Z_$]/.test(name.charAt(0))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for subsequent characters: letters, digits, underscores, or dollar signs
|
||||
for (var i = 1; i < name.length; i++) {
|
||||
if (!/^[0-9a-zA-Z_$]/.test(name.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the name is a reserved word
|
||||
const reservedWords = [
|
||||
'abstract', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const',
|
||||
'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'export', 'extends',
|
||||
'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import',
|
||||
'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', 'null', 'package',
|
||||
'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized',
|
||||
'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield'
|
||||
];
|
||||
|
||||
if (reservedWords.includes(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If all checks passed, the name is valid
|
||||
return true;
|
||||
}
|
||||
|
||||
function filterUniqueRootPaths(paths) {
|
||||
if (paths.length < 2) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
// Always compare canonocal paths
|
||||
const canonicalPaths = paths.map(function(folder) {
|
||||
return FileInfo.cleanPath(folder);
|
||||
});
|
||||
|
||||
const isChildOf = function(child, parent) {
|
||||
if (child === parent) return false;
|
||||
|
||||
var parentTokens = parent.split('/').filter(function(i) {
|
||||
return i.length;
|
||||
});
|
||||
|
||||
var childTokens = child.split('/').filter(function(i) {
|
||||
return i.length;
|
||||
});
|
||||
|
||||
return parentTokens.every(function(t, i) {
|
||||
return childTokens[i] === t;
|
||||
});
|
||||
}
|
||||
|
||||
return canonicalPaths.filter(function(folder) {
|
||||
return !canonicalPaths.some(function(otherFolder) {
|
||||
return folder !== otherFolder && isChildOf(folder, otherFolder);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -48,6 +48,18 @@ Module {
|
|||
|
||||
return project.enableConan;
|
||||
}
|
||||
readonly property bool conanXercesEnabled : project.conanWithXerces
|
||||
readonly property bool conanCrashReportingEnabled : {
|
||||
if (qbs.targetOS.contains("windows")) {
|
||||
if (qbs.toolchain.contains("msvc")) {
|
||||
return project.conanWithCrashReporting;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return project.conanWithCrashReporting;
|
||||
}
|
||||
}
|
||||
|
||||
readonly property bool enableCodeSigning: project.enableSigning
|
||||
|
||||
|
@ -140,6 +152,9 @@ Module {
|
|||
if (enableMultiBundle)
|
||||
defines.push('MULTI_BUNDLE');
|
||||
|
||||
if (useConanPackages && conanCrashReportingEnabled)
|
||||
defines.push('CRASH_REPORTING');
|
||||
|
||||
return defines;
|
||||
}
|
||||
|
||||
|
@ -827,39 +842,6 @@ Module {
|
|||
}
|
||||
}
|
||||
|
||||
if (Utilities.versionCompare(qbs.version, "1.22") < 0)
|
||||
{
|
||||
var qtLibs = [
|
||||
"QtCore",
|
||||
"QtSvg",
|
||||
"QtXml",
|
||||
"QtPrintSupport",
|
||||
"QtXmlPatterns",
|
||||
"QtWidgets",
|
||||
"QtGui",
|
||||
"QtNetwork",
|
||||
"QtTest",
|
||||
"QtConcurrent"
|
||||
];
|
||||
|
||||
if (!qbs.targetOS.contains("macos"))
|
||||
{
|
||||
paths.push(Qt.core.incPath);
|
||||
|
||||
for (var i = 0; i < qtLibs.length; i++) {
|
||||
paths.push(FileInfo.joinPaths(Qt.core.incPath, qtLibs[i]));
|
||||
}
|
||||
|
||||
} else {
|
||||
for (var i = 0; i < qtLibs.length; i++) {
|
||||
paths.push(FileInfo.joinPaths(Qt.core.incPath,
|
||||
qtLibs[i] + ".framework/Versions/" + Qt.core.versionMajor +
|
||||
"/Headers"));
|
||||
paths.push(FileInfo.joinPaths(Qt.core.incPath, qtLibs[i] + ".framework/Headers"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,14 @@ import qbs.Utilities
|
|||
Module {
|
||||
property string type: typeProbe.type
|
||||
property string repoDir: project.sourceDirectory
|
||||
|
||||
// TODO: If minimal qbs version is 1.23 replace with FileInfo.executableSuffix()
|
||||
readonly property string executableSuffix: project.qbs.targetOS.contains("windows") ? ".exe" : ""
|
||||
property string toolFilePath: {
|
||||
if (type === "git")
|
||||
return "git";
|
||||
return "git" + executableSuffix;
|
||||
if (type === "svn")
|
||||
return "svn";
|
||||
return "svn" + executableSuffix;
|
||||
}
|
||||
|
||||
property string headerFileName: "vcs-repo-state.h"
|
||||
|
@ -101,13 +104,14 @@ Module {
|
|||
// 3. latest commit is gSHA
|
||||
proc.exec(tool, ["describe", "--always", "HEAD"], true);
|
||||
repoState = proc.readStdOut().trim();
|
||||
if (repoState)
|
||||
if (repoState) {
|
||||
found = true;
|
||||
|
||||
const tagSections = repoState.split("-");
|
||||
repoStateTag = tagSections[0];
|
||||
repoStateDistance = tagSections[1];
|
||||
repoStateRevision = tagSections[2];
|
||||
}
|
||||
} finally {
|
||||
proc.close();
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
#!/bin/sh
|
||||
# This script helps run cppcheck with the same keys we have on codeship.com (except for key --platform=unix32).
|
||||
# Please, run this script from folder <root_folder>/scripts.
|
||||
|
||||
# Because we use the last available cppcheck version usually we build it manually.
|
||||
CPPCHECK="../../../../cppcheck-2.8/cppcheck"
|
||||
$CPPCHECK \
|
||||
-j4 -f -q \
|
||||
-UDRW_DBG \
|
||||
-U__INTEL_COMPILER_UPDATE \
|
||||
--template '{file}:{line}:{message}:{id}' \
|
||||
--inline-suppr \
|
||||
--platform=unix64 \
|
||||
--std=c++17 \
|
||||
--enable=all \
|
||||
--library=qt \
|
||||
--library=std \
|
||||
--library=posix \
|
||||
--inconclusive \
|
||||
--suppress=*:*/vdxf/libdxfrw/intern/make_unique.h \
|
||||
--inconclusive \
|
||||
--suppress=*:*/qmuparser/make_unique.h \
|
||||
../src
|
|
@ -1,75 +0,0 @@
|
|||
rem script helps create installer
|
||||
|
||||
rem find target architecture
|
||||
IF "%PROCESSOR_ARCHITECTURE%"=="x86" (set ARCHITECTURE=32BIT) else (set ARCHITECTURE=64BIT)
|
||||
|
||||
rem Path to Inno Setup according to architecture
|
||||
if %ARCHITECTURE%==32BIT set nsis_path="C:/Program Files/Inno Setup 5/iscc.exe"
|
||||
if %ARCHITECTURE%==64BIT set nsis_path="C:/Program Files (x86)/Inno Setup 5/iscc.exe"
|
||||
|
||||
if not exist %nsis_path% (
|
||||
echo Coudn't find Inno Setup. Package will not be created.
|
||||
)
|
||||
|
||||
:CONTINUE
|
||||
rem detect windows version
|
||||
ver | find "6.1" > nul
|
||||
|
||||
IF ERRORLEVEL = 1 GOTO PREPARE
|
||||
IF ERRORLEVEL = 0 GOTO WIN7
|
||||
|
||||
:WIN7
|
||||
chcp 65001
|
||||
|
||||
:PREPARE
|
||||
cd ..
|
||||
cd
|
||||
rem force qmake create new qm files
|
||||
del /Q share\translations\*.qm
|
||||
IF exist build (
|
||||
echo Build exists. Clearing.
|
||||
rd /s /q build\package
|
||||
del /s /q /f build\Makefile
|
||||
del /s /q /f build\*.exe
|
||||
del /s /q /f build\*.dll
|
||||
del /q /f build\src\app\tape\obj\dialogabouttape.o
|
||||
del /q /f build\src\app\valentina\obj\dialogaboutapp.o
|
||||
)
|
||||
mkdir build && echo build created
|
||||
cd build
|
||||
cd
|
||||
|
||||
qmake -r CONFIG+=noTests ..\Valentina.pro
|
||||
IF ERRORLEVEL 1 GOTO ERRORQMAKE1
|
||||
IF ERRORLEVEL 0 GOTO MAKE
|
||||
|
||||
:MAKE
|
||||
mingw32-make -j%NUMBER_OF_PROCESSORS%
|
||||
IF ERRORLEVEL 1 GOTO ERRORMAKE
|
||||
IF ERRORLEVEL 0 GOTO MAKEINSTALL
|
||||
|
||||
:MAKEINSTALL
|
||||
mingw32-make install
|
||||
IF ERRORLEVEL 1 GOTO ERRORMAKEINSTALL
|
||||
IF ERRORLEVEL 0 GOTO ONEXIT
|
||||
|
||||
:ERRORMAKEINSTALL
|
||||
echo Failed to create installer!
|
||||
@pause
|
||||
exit /b 1
|
||||
:ERRORMAKE
|
||||
echo Failed to build project!
|
||||
@pause
|
||||
exit /b 1
|
||||
:ERRORQMAKE2
|
||||
echo Failed to make the second run qmake!
|
||||
@pause
|
||||
exit /b 1
|
||||
:ERRORQMAKE1
|
||||
echo Failed to make the first run qmake!
|
||||
@pause
|
||||
exit /b 1
|
||||
:ONEXIT
|
||||
echo Done!
|
||||
@pause
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Use the script to sign your app bundle on Mac OS X.
|
||||
# Requirement Mac OS El Capitan or later.
|
||||
# An app bundle must be in the same folder.
|
||||
|
||||
# Name of your certificate in look "Developer ID Application: <yourID>"
|
||||
# Be sure that you use Developer ID certificate!
|
||||
CERTIFICATE="Developer ID Application: <yourID>"
|
||||
BUNDLE=Valentina.app
|
||||
|
||||
# all must be signed
|
||||
#s ign all *.dylib
|
||||
find $BUNDLE -name *.dylib | xargs -I $ codesign -f -v -v -vvvv --deep --strict -s "$CERTIFICATE" $
|
||||
|
||||
# sign Qt frameworks
|
||||
find $BUNDLE -name Qt* -type f | xargs -I $ codesign -f -v -v -vvvv --deep --strict -s "$CERTIFICATE" $
|
||||
|
||||
# sign all binaries
|
||||
find $BUNDLE -path */MacOS/* -type f | xargs -I $ codesign -f -v -v -vvvv --deep --strict -s "$CERTIFICATE" $
|
||||
|
||||
# sign the app bundle
|
||||
codesign -f -v -v -vvvv --deep --strict -s "$CERTIFICATE" ./$BUNDLE
|
||||
|
||||
#verify in the end
|
||||
codesign -v -vvvv ./$BUNDLE
|
||||
spctl -a -t exec -vv ./$BUNDLE
|
158
scripts/symupload.py
Normal file
158
scripts/symupload.py
Normal file
|
@ -0,0 +1,158 @@
|
|||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import glob
|
||||
import zipfile
|
||||
|
||||
database = "valentina"
|
||||
|
||||
def debug_extension():
|
||||
platform = sys.platform
|
||||
if platform == "darwin":
|
||||
debug_ext = ".dSYM"
|
||||
elif platform == "win32":
|
||||
debug_ext = ".pdb"
|
||||
elif platform == "linux":
|
||||
debug_ext = ".debug"
|
||||
else:
|
||||
print(f"Unsupported platform {platform}")
|
||||
return "uknown"
|
||||
|
||||
return debug_ext
|
||||
|
||||
def check_binary(binary):
|
||||
# Check if binary file exists
|
||||
if not os.path.exists(binary):
|
||||
# If binary file doesn't exist, it may be part of a framework
|
||||
framework_binary = os.path.basename(binary.replace(".framework", ""))
|
||||
for root, dirs, files in os.walk(binary):
|
||||
for file in files:
|
||||
if file == framework_binary:
|
||||
return os.path.join(root, file)
|
||||
return binary
|
||||
|
||||
def zip_sym(sym_file):
|
||||
zip_sym_file = sym_file + ".zip"
|
||||
with zipfile.ZipFile(zip_sym_file, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
||||
zipf.write(sym_file, os.path.basename(sym_file))
|
||||
return zip_sym_file
|
||||
|
||||
def generate_sym_files(install_root):
|
||||
sym_files = []
|
||||
|
||||
platform = sys.platform
|
||||
debug_ext = debug_extension()
|
||||
|
||||
debug_files = glob.glob(os.path.join(install_root, "**", "*" + debug_ext), recursive=True)
|
||||
|
||||
for debug_file in debug_files:
|
||||
print(f"Generating symbols for: {os.path.basename(debug_file)}")
|
||||
if platform == "win32":
|
||||
# For Windows, return the executable file
|
||||
sym_file = os.path.splitext(debug_file)[0] + ".exe"
|
||||
else:
|
||||
sym_file = os.path.splitext(debug_file)[0] + ".sym"
|
||||
if platform == "darwin":
|
||||
binary = check_binary(os.path.splitext(debug_file)[0])
|
||||
dump_syms_cmd = ["dump_syms", "-g", debug_file, binary]
|
||||
elif platform == "linux":
|
||||
dump_syms_cmd = ["dump_syms", debug_file]
|
||||
|
||||
with open(sym_file, "w") as f:
|
||||
subprocess.run(dump_syms_cmd, check=True, stdout=f)
|
||||
|
||||
if platform == "linux":
|
||||
# When symbols are dumped from a debug file Crashpad creates an incorrect module name.
|
||||
sed_cmd = ["sed", "-i", "1s/.debug//", sym_file]
|
||||
subprocess.run(sed_cmd, check=True)
|
||||
|
||||
sym_files.append((debug_file, zip_sym(sym_file)))
|
||||
|
||||
return sym_files
|
||||
|
||||
def generate_version_string(val_version, commit_hash, qt_version):
|
||||
# Determine the platform
|
||||
platform = sys.platform
|
||||
if platform == "win32":
|
||||
platform_str = "windows"
|
||||
elif platform == "darwin":
|
||||
platform_str = "macos"
|
||||
elif platform == "linux":
|
||||
platform_str = "linux"
|
||||
else:
|
||||
platform_str = "unknown"
|
||||
|
||||
# Generate the version string
|
||||
version_string = f"{val_version}-{commit_hash}-Qt_{qt_version}-{platform_str}"
|
||||
return version_string
|
||||
|
||||
def get_app_name(sym_file):
|
||||
# Get the base name of the symbol file without extension
|
||||
base_name = os.path.splitext(os.path.basename(sym_file))[0].lower()
|
||||
|
||||
# Determine the platform
|
||||
platform = sys.platform
|
||||
if platform == "linux":
|
||||
if base_name.startswith("lib"):
|
||||
base_name = base_name[3:]
|
||||
return base_name.split(".so")[0]
|
||||
elif platform == "darwin":
|
||||
if base_name.endswith(".framework"):
|
||||
return base_name.split(".framework")[0]
|
||||
|
||||
return base_name
|
||||
|
||||
def upload_symbols(install_root, val_version, commit_hash, qt_version, clean=False):
|
||||
# Platform-specific commands for generating and uploading symbol files
|
||||
platform = sys.platform
|
||||
sym_files = generate_sym_files(install_root)
|
||||
app_version = generate_version_string(val_version, commit_hash, qt_version)
|
||||
print(f"Uploading symbols for version {app_version}")
|
||||
|
||||
for _, sym_file in sym_files:
|
||||
app_name = get_app_name(sym_file)
|
||||
print(f"Uploading symbols for application {app_name}")
|
||||
|
||||
if platform == "linux":
|
||||
upload_cmd = ["sym_upload", sym_file, f"https://{database}.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName={app_name}&appVer={app_version}"]
|
||||
elif platform == "darwin":
|
||||
upload_cmd = ["symupload", sym_file, f"https://{database}.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName={app_name}&appVer={app_version}"]
|
||||
elif platform == "win32":
|
||||
upload_cmd = ["symupload.exe", "--product", app_name, sym_file, f"https://{database}.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName={app_name}&appVer={app_version}"]
|
||||
|
||||
try:
|
||||
subprocess.run(upload_cmd, check=True)
|
||||
print(f"Symbol file '{sym_file}' uploaded successfully.")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
# Cleanup if requested
|
||||
if clean:
|
||||
debug_ext = debug_extension()
|
||||
for debug_file, sym_file in sym_files:
|
||||
os.remove(sym_file)
|
||||
print(f"Symbol file '{sym_file}' removed.")
|
||||
os.remove(debug_file)
|
||||
print(f"Debug file '{debug_file}' removed.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Command-line usage: python symupload.py /path/to/install_root/folder 0_7_52 abcdef123456 6_6 --clean
|
||||
# - First argument: Path to the install root folder
|
||||
# - Second argument: Valentina version
|
||||
# - Third argument: Commit git hash
|
||||
# - Fourth argument: Qt version
|
||||
# - Optional argument: --clean (Clean up after upload)
|
||||
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="Upload symbols to BugSplat.")
|
||||
parser.add_argument("install_root", type=str, help="Path to the installation folder")
|
||||
parser.add_argument("val_version", type=str, help="Valentina version")
|
||||
parser.add_argument("hash", type=str, help="Commit git hash")
|
||||
parser.add_argument("qt_version", type=str, help="Qt version")
|
||||
parser.add_argument("--clean", action="store_true", help="Clean up after upload")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Call install_package function with provided arguments
|
||||
upload_symbols(args.install_root, args.val_version, args.hash, args.qt_version, args.clean)
|
|
@ -117,6 +117,21 @@ PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *
|
|||
|
||||
// Tab Privacy
|
||||
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
|
||||
|
||||
#if !defined(CRASH_REPORTING)
|
||||
ui->groupBoxCrashReports->setDisabled(true);
|
||||
#endif
|
||||
|
||||
ui->checkBoxSendCrashReports->setChecked(settings->IsSendCrashReport());
|
||||
connect(ui->checkBoxSendCrashReports, &QCheckBox::stateChanged, this,
|
||||
[this]() { m_sendCrashReportsChanged = true; });
|
||||
|
||||
QRegularExpression const rx(QStringLiteral("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b"),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
ui->lineEditCrashUserEmail->setValidator(new QRegularExpressionValidator(rx, this));
|
||||
ui->lineEditCrashUserEmail->setText(settings->GetCrashEmail());
|
||||
connect(ui->lineEditCrashUserEmail, &QLineEdit::editingFinished, this,
|
||||
[this]() { m_crashUserEmailChanged = true; });
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -229,6 +244,22 @@ auto PuzzlePreferencesConfigurationPage::Apply() -> QStringList
|
|||
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
|
||||
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
|
||||
|
||||
#if defined(CRASH_REPORTING)
|
||||
if (m_sendCrashReportsChanged)
|
||||
{
|
||||
settings->SeSendCrashReport(ui->checkBoxSendCrashReports->isChecked());
|
||||
m_sendCrashReportsChanged = false;
|
||||
preferences.append(tr("send crash report"));
|
||||
}
|
||||
|
||||
if (m_crashUserEmailChanged)
|
||||
{
|
||||
settings->SetCrashEmail(ui->lineEditCrashUserEmail->text());
|
||||
m_crashUserEmailChanged = false;
|
||||
preferences.append(tr("user email in case of crash"));
|
||||
}
|
||||
#endif
|
||||
|
||||
return preferences;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ private:
|
|||
Q_DISABLE_COPY_MOVE(PuzzlePreferencesConfigurationPage) // NOLINT
|
||||
std::unique_ptr<Ui::PuzzlePreferencesConfigurationPage> ui;
|
||||
bool m_langChanged{false};
|
||||
bool m_sendCrashReportsChanged{false};
|
||||
bool m_crashUserEmailChanged{false};
|
||||
QList<QStringList> m_transientShortcuts{};
|
||||
|
||||
void SetThemeModeComboBox();
|
||||
|
|
|
@ -522,22 +522,75 @@ This option will take an affect after restart.</string>
|
|||
<attribute name="title">
|
||||
<string>Privacy</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
<widget class="QGroupBox" name="groupBox_12">
|
||||
<property name="title">
|
||||
<string>Usage statistic</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
<widget class="QGroupBox" name="groupBoxCrashReports">
|
||||
<property name="title">
|
||||
<string>Crash reports</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendCrashReports">
|
||||
<property name="text">
|
||||
<string>Send automatic crash reports</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Email:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditCrashUserEmail">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Reporting crash reports will help us make Valentina more reliable. All information is treated as confidential and is only used to improve future versions of this program. Please activate sending automatic crash reports and fill your email address (optional). If provided, we may contact you with additional information about the crash.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -35,6 +35,11 @@
|
|||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef CRASH_REPORTING
|
||||
#include "../vmisc/crashhandler/crashhandler.h"
|
||||
#include "version.h"
|
||||
#endif
|
||||
|
||||
// Fix bug in Qt. Deprecation warning in QMessageBox::critical.
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
#undef QT_REQUIRE_VERSION
|
||||
|
@ -81,6 +86,10 @@ auto main(int argc, char *argv[]) -> int
|
|||
Q_INIT_RESOURCE(win_light_theme); // NOLINT
|
||||
Q_INIT_RESOURCE(win_dark_theme); // NOLINT
|
||||
|
||||
#ifdef CRASH_REPORTING
|
||||
InitializeCrashpad(QStringLiteral(VER_PRODUCTNAME_STR).toLower());
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
VAbstractApplication::WinAttachConsole();
|
||||
#endif
|
||||
|
|
|
@ -36,11 +36,17 @@ VToolApp {
|
|||
type: base.concat("install_root_svg_fonts")
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && qbs.targetOS.contains("macos") && buildconfig.enableMultiBundle
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanXercesEnabled && qbs.targetOS.contains("macos") && buildconfig.enableMultiBundle
|
||||
conan.XercesC.libInstallDir: qbs.installPrefix + "/" + buildconfig.installLibraryPath
|
||||
conan.XercesC.installLib: true
|
||||
}
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled && qbs.targetOS.contains("macos") && buildconfig.enableMultiBundle
|
||||
conan.crashpad.installBin: true
|
||||
conan.crashpad.binInstallDir: qbs.installPrefix + "/" + buildconfig.installBinaryPath
|
||||
}
|
||||
|
||||
files: [
|
||||
"main.cpp",
|
||||
"vpapplication.cpp",
|
||||
|
|
|
@ -4701,15 +4701,20 @@ void VPMainWindow::AskDefaultSettings()
|
|||
}
|
||||
}
|
||||
|
||||
if (settings->IsAskCollectStatistic())
|
||||
if (settings->IsAskCollectStatistic() || settings->IsAskSendCrashReport())
|
||||
{
|
||||
DialogAskCollectStatistic dialog(this);
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
settings->SetCollectStatistic(dialog.CollectStatistic());
|
||||
#if defined(CRASH_REPORTING)
|
||||
settings->SeSendCrashReport(dialog.SendCrashReport());
|
||||
settings->SetCrashEmail(dialog.UserEmail());
|
||||
#endif
|
||||
}
|
||||
|
||||
settings->SetAskCollectStatistic(false);
|
||||
settings->SetAskSendCrashReport(false);
|
||||
}
|
||||
|
||||
if (settings->IsCollectStatistic())
|
||||
|
|
|
@ -115,6 +115,21 @@ TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *pare
|
|||
|
||||
// Tab Privacy
|
||||
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
|
||||
|
||||
#if !defined(CRASH_REPORTING)
|
||||
ui->groupBoxCrashReports->setDisabled(true);
|
||||
#endif
|
||||
|
||||
ui->checkBoxSendCrashReports->setChecked(settings->IsSendCrashReport());
|
||||
connect(ui->checkBoxSendCrashReports, &QCheckBox::stateChanged, this,
|
||||
[this]() { m_sendCrashReportsChanged = true; });
|
||||
|
||||
QRegularExpression const rx(QStringLiteral("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b"),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
ui->lineEditCrashUserEmail->setValidator(new QRegularExpressionValidator(rx, this));
|
||||
ui->lineEditCrashUserEmail->setText(settings->GetCrashEmail());
|
||||
connect(ui->lineEditCrashUserEmail, &QLineEdit::editingFinished, this,
|
||||
[this]() { m_crashUserEmailChanged = true; });
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -202,6 +217,22 @@ auto TapePreferencesConfigurationPage::Apply() -> QStringList
|
|||
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
|
||||
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
|
||||
|
||||
#if defined(CRASH_REPORTING)
|
||||
if (m_sendCrashReportsChanged)
|
||||
{
|
||||
settings->SeSendCrashReport(ui->checkBoxSendCrashReports->isChecked());
|
||||
m_sendCrashReportsChanged = false;
|
||||
preferences.append(tr("send crash report"));
|
||||
}
|
||||
|
||||
if (m_crashUserEmailChanged)
|
||||
{
|
||||
settings->SetCrashEmail(ui->lineEditCrashUserEmail->text());
|
||||
m_crashUserEmailChanged = false;
|
||||
preferences.append(tr("user email in case of crash"));
|
||||
}
|
||||
#endif
|
||||
|
||||
return preferences;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ private:
|
|||
std::unique_ptr<Ui::TapePreferencesConfigurationPage> ui;
|
||||
bool m_langChanged;
|
||||
bool m_systemChanged;
|
||||
bool m_sendCrashReportsChanged{false};
|
||||
bool m_crashUserEmailChanged{false};
|
||||
QList<QStringList> m_transientShortcuts{};
|
||||
|
||||
void RetranslateUi();
|
||||
|
|
|
@ -312,20 +312,73 @@
|
|||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
<widget class="QGroupBox" name="groupBox_10">
|
||||
<property name="title">
|
||||
<string>Usage statistic</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
<widget class="QGroupBox" name="groupBoxCrashReports">
|
||||
<property name="title">
|
||||
<string>Crash reports</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendCrashReports">
|
||||
<property name="text">
|
||||
<string>Send automatic crash reports</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Email:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditCrashUserEmail">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Reporting crash reports will help us make Valentina more reliable. All information is treated as confidential and is only used to improve future versions of this program. Please activate sending automatic crash reports and fill your email address (optional). If provided, we may contact you with additional information about the crash.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -35,6 +35,11 @@
|
|||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef CRASH_REPORTING
|
||||
#include "../vmisc/crashhandler/crashhandler.h"
|
||||
#include "version.h"
|
||||
#endif
|
||||
|
||||
// Fix bug in Qt. Deprecation warning in QMessageBox::critical.
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
#undef QT_REQUIRE_VERSION
|
||||
|
@ -79,6 +84,10 @@ auto main(int argc, char *argv[]) -> int
|
|||
Q_INIT_RESOURCE(win_light_theme); // NOLINT
|
||||
Q_INIT_RESOURCE(win_dark_theme); // NOLINT
|
||||
|
||||
#ifdef CRASH_REPORTING
|
||||
InitializeCrashpad(QStringLiteral(VER_PRODUCTNAME_STR).toLower());
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
VAbstractApplication::WinAttachConsole();
|
||||
#endif
|
||||
|
|
|
@ -18,12 +18,14 @@ VToolApp {
|
|||
|
||||
Depends {
|
||||
name: "xerces-c";
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && !buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 &&
|
||||
(!buildconfig.useConanPackages || (buildconfig.useConanPackages && !buildconfig.conanXercesEnabled))
|
||||
}
|
||||
|
||||
Depends {
|
||||
name: "conan.XercesC";
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages &&
|
||||
buildconfig.conanXercesEnabled
|
||||
}
|
||||
|
||||
// Explicitly link to libcrypto and libssl to avoid error: Failed to load libssl/libcrypto.
|
||||
|
@ -45,11 +47,17 @@ VToolApp {
|
|||
multibundle.targetApps: ["Valentina"]
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && qbs.targetOS.contains("macos") && buildconfig.enableMultiBundle
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanXercesEnabled && qbs.targetOS.contains("macos") && buildconfig.enableMultiBundle
|
||||
conan.XercesC.libInstallDir: qbs.installPrefix + "/" + buildconfig.installLibraryPath
|
||||
conan.XercesC.installLib: true
|
||||
}
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled && qbs.targetOS.contains("macos") && buildconfig.enableMultiBundle
|
||||
conan.crashpad.installBin: true
|
||||
conan.crashpad.binInstallDir: qbs.installPrefix + "/" + buildconfig.installBinaryPath
|
||||
}
|
||||
|
||||
files: [
|
||||
"main.cpp",
|
||||
"tkmmainwindow.cpp",
|
||||
|
|
|
@ -1513,15 +1513,20 @@ void TKMMainWindow::AskDefaultSettings()
|
|||
}
|
||||
}
|
||||
|
||||
if (settings->IsAskCollectStatistic())
|
||||
if (settings->IsAskCollectStatistic() || settings->IsAskSendCrashReport())
|
||||
{
|
||||
DialogAskCollectStatistic dialog(this);
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
settings->SetCollectStatistic(dialog.CollectStatistic());
|
||||
#if defined(CRASH_REPORTING)
|
||||
settings->SeSendCrashReport(dialog.SendCrashReport());
|
||||
settings->SetCrashEmail(dialog.UserEmail());
|
||||
#endif
|
||||
}
|
||||
|
||||
settings->SetAskCollectStatistic(false);
|
||||
settings->SetAskSendCrashReport(false);
|
||||
}
|
||||
|
||||
if (settings->IsCollectStatistic())
|
||||
|
|
|
@ -2777,15 +2777,20 @@ void TMainWindow::AskDefaultSettings()
|
|||
}
|
||||
}
|
||||
|
||||
if (settings->IsAskCollectStatistic())
|
||||
if (settings->IsAskCollectStatistic() || settings->IsAskSendCrashReport())
|
||||
{
|
||||
DialogAskCollectStatistic dialog(this);
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
settings->SetCollectStatistic(dialog.CollectStatistic());
|
||||
#if defined(CRASH_REPORTING)
|
||||
settings->SeSendCrashReport(dialog.SendCrashReport());
|
||||
settings->SetCrashEmail(dialog.UserEmail());
|
||||
#endif
|
||||
}
|
||||
|
||||
settings->SetAskCollectStatistic(false);
|
||||
settings->SetAskSendCrashReport(false);
|
||||
}
|
||||
|
||||
if (settings->IsCollectStatistic())
|
||||
|
|
|
@ -29,9 +29,11 @@
|
|||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#define VER_INTERNALNAME_STR "Tape" // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#define VER_ORIGINALFILENAME_STR "tape.exe" // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#define VER_PRODUCTNAME_STR "Tape" // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#define VER_FILEDESCRIPTION_STR "Valentina's measurements editor." // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#include "../../libs/vmisc/projectversion.h"
|
||||
|
||||
#define VER_INTERNALNAME_STR "Tape" // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#define VER_ORIGINALFILENAME_STR "tape.exe" // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#define VER_PRODUCTNAME_STR "Tape" // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#define VER_FILEDESCRIPTION_STR "Valentina's measurements editor." // NOLINT(cppcoreguidelines-macro-usage)
|
||||
|
||||
#endif // VERSION_H
|
||||
|
|
|
@ -92,8 +92,6 @@ Q_LOGGING_CATEGORY(vApp, "v.application") // NOLINT
|
|||
|
||||
QT_WARNING_POP
|
||||
|
||||
Q_DECL_CONSTEXPR auto DAYS_TO_KEEP_LOGS = 3;
|
||||
|
||||
namespace
|
||||
{
|
||||
auto AppFilePath(const QString &appName) -> QString
|
||||
|
@ -537,38 +535,13 @@ auto VApplication::PuzzleFilePath() -> QString
|
|||
return AppFilePath(appName);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VApplication::LogDirPath() -> QString
|
||||
{
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_OSX)
|
||||
const QString logDirPath =
|
||||
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString(), QStandardPaths::LocateDirectory) +
|
||||
"Valentina";
|
||||
#else
|
||||
const QString logDirPath =
|
||||
QStandardPaths::locate(QStandardPaths::ConfigLocation, QString(), QStandardPaths::LocateDirectory) +
|
||||
QCoreApplication::organizationName();
|
||||
#endif
|
||||
return logDirPath;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VApplication::LogPath() -> QString
|
||||
{
|
||||
// Keep in sync with VCrashPaths::GetAttachmentPath
|
||||
return QStringLiteral("%1/valentina-pid%2.log").arg(LogDirPath()).arg(applicationPid());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VApplication::CreateLogDir() -> bool
|
||||
{
|
||||
QDir const logDir(LogDirPath());
|
||||
if (not logDir.exists())
|
||||
{
|
||||
return logDir.mkpath(QChar('.')); // Create directory for log if need
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VApplication::BeginLogging()
|
||||
{
|
||||
|
@ -594,58 +567,6 @@ void VApplication::BeginLogging()
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VApplication::ClearOldLogs()
|
||||
{
|
||||
const QString workingDirectory = QDir::currentPath(); // Save the app working directory
|
||||
const QString logDirPath = LogDirPath();
|
||||
QDir logsDir(logDirPath);
|
||||
|
||||
if (!logsDir.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logsDir.setNameFilters(QStringList(QStringLiteral("*.log")));
|
||||
QDir::setCurrent(logDirPath);
|
||||
|
||||
// Restore working directory
|
||||
auto restore = qScopeGuard([workingDirectory] { QDir::setCurrent(workingDirectory); });
|
||||
|
||||
const QStringList allFiles = logsDir.entryList(QDir::NoDotAndDotDot | QDir::Files);
|
||||
if (allFiles.isEmpty())
|
||||
{
|
||||
qCDebug(vApp, "There are no old logs.");
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(vApp, "Clearing old logs");
|
||||
for (const auto &fn : allFiles)
|
||||
{
|
||||
QFileInfo const info(fn);
|
||||
const QDateTime created = info.birthTime();
|
||||
if (created.daysTo(QDateTime::currentDateTime()) >= DAYS_TO_KEEP_LOGS)
|
||||
{
|
||||
VLockGuard<QFile> const tmp(info.absoluteFilePath(), [&fn]() { return new QFile(fn); });
|
||||
if (tmp.GetProtected() != nullptr)
|
||||
{
|
||||
if (tmp.GetProtected()->remove())
|
||||
{
|
||||
qCDebug(vApp, "Deleted %s", qUtf8Printable(info.absoluteFilePath()));
|
||||
}
|
||||
else
|
||||
{
|
||||
qCDebug(vApp, "Could not delete %s", qUtf8Printable(info.absoluteFilePath()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qCDebug(vApp, "Failed to lock %s", qUtf8Printable(info.absoluteFilePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VApplication::InitOptions()
|
||||
{
|
||||
|
|
|
@ -101,11 +101,8 @@ private:
|
|||
VKnownMeasurementsDatabase *m_knownMeasurementsDatabase{nullptr};
|
||||
QFileSystemWatcher *m_knownMeasurementsDatabaseWatcher{nullptr};
|
||||
|
||||
static auto LogDirPath() -> QString;
|
||||
static auto LogPath() -> QString;
|
||||
static auto CreateLogDir() -> bool;
|
||||
void BeginLogging();
|
||||
static void ClearOldLogs();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -176,6 +176,21 @@ PreferencesConfigurationPage::PreferencesConfigurationPage(QWidget *parent)
|
|||
|
||||
// Tab Privacy
|
||||
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
|
||||
|
||||
#if !defined(CRASH_REPORTING)
|
||||
ui->groupBoxCrashReports->setDisabled(true);
|
||||
#endif
|
||||
|
||||
ui->checkBoxSendCrashReports->setChecked(settings->IsSendCrashReport());
|
||||
connect(ui->checkBoxSendCrashReports, &QCheckBox::stateChanged, this,
|
||||
[this]() { m_sendCrashReportsChanged = true; });
|
||||
|
||||
QRegularExpression const rx(QStringLiteral("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b"),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
ui->lineEditCrashUserEmail->setValidator(new QRegularExpressionValidator(rx, this));
|
||||
ui->lineEditCrashUserEmail->setText(settings->GetCrashEmail());
|
||||
connect(ui->lineEditCrashUserEmail, &QLineEdit::editingFinished, this,
|
||||
[this]() { m_crashUserEmailChanged = true; });
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -306,6 +321,22 @@ auto PreferencesConfigurationPage::Apply() -> QStringList
|
|||
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
|
||||
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
|
||||
|
||||
#if defined(CRASH_REPORTING)
|
||||
if (m_sendCrashReportsChanged)
|
||||
{
|
||||
settings->SeSendCrashReport(ui->checkBoxSendCrashReports->isChecked());
|
||||
m_sendCrashReportsChanged = false;
|
||||
preferences.append(tr("send crash report"));
|
||||
}
|
||||
|
||||
if (m_crashUserEmailChanged)
|
||||
{
|
||||
settings->SetCrashEmail(ui->lineEditCrashUserEmail->text());
|
||||
m_crashUserEmailChanged = false;
|
||||
preferences.append(tr("user email in case of crash"));
|
||||
}
|
||||
#endif
|
||||
|
||||
return preferences;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ private:
|
|||
bool m_pieceLabelLangChanged{false};
|
||||
bool m_unitChanged{false};
|
||||
bool m_labelLangChanged{false};
|
||||
bool m_sendCrashReportsChanged{false};
|
||||
bool m_crashUserEmailChanged{false};
|
||||
QList<QStringList> m_transientShortcuts{};
|
||||
|
||||
void SetLabelComboBox(const QStringList &list);
|
||||
|
|
|
@ -661,22 +661,75 @@
|
|||
<attribute name="title">
|
||||
<string>Privacy</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
<widget class="QGroupBox" name="groupBox_10">
|
||||
<property name="title">
|
||||
<string>Usage statistic</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
<widget class="QGroupBox" name="groupBoxCrashReports">
|
||||
<property name="title">
|
||||
<string>Crash reports</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendCrashReports">
|
||||
<property name="text">
|
||||
<string>Send automatic crash reports</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Email:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditCrashUserEmail">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Reporting crash reports will help us make Valentina more reliable. All information is treated as confidential and is only used to improve future versions of this program. Please activate sending automatic crash reports and fill your email address (optional). If provided, we may contact you with additional information about the crash.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef CRASH_REPORTING
|
||||
#include "../vmisc/crashhandler/crashhandler.h"
|
||||
#include "version.h"
|
||||
#endif
|
||||
|
||||
// Fix bug in Qt. Deprecation warning in QMessageBox::critical.
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
#undef QT_REQUIRE_VERSION
|
||||
|
@ -69,7 +74,6 @@
|
|||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
auto main(int argc, char *argv[]) -> int
|
||||
{
|
||||
Q_INIT_RESOURCE(cursor); // NOLINT
|
||||
|
@ -88,6 +92,10 @@ auto main(int argc, char *argv[]) -> int
|
|||
Q_INIT_RESOURCE(win_light_theme); // NOLINT
|
||||
Q_INIT_RESOURCE(win_dark_theme); // NOLINT
|
||||
|
||||
#ifdef CRASH_REPORTING
|
||||
InitializeCrashpad(QStringLiteral(VER_PRODUCTNAME_STR).toLower());
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
VAbstractApplication::WinAttachConsole();
|
||||
#endif
|
||||
|
|
|
@ -4930,15 +4930,20 @@ void MainWindow::AskDefaultSettings()
|
|||
}
|
||||
}
|
||||
|
||||
if (settings->IsAskCollectStatistic())
|
||||
if (settings->IsAskCollectStatistic() || settings->IsAskSendCrashReport())
|
||||
{
|
||||
DialogAskCollectStatistic dialog(this);
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
settings->SetCollectStatistic(dialog.CollectStatistic());
|
||||
#if defined(CRASH_REPORTING)
|
||||
settings->SeSendCrashReport(dialog.SendCrashReport());
|
||||
settings->SetCrashEmail(dialog.UserEmail());
|
||||
#endif
|
||||
}
|
||||
|
||||
settings->SetAskCollectStatistic(false);
|
||||
settings->SetAskSendCrashReport(false);
|
||||
}
|
||||
|
||||
if (settings->IsCollectStatistic())
|
||||
|
|
|
@ -51,7 +51,7 @@ VToolApp {
|
|||
type: base.concat("install_root_svg_fonts")
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && (qbs.targetOS.contains("windows") || qbs.targetOS.contains("macos"))
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanXercesEnabled && (qbs.targetOS.contains("windows") || qbs.targetOS.contains("macos"))
|
||||
conan.XercesC.libInstallDir: qbs.installPrefix + "/" + buildconfig.installLibraryPath
|
||||
conan.XercesC.binInstallDir: qbs.installPrefix + "/" + buildconfig.installBinaryPath
|
||||
conan.XercesC.installLib: {
|
||||
|
@ -66,6 +66,12 @@ VToolApp {
|
|||
}
|
||||
}
|
||||
|
||||
Properties {
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
conan.crashpad.installBin: true
|
||||
conan.crashpad.binInstallDir: qbs.installPrefix + "/" + buildconfig.installBinaryPath
|
||||
}
|
||||
|
||||
files: [
|
||||
"main.cpp",
|
||||
"mainwindow.cpp",
|
||||
|
|
|
@ -11,12 +11,14 @@ VLib {
|
|||
|
||||
Depends {
|
||||
name: "xerces-c"
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && !buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 &&
|
||||
(!buildconfig.useConanPackages || (buildconfig.useConanPackages && !buildconfig.conanXercesEnabled))
|
||||
}
|
||||
|
||||
Depends {
|
||||
name: "conan.XercesC"
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages &&
|
||||
buildconfig.conanXercesEnabled
|
||||
}
|
||||
|
||||
name: "IFCLib"
|
||||
|
@ -102,8 +104,11 @@ VLib {
|
|||
Depends { name: "cpp" }
|
||||
Depends { name: "Qt"; submodules: ["core", "xml"] }
|
||||
Depends { name: "VMiscLib" }
|
||||
Depends { name: "xerces-c"; condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && !buildconfig.useConanPackages }
|
||||
Depends { name: "conan.XercesC"; condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages }
|
||||
Depends { name: "xerces-c"; condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 &&
|
||||
(!buildconfig.useConanPackages ||
|
||||
(buildconfig.useConanPackages && !buildconfig.conanXercesEnabled)) }
|
||||
Depends { name: "conan.XercesC"; condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 &&
|
||||
buildconfig.useConanPackages && buildconfig.conanXercesEnabled }
|
||||
cpp.includePaths: [exportingProduct.sourceDirectory]
|
||||
}
|
||||
}
|
||||
|
|
251
src/libs/vmisc/crashhandler/crashhandler.cpp
Normal file
251
src/libs/vmisc/crashhandler/crashhandler.cpp
Normal file
|
@ -0,0 +1,251 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file crashhandler.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 4 3, 2024
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2024 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#include "crashhandler.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
#include <QDir>
|
||||
#include <QMap>
|
||||
#include <unistd.h>
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y)) // NOLINT
|
||||
#endif
|
||||
|
||||
#include <client/crash_report_database.h>
|
||||
#include <client/crashpad_client.h>
|
||||
#include <client/settings.h>
|
||||
|
||||
#include "vcrashpaths.h"
|
||||
|
||||
#include "../projectversion.h"
|
||||
#include "../vcommonsettings.h"
|
||||
|
||||
#if defined(APPIMAGE) && defined(Q_OS_LINUX)
|
||||
#include "../appimage.h"
|
||||
#endif
|
||||
|
||||
#include <vcsRepoState.h>
|
||||
|
||||
using namespace base;
|
||||
using namespace crashpad;
|
||||
|
||||
namespace
|
||||
{
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
Q_REQUIRED_RESULT auto AppSettings(const QString &appName) -> VCommonSettings *
|
||||
{
|
||||
return new VCommonSettings(QSettings::IniFormat, QSettings::UserScope, QStringLiteral(VER_COMPANYNAME_STR),
|
||||
appName);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto AppCrashVersion() -> QString
|
||||
{
|
||||
QString const version = QStringLiteral("%1_%2_%3").arg(MAJOR_VERSION).arg(MINOR_VERSION).arg(DEBUG_VERSION);
|
||||
QString const qtVersion = QStringLiteral("Qt_%1_%2").arg(QT_VERSION_MAJOR).arg(QT_VERSION_MINOR);
|
||||
|
||||
#if defined(Q_OS_MACOS)
|
||||
QString const platform = QStringLiteral("macos");
|
||||
#elif defined(Q_OS_WIN)
|
||||
QString const platform = QStringLiteral("windows");
|
||||
#elif defined(Q_OS_LINUX)
|
||||
QString const platform = QStringLiteral("linux");
|
||||
#else
|
||||
QString const platform = QStringLiteral("unknown");
|
||||
#endif
|
||||
|
||||
return QStringLiteral("%1-%2-%3-%4").arg(version, VCS_REPO_STATE_REVISION, qtVersion, platform);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto GetExecutableDir() -> QString
|
||||
{
|
||||
#if defined(Q_OS_MAC)
|
||||
unsigned int bufferSize = 512;
|
||||
std::vector<char> buffer(bufferSize + 1);
|
||||
|
||||
if (_NSGetExecutablePath(&buffer[0], &bufferSize))
|
||||
{
|
||||
buffer.resize(bufferSize);
|
||||
_NSGetExecutablePath(&buffer[0], &bufferSize);
|
||||
}
|
||||
|
||||
char *lastForwardSlash = strrchr(&buffer[0], '/');
|
||||
if (lastForwardSlash == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
*lastForwardSlash = 0;
|
||||
|
||||
return &buffer[0];
|
||||
#elif defined(Q_OS_WINDOWS)
|
||||
HMODULE hModule = GetModuleHandleW(NULL);
|
||||
WCHAR path[MAX_PATH];
|
||||
DWORD retVal = GetModuleFileNameW(hModule, path, MAX_PATH);
|
||||
if (retVal == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wchar_t *lastBackslash = wcsrchr(path, '\\');
|
||||
if (lastBackslash == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
*lastBackslash = 0;
|
||||
|
||||
return QString::fromWCharArray(path);
|
||||
#elif defined(Q_OS_LINUX)
|
||||
char pBuf[FILENAME_MAX];
|
||||
int len = sizeof(pBuf);
|
||||
int bytes = MIN(static_cast<int>(readlink("/proc/self/exe", pBuf, static_cast<size_t>(len))), len - 1);
|
||||
if (bytes >= 0)
|
||||
{
|
||||
pBuf[bytes] = '\0';
|
||||
}
|
||||
|
||||
char *lastForwardSlash = strrchr(&pBuf[0], '/');
|
||||
if (lastForwardSlash == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
*lastForwardSlash = '\0';
|
||||
|
||||
return QString::fromStdString(pBuf);
|
||||
#else
|
||||
#error GetExecutableDir not implemented on this platform
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto InitializeCrashpad(const QString &appName) -> bool
|
||||
{
|
||||
QScopedPointer<VCommonSettings> const appSettings(AppSettings(appName));
|
||||
|
||||
if (!appSettings->IsSendCrashReport())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get directory where the exe lives so we can pass a full path to handler, reportsDir and metricsDir
|
||||
#if defined(APPIMAGE) && defined(Q_OS_LINUX)
|
||||
QString const exeDir = AppImageRoot(GetExecutableDir(), QString(BINDIR));
|
||||
#else
|
||||
QString const exeDir = GetExecutableDir();
|
||||
#endif
|
||||
|
||||
// Helper class for cross-platform file systems
|
||||
VCrashPaths crashpadPaths(exeDir);
|
||||
|
||||
auto MakeDir = [](const QString &path)
|
||||
{
|
||||
QDir const directory(path);
|
||||
if (not directory.exists())
|
||||
{
|
||||
directory.mkpath(QChar('.'));
|
||||
}
|
||||
};
|
||||
|
||||
// Directory where reports will be saved. Important! Must be writable or crashpad_handler will crash.
|
||||
QString const reportsPath = VCrashPaths::GetReportsPath();
|
||||
MakeDir(reportsPath);
|
||||
FilePath const reportsDir(VCrashPaths::GetPlatformString(reportsPath));
|
||||
|
||||
// Initialize crashpad database
|
||||
std::unique_ptr<CrashReportDatabase> database = CrashReportDatabase::Initialize(reportsDir);
|
||||
if (database == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enable automated crash uploads
|
||||
Settings *settings = database->GetSettings();
|
||||
if (settings == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
settings->SetUploadsEnabled(true);
|
||||
|
||||
// Attachments to be uploaded alongside the crash - default bundle size limit is 20MB
|
||||
std::vector<FilePath> attachments;
|
||||
FilePath const attachment(VCrashPaths::GetPlatformString(VCrashPaths::GetAttachmentPath(appName)));
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX)
|
||||
// Crashpad hasn't implemented attachments on OS X yet
|
||||
attachments.push_back(attachment);
|
||||
#endif
|
||||
|
||||
// Ensure that crashpad_handler is shipped with your application
|
||||
FilePath const handler(VCrashPaths::GetPlatformString(crashpadPaths.GetHandlerPath()));
|
||||
|
||||
// Directory where metrics will be saved. Important! Must be writable or crashpad_handler will crash.
|
||||
QString const metricsPath = VCrashPaths::GetMetricsPath();
|
||||
MakeDir(metricsPath);
|
||||
FilePath const metricsDir(VCrashPaths::GetPlatformString(metricsPath));
|
||||
|
||||
QString const dbName = QStringLiteral("valentina");
|
||||
// Configure url with your BugSplat database
|
||||
QString const url = QStringLiteral("https://%1.bugsplat.com/post/bp/crash/crashpad.php").arg(dbName);
|
||||
|
||||
// Metadata that will be posted to BugSplat
|
||||
QMap<std::string, std::string> annotations;
|
||||
annotations["format"] = "minidump"; // Required: Crashpad setting to save crash as a minidump
|
||||
annotations["database"] = dbName.toStdString(); // Required: BugSplat database
|
||||
annotations["product"] = appName.toStdString(); // Required: BugSplat appName
|
||||
annotations["version"] = AppCrashVersion().toStdString(); // Required: BugSplat appVersion
|
||||
|
||||
QString clientID = appSettings->GetClientID();
|
||||
if (clientID.isEmpty())
|
||||
{
|
||||
clientID = QUuid::createUuid().toString();
|
||||
appSettings->SetClientID(clientID);
|
||||
}
|
||||
annotations["key"] = clientID.toStdString(); // Optional: BugSplat key field
|
||||
|
||||
QString const userEmail = appSettings->GetCrashEmail();
|
||||
if (!userEmail.isEmpty())
|
||||
{
|
||||
annotations["user"] = userEmail.toStdString(); // Optional: BugSplat user email
|
||||
}
|
||||
|
||||
// Disable crashpad rate limiting so that all crashes have dmp files
|
||||
std::vector<std::string> arguments;
|
||||
arguments.emplace_back("--no-rate-limit");
|
||||
|
||||
// Start crash handler
|
||||
auto *client = new CrashpadClient();
|
||||
return client->StartHandler(handler, reportsDir, metricsDir, url.toStdString(), annotations.toStdMap(), arguments,
|
||||
true, true, attachments);
|
||||
}
|
35
src/libs/vmisc/crashhandler/crashhandler.h
Normal file
35
src/libs/vmisc/crashhandler/crashhandler.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file crashhandler.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 4 3, 2024
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2024 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#ifndef CRASHHANDLER_H
|
||||
#define CRASHHANDLER_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
auto InitializeCrashpad(const QString &appName) -> bool;
|
||||
|
||||
#endif // CRASHHANDLER_H
|
91
src/libs/vmisc/crashhandler/vcrashpaths.cpp
Normal file
91
src/libs/vmisc/crashhandler/vcrashpaths.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vcrashpaths.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 4 3, 2024
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2024 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <utility>
|
||||
|
||||
#include "../projectversion.h"
|
||||
#include "vcrashpaths.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
VCrashPaths::VCrashPaths(QString exeDir)
|
||||
: m_exeDir(std::move(exeDir))
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VCrashPaths::GetAttachmentPath(const QString &appName) -> QString
|
||||
{
|
||||
const QString logDirPath =
|
||||
QStandardPaths::locate(QStandardPaths::ConfigLocation, QString(), QStandardPaths::LocateDirectory) +
|
||||
QStringLiteral(VER_COMPANYNAME_STR);
|
||||
return QStringLiteral("%1/%2-pid%3.log").arg(logDirPath, appName.toLower()).arg(QCoreApplication::applicationPid());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VCrashPaths::GetHandlerPath() -> QString
|
||||
{
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
const QString handler = QStringLiteral("crashpad_handler.exe");
|
||||
#elif defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
||||
const QString handler = QStringLiteral("crashpad_handler");
|
||||
#else
|
||||
#error GetHandlerPath not implemented on this platform
|
||||
#endif
|
||||
return m_exeDir + QDir::separator() + handler;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VCrashPaths::GetReportsPath() -> QString
|
||||
{
|
||||
return QStandardPaths::locate(QStandardPaths::AppConfigLocation, QString(), QStandardPaths::LocateDirectory) +
|
||||
QStringList{VER_COMPANYNAME_STR, "User Data", "Crashpad", "Reports"}.join(QDir::separator());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VCrashPaths::GetMetricsPath() -> QString
|
||||
{
|
||||
return QStandardPaths::locate(QStandardPaths::AppConfigLocation, QString(), QStandardPaths::LocateDirectory) +
|
||||
QStringList{VER_COMPANYNAME_STR, "User Data", "Crashpad", "Metrics"}.join(QDir::separator());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
#if defined(Q_OS_UNIX)
|
||||
auto VCrashPaths::GetPlatformString(const QString &string) -> std::string
|
||||
{
|
||||
return string.toStdString();
|
||||
}
|
||||
#elif defined(Q_OS_WINDOWS)
|
||||
auto VCrashPaths::GetPlatformString(const QString &string) -> std::wstring
|
||||
{
|
||||
return string.toStdWString();
|
||||
}
|
||||
#else
|
||||
#error GetPlatformString not implemented on this platform
|
||||
#endif
|
56
src/libs/vmisc/crashhandler/vcrashpaths.h
Normal file
56
src/libs/vmisc/crashhandler/vcrashpaths.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file vcrashpaths.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 4 3, 2024
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2024 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#ifndef VCRASHPATHS_H
|
||||
#define VCRASHPATHS_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class VCrashPaths
|
||||
{
|
||||
public:
|
||||
explicit VCrashPaths(QString exeDir);
|
||||
|
||||
auto GetHandlerPath() -> QString;
|
||||
|
||||
static auto GetAttachmentPath(const QString &appName) -> QString;
|
||||
static auto GetReportsPath() -> QString;
|
||||
static auto GetMetricsPath() -> QString;
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
static auto GetPlatformString(const QString &string) -> std::string;
|
||||
#elif defined(Q_OS_WINDOWS)
|
||||
static auto GetPlatformString(QString string) -> std::wstring;
|
||||
#else
|
||||
#error GetPlatformString not implemented on this platform
|
||||
#endif
|
||||
|
||||
private:
|
||||
QString m_exeDir;
|
||||
};
|
||||
|
||||
#endif // VCRASHPATHS_H
|
|
@ -28,12 +28,28 @@
|
|||
#include "dialogaskcollectstatistic.h"
|
||||
#include "ui_dialogaskcollectstatistic.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionValidator>
|
||||
|
||||
#include "../vabstractapplication.h"
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogAskCollectStatistic::DialogAskCollectStatistic(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::DialogAskCollectStatistic)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
#if !defined(CRASH_REPORTING)
|
||||
ui->groupBoxCrashReports->setDisabled(true);
|
||||
#endif
|
||||
|
||||
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
|
||||
|
||||
QRegularExpression const rx(QStringLiteral("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b"),
|
||||
QRegularExpression::CaseInsensitiveOption);
|
||||
ui->lineEditCrashUserEmail->setValidator(new QRegularExpressionValidator(rx, this));
|
||||
ui->lineEditCrashUserEmail->setText(settings->GetCrashEmail());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -43,7 +59,19 @@ DialogAskCollectStatistic::~DialogAskCollectStatistic()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto DialogAskCollectStatistic::CollectStatistic() -> bool
|
||||
auto DialogAskCollectStatistic::CollectStatistic() const -> bool
|
||||
{
|
||||
return ui->checkBoxSendUsageStatistics->isChecked();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto DialogAskCollectStatistic::SendCrashReport() const -> bool
|
||||
{
|
||||
return ui->checkBoxSendCrashReports->isChecked();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto DialogAskCollectStatistic::UserEmail() const -> QString
|
||||
{
|
||||
return ui->lineEditCrashUserEmail->text();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,9 @@ public:
|
|||
explicit DialogAskCollectStatistic(QWidget *parent = nullptr);
|
||||
~DialogAskCollectStatistic() override;
|
||||
|
||||
auto CollectStatistic() -> bool;
|
||||
auto CollectStatistic() const -> bool;
|
||||
auto SendCrashReport() const -> bool;
|
||||
auto UserEmail() const -> QString;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(DialogAskCollectStatistic) // NOLINT
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>376</width>
|
||||
<height>183</height>
|
||||
<width>593</width>
|
||||
<height>406</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -19,23 +19,79 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
<widget class="QGroupBox" name="groupBox_12">
|
||||
<property name="title">
|
||||
<string>Usage statistic</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||
<property name="text">
|
||||
<string>Send usage statistics</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
<widget class="QGroupBox" name="groupBoxCrashReports">
|
||||
<property name="title">
|
||||
<string>Crash reports</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSendCrashReports">
|
||||
<property name="text">
|
||||
<string>Send automatic crash reports</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Email:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditCrashUserEmail">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Reporting crash reports will help us make Valentina more reliable. All information is treated as confidential and is only used to improve future versions of this program. Please activate sending automatic crash reports and fill your email address (optional). If provided, we may contact you with additional information about the crash.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -58,7 +58,7 @@ constexpr inline auto AppVersion() -> unsigned
|
|||
#define VER_PRODUCTVERSION VER_FILEVERSION
|
||||
#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
|
||||
|
||||
#define VER_COMPANYNAME_STR "ValentinaTeam"
|
||||
#define VER_COMPANYNAME_STR "Valentina"
|
||||
// #define VER_FILEDESCRIPTION_STR "Patternmaking program." // Defined in program
|
||||
// #define VER_INTERNALNAME_STR "Valentina" // Defined in program
|
||||
#define VER_LEGALCOPYRIGHT_STR "Copyright © 2014-2022 Valentina Team"
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "compatibility.h"
|
||||
#include "svgfont/vsvgfontdatabase.h"
|
||||
#include "vlockguard.h"
|
||||
#include "vtranslator.h"
|
||||
|
||||
#include "QtConcurrent/qtconcurrentrun.h"
|
||||
|
@ -67,6 +68,8 @@ using namespace Qt::Literals::StringLiterals;
|
|||
|
||||
namespace
|
||||
{
|
||||
Q_DECL_CONSTEXPR auto DAYS_TO_KEEP_LOGS = 3;
|
||||
|
||||
auto FilterLocales(const QStringList &locales) -> QStringList
|
||||
{
|
||||
QStringList filtered;
|
||||
|
@ -625,3 +628,75 @@ void VAbstractApplication::InitHighDpiScaling(int argc, char *argv[])
|
|||
Q_UNUSED(argv);
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractApplication::LogDirPath() -> QString
|
||||
{
|
||||
const QString logDirPath =
|
||||
QStandardPaths::locate(QStandardPaths::ConfigLocation, QString(), QStandardPaths::LocateDirectory) +
|
||||
QCoreApplication::organizationName();
|
||||
return logDirPath;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VAbstractApplication::CreateLogDir() -> bool
|
||||
{
|
||||
QDir const logDir(LogDirPath());
|
||||
if (not logDir.exists())
|
||||
{
|
||||
return logDir.mkpath(QChar('.')); // Create directory for log if need
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VAbstractApplication::ClearOldLogs()
|
||||
{
|
||||
const QString workingDirectory = QDir::currentPath(); // Save the app working directory
|
||||
const QString logDirPath = LogDirPath();
|
||||
QDir logsDir(logDirPath);
|
||||
|
||||
if (!logsDir.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logsDir.setNameFilters(QStringList(QStringLiteral("*.log")));
|
||||
QDir::setCurrent(logDirPath);
|
||||
|
||||
// Restore working directory
|
||||
auto restore = qScopeGuard([workingDirectory] { QDir::setCurrent(workingDirectory); });
|
||||
|
||||
const QStringList allFiles = logsDir.entryList(QDir::NoDotAndDotDot | QDir::Files);
|
||||
if (allFiles.isEmpty())
|
||||
{
|
||||
qDebug("There are no old logs.");
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("Clearing old logs");
|
||||
for (const auto &fn : allFiles)
|
||||
{
|
||||
QFileInfo const info(fn);
|
||||
const QDateTime created = info.birthTime();
|
||||
if (created.daysTo(QDateTime::currentDateTime()) >= DAYS_TO_KEEP_LOGS)
|
||||
{
|
||||
VLockGuard<QFile> const tmp(info.absoluteFilePath(), [&fn]() { return new QFile(fn); });
|
||||
if (tmp.GetProtected() != nullptr)
|
||||
{
|
||||
if (tmp.GetProtected()->remove())
|
||||
{
|
||||
qDebug("Deleted %s", qUtf8Printable(info.absoluteFilePath()));
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("Could not delete %s", qUtf8Printable(info.absoluteFilePath()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("Failed to lock %s", qUtf8Printable(info.absoluteFilePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,10 @@ public:
|
|||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays, modernize-avoid-c-arrays)
|
||||
static void InitHighDpiScaling(int argc, char *argv[]);
|
||||
|
||||
static auto LogDirPath() -> QString;
|
||||
static auto CreateLogDir() -> bool;
|
||||
static void ClearOldLogs();
|
||||
|
||||
protected:
|
||||
QUndoStack *undoStack;
|
||||
|
||||
|
|
|
@ -131,6 +131,13 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingConfigurationInteractiveTools, (
|
|||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingConfigurationDontUseNativeDialog,
|
||||
("configuration/dontUseNativeDialog"_L1))
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingsConfigurationCrashEmail, ("configuration/crashEmail"_L1)) // NOLINT
|
||||
// NOLINTNEXTLINE
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingsConfigurationSendCrashReport, ("configuration/sendCrashReport"_L1))
|
||||
// NOLINTNEXTLINE
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingsConfigurationAskSendCrashReport,
|
||||
("configuration/askSendCrashReport"_L1))
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternUndo, ("pattern/undo"_L1)) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternForbidFlipping, ("pattern/forbidFlipping"_L1)) // NOLINT
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPatternForceFlipping, ("pattern/forceFlipping"_L1)) // NOLINT
|
||||
|
@ -1698,3 +1705,48 @@ void VCommonSettings::SetActionShortcuts(const QString &name, const QStringList
|
|||
settings.setValue(name, shortcuts);
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VCommonSettings::GetCrashEmail() const -> QString
|
||||
{
|
||||
QSettings const settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||
return settings.value(*settingsConfigurationCrashEmail, QString()).toString();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VCommonSettings::SetCrashEmail(const QString &value)
|
||||
{
|
||||
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||
settings.setValue(*settingsConfigurationCrashEmail, value);
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VCommonSettings::IsSendCrashReport() const -> bool
|
||||
{
|
||||
QSettings const settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||
return settings.value(*settingsConfigurationSendCrashReport, 1).toBool();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VCommonSettings::SeSendCrashReport(bool value)
|
||||
{
|
||||
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||
settings.setValue(*settingsConfigurationSendCrashReport, value);
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto VCommonSettings::IsAskSendCrashReport() const -> bool
|
||||
{
|
||||
QSettings const settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||
return settings.value(*settingsConfigurationAskSendCrashReport, 1).toBool();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void VCommonSettings::SetAskSendCrashReport(bool value)
|
||||
{
|
||||
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||
settings.setValue(*settingsConfigurationAskSendCrashReport, value);
|
||||
settings.sync();
|
||||
}
|
||||
|
|
|
@ -349,6 +349,15 @@ public:
|
|||
auto GetActionShortcuts(const QString &name, const QStringList &defaultShortcuts) -> QStringList;
|
||||
void SetActionShortcuts(const QString &name, const QStringList &shortcuts);
|
||||
|
||||
auto GetCrashEmail() const -> QString;
|
||||
void SetCrashEmail(const QString &value);
|
||||
|
||||
auto IsSendCrashReport() const -> bool;
|
||||
void SeSendCrashReport(bool value);
|
||||
|
||||
auto IsAskSendCrashReport() const -> bool;
|
||||
void SetAskSendCrashReport(bool value);
|
||||
|
||||
signals:
|
||||
void SVGFontsPathChanged(const QString &oldPath, const QString &newPath);
|
||||
void KnownMeasurementsPathChanged(const QString &oldPath, const QString &newPath);
|
||||
|
|
|
@ -2,6 +2,12 @@ import qbs.Utilities
|
|||
|
||||
VLib {
|
||||
Depends { name: "Qt"; submodules: ["core", "printsupport", "gui", "widgets"] }
|
||||
Depends { name: "buildconfig" }
|
||||
|
||||
Depends {
|
||||
name: "conan.crashpad";
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
}
|
||||
|
||||
name: "VMiscLib"
|
||||
files: {
|
||||
|
@ -178,9 +184,25 @@ VLib {
|
|||
condition: qbs.targetOS.contains("macos")
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "crashhandler"
|
||||
prefix: "crashhandler/"
|
||||
files: [
|
||||
"crashhandler.h",
|
||||
"crashhandler.cpp",
|
||||
"vcrashpaths.cpp",
|
||||
"vcrashpaths.h",
|
||||
]
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
}
|
||||
|
||||
Export {
|
||||
Depends { name: "cpp" }
|
||||
Depends { name: "Qt"; submodules: ["printsupport", "widgets"] }
|
||||
Depends {
|
||||
name: "conan.crashpad";
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
}
|
||||
cpp.includePaths: [exportingProduct.sourceDirectory]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
VDynamicLib {
|
||||
Depends { name: "Qt"; submodules: ["gui", "widgets"] }
|
||||
Depends { name: "VMiscLib" }
|
||||
Depends { name: "IFCLib" }
|
||||
Depends { name: "multibundle"; }
|
||||
|
||||
name: "VPropertyExplorerLib"
|
||||
|
|
|
@ -10,14 +10,20 @@ VTestApp {
|
|||
|
||||
Depends {
|
||||
name: "xerces-c"
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && !buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 &&
|
||||
(!buildconfig.useConanPackages || (buildconfig.useConanPackages && !buildconfig.conanXercesEnabled))
|
||||
}
|
||||
|
||||
Depends {
|
||||
name: "conan.XercesC"
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages &&
|
||||
buildconfig.conanXercesEnabled
|
||||
}
|
||||
|
||||
Depends {
|
||||
name: "conan.crashpad";
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
}
|
||||
|
||||
name: "CollectionTest"
|
||||
buildconfig.appTarget: qbs.targetOS.contains("macos") ? "CollectionTest" : "collectionTest"
|
||||
|
|
|
@ -9,12 +9,19 @@ VTestApp {
|
|||
|
||||
Depends {
|
||||
name: "xerces-c"
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && !buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 &&
|
||||
(!buildconfig.useConanPackages || (buildconfig.useConanPackages && !buildconfig.conanXercesEnabled))
|
||||
}
|
||||
|
||||
Depends {
|
||||
name: "conan.XercesC"
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages
|
||||
condition: Utilities.versionCompare(Qt.core.version, "6") >= 0 && buildconfig.useConanPackages &&
|
||||
buildconfig.conanXercesEnabled
|
||||
}
|
||||
|
||||
Depends {
|
||||
name: "conan.crashpad";
|
||||
condition: buildconfig.useConanPackages && buildconfig.conanCrashReportingEnabled
|
||||
}
|
||||
|
||||
name: "TranslationsTest"
|
||||
|
|
|
@ -4,10 +4,12 @@ import "qbs/imports/conan/ConanfileProbe.qbs" as ConanfileProbe
|
|||
|
||||
Project {
|
||||
name: "Valentina"
|
||||
minimumQbsVersion: "1.21"
|
||||
minimumQbsVersion: "1.22"
|
||||
qbsModuleProviders: ["Qt", "conan", "qbspkgconfig"]
|
||||
|
||||
property bool enableConan: false
|
||||
property bool conanWithXerces: false
|
||||
property bool conanWithCrashReporting: false
|
||||
property string minimumMacosVersion: undefined
|
||||
property string minimumQtVersion: "5.15"
|
||||
property stringList conanProfiles: []
|
||||
|
@ -16,10 +18,19 @@ Project {
|
|||
// Temporary probe until qbs doesn't support conan 2.0
|
||||
ConanfileProbe {
|
||||
id: thirdPartyConanPackages
|
||||
condition: enableConan
|
||||
condition: enableConan && (conanWithXerces || conanWithCrashReporting)
|
||||
conanfilePath: project.sourceDirectory + "/conanfile.py"
|
||||
verbose: true
|
||||
profiles: conanProfiles
|
||||
options: {
|
||||
var o = {};
|
||||
if (conanWithXerces)
|
||||
o.with_xerces = "True";
|
||||
|
||||
if (conanWithCrashReporting)
|
||||
o.with_crash_reporting = "True";
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
references: [
|
||||
|
|
Loading…
Reference in New Issue
Block a user