Compare commits

...

21 Commits

Author SHA1 Message Date
Roman Telezhynskyi ee109cd303 Build crash report on Windows only with MSVC. 2024-03-21 18:05:22 +02:00
Roman Telezhynskyi 73dae25d8a Fix build on Windows. 2024-03-21 18:04:37 +02:00
Roman Telezhynskyi 08a0f54249 Ignore certificate import error. 2024-03-21 17:23:25 +02:00
Roman Telezhynskyi 09730f8a53 Switch to dump_syms from mozilla project. 2024-03-21 17:18:10 +02:00
Roman Telezhynskyi 6d26411500 Improve ConanfileProbe.
Add remote option.
2024-03-21 15:21:45 +02:00
Roman Telezhynskyi f9f61069fe Make .bak files hidden on Unix systems. 2024-03-18 11:37:43 +02:00
Roman Telezhynskyi abd382ff97 Avoid writing optional data. 2024-03-16 15:32:41 +02:00
Roman Telezhynskyi 75c329a08e Refactoring.
Code style.
2024-03-16 15:32:41 +02:00
Roman Telezhynskyi 62efe1dd8a Fix width of box notch. 2024-03-16 15:32:41 +02:00
Roman Telezhynskyi 6ebd9e7033 Improve compatibility with Richpeace CAD. 2024-03-16 15:32:41 +02:00
Roman Telezhynskyi 4d849163fb Refactoring.
Code style.
2024-03-14 13:35:48 +02:00
Roman Telezhynskyi 3dfc62e99a New dialog to improve user experience.
Most users don't understand how to work with new known measurements system. This dialog should help them.
2024-03-14 13:35:28 +02:00
Roman Telezhynskyi 47fd57113e Fix Tape crash. 2024-03-14 10:12:14 +02:00
Roman Telezhynskyi 78d878322d Fix incorrect piece geometry refresh if disable a mirror line.
Fold line still visible.
2024-03-13 16:26:10 +02:00
Roman Telezhynskyi 24d39bffb7 Save logs for Tape and Puzzle apps in log file on disk for sending with crash reports. 2024-03-13 15:45:28 +02:00
Roman Telezhynskyi eb4f8719f2 Fix Puzzle's crash. 2024-03-13 15:11:56 +02:00
Roman Telezhynskyi 88cee6b7a7 Issue with QT_REQUIRE_VERSION macro has been fixes since Qt 6.6. 2024-03-12 18:41:13 +02:00
Roman Telezhynskyi 6292ce3d8f Link with gcov. 2024-03-12 18:40:44 +02:00
Roman Telezhynskyi 0e43aefe79 Fix build. 2024-03-12 18:40:22 +02:00
Roman Telezhynskyi b4fba6a7da Add path to conan. 2024-03-12 18:39:55 +02:00
Roman Telezhynskyi 23e0631fbd Ignore certificate import error. 2024-03-12 17:02:38 +02:00
58 changed files with 1055 additions and 193 deletions

View File

@ -130,13 +130,14 @@ appimage_task_template: &APPIMAGE_TASK_TEMPLATE
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' conan==1.63.0
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0 requests
build_script:
- uname -a
- mkdir -pm 0700 $XDG_RUNTIME_DIR
- Xvfb $DISPLAY -ac -screen 0 1600x1200x24+32 -nolisten tcp -nolisten unix &
- sleep 1
- ccache --set-config sloppiness=pch_defines,time_macros max_size="$CCACHE_SIZE"
- export PATH="${PATH}:/root/.local/bin"
- echo $PATH
- which qmake
- which qbs
@ -148,6 +149,7 @@ appimage_task_template: &APPIMAGE_TASK_TEMPLATE
- conan profile new valentina
- conan profile update settings.build_type=Release valentina
- conan profile update settings.os=Linux valentina
- conan profile update settings.arch=x86_64
- conan profile update settings.compiler=gcc valentina
- conan profile update settings.compiler.cppstd=17 valentina
- conan profile update settings.compiler.libcxx=libstdc++11 valentina
@ -156,14 +158,12 @@ appimage_task_template: &APPIMAGE_TASK_TEMPLATE
- qbs setup-qt /opt/qt515/bin/qmake qt5
- qbs config defaultProfile qt5
- qbs config profiles.qt5.baseProfile ${COMPILER}
- conan install . -s os=Linux --build=missing -o with_crash_reporting=True -pr valentina -g virtualrunenv
- conan install . -s os=Linux --build=missing -o with_crash_reporting=True -pr=valentina
- 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:
@ -339,10 +339,10 @@ macos_task_template: &MACOS_TASK_TEMPLATE
# Add certificates to keychain and allow codesign to access them
# 1) Apple Worldwide Developer Relations Certification Authority
- curl https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer --output $HOME/AppleWWDRCAG3.cer --silent
- sudo security import $HOME/AppleWWDRCAG3.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
- sudo security import $HOME/AppleWWDRCAG3.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign || true
# 2) Developer Authentication Certification Authority
- curl https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer --output $HOME/DeveloperIDG2CA.cer --silent
- sudo security import $HOME/DeveloperIDG2CA.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
- sudo security import $HOME/DeveloperIDG2CA.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign || true
# 3) Developer ID
- security import certificate.p12 -k $HOME/Library/Keychains/build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
# Delete the files, we no longer need them
@ -366,7 +366,7 @@ 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' conan==1.63.0
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0 requests
- ccache --set-config sloppiness=pch_defines,time_macros max_size="$CCACHE_SIZE"
- qmake --version
- which qmake
@ -397,13 +397,11 @@ macos_task_template: &MACOS_TASK_TEMPLATE
- 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
- conan install . -s os=Macos --build=missing -o with_crash_reporting=True -pr=valentina
- 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
@ -428,7 +426,7 @@ macos_task_template: &MACOS_TASK_TEMPLATE
macos_task:
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode:14
image: ghcr.io/cirruslabs/macos-sonoma-xcode:latest
<< : *MACOS_TASK_TEMPLATE
env:
DEPLOY: "true"

View File

@ -65,6 +65,7 @@
- Minimal Qt version increased to Qt 5.15. Minimal C++ standard to C++17.
- Updated Windows installer.
- Automatic crash reports.
- Improve compatibility with Richpeace CAD.
# Valentina 0.7.52 September 12, 2022
- Fix crash when default locale is ru.

View File

@ -62,6 +62,7 @@ environment:
WINDEPLOYQT_NO_COMPILER_RUNTIME: "false"
DEPLOY: true
RUN_TESTS: true
WITH_CRASH_REPORTING: True
- job_name: Windows_Qt_5_15_(qbs_GCC_x86)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
@ -84,6 +85,7 @@ environment:
WINDEPLOYQT_NO_COMPILER_RUNTIME: "false"
DEPLOY: true
RUN_TESTS: true
WITH_CRASH_REPORTING: False
# - job_name: Windows_Qt_6_5_(GCC_x64)
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
@ -107,6 +109,7 @@ environment:
# WINDEPLOYQT_NO_COMPILER_RUNTIME: "true"
# DEPLOY: true
# RUN_TESTS: true
# WITH_CRASH_REPORTING: False
- job_name: MacOS_12_Qt_5_15 (qbs, multibundle)
APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey
@ -193,6 +196,7 @@ environment:
WINDEPLOYQT_NO_COMPILER_RUNTIME: "false"
DEPLOY: false
RUN_TESTS: true
WITH_CRASH_REPORTING: False
- job_name: Windows_Qt_5_15_(qbs_MSVC_x64)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
@ -213,6 +217,7 @@ environment:
WINDEPLOYQT_NO_COMPILER_RUNTIME: "false"
DEPLOY: false
RUN_TESTS: true
WITH_CRASH_REPORTING: False
- job_name: Windows_Qt_5_15_(make_GCC_x64)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
@ -399,7 +404,7 @@ for:
build_script:
- conan profile list
- conan install . -s os=Windows --build=missing -o with_crash_reporting=True -o with_xerces=True -pr valentina -g virtualrunenv
- conan install . -s os=Windows --build=missing -o with_crash_reporting=%WITH_CRASH_REPORTING% -o with_xerces=True -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 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:
@ -408,16 +413,14 @@ for:
deploy_script:
- ps: |
if ($env:DEPLOY -eq "true") {
if ($env:WITH_CRASH_REPORTING -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 "%WITH_CRASH_REPORTING%" == "True" (python3 scripts/symupload.py %APPVEYOR_BUILD_FOLDER%\build\install-root\valentina $VALENTINA_VERSION $CRASH_SHORT_SHA $CRASH_QT_VERSION --clean)
- 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
@ -576,10 +579,10 @@ for:
# Add certificates to keychain and allow codesign to access them
# 1) Apple Worldwide Developer Relations Certification Authority
- curl https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer --output $HOME/AppleWWDRCAG3.cer --silent
- sudo security import $HOME/AppleWWDRCAG3.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
- sudo security import $HOME/AppleWWDRCAG3.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign || true
# 2) Developer Authentication Certification Authority
- curl https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer --output $HOME/DeveloperIDG2CA.cer --silent
- sudo security import $HOME/DeveloperIDG2CA.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
- sudo security import $HOME/DeveloperIDG2CA.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign || true
# 3) Developer ID
- security import certificate.p12 -k $HOME/Library/Keychains/build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
# Delete the files, we no longer need them
@ -655,7 +658,7 @@ for:
fi
- sudo python3 -m pip install --upgrade pip
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0 requests
- export QTDIR=`$(brew --prefix qt6)`
- export PATH="$PATH:`python3 -m site --user-base`/bin:$QTDIR/bin"
- echo $PATH
@ -689,13 +692,11 @@ for:
- qbs setup-qt $(brew --prefix 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
- conan install . -s os=Macos --build=missing -o with_crash_reporting=True -pr=valentina
- 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
@ -774,10 +775,10 @@ for:
# Add certificates to keychain and allow codesign to access them
# 1) Apple Worldwide Developer Relations Certification Authority
- curl https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer --output $HOME/AppleWWDRCAG3.cer --silent
- sudo security import $HOME/AppleWWDRCAG3.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
- sudo security import $HOME/AppleWWDRCAG3.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign || true
# 2) Developer Authentication Certification Authority
- curl https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer --output $HOME/DeveloperIDG2CA.cer --silent
- sudo security import $HOME/DeveloperIDG2CA.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign
- sudo security import $HOME/DeveloperIDG2CA.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign || true
# 3) Developer ID
- security import certificate.p12 -k $HOME/Library/Keychains/build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
# Delete the files, we no longer need them
@ -854,7 +855,7 @@ for:
fi
- sudo python3 -m pip install --upgrade pip
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0
- pip3 install --user --upgrade pip dropbox py7zr 'urllib3<2.0' conan==1.63.0 requests
- export PATH="`brew --prefix qbs`/bin:$PATH"
- echo $PATH
- clang --version
@ -886,13 +887,11 @@ for:
- qbs setup-qt ${QTDIR}/bin/qmake qt5
- qbs config defaultProfile qt5
- qbs config profiles.qt5.baseProfile clang
- conan install . -s os=Macos --build=missing -o with_crash_reporting=True -pr valentina -g virtualrunenv
- conan install . -s os=Macos --build=missing -o with_crash_reporting=True -pr=valentina
- 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

View File

@ -4,7 +4,7 @@ from conan import ConanFile
class Recipe(ConanFile):
settings = "os"
requires = "xerces-c/[~3.2]", "crashpad/cci.20220219", "breakpad/cci.20210521"
requires = "xerces-c/[~3.2]", "sentry-crashpad/0.6.5"
options = {
"with_xerces": [True, False],
"with_crash_reporting": [True, False]
@ -27,5 +27,4 @@ class Recipe(ConanFile):
del self.requires["xerces-c"]
if not self.options.with_crash_reporting:
del self.requires["crashpad/cci.20220219"]
del self.requires["breakpad/cci.20210521"]
del self.requires["sentry-crashpad/0.6.5"]

View File

@ -97,6 +97,20 @@ The path to output destination folder. By default the directory at which the app
.RE
.IP "--bdxf"
.RB "Export dxf in binary form."
.IP "--dxfApparelComp <Mode number>"
.RB "Number corresponding to compatibility mode for DXF AAMA/ASTM format (default = 0, " "export mode" "):
.RS
.BR "*" " By standard = 0,"
.RE
.RS
.BR "*" " Richpeace CAD V8 = 1,"
.RE
.RS
.BR "*" " Richpeace CAD V9 = 2,"
.RE
.RS
.BR "*" " Richpeace CAD V10 = 3."
.RE
.IP "--noGrainline"
.RB "Show/hide grainline when export layout."
.IP "--text2paths"

View File

@ -97,6 +97,20 @@ The path to output destination folder. By default the directory at which the app
.RE
.IP "--bdxf"
.RB "Export dxf in binary form."
.IP "--dxfApparelComp <Mode number>"
.RB "Number corresponding to compatibility mode for DXF AAMA/ASTM format (default = 0, " "export mode" "):
.RS
.BR "*" " By standard = 0,"
.RE
.RS
.BR "*" " Richpeace CAD V8 = 1,"
.RE
.RS
.BR "*" " Richpeace CAD V9 = 2,"
.RE
.RS
.BR "*" " Richpeace CAD V10 = 3."
.RE
.IP "--noGrainline"
.RB "Show/hide grainline when export layout."
.IP "--text2paths"

View File

@ -45,6 +45,7 @@ Probe {
property var settings
property bool verbose: false
property stringList profiles: []
property string remote
// Output
property var dependencies
@ -115,6 +116,11 @@ Probe {
Utilities.getHash(args.join()));
args = args.concat(["-if", generatedFilesPath]);
if (remote) {
args = args.concat(["--remote", remote]);
}
var p = new Process();
p.start(executable, args);
while (!p.waitForFinished(500)) {

View File

@ -20,6 +20,11 @@ Module {
return flags;
}
Properties {
condition: qbs.toolchain.contains("gcc") && !qbs.toolchain.contains("clang")
cpp.staticLibraries: ["gcov"]
}
Rule { // Fake rule for '*.gcno' generation.
condition: qbs.debugInformation && qbs.toolchain.contains("gcc") && !qbs.toolchain.contains("clang")
inputs: ["cpp", "c"]

View File

@ -4,6 +4,7 @@ import subprocess
import sys
import glob
import zipfile
import requests
database = "valentina"
@ -21,17 +22,6 @@ def debug_extension():
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:
@ -48,24 +38,10 @@ def generate_sym_files(install_root):
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_file = os.path.splitext(debug_file)[0] + ".sym"
dump_syms_cmd = ["dump_syms", '-o', sym_file, debug_file]
subprocess.run(dump_syms_cmd, check=True)
sym_files.append((debug_file, zip_sym(sym_file)))
@ -89,7 +65,7 @@ def generate_version_string(val_version, commit_hash, qt_version):
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()
base_name = os.path.basename(sym_file).split(".sym")[0].lower()
# Determine the platform
platform = sys.platform
@ -114,18 +90,18 @@ def upload_symbols(install_root, val_version, commit_hash, qt_version, clean=Fal
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}"]
sym_file_name = os.path.basename(sym_file)
url = f"https://{database}.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName={app_name}&appVer={app_version}&code_file={sym_file_name}"
try:
subprocess.run(upload_cmd, check=True)
files = {'symbol_file': (f'{sym_file_name}', open(sym_file, 'rb'))}
response = requests.post(url, files=files)
if response.status_code == 200:
print(f"Symbol file '{sym_file}' uploaded successfully.")
except subprocess.CalledProcessError as e:
print(f"Error: {e}")
else:
print("Request failed with status code:", response.status_code)
print("Server response:")
print(response.text)
# Cleanup if requested
if clean:

View File

@ -111,6 +111,8 @@ DialogSaveManualLayout::DialogSaveManualLayout(vsizetype count, bool consoleExpo
// RemoveFormatFromList(LayoutExportFormats::NC); // No support for now
InitDxfCompatibility();
connect(bOk, &QPushButton::clicked, this, &DialogSaveManualLayout::Save);
connect(ui->lineEditFileName, &QLineEdit::textChanged, this, &DialogSaveManualLayout::ShowExample);
connect(ui->comboBoxFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
@ -224,6 +226,45 @@ auto DialogSaveManualLayout::IsBinaryDXFFormat() const -> bool
}
}
//---------------------------------------------------------------------------------------------------------------------
auto DialogSaveManualLayout::DxfCompatibility() const -> DXFApparelCompatibility
{
switch (Format())
{
case LayoutExportFormats::DXF_AAMA:
case LayoutExportFormats::DXF_ASTM:
return static_cast<DXFApparelCompatibility>(ui->comboBoxDxfCompatibility->currentData().toInt());
default:
return DXFApparelCompatibility::STANDARD;
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveManualLayout::SetDxfCompatibility(DXFApparelCompatibility type)
{
switch (Format())
{
case LayoutExportFormats::DXF_AAMA:
case LayoutExportFormats::DXF_ASTM:
{
if (static_cast<int>(type) < 0 || type >= DXFApparelCompatibility::COUNT)
{
break;
}
const int i = ui->comboBoxDxfCompatibility->findData(static_cast<int>(type));
if (i < 0)
{
break;
}
ui->comboBoxDxfCompatibility->setCurrentIndex(i);
break;
}
default:
break;
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveManualLayout::SetShowGrainline(bool show)
{
@ -491,6 +532,8 @@ void DialogSaveManualLayout::ShowExample()
ui->checkBoxExportUnified->setVisible(false);
ui->checkBoxTilesScheme->setVisible(false);
ui->checkBoxShowGrainline->setVisible(false);
ui->labelDxfCompatibility->setVisible(false);
ui->comboBoxDxfCompatibility->setVisible(false);
const bool editableTextAsPaths = !settings->GetSingleLineFonts() && !settings->GetSingleStrokeOutlineFont();
@ -499,6 +542,8 @@ void DialogSaveManualLayout::ShowExample()
case LayoutExportFormats::DXF_AAMA:
case LayoutExportFormats::DXF_ASTM:
ui->checkBoxBinaryDXF->setVisible(true);
ui->labelDxfCompatibility->setVisible(true);
ui->comboBoxDxfCompatibility->setVisible(true);
break;
case LayoutExportFormats::PDFTiled:
ui->checkBoxTextAsPaths->setVisible(editableTextAsPaths);
@ -616,6 +661,8 @@ void DialogSaveManualLayout::ReadSettings()
qDebug() << qUtf8Printable(e.ErrorMessage());
}
SetShowGrainline(settings->GetShowGrainline());
SetDxfCompatibility(static_cast<DXFApparelCompatibility>(settings->GetDxfCompatibility()));
}
//---------------------------------------------------------------------------------------------------------------------
@ -629,4 +676,19 @@ void DialogSaveManualLayout::WriteSettings() const
VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
settings->SetLayoutExportFormat(static_cast<qint8>(Format()));
settings->SetShowGrainline(IsShowGrainline());
settings->SetDxfCompatibility(static_cast<qint8>(DxfCompatibility()));
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveManualLayout::InitDxfCompatibility()
{
ui->comboBoxDxfCompatibility->addItem(tr("By standard"),
QVariant(static_cast<int>(DXFApparelCompatibility::STANDARD)));
ui->comboBoxDxfCompatibility->addItem("Richpeace CAD V8"_L1,
QVariant(static_cast<int>(DXFApparelCompatibility::RPCADV08)));
ui->comboBoxDxfCompatibility->addItem("Richpeace CAD V9"_L1,
QVariant(static_cast<int>(DXFApparelCompatibility::RPCADV09)));
ui->comboBoxDxfCompatibility->addItem("Richpeace CAD V10"_L1,
QVariant(static_cast<int>(DXFApparelCompatibility::RPCADV10)));
}

View File

@ -30,6 +30,7 @@
#include <memory>
#include "../vdxf/dxfdef.h"
#include "../vlayout/dialogs/vabstractlayoutdialog.h"
#include "../vlayout/vlayoutdef.h"
#include "../vmisc/defglobal.h"
@ -57,6 +58,9 @@ public:
void SetBinaryDXFFormat(bool binary);
auto IsBinaryDXFFormat() const -> bool;
auto DxfCompatibility() const -> DXFApparelCompatibility;
void SetDxfCompatibility(DXFApparelCompatibility type);
void SetShowGrainline(bool show);
auto IsShowGrainline() const -> bool;
@ -95,6 +99,8 @@ private:
void ReadSettings();
void WriteSettings() const;
void InitDxfCompatibility();
};
#endif // DIALOGSAVEMANUALLAYOUT_H

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>390</width>
<height>283</height>
<width>464</width>
<height>287</height>
</rect>
</property>
<property name="windowTitle">
@ -111,7 +111,7 @@
<property name="title">
<string>Options</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="labelOptionsNotAvailable">
<property name="text">
@ -178,6 +178,20 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labelDxfCompatibility">
<property name="text">
<string>Compatibility:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxDxfCompatibility"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>

View File

@ -41,7 +41,7 @@
#endif
// Fix bug in Qt. Deprecation warning in QMessageBox::critical.
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) && QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#undef QT_REQUIRE_VERSION
#define QT_REQUIRE_VERSION(argc, argv, str) \
{ \

View File

@ -33,12 +33,11 @@
#include "../ifc/exception/vexceptionemptyparameter.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/exception/vexceptionwrongid.h"
#include "../vganalytics/def.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/projectversion.h"
#include "../vmisc/qt_dispatch/qt_dispatch.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vsysexits.h"
#include "version.h"
#include "vpmainwindow.h"
#include "vpuzzleshortcutmanager.h"
@ -159,29 +158,55 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
type = QtDebugMsg;
}
switch (type)
{
case QtDebugMsg:
vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << msg << "\n";
return;
case QtWarningMsg:
vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << msg << "\n";
break;
case QtCriticalMsg:
vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << msg << "\n";
break;
case QtFatalMsg:
vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << msg << "\n";
break;
case QtInfoMsg:
vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << msg << "\n";
break;
default:
break;
}
QString debugdate = "["_L1 + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss"));
vStdOut().flush();
vStdErr().flush();
switch (type)
{
case QtDebugMsg:
debugdate += QStringLiteral(":DEBUG:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, msg);
vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << msg << "\n";
break;
case QtWarningMsg:
debugdate += QStringLiteral(":WARNING:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, msg);
vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << msg << "\n";
break;
case QtCriticalMsg:
debugdate += QStringLiteral(":CRITICAL:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, msg);
vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << msg << "\n";
break;
case QtFatalMsg:
debugdate += QStringLiteral(":FATAL:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, msg);
vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << msg << "\n";
break;
case QtInfoMsg:
debugdate += QStringLiteral(":INFO:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, msg);
vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << msg << "\n";
break;
default:
break;
}
vStdOut().flush();
vStdErr().flush();
(*VPApplication::VApp()->LogFile()) << debugdate << Qt::endl;
}
if (isGuiThread)
{
@ -209,8 +234,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
messageBox.setIcon(QMessageBox::Information);
break;
case QtDebugMsg:
Q_UNREACHABLE(); //-V501
break;
default:
break;
}
@ -405,10 +428,10 @@ auto VPApplication::NewMainWindow(const VPCommandLinePtr &cmd) -> VPMainWindow *
//---------------------------------------------------------------------------------------------------------------------
void VPApplication::InitOptions()
{
qInstallMessageHandler(noisyFailureMsgHandler);
OpenSettings();
StartLogging();
qCDebug(pApp, "Version: %s", qUtf8Printable(AppVersionStr()));
qCDebug(pApp, "Build revision: %s", BUILD_REVISION);
qCDebug(pApp, "%s", qUtf8Printable(buildCompatibilityString()));
@ -443,6 +466,22 @@ void VPApplication::InitOptions()
m_shortcutManager = new VPuzzleShortcutManager(this);
}
//---------------------------------------------------------------------------------------------------------------------
void VPApplication::StartLogging()
{
if (CreateLogDir())
{
BeginLogging();
ClearOldLogs();
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VPApplication::LogFile() -> QTextStream *
{
return m_out.get();
}
//---------------------------------------------------------------------------------------------------------------------
auto VPApplication::TrVars() -> const VTranslateVars *
{
@ -723,6 +762,38 @@ auto VPApplication::SingleStart(const VPCommandLinePtr &cmd, const QStringList &
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPApplication::LogPath() -> QString
{
// Keep in sync with VCrashPaths::GetAttachmentPath
return QStringLiteral("%1/puzzle-pid%2.log").arg(LogDirPath()).arg(applicationPid());
}
//---------------------------------------------------------------------------------------------------------------------
void VPApplication::BeginLogging()
{
VlpCreateLock(m_lockLog, LogPath(), []() { return new QFile(LogPath()); });
if (m_lockLog->IsLocked())
{
if (m_lockLog->GetProtected()->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
{
m_out.reset(new QTextStream(m_lockLog->GetProtected().data()));
qInstallMessageHandler(noisyFailureMsgHandler);
qCDebug(pApp, "Log file %s was locked.", qUtf8Printable(LogPath()));
}
else
{
qCDebug(pApp, "Error opening log file \'%s\'. All debug output redirected to console.",
qUtf8Printable(LogPath()));
}
}
else
{
qCDebug(pApp, "Failed to lock %s", qUtf8Printable(LogPath()));
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VPApplication::CommandLine() -> VPCommandLinePtr
{

View File

@ -30,6 +30,7 @@
#include "../vmisc/def.h"
#include "../vmisc/vabstractapplication.h"
#include "../vmisc/vlockguard.h"
#include "vpcommandline.h"
#include "vpsettings.h"
@ -62,6 +63,9 @@ public:
void InitOptions();
void StartLogging();
auto LogFile() -> QTextStream *;
auto TrVars() -> const VTranslateVars * override;
void OpenSettings() override;
@ -95,6 +99,8 @@ private:
QList<QPointer<VPMainWindow>> m_mainWindows{};
QLocalServer *m_localServer{nullptr};
QWeakPointer<DialogPuzzlePreferences> m_preferencesDialog{};
QSharedPointer<VLockGuard<QFile>> m_lockLog{};
std::shared_ptr<QTextStream> m_out{nullptr};
void Clean();
@ -102,6 +108,9 @@ private:
auto StartWithFiles(const VPCommandLinePtr &cmd, const QStringList &rawLayouts) -> bool;
auto SingleStart(const VPCommandLinePtr &cmd, const QStringList &rawLayouts) -> bool;
static auto LogPath() -> QString;
void BeginLogging();
};
#endif // VPAPPLICATION_H

View File

@ -313,6 +313,7 @@ struct VPExportData
QString fileName{};
qreal xScale{1.};
qreal yScale{1.};
DXFApparelCompatibility dxfCompatibility{DXFApparelCompatibility::STANDARD};
bool isBinaryDXF{false};
bool textAsPaths{false};
bool exportUnified{true};
@ -573,7 +574,10 @@ auto VPMainWindow::LoadFile(const QString &path) -> bool
void VPMainWindow::LayoutWasSaved(bool saved)
{
setWindowModified(!saved);
not IsLayoutReadOnly() ? ui->actionSave->setEnabled(!saved) : ui->actionSave->setEnabled(false);
if (ui)
{
not IsLayoutReadOnly() ? ui->actionSave->setEnabled(!saved) : ui->actionSave->setEnabled(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -2320,10 +2324,12 @@ void VPMainWindow::ExportApparelLayout(const VPExportData &data, const QVector<V
{
case LayoutExportFormats::DXF_ASTM:
exporter.SetDxfVersion(DRW::AC1009);
exporter.SetDxfApparelCompatibility(data.dxfCompatibility);
exporter.ExportToASTMDXF(details);
break;
case LayoutExportFormats::DXF_AAMA:
exporter.SetDxfVersion(DRW::AC1009);
exporter.SetDxfApparelCompatibility(data.dxfCompatibility);
exporter.ExportToAAMADXF(details);
break;
case LayoutExportFormats::RLD:
@ -4214,6 +4220,7 @@ void VPMainWindow::on_ExportLayout()
data.exportUnified = dialog.IsExportUnified();
data.showTilesScheme = dialog.IsTilesScheme();
data.showGrainline = dialog.IsShowGrainline();
data.dxfCompatibility = dialog.DxfCompatibility();
ExportData(data);
}
@ -4265,6 +4272,7 @@ void VPMainWindow::on_ExportSheet()
data.exportUnified = dialog.IsExportUnified();
data.showTilesScheme = dialog.IsTilesScheme();
data.showGrainline = dialog.IsShowGrainline();
data.dxfCompatibility = dialog.DxfCompatibility();
ExportData(data);
}

View File

@ -70,6 +70,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutWarningPiecesOutOfBound, (
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutFollowGrainline, ("layout/followGrainline"_L1))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutPieceGap, ("layout/pieceGap"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutExportFormat, ("layout/exportFormat"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingDxfCompatibility, ("layout/dxfCompatibility"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutLineWidth, ("layout/lineWidth"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutShowGrainline, ("layout/showGrainline"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPathsRawLayoutData, ("paths/rawLatoutData"_L1)) // NOLINT
@ -357,6 +358,18 @@ void VPSettings::SetLayoutExportFormat(qint8 format)
setValue(*settingLayoutExportFormat, format);
}
//---------------------------------------------------------------------------------------------------------------------
auto VPSettings::GetDxfCompatibility() const -> qint8
{
return CastToLayoutExportFormat(qvariant_cast<qint8>(value(*settingDxfCompatibility, 0)));
}
//---------------------------------------------------------------------------------------------------------------------
void VPSettings::SetDxfCompatibility(qint8 type)
{
setValue(*settingDxfCompatibility, type);
}
//---------------------------------------------------------------------------------------------------------------------
auto VPSettings::GetLayoutLineWidth() const -> int
{

View File

@ -105,6 +105,9 @@ public:
auto GetLayoutExportFormat() const -> qint8;
void SetLayoutExportFormat(qint8 format);
auto GetDxfCompatibility() const -> qint8;
void SetDxfCompatibility(qint8 type);
auto GetLayoutLineWidth() const -> int;
void SetLayoutLineWidth(int width);

View File

@ -0,0 +1,43 @@
/************************************************************************
**
** @file dialognoknownmeasurements.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 14 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 "dialognoknownmeasurements.h"
#include "ui_dialognoknownmeasurements.h"
//---------------------------------------------------------------------------------------------------------------------
DialogNoKnownMeasurements::DialogNoKnownMeasurements(QWidget *parent)
: QDialog(parent),
ui(new Ui::DialogNoKnownMeasurements)
{
ui->setupUi(this);
}
//---------------------------------------------------------------------------------------------------------------------
DialogNoKnownMeasurements::~DialogNoKnownMeasurements()
{
delete ui;
}

View File

@ -0,0 +1,51 @@
/************************************************************************
**
** @file dialognoknownmeasurements.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 14 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 DIALOGNOKNOWNMEASUREMENTS_H
#define DIALOGNOKNOWNMEASUREMENTS_H
#include <QDialog>
namespace Ui
{
class DialogNoKnownMeasurements;
}
class DialogNoKnownMeasurements : public QDialog
{
Q_OBJECT // NOLINT
public:
explicit DialogNoKnownMeasurements(QWidget *parent = nullptr);
~DialogNoKnownMeasurements() override;
private:
Ui::DialogNoKnownMeasurements *ui;
Q_DISABLE_COPY_MOVE(DialogNoKnownMeasurements) // NOLINT
};
#endif // DIALOGNOKNOWNMEASUREMENTS_H

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogNoKnownMeasurements</class>
<widget class="QDialog" name="DialogNoKnownMeasurements">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>470</width>
<height>189</height>
</rect>
</property>
<property name="windowTitle">
<string>Known measurements</string>
</property>
<property name="windowIcon">
<iconset resource="../share/resources/tapeicon.qrc">
<normaloff>:/tapeicon/64x64/logo.png</normaloff>:/tapeicon/64x64/logo.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>The measurements file is not currently connected to the database of known measurements. Before adding known measurements, you'll need to create a database and connect it to your measurements file. To connect to one of the known sets, please navigate to the 'Information' tab. After doing so, you can retry your action. Alternatively, you can create a new database of known measurements and connect it to your measurements file. Would you like to create it now?</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::No|QDialogButtonBox::Yes</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../share/resources/tapeicon.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DialogNoKnownMeasurements</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DialogNoKnownMeasurements</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -40,14 +40,13 @@ class DialogRestrictDimension;
class QTableWidgetItem;
enum class RestrictDimension: qint8
enum class RestrictDimension : qint8
{
First = 0,
Second = 1,
Third = 2
};
class DialogRestrictDimension : public QDialog
{
Q_OBJECT // NOLINT
@ -61,7 +60,7 @@ public:
auto Restrictions() const -> QMap<QString, VDimensionRestriction>;
protected:
void changeEvent(QEvent* event) override;
void changeEvent(QEvent *event) override;
protected slots:
void RowSelected();
@ -94,11 +93,11 @@ private:
void FillBases(const QVector<qreal> &bases, const MeasurementDimension_p &dimension, QComboBox *control) const;
void FillBase(double base, const MeasurementDimension_p &dimension, QComboBox *control) const;
static auto FillDimensionXBases(const QVector<qreal> &bases,
const MeasurementDimension_p &dimension) -> QStringList;
static auto FillDimensionXBases(const QVector<qreal> &bases, const MeasurementDimension_p &dimension)
-> QStringList;
auto FillDimensionYBases(const QVector<qreal> &bases, const MeasurementDimension_p &dimension) const -> QStringList;
auto FillDimensionWZBases(const QVector<qreal> &bases,
const MeasurementDimension_p &dimension) const -> QStringList;
auto FillDimensionWZBases(const QVector<qreal> &bases, const MeasurementDimension_p &dimension) const
-> QStringList;
auto DimensionLabels(const QVector<qreal> &bases, const MeasurementDimension_p &dimension) const -> QStringList;
auto DimensionRestrictedValues(const MeasurementDimension_p &dimension) const -> QVector<qreal>;
@ -106,7 +105,7 @@ private:
};
//---------------------------------------------------------------------------------------------------------------------
inline auto DialogRestrictDimension::Restrictions() const -> QMap<QString, VDimensionRestriction >
inline auto DialogRestrictDimension::Restrictions() const -> QMap<QString, VDimensionRestriction>
{
return m_restrictions;
}

View File

@ -29,6 +29,7 @@
#include "mapplication.h"
#include <QMessageBox> // For QT_REQUIRE_VERSION
#include <QScopeGuard>
#include <QTimer>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@ -41,7 +42,7 @@
#endif
// Fix bug in Qt. Deprecation warning in QMessageBox::critical.
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) && QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#undef QT_REQUIRE_VERSION
#define QT_REQUIRE_VERSION(argc, argv, str) \
{ \

View File

@ -35,7 +35,6 @@
#include "../ifc/exception/vexceptionwrongid.h"
#include "../qmuparser/qmuparsererror.h"
#include "../vformat/knownmeasurements/vknownmeasurementsdatabase.h"
#include "../vganalytics/def.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/projectversion.h"
#include "../vmisc/qt_dispatch/qt_dispatch.h"
@ -66,7 +65,6 @@
#include <QThread>
#include <QTranslator>
#include <QUuid>
#include <iostream>
#if !defined(BUILD_REVISION) && defined(QBS_BUILD)
#include <QEvent>
@ -197,29 +195,55 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
logMsg = logMsg.remove(VAbstractApplication::warningMessageSignature);
}
switch (type)
{
case QtDebugMsg:
vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << logMsg << "\n";
return;
case QtWarningMsg:
vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << logMsg << "\n";
break;
case QtCriticalMsg:
vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << logMsg << "\n";
break;
case QtFatalMsg:
vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << logMsg << "\n";
break;
case QtInfoMsg:
vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << logMsg << "\n";
break;
default:
break;
}
QString debugdate = "["_L1 + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss"));
vStdOut().flush();
vStdErr().flush();
switch (type)
{
case QtDebugMsg:
debugdate += QStringLiteral(":DEBUG:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, logMsg);
vStdOut() << QApplication::translate("mNoisyHandler", "DEBUG:") << logMsg << "\n";
break;
case QtWarningMsg:
debugdate += QStringLiteral(":WARNING:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, logMsg);
vStdErr() << QApplication::translate("mNoisyHandler", "WARNING:") << logMsg << "\n";
break;
case QtCriticalMsg:
debugdate += QStringLiteral(":CRITICAL:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, logMsg);
vStdErr() << QApplication::translate("mNoisyHandler", "CRITICAL:") << logMsg << "\n";
break;
case QtFatalMsg:
debugdate += QStringLiteral(":FATAL:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, logMsg);
vStdErr() << QApplication::translate("mNoisyHandler", "FATAL:") << logMsg << "\n";
break;
case QtInfoMsg:
debugdate += QStringLiteral(":INFO:%1(%2)] %3: %4: %5")
.arg(context.file)
.arg(context.line)
.arg(context.function, context.category, logMsg);
vStdOut() << QApplication::translate("mNoisyHandler", "INFO:") << logMsg << "\n";
break;
default:
break;
}
vStdOut().flush();
vStdErr().flush();
(*MApplication::VApp()->LogFile()) << debugdate << Qt::endl;
}
if (isGuiThread)
{
@ -247,8 +271,6 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
messageBox.setIcon(QMessageBox::Information);
break;
case QtDebugMsg:
Q_UNREACHABLE(); //-V501
break;
default:
break;
}
@ -450,10 +472,10 @@ auto MApplication::MainTapeWindows() -> QList<TMainWindow *>
//---------------------------------------------------------------------------------------------------------------------
void MApplication::InitOptions()
{
qInstallMessageHandler(noisyFailureMsgHandler);
OpenSettings();
StartLogging();
qCDebug(mApp, "Version: %s", qUtf8Printable(AppVersionStr()));
qCDebug(mApp, "Build revision: %s", BUILD_REVISION);
qCDebug(mApp, "%s", qUtf8Printable(buildCompatibilityString()));
@ -484,6 +506,22 @@ void MApplication::InitOptions()
m_shortcutManager = new VTapeShortcutManager(this);
}
//---------------------------------------------------------------------------------------------------------------------
void MApplication::StartLogging()
{
if (CreateLogDir())
{
BeginLogging();
ClearOldLogs();
}
}
//---------------------------------------------------------------------------------------------------------------------
auto MApplication::LogFile() -> QTextStream *
{
return m_out.get();
}
//---------------------------------------------------------------------------------------------------------------------
void MApplication::InitTrVars()
{
@ -722,6 +760,38 @@ void MApplication::RestartKnownMeasurementsDatabaseWatcher()
}
}
//---------------------------------------------------------------------------------------------------------------------
auto MApplication::LogPath() -> QString
{
// Keep in sync with VCrashPaths::GetAttachmentPath
return QStringLiteral("%1/tape-pid%2.log").arg(LogDirPath()).arg(applicationPid());
}
//---------------------------------------------------------------------------------------------------------------------
void MApplication::BeginLogging()
{
VlpCreateLock(m_lockLog, LogPath(), []() { return new QFile(LogPath()); });
if (m_lockLog->IsLocked())
{
if (m_lockLog->GetProtected()->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
{
m_out.reset(new QTextStream(m_lockLog->GetProtected().data()));
qInstallMessageHandler(noisyFailureMsgHandler);
qCDebug(mApp, "Log file %s was locked.", qUtf8Printable(LogPath()));
}
else
{
qCDebug(mApp, "Error opening log file \'%s\'. All debug output redirected to console.",
qUtf8Printable(LogPath()));
}
}
else
{
qCDebug(mApp, "Failed to lock %s", qUtf8Printable(LogPath()));
}
}
//---------------------------------------------------------------------------------------------------------------------
auto MApplication::NewMainTapeWindow() -> TMainWindow *
{

View File

@ -30,6 +30,7 @@
#define MAPPLICATION_H
#include "../vmisc/vabstractapplication.h"
#include "../vmisc/vlockguard.h"
#include "../vpatterndb/vtranslatevars.h"
#include "dialogs/dialogmdatabase.h"
#include "vtapesettings.h"
@ -71,6 +72,9 @@ public:
void InitOptions();
void StartLogging();
auto LogFile() -> QTextStream *;
auto TrVars() -> const VTranslateVars * override;
void OpenSettings() override;
@ -113,6 +117,8 @@ private:
VKnownMeasurementsDatabase *m_knownMeasurementsDatabase{nullptr};
QFileSystemWatcher *m_knownMeasurementsDatabaseWatcher{nullptr};
QFutureWatcher<void> *m_knownMeasurementsRepopulateWatcher;
QSharedPointer<VLockGuard<QFile>> m_lockLog{};
std::shared_ptr<QTextStream> m_out{nullptr};
void CleanTapeWindows();
void CleanKMWindows();
@ -131,6 +137,9 @@ private:
static void ParseUnitsOption(QCommandLineParser &parser, Unit &unit, bool &flagUnits);
void RestartKnownMeasurementsDatabaseWatcher();
static auto LogPath() -> QString;
void BeginLogging();
};
//---------------------------------------------------------------------------------------------------------------------

View File

@ -90,6 +90,9 @@ VToolApp {
"dialogknownmeasurementscsvcolumns.h",
"dialogknownmeasurementscsvcolumns.ui",
"dialogmeasurementscsvcolumns.cpp",
"dialognoknownmeasurements.cpp",
"dialognoknownmeasurements.h",
"dialognoknownmeasurements.ui",
"dialogrestrictdimension.cpp",
"dialogabouttape.cpp",
"dialognewmeasurements.cpp",

View File

@ -58,6 +58,7 @@
#include "dialogs/dialogmdatabase.h"
#include "dialogs/dialogmeasurementscsvcolumns.h"
#include "dialogs/dialognewmeasurements.h"
#include "dialogs/dialognoknownmeasurements.h"
#include "dialogs/dialogrestrictdimension.h"
#include "dialogs/dialogsetupmultisize.h"
#include "mapplication.h" // Should be last because of definning qApp
@ -1710,13 +1711,23 @@ void TMainWindow::AddCustom()
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::AddKnown()
{
if (m_m->KnownMeasurements().isNull())
{
DialogNoKnownMeasurements dialog(this);
if (dialog.exec() == QDialog::Accepted)
{
MApplication::VApp()->NewMainKMWindow();
}
return;
}
QScopedPointer<DialogMDataBase> const dialog(new DialogMDataBase(m_m->KnownMeasurements(), m_m->ListKnown(), this));
if (dialog->exec() == QDialog::Rejected)
{
return;
}
vsizetype currentRow;
vsizetype currentRow = -1;
const QStringList list = dialog->GetNewNames();
VKnownMeasurementsDatabase *db = MApplication::VApp()->KnownMeasurementsDatabase();
VKnownMeasurements const knownDB = db->KnownMeasurements(m_m->KnownMeasurements());
@ -4780,6 +4791,11 @@ void TMainWindow::InitKnownMeasurements(QComboBox *combo)
SCASSERT(combo != nullptr)
combo->addItem(tr("None"), QUuid());
if (m_m == nullptr)
{
return;
}
QUuid const kmId = m_m->KnownMeasurements();
if (!kmId.isNull() && !known.contains(kmId))
{

View File

@ -224,7 +224,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
}
{
QString debugdate = "[" + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss"));
QString debugdate = "["_L1 + QDateTime::currentDateTime().toString(QStringLiteral("yyyy.MM.dd hh:mm:ss"));
switch (type)
{
@ -572,7 +572,6 @@ void VApplication::InitOptions()
{
OpenSettings();
// Run creation log after sending crash report
StartLogging();
qDebug() << "Version:" << AppVersionStr();

View File

@ -322,6 +322,17 @@ auto VCommandLine::OptExportType() const -> int
return r;
}
//---------------------------------------------------------------------------------------------------------------------
int VCommandLine::DXFApparelCompatibilityType() const
{
int r = 0;
if (IsOptionSet(LONG_OPTION_DXF_APPAREL_COMP))
{
r = OptionValue(LONG_OPTION_DXF_APPAREL_COMP).toInt();
}
return r;
}
//---------------------------------------------------------------------------------------------------------------------
auto VCommandLine::IsBinaryDXF() const -> bool
{
@ -631,6 +642,11 @@ void VCommandLine::InitCommandLineOptions()
translate("VCommandLine", "Format number"),
QChar('0')},
{LONG_OPTION_BINARYDXF, translate("VCommandLine", "Export dxf in binary form.")},
{LONG_OPTION_DXF_APPAREL_COMP,
translate("VCommandLine",
"Number corresponding to compatibility mode for DXF AAMA/ASTM format (default = 0, export mode):") +
DialogSaveLayout::MakeHelpDxfApparelCompatibilityList(),
translate("VCommandLine", "Mode number"), QChar('0')},
{LONG_OPTION_NOGRAINLINE, translate("VCommandLine", "Show/hide grainline when export layout.")},
{LONG_OPTION_TEXT2PATHS, translate("VCommandLine", "Export text as paths.")},
{LONG_OPTION_EXPORTONLYDETAILS,

View File

@ -82,6 +82,8 @@ public:
//@brief returns export type set, defaults 0 - svg
auto OptExportType() const -> int;
auto DXFApparelCompatibilityType() const -> int;
auto IsBinaryDXF() const -> bool;
auto IsNoGrainline() const -> bool;
auto IsTextAsPaths() const -> bool;

View File

@ -124,6 +124,8 @@ DialogSaveLayout::DialogSaveLayout(int count, Draw mode, const QString &fileName
RemoveFormatFromList(LayoutExportFormats::RLD);
}
InitDxfCompatibility();
connect(bOk, &QPushButton::clicked, this, &DialogSaveLayout::Save);
connect(ui->lineEditFileName, &QLineEdit::textChanged, this, &DialogSaveLayout::ShowExample);
connect(ui->comboBoxFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
@ -226,6 +228,45 @@ auto DialogSaveLayout::IsBinaryDXFFormat() const -> bool
}
}
//---------------------------------------------------------------------------------------------------------------------
auto DialogSaveLayout::DxfCompatibility() const -> DXFApparelCompatibility
{
switch (Format())
{
case LayoutExportFormats::DXF_AAMA:
case LayoutExportFormats::DXF_ASTM:
return static_cast<DXFApparelCompatibility>(ui->comboBoxDxfCompatibility->currentData().toInt());
default:
return DXFApparelCompatibility::STANDARD;
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveLayout::SetDxfCompatibility(DXFApparelCompatibility type)
{
switch (Format())
{
case LayoutExportFormats::DXF_AAMA:
case LayoutExportFormats::DXF_ASTM:
{
if (static_cast<int>(type) < 0 || type >= DXFApparelCompatibility::COUNT)
{
break;
}
const int i = ui->comboBoxDxfCompatibility->findData(static_cast<int>(type));
if (i < 0)
{
break;
}
ui->comboBoxDxfCompatibility->setCurrentIndex(i);
break;
}
default:
break;
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveLayout::SetShowGrainline(bool show)
{
@ -293,8 +334,7 @@ auto DialogSaveLayout::MakeHelpFormatList() -> QString
const auto formats = InitFormats();
for (int i = 0; i < formats.size(); ++i)
{
out += QStringLiteral("\t* ") + formats.at(i).first + QStringLiteral(" = ") +
QString::number(static_cast<int>(formats.at(i).second));
out += "\t* "_L1 + formats.at(i).first + " = "_L1 + QString::number(static_cast<int>(formats.at(i).second));
if (i < formats.size() - 1)
{
@ -308,6 +348,20 @@ auto DialogSaveLayout::MakeHelpFormatList() -> QString
return out;
}
//---------------------------------------------------------------------------------------------------------------------
auto DialogSaveLayout::MakeHelpDxfApparelCompatibilityList() -> QString
{
QString out("\n"_L1);
out += QStringLiteral("\t* %1 = %2,\n")
.arg(tr("By standard"))
.arg(static_cast<int>(DXFApparelCompatibility::STANDARD));
out += QStringLiteral("\t* Richpeace CAD V8 = %1,\n").arg(static_cast<int>(DXFApparelCompatibility::RPCADV08));
out += QStringLiteral("\t* Richpeace CAD V9 = %1,\n").arg(static_cast<int>(DXFApparelCompatibility::RPCADV09));
out += QStringLiteral("\t* Richpeace CAD V10 = %1.\n").arg(static_cast<int>(DXFApparelCompatibility::RPCADV10));
return out;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveLayout::SetDestinationPath(const QString &cmdDestinationPath)
{
@ -437,6 +491,8 @@ void DialogSaveLayout::ShowExample()
ui->checkBoxTextAsPaths->setEnabled(true);
ui->checkBoxShowGrainline->setVisible(false);
ui->checkBoxTogetherWithNotches->setVisible(false);
ui->labelDxfCompatibility->setVisible(false);
ui->comboBoxDxfCompatibility->setVisible(false);
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
@ -446,6 +502,8 @@ void DialogSaveLayout::ShowExample()
case LayoutExportFormats::DXF_ASTM:
ui->checkBoxBinaryDXF->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
ui->labelDxfCompatibility->setVisible(true);
ui->comboBoxDxfCompatibility->setVisible(true);
break;
case LayoutExportFormats::PDFTiled:
ui->groupBoxPaperFormat->setEnabled(true);
@ -808,6 +866,8 @@ void DialogSaveLayout::ReadSettings()
}
SetShowGrainline(settings->GetShowGrainline());
}
SetDxfCompatibility(static_cast<DXFApparelCompatibility>(settings->GetDxfCompatibility()));
}
//---------------------------------------------------------------------------------------------------------------------
@ -856,4 +916,19 @@ void DialogSaveLayout::WriteSettings() const
settings->SetLayoutExportFormat(static_cast<qint8>(Format()));
settings->SetShowGrainline(IsShowGrainline());
}
settings->SetDxfCompatibility(static_cast<qint8>(DxfCompatibility()));
}
//---------------------------------------------------------------------------------------------------------------------
void DialogSaveLayout::InitDxfCompatibility()
{
ui->comboBoxDxfCompatibility->addItem(tr("By standard"),
QVariant(static_cast<int>(DXFApparelCompatibility::STANDARD)));
ui->comboBoxDxfCompatibility->addItem("Richpeace CAD V8"_L1,
QVariant(static_cast<int>(DXFApparelCompatibility::RPCADV08)));
ui->comboBoxDxfCompatibility->addItem("Richpeace CAD V9"_L1,
QVariant(static_cast<int>(DXFApparelCompatibility::RPCADV09)));
ui->comboBoxDxfCompatibility->addItem("Richpeace CAD V10"_L1,
QVariant(static_cast<int>(DXFApparelCompatibility::RPCADV10)));
}

View File

@ -29,6 +29,7 @@
#ifndef DIALOGSAVELAYOUT_H
#define DIALOGSAVELAYOUT_H
#include "../vdxf/dxfdef.h"
#include "../vlayout/dialogs/vabstractlayoutdialog.h"
#include "../vlayout/vlayoutdef.h"
#include "../vmisc/def.h"
@ -56,10 +57,15 @@ public:
void SetBinaryDXFFormat(bool binary);
auto IsBinaryDXFFormat() const -> bool;
auto DxfCompatibility() const -> DXFApparelCompatibility;
void SetDxfCompatibility(DXFApparelCompatibility type);
void SetShowGrainline(bool show);
auto IsShowGrainline() const -> bool;
static auto MakeHelpFormatList() -> QString;
static auto MakeHelpDxfApparelCompatibilityList() -> QString;
void SetDestinationPath(const QString &cmdDestinationPath);
auto Mode() const -> Draw;
@ -117,6 +123,8 @@ private:
void ReadSettings();
void WriteSettings() const;
void InitDxfCompatibility();
};
#endif // DIALOGSAVELAYOUT_H

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>544</width>
<height>439</height>
<height>472</height>
</rect>
</property>
<property name="windowTitle">
@ -149,6 +149,20 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="labelDxfCompatibility">
<property name="text">
<string>Compatibility:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxDxfCompatibility"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="labelOptionsNotAvailable">
<property name="text">

View File

@ -33,6 +33,7 @@
#include "vabstractapplication.h"
#include <QMessageBox> // For QT_REQUIRE_VERSION
#include <QScopeGuard>
#include <QTimer>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@ -45,7 +46,7 @@
#endif
// Fix bug in Qt. Deprecation warning in QMessageBox::critical.
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) && QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#undef QT_REQUIRE_VERSION
#define QT_REQUIRE_VERSION(argc, argv, str) \
{ \

View File

@ -7227,6 +7227,8 @@ auto MainWindow::DoExport(const VCommandLinePtr &expParams) -> bool
m_dialogSaveLayout->SetDestinationPath(expParams->OptDestinationPath());
m_dialogSaveLayout->SelectFormat(static_cast<LayoutExportFormats>(expParams->OptExportType()));
m_dialogSaveLayout->SetBinaryDXFFormat(expParams->IsBinaryDXF());
m_dialogSaveLayout->SetDxfCompatibility(
static_cast<DXFApparelCompatibility>(expParams->DXFApparelCompatibilityType()));
m_dialogSaveLayout->SetShowGrainline(!expParams->IsNoGrainline());
m_dialogSaveLayout->SetTextAsPaths(expParams->IsTextAsPaths());
m_dialogSaveLayout->SetXScale(expParams->ExportXScale());
@ -7266,6 +7268,8 @@ auto MainWindow::DoExport(const VCommandLinePtr &expParams) -> bool
m_dialogSaveLayout->SetDestinationPath(expParams->OptDestinationPath());
m_dialogSaveLayout->SelectFormat(static_cast<LayoutExportFormats>(expParams->OptExportType()));
m_dialogSaveLayout->SetBinaryDXFFormat(expParams->IsBinaryDXF());
m_dialogSaveLayout->SetDxfCompatibility(
static_cast<DXFApparelCompatibility>(expParams->DXFApparelCompatibilityType()));
m_dialogSaveLayout->SetShowGrainline(!expParams->IsNoGrainline());
m_dialogSaveLayout->SetXScale(expParams->ExportXScale());
m_dialogSaveLayout->SetYScale(expParams->ExportYScale());

View File

@ -680,10 +680,12 @@ void MainWindowsNoGUI::ExportApparelLayout(const QVector<VLayoutPiece> &details,
{
case LayoutExportFormats::DXF_ASTM:
exporter.SetDxfVersion(DRW::AC1009);
exporter.SetDxfApparelCompatibility(m_dialogSaveLayout->DxfCompatibility());
exporter.ExportToASTMDXF(details);
break;
case LayoutExportFormats::DXF_AAMA:
exporter.SetDxfVersion(DRW::AC1009);
exporter.SetDxfApparelCompatibility(m_dialogSaveLayout->DxfCompatibility());
exporter.ExportToAAMADXF(details);
break;
case LayoutExportFormats::RLD:

View File

@ -109,8 +109,13 @@ void VAbstractConverter::ReserveFile() const
// For such cases we will store old version in a reserve file.
QString error;
QFileInfo const info(m_convertedFileName);
const QString reserveFileName = u"%1/%2(v%3).%4.bak"_s.arg(info.absoluteDir().absolutePath(), info.baseName(),
GetFormatVersionStr(), info.completeSuffix());
#if defined(Q_OS_UNIX) || defined(Q_OS_MACOS)
const QChar hidden = QChar('.');
#else
const QChar hidden;
#endif
const QString reserveFileName = u"%1/%2%3(v%4).%5.bak"_s.arg(
info.absoluteDir().absolutePath(), hidden, info.baseName(), GetFormatVersionStr(), info.completeSuffix());
if (not SafeCopy(m_convertedFileName, reserveFileName, error))
{
// #ifdef Q_OS_WIN32

View File

@ -51,6 +51,15 @@ enum class VarInsunits : quint8
Centimeters = 5
};
enum class DXFApparelCompatibility : qint8
{
STANDARD = 0, // According to specification AAMA/ASTM
RPCADV08 = 1, // Richpeace CAD V8
RPCADV09 = 2, // Richpeace CAD V9
RPCADV10 = 3, // Richpeace CAD V10
COUNT /*Use only for validation*/
};
// Helps mark end of string. See VDxfEngine::drawTextItem for more details
extern const QString endStringPlaceholder;

View File

@ -346,15 +346,13 @@ void dx_iface::AddASTMLayers()
layer.color = DRW::black;
cData.layers.push_back(layer);
// Do not support
// layer.name = '2';// turn points
// layer.color = DRW::black;
// cData.layers.push_back(layer);
layer.name = '2'; // turn points
layer.color = DRW::black;
cData.layers.push_back(layer);
// Do not support
// layer.name = '3';// curve points
// layer.color = DRW::black;
// cData.layers.push_back(layer);
layer.name = '3'; // curve points
layer.color = DRW::black;
cData.layers.push_back(layer);
layer.name = '4'; // V-notch and slit notch
layer.color = DRW::black;
@ -365,10 +363,9 @@ void dx_iface::AddASTMLayers()
// layer.color = DRW::black;
// cData.layers.push_back(layer);
// Do not support
// layer.name = '6';// mirror line
// layer.color = DRW::black;
// cData.layers.push_back(layer);
layer.name = '6'; // mirror line
layer.color = DRW::black;
cData.layers.push_back(layer);
layer.name = '7'; // grainline
layer.color = DRW::black;

View File

@ -249,14 +249,13 @@ static inline auto DRW_FuzzyComparePossibleNulls(double p1, double p2) -> bool
{
return qFuzzyIsNull(p2);
}
if (qFuzzyIsNull(p2))
{
return false;
}
else
{
return qFuzzyCompare(p1, p2);
}
return qFuzzyCompare(p1, p2);
}
//! Class to handle 3D coordinate point

View File

@ -194,7 +194,7 @@ auto dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin) -> bool
auto dxfRW::writeEntity(DRW_Entity *ent) -> bool
{
// A handle is an arbitrary but in your DXF file unique hex value as string like 10FF. It is common to to use
// A handle is arbitrary, but in your DXF file unique hex value as string like 10FF. It is common to to use
// uppercase letters for hex numbers. Handle can have up to 16 hexadecimal digits (8 bytes).
//
// For DXF R10 until R12 the usage of handles was optional. The header variable $HANDLING set to 1 indicate the
@ -223,8 +223,12 @@ auto dxfRW::writeEntity(DRW_Entity *ent) -> bool
{
writer->writeString(100, "AcDbEntity");
}
if (ent->space == 1)
{
writer->writeInt16(67, 1);
}
if (version > DRW::AC1009)
{
writer->writeUtf8String(8, ent->layer);
@ -1062,7 +1066,9 @@ auto dxfRW::writePolyline(DRW_Polyline *ent) -> bool
}
}
else
{
writer->writeInt16(66, 1);
}
writer->writeDouble(10, 0.0);
writer->writeDouble(20, 0.0);
writer->writeDouble(30, ent->basePoint.z);
@ -1508,24 +1514,64 @@ auto dxfRW::writeInsert(DRW_Insert *ent) -> bool
{
writer->writeString(0, "INSERT");
writeEntity(ent);
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbBlockReference");
writer->writeUtf8String(2, ent->name);
}
else
{
writer->writeUtf8Caps(2, ent->name);
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(41, ent->xscale);
writer->writeDouble(42, ent->yscale);
writer->writeDouble(43, ent->zscale);
writer->writeDouble(50, (ent->angle) * ARAD); // in dxf angle is writed in degrees
writer->writeInt16(70, ent->colcount);
writer->writeInt16(71, ent->rowcount);
writer->writeDouble(44, ent->colspace);
writer->writeDouble(45, ent->rowspace);
if (!qFuzzyIsNull(ent->basePoint.z))
{
writer->writeDouble(30, ent->basePoint.z);
}
if (!DRW_FuzzyComparePossibleNulls(ent->xscale, 1))
{
writer->writeDouble(41, ent->xscale);
}
if (!DRW_FuzzyComparePossibleNulls(ent->yscale, 1))
{
writer->writeDouble(42, ent->yscale);
}
if (!DRW_FuzzyComparePossibleNulls(ent->zscale, 1))
{
writer->writeDouble(43, ent->zscale);
}
if (!qFuzzyIsNull(ent->angle))
{
writer->writeDouble(50, (ent->angle) * ARAD); // in dxf angle is writed in degrees
}
if (!DRW_FuzzyComparePossibleNulls(ent->colcount, 1))
{
writer->writeInt16(70, ent->colcount);
}
if (!DRW_FuzzyComparePossibleNulls(ent->rowcount, 1))
{
writer->writeInt16(71, ent->rowcount);
}
if (!qFuzzyIsNull(ent->colspace))
{
writer->writeDouble(44, ent->colspace);
}
if (!qFuzzyIsNull(ent->rowspace))
{
writer->writeDouble(45, ent->rowspace);
}
return true;
}
@ -1540,7 +1586,10 @@ auto dxfRW::writeText(DRW_Text *ent) -> bool
// writer->writeDouble(39, ent->thickness);
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
if (not qFuzzyIsNull(ent->basePoint.z))
{
writer->writeDouble(30, ent->basePoint.z);
}
writer->writeDouble(40, ent->height);
writer->writeUtf8String(1, ent->text);
writer->writeDouble(50, ent->angle);
@ -1751,7 +1800,9 @@ auto dxfRW::writeBlock(DRW_Block *bk) -> bool
writer->writeUtf8String(2, bk->name);
}
else
{
writer->writeUtf8Caps(2, bk->name);
}
writer->writeInt16(70, bk->flags);
writer->writeDouble(10, bk->basePoint.x);
writer->writeDouble(20, bk->basePoint.y);
@ -1760,9 +1811,13 @@ auto dxfRW::writeBlock(DRW_Block *bk) -> bool
writer->writeDouble(30, bk->basePoint.z);
}
if (version > DRW::AC1009)
{
writer->writeUtf8String(3, bk->name);
}
else
{
writer->writeUtf8Caps(3, bk->name);
}
writer->writeString(1, "");
return true;

View File

@ -28,6 +28,7 @@
#include "vdxfengine.h"
#include <QApplication>
#include <QByteArray>
#include <QColor>
#include <QDateTime>
@ -36,6 +37,7 @@
#include <QFont>
#include <QLineF>
#include <QList>
#include <QLoggingCategory>
#include <QMessageLogger>
#include <QPaintEngineState>
#include <QPainterPath>
@ -70,6 +72,14 @@
using namespace Qt::Literals::StringLiterals;
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes")
QT_WARNING_DISABLE_INTEL(1418)
Q_LOGGING_CATEGORY(vDxf, "v.undo") // NOLINT
QT_WARNING_POP
namespace
{
const qreal AAMATextHeight = 2.5;
@ -214,13 +224,13 @@ auto VDxfEngine::begin(QPaintDevice *pdev) -> bool
if (isActive())
{
qWarning("VDxfEngine::begin(), the engine was alredy activated");
qCWarning(vDxf) << qUtf8Printable("VDxfEngine::begin(), the engine was alredy activated"_L1);
return false;
}
if (not m_size.isValid())
{
qWarning() << "VDxfEngine::begin(), size is not valid";
qCWarning(vDxf) << qUtf8Printable("VDxfEngine::begin(), size is not valid"_L1);
return false;
}
@ -735,6 +745,18 @@ auto VDxfEngine::IsBoundaryTogetherWithNotches() const -> bool
return m_togetherWithNotches;
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::DxfApparelCompatibility() const -> DXFApparelCompatibility
{
return m_compatibilityMode;
}
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::SetDxfApparelCompatibility(DXFApparelCompatibility mode)
{
m_compatibilityMode = mode;
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfEngine::ErrorString() const -> QString
{
@ -778,7 +800,7 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
{
if (not m_size.isValid())
{
qWarning() << "VDxfEngine::begin(), size is not valid";
qCWarning(vDxf) << qUtf8Printable("VDxfEngine::ExportToAAMA(), size is not valid"_L1);
return false;
}
@ -1111,9 +1133,24 @@ void VDxfEngine::ExportPieceText(const QSharedPointer<dx_ifaceBlock> &detailBloc
QVector<QPointF> const labelShape = detail.GetPieceLabelRect();
if (labelShape.count() != 4)
{
if (m_compatibilityMode == DXFApparelCompatibility::STANDARD)
{
qCWarning(vDxf) << qUtf8Printable(
QApplication::translate("VDxfEngine", "Piece '%1'. Piece System Text is missing.")
.arg(detail.GetName()));
}
return;
}
if (m_compatibilityMode == DXFApparelCompatibility::RPCADV08)
{
CheckLabelCompatibilityRPCADV08(detail);
}
else if (m_compatibilityMode == DXFApparelCompatibility::RPCADV09)
{
CheckLabelCompatibilityRPCADV09(detail);
}
const qreal scale = qMin(detail.GetXScale(), detail.GetYScale());
const qreal dW = QLineF(labelShape.at(0), labelShape.at(1)).length();
const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length();
@ -1251,6 +1288,13 @@ void VDxfEngine::ExportStyleSystemText(const QSharedPointer<dx_iface> &input, co
return;
}
}
if (m_compatibilityMode == DXFApparelCompatibility::STANDARD)
{
// According to ASTM standard Style System Text is mandatory.
// Some applications may refuse file without Style System Text.
qCWarning(vDxf) << qUtf8Printable(QApplication::translate("VDxfEngine", "Style System Text is missing."));
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -1315,7 +1359,7 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
{
if (not m_size.isValid())
{
qWarning() << "VDxfEngine::begin(), size is not valid";
qCWarning(vDxf) << qUtf8Printable("VDxfEngine::ExportToASTM(), size is not valid"_L1);
return false;
}
@ -1786,7 +1830,18 @@ auto VDxfEngine::ExportASTMNotch(const VLayoutPassmark &passmark) -> DRW_ASTMNot
notch->angle = passmark.baseLine.angle();
switch (passmark.type)
PassmarkLineType type = passmark.type;
if (m_compatibilityMode == DXFApparelCompatibility::RPCADV08 ||
m_compatibilityMode == DXFApparelCompatibility::RPCADV09 ||
m_compatibilityMode == DXFApparelCompatibility::RPCADV10)
{
if (type == PassmarkLineType::ExternalVMark || type == PassmarkLineType::InternalVMark)
{
type = PassmarkLineType::CheckMark;
}
}
switch (type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::TwoLines:
@ -1876,7 +1931,7 @@ auto VDxfEngine::ExportASTMNotchDataDependecy(const VLayoutPassmark &passmark, c
attdef->height = 3.0;
attdef->text = "Link:" + notchLayer;
attdef->name = "Dependency";
attdef->flags = 2; // this is a constant attribute
attdef->flags |= 0x2; // this is a constant attribute
attdef->horizontalAdjustment = 3; // aligned (if vertical alignment = 0)
return attdef;
@ -2135,6 +2190,77 @@ void VDxfEngine::ASTMDrawFoldLineTwoArrows(const QVector<QVector<QPointF>> &poin
}
}
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::CheckLabelCompatibilityRPCADV09(const VLayoutPiece &detail)
{
// According to ASTM standard Piece System Text is mandatory.
// Richpeace CAD V9. At least 'Piece Name:' or 'Size:' identifiers must be present.
const QStringList strings = detail.GetPieceText();
bool pieceNameFound = false;
bool sizeFound = false;
for (const QString &line : strings)
{
if (line.startsWith("Piece Name:"_L1))
{
pieceNameFound = true;
}
else if (line.startsWith("Size:"_L1))
{
sizeFound = true;
}
// Break the loop early if both conditions are met
if (pieceNameFound || sizeFound)
{
break;
}
}
if (!pieceNameFound && !sizeFound)
{
qCWarning(vDxf) << qUtf8Printable(
QApplication::translate("VDxfEngine", "Piece '%1'. 'Piece Name:' or 'Size:' identifier is missing.")
.arg(detail.GetName()));
}
}
//---------------------------------------------------------------------------------------------------------------------
void VDxfEngine::CheckLabelCompatibilityRPCADV08(const VLayoutPiece &detail)
{
// According to ASTM standard Piece System Text is mandatory.
// Richpeace CAD V8. If present 'Piece Name:' identifier, 'Size:' identifier must also be present.
const QStringList strings = detail.GetPieceText();
bool pieceNameFound = false;
bool sizeFound = false;
for (const QString &line : strings)
{
if (line.startsWith("Piece Name:"_L1))
{
pieceNameFound = true;
}
else if (line.startsWith("Size:"_L1))
{
sizeFound = true;
}
// Break the loop early if both conditions are met
if (pieceNameFound && sizeFound)
{
break;
}
}
if (pieceNameFound && !sizeFound)
{
qCWarning(vDxf) << qUtf8Printable(
QApplication::translate("VDxfEngine",
"Piece '%1'. 'Piece Name:' identifier requires 'Size:' identifier to be present.")
.arg(detail.GetName()));
}
}
//---------------------------------------------------------------------------------------------------------------------
template <class P, class V, class C>
auto VDxfEngine::CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer, bool forceClosed) -> P *
@ -2156,7 +2282,17 @@ auto VDxfEngine::CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &
for (const auto &p : polygon)
{
poly->addVertex(V(FromPixel(p.x(), m_varInsunits), FromPixel(GetSize().height() - p.y(), m_varInsunits)));
V vertex(FromPixel(p.x(), m_varInsunits), FromPixel(GetSize().height() - p.y(), m_varInsunits));
if constexpr (std::is_same_v<V, DRW_Vertex>)
{
if (p.CurvePoint())
{
vertex.flags |= 0x1;
}
}
poly->addVertex(vertex);
}
return poly;

View File

@ -117,6 +117,9 @@ public:
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
auto DxfApparelCompatibility() const -> DXFApparelCompatibility;
void SetDxfApparelCompatibility(DXFApparelCompatibility mode);
auto ErrorString() const -> QString;
private:
@ -135,6 +138,7 @@ private:
qreal m_xscale{1};
qreal m_yscale{1};
bool m_togetherWithNotches{false};
DXFApparelCompatibility m_compatibilityMode{DXFApparelCompatibility::STANDARD};
Q_REQUIRED_RESULT auto FromPixel(double pix, const VarInsunits &unit) const -> double;
Q_REQUIRED_RESULT auto ToPixel(double val, const VarInsunits &unit) const -> double;
@ -200,6 +204,9 @@ private:
void ASTMDrawFoldLineTwoArrows(const QVector<QVector<QPointF>> &points,
const QSharedPointer<dx_ifaceBlock> &detailBlock);
static void CheckLabelCompatibilityRPCADV09(const VLayoutPiece &detail);
static void CheckLabelCompatibilityRPCADV08(const VLayoutPiece &detail);
};
#endif // VDXFENGINE_H

View File

@ -214,6 +214,24 @@ auto VDxfPaintDevice::IsBoundaryTogetherWithNotches() const -> bool
return m_engine->IsBoundaryTogetherWithNotches();
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfPaintDevice::DxfApparelCompatibility() const -> DXFApparelCompatibility
{
return m_engine->DxfApparelCompatibility();
}
//---------------------------------------------------------------------------------------------------------------------
void VDxfPaintDevice::SetDxfApparelCompatibility(DXFApparelCompatibility mode)
{
if (m_engine->isActive())
{
qWarning("VDxfPaintDevice::SetDxfApparelCompatibility(), cannot set compatibility mode while Dxf is being "
"generated");
return;
}
m_engine->SetDxfApparelCompatibility(mode);
}
//---------------------------------------------------------------------------------------------------------------------
auto VDxfPaintDevice::ExportToAAMA(const QVector<VLayoutPiece> &details) const -> bool
{

View File

@ -75,6 +75,9 @@ public:
void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool;
auto DxfApparelCompatibility() const -> DXFApparelCompatibility;
void SetDxfApparelCompatibility(DXFApparelCompatibility mode);
auto ExportToAAMA(const QVector<VLayoutPiece> &details) const -> bool;
auto ExportToASTM(const QVector<VLayoutPiece> &details) const -> bool;

View File

@ -290,6 +290,12 @@ void VFoldLine::UpdateFoldLineLabel(QGraphicsSimpleTextItem *item) const
return;
}
if (m_foldLine.isNull())
{
item->setVisible(false);
return;
}
if (m_type == FoldLineType::TwoArrows || m_type == FoldLineType::ThreeDots || m_type == FoldLineType::ThreeX ||
m_type == FoldLineType::None)
{

View File

@ -128,6 +128,18 @@ void RestoreDetailsAfterDXF(const QString &placeholder, const QList<QGraphicsIte
}
} // namespace
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutExporter::DxfApparelCompatibility() const -> DXFApparelCompatibility
{
return m_dxfCompatibility;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutExporter::SetDxfApparelCompatibility(DXFApparelCompatibility mode)
{
m_dxfCompatibility = mode;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutExporter::IsShowGrainline() const -> bool
{
@ -325,6 +337,7 @@ void VLayoutExporter::ExportToAAMADXF(const QVector<VLayoutPiece> &details) cons
generator.SetXScale(m_xScale);
generator.SetYScale(m_yScale);
generator.SetBoundaryTogetherWithNotches(m_togetherWithNotches);
generator.SetDxfApparelCompatibility(m_dxfCompatibility);
if (not generator.ExportToAAMA(details))
{
qCritical() << tr("Can't create an AAMA dxf file.") << generator.ErrorString();
@ -344,6 +357,7 @@ void VLayoutExporter::ExportToASTMDXF(const QVector<VLayoutPiece> &details) cons
generator.SetXScale(m_xScale);
generator.SetYScale(m_yScale);
generator.SetBoundaryTogetherWithNotches(m_togetherWithNotches);
generator.SetDxfApparelCompatibility(m_dxfCompatibility);
if (not generator.ExportToASTM(details))
{
qCritical() << tr("Can't create an ASTM dxf file.") << generator.ErrorString();

View File

@ -34,6 +34,7 @@
#include <QRectF>
#include <QString>
#include "../vdxf/dxfdef.h"
#include "../vlayout/vlayoutdef.h"
class QGraphicsScene;
@ -77,6 +78,9 @@ public:
auto BinaryDxfFormat() const -> bool;
void SetBinaryDxfFormat(bool binaryFormat);
auto DxfApparelCompatibility() const -> DXFApparelCompatibility;
void SetDxfApparelCompatibility(DXFApparelCompatibility mode);
auto IsShowGrainline() const -> bool;
void SetShowGrainline(bool show);
@ -138,6 +142,7 @@ private:
bool m_singleStrokeOutlineFont{false};
int m_penWidth{1};
bool m_togetherWithNotches{false};
DXFApparelCompatibility m_dxfCompatibility{DXFApparelCompatibility::STANDARD};
void ExportToPDF(QGraphicsScene *scene, const QList<QGraphicsItem *> &details, const QString &filename) const;
};

View File

@ -46,6 +46,7 @@ const QString SINGLE_OPTION_PAGETEMPLATE = QStringLiteral("p");
const QString LONG_OPTION_EXP2FORMAT = QStringLiteral("format");
const QString SINGLE_OPTION_EXP2FORMAT = QStringLiteral("f");
const QString LONG_OPTION_DXF_APPAREL_COMP = QStringLiteral("dxfApparelComp");
const QString LONG_OPTION_BINARYDXF = QStringLiteral("bdxf");
const QString LONG_OPTION_NOGRAINLINE = QStringLiteral("noGrainline"); // NOLINT
const QString LONG_OPTION_TEXT2PATHS = QStringLiteral("text2paths");
@ -152,6 +153,7 @@ auto AllKeys() -> QStringList
SINGLE_OPTION_PAGETEMPLATE,
LONG_OPTION_EXP2FORMAT,
SINGLE_OPTION_EXP2FORMAT,
LONG_OPTION_DXF_APPAREL_COMP,
LONG_OPTION_BINARYDXF,
LONG_OPTION_NOGRAINLINE,
LONG_OPTION_TEXT2PATHS,

View File

@ -46,6 +46,7 @@ extern const QString SINGLE_OPTION_PAGETEMPLATE;
extern const QString LONG_OPTION_EXP2FORMAT;
extern const QString SINGLE_OPTION_EXP2FORMAT;
extern const QString LONG_OPTION_DXF_APPAREL_COMP;
extern const QString LONG_OPTION_BINARYDXF;
extern const QString LONG_OPTION_NOGRAINLINE;
extern const QString LONG_OPTION_TEXT2PATHS;

View File

@ -44,7 +44,7 @@ public:
#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;
static auto GetPlatformString(const QString &string) -> std::wstring;
#else
#error GetPlatformString not implemented on this platform
#endif

View File

@ -40,6 +40,7 @@
#include <QLibraryInfo>
#include <QLoggingCategory>
#include <QMessageLogger>
#include <QScopeGuard>
#include <QStandardPaths>
#include <QTranslator>
#include <QUndoStack>

View File

@ -107,8 +107,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingTextAsPaths, ("layout/textAsPath
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingNestingTime, ("layout/time"_L1)) // NOLINT
// NOLINTNEXTLINE
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingEfficiencyCoefficient, ("layout/efficiencyCoefficient"_L1))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutExportFormat, ("layout/exportFormat"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingDetailExportFormat, ("detail/exportFormat"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingLayoutExportFormat, ("layout/exportFormat"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingDetailExportFormat, ("detail/exportFormat"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingDxfCompatibility, ("layout/dxfCompatibility"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingTiledPDFPaperHeight, ("tiledPDF/paperHeight"_L1)) // NOLINT
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingTiledPDFPaperWidth, ("tiledPDF/paperWidth"_L1)) // NOLINT
@ -774,6 +775,18 @@ void VValentinaSettings::SetDetailExportFormat(qint8 format)
setValue(*settingDetailExportFormat, format);
}
//---------------------------------------------------------------------------------------------------------------------
auto VValentinaSettings::GetDxfCompatibility() const -> qint8
{
return CastToLayoutExportFormat(qvariant_cast<qint8>(value(*settingDxfCompatibility, 0)));
}
//---------------------------------------------------------------------------------------------------------------------
void VValentinaSettings::SetDxfCompatibility(qint8 type)
{
setValue(*settingDxfCompatibility, type);
}
//---------------------------------------------------------------------------------------------------------------------
auto VValentinaSettings::GetHistorySearchHistory() const -> QStringList
{

View File

@ -182,6 +182,9 @@ public:
auto GetDetailExportFormat() const -> qint8;
void SetDetailExportFormat(qint8 format);
auto GetDxfCompatibility() const -> qint8;
void SetDxfCompatibility(qint8 type);
auto GetHistorySearchHistory() const -> QStringList;
void SetHistorySearchHistory(const QStringList &history);

View File

@ -484,7 +484,7 @@ auto CreateUMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &l
auto CreateBoxMarkPassmark(const VPiecePassmarkData &passmarkData, const QLineF &line,
const QVector<QPointF> &seamAllowance) -> QVector<QLineF>
{
const qreal defWidth = line.length() * VPassmark::passmarkRadiusFactor;
const qreal defWidth = line.length() * VPassmark::passmarkRadiusFactor * 2;
const qreal width = PassmarkWidth(passmarkData, defWidth);
QPointF l1p1;

View File

@ -2740,10 +2740,7 @@ void VToolSeamAllowance::UpdateFoldLine(const VFoldLine &foldLine)
if (detail.GetFoldLineType() == FoldLineType::ThreeDots || detail.GetFoldLineType() == FoldLineType::ThreeX ||
detail.GetFoldLineType() == FoldLineType::TwoArrows)
{
if (!shape.isEmpty())
{
m_foldLineMark->setPath(shape.constFirst());
}
m_foldLineMark->setPath(!shape.isEmpty() ? shape.constFirst() : QPainterPath());
m_foldLineLabel->setPath(QPainterPath());
}
else if (detail.GetFoldLineType() == FoldLineType::Text)
@ -2765,10 +2762,7 @@ void VToolSeamAllowance::UpdateFoldLine(const VFoldLine &foldLine)
}
else
{
if (!shape.isEmpty())
{
m_foldLineMark->setPath(shape.constFirst());
}
m_foldLineMark->setPath(!shape.isEmpty() ? shape.constFirst() : QPainterPath());
if (shape.size() > 1 && (settings->GetSingleStrokeOutlineFont() || settings->GetSingleLineFonts()))
{

View File

@ -26,6 +26,7 @@
**
*************************************************************************/
#include <QScopeGuard>
#include <QtTest>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)

View File

@ -10,6 +10,7 @@ Project {
property bool enableConan: false
property bool conanWithXerces: false
property bool conanWithCrashReporting: false
property string conanRemote
property string minimumMacosVersion: undefined
property string minimumQtVersion: "5.15"
property stringList conanProfiles: []
@ -22,6 +23,7 @@ Project {
conanfilePath: project.sourceDirectory + "/conanfile.py"
verbose: true
profiles: conanProfiles
remote: conanRemote
options: {
var o = {};
if (conanWithXerces)