Merge remote-tracking branch 'refs/remotes/upstream/feature/manual-layout'

Conflicts:
	src/app/puzzle/vpmainwindow.cpp
	src/app/puzzle/vpmainwindow.h
This commit is contained in:
Ronan 2021-05-22 09:11:48 +02:00
commit c9a25613f5
81 changed files with 22238 additions and 1619 deletions

View File

@ -53,6 +53,3 @@ unix {
TEMPLATE = subdirs TEMPLATE = subdirs
SUBDIRS = src SUBDIRS = src
RESOURCES += \
src/app/puzzle/share/resources/puzzleicon.qrc

1
dist/debian/menu vendored
View File

@ -1,2 +1,3 @@
?package(valentina): needs="X11" section="Applications/Graphics" title="Valentina" command="valentina" ?package(valentina): needs="X11" section="Applications/Graphics" title="Valentina" command="valentina"
?package(valentina): needs="X11" section="Applications/Data Management" title="Tape" command="tape" ?package(valentina): needs="X11" section="Applications/Data Management" title="Tape" command="tape"
?package(valentina): needs="X11" section="Applications/Data Management" title="Puzzle" command="puzzle"

View File

@ -50,10 +50,6 @@ Disable high dpi scaling. Call this option if has problem with scaling (by defau
\- the manual layout file. \- the manual layout file.
.SH AUTHOR .SH AUTHOR
.RI "This manual page was written by Roman Telezhynskyi <" dismine@gmail.com ">" .RI "This manual page was written by Roman Telezhynskyi <" dismine@gmail.com ">"
.SH "SEE ALSO"
.RB "Full " "User Manual" " is availiable in"
.UR https://bitbucket.org/dismine/valentina/wiki/manual/Content
.UE
.BR valentina (1) .BR valentina (1)

View File

@ -1,10 +1,13 @@
debian/usr/share/pixmaps/valentina.png debian/usr/share/pixmaps/valentina.png
debian/usr/share/pixmaps/tape.png debian/usr/share/pixmaps/tape.png
debian/usr/share/pixmaps/puzzle.png
debian/usr/share/pixmaps/application-x-valentina-pattern.png debian/usr/share/pixmaps/application-x-valentina-pattern.png
debian/usr/share/pixmaps/application-x-valentina-i-measurements.png debian/usr/share/pixmaps/application-x-valentina-i-measurements.png
debian/usr/share/pixmaps/application-x-valentina-s-measurements.png debian/usr/share/pixmaps/application-x-valentina-s-measurements.png
debian/usr/share/pixmaps/application-x-valentina-layout.png
debian/valentina/usr/bin/valentina debian/valentina/usr/bin/valentina
debian/valentina/usr/bin/tape debian/valentina/usr/bin/tape
debian/valentina/usr/bin/puzzle
debian/valentina/usr/share/valentina/diagrams.rcc debian/valentina/usr/share/valentina/diagrams.rcc
debian/valentina/usr/share/valentina/translations/measurements_p0_cs_CZ.qm debian/valentina/usr/share/valentina/translations/measurements_p0_cs_CZ.qm
debian/valentina/usr/share/valentina/translations/measurements_p0_de_DE.qm debian/valentina/usr/share/valentina/translations/measurements_p0_de_DE.qm

View File

@ -1,2 +1,3 @@
debian/valentina.1 debian/valentina.1
debian/tape.1 debian/tape.1
debian/puzzle.1

View File

@ -1,3 +1,4 @@
application/x-valentina-pattern; valentina %s; nametemplate=%s.val; description="Valentina pattern" edit=valentina '%s'; priority=6 application/x-valentina-pattern; valentina %s; nametemplate=%s.val; description="Valentina pattern" edit=valentina '%s'; priority=6
application/x-valentina-i-pattern; tape %s; nametemplate=%s.vit; description="Valentina individual measurments" edit=tape '%s'; priority=6 application/x-valentina-i-pattern; tape %s; nametemplate=%s.vit; description="Valentina individual measurments" edit=tape '%s'; priority=6
application/x-valentina-s-pattern; tape %s; nametemplate=%s.vst; description="Valentina standard measurments" edit=tape '%s'; priority=6 application/x-valentina-s-pattern; tape %s; nametemplate=%s.vst; description="Valentina standard measurments" edit=tape '%s'; priority=6
application/x-valentina-layout; puzzle %s; nametemplate=%s.vlt; description="Valentina layout" edit=puzzle '%s'; priority=6

View File

@ -282,4 +282,98 @@
<glob pattern="*.vst"/> <glob pattern="*.vst"/>
<icon name="application-x-valentina-s-measurements"/> <icon name="application-x-valentina-s-measurements"/>
</mime-type> </mime-type>
<mime-type type="application/x-valentina-layout">
<sub-class-of type="text/xml"/>
<_comment>Valentina layout</_comment>
<comment xml:lang="af">Valentina layout</comment>
<comment xml:lang="ar">Valentina layout</comment>
<comment xml:lang="as">Valentina layout</comment>
<comment xml:lang="ast">Valentina layout</comment>
<comment xml:lang="be">Valentina layout</comment>
<comment xml:lang="bg">Valentina layout</comment>
<comment xml:lang="bn">Valentina layout</comment>
<comment xml:lang="br">Valentina layout</comment>
<comment xml:lang="bs">Valentina layout</comment>
<comment xml:lang="ca">Valentina layout</comment>
<comment xml:lang="ca-valencia">Valentina layout</comment>
<comment xml:lang="cs">Valentina layout</comment>
<comment xml:lang="cy">Valentina layout</comment>
<comment xml:lang="da">Valentina layout</comment>
<comment xml:lang="de">Valentina layout</comment>
<comment xml:lang="dz">Valentina layout</comment>
<comment xml:lang="el">Valentina layout</comment>
<comment xml:lang="en-GB">Valentina layout</comment>
<comment xml:lang="en-ZA">Valentina layout</comment>
<comment xml:lang="eo">Valentina layout</comment>
<comment xml:lang="es">Valentina layout</comment>
<comment xml:lang="et">Valentina layout</comment>
<comment xml:lang="eu">Valentina layout</comment>
<comment xml:lang="fa">Valentina layout</comment>
<comment xml:lang="fi">Valentina layout</comment>
<comment xml:lang="fr">Valentina layout</comment>
<comment xml:lang="ga">Valentina layout</comment>
<comment xml:lang="gd">Valentina layout</comment>
<comment xml:lang="gl">Valentina layout</comment>
<comment xml:lang="gu">Valentina layout</comment>
<comment xml:lang="he">Valentina layout</comment>
<comment xml:lang="hi">Valentina layout</comment>
<comment xml:lang="hr">Valentina layout</comment>
<comment xml:lang="hu">Valentina layout</comment>
<comment xml:lang="id">Valentina layout</comment>
<comment xml:lang="is">Valentina layout</comment>
<comment xml:lang="it">Valentina layout</comment>
<comment xml:lang="ja">Valentina layout</comment>
<comment xml:lang="ka">Valentina layout</comment>
<comment xml:lang="kk">Valentina layout</comment>
<comment xml:lang="km">Valentina layout</comment>
<comment xml:lang="kmr-Latn">Valentina layout</comment>
<comment xml:lang="ko">Valentina layout</comment>
<comment xml:lang="lt">Valentina layout</comment>
<comment xml:lang="lv">Valentina layout</comment>
<comment xml:lang="mk">Valentina layout</comment>
<comment xml:lang="ml">Valentina layout</comment>
<comment xml:lang="mn">Valentina layout</comment>
<comment xml:lang="mr">Valentina layout</comment>
<comment xml:lang="nb">Valentina layout</comment>
<comment xml:lang="ne">Valentina layout</comment>
<comment xml:lang="nl">Valentina layout</comment>
<comment xml:lang="nn">Valentina layout</comment>
<comment xml:lang="nr">Valentina layout</comment>
<comment xml:lang="nso">Valentina layout</comment>
<comment xml:lang="oc">Valentina layout</comment>
<comment xml:lang="om">Valentina layout</comment>
<comment xml:lang="or">Valentina layout</comment>
<comment xml:lang="pa-IN">Valentina layout</comment>
<comment xml:lang="pl">Valentina layout</comment>
<comment xml:lang="pt">Valentina layout</comment>
<comment xml:lang="pt-BR">Valentina layout</comment>
<comment xml:lang="ro">Valentina layout</comment>
<comment xml:lang="ru">Valentina раскладка</comment>
<comment xml:lang="rw">Valentina layout</comment>
<comment xml:lang="si">Valentina layout</comment>
<comment xml:lang="sk">Valentina layout</comment>
<comment xml:lang="sl">Valentina layout</comment>
<comment xml:lang="sr">Valentina layout</comment>
<comment xml:lang="ss">Valentina layout</comment>
<comment xml:lang="st">Valentina layout</comment>
<comment xml:lang="sv">Valentina layout</comment>
<comment xml:lang="ta">Valentina layout</comment>
<comment xml:lang="te">Valentina layout</comment>
<comment xml:lang="tg">Valentina layout</comment>
<comment xml:lang="th">Valentina layout</comment>
<comment xml:lang="tn">Valentina layout</comment>
<comment xml:lang="tr">Valentina layout</comment>
<comment xml:lang="ts">Valentina layout</comment>
<comment xml:lang="ug">Valentina layout</comment>
<comment xml:lang="uk">Valentina розкладка</comment>
<comment xml:lang="uz">Valentina layout</comment>
<comment xml:lang="ve">Valentina layout</comment>
<comment xml:lang="vi">Valentina layout</comment>
<comment xml:lang="xh">Valentina layout</comment>
<comment xml:lang="zh-CN">Valentina layout</comment>
<comment xml:lang="zh-TW">Valentina layout</comment>
<comment xml:lang="zu">Valentina layout</comment>
<glob pattern="*.vlt"/>
<icon name="application-x-valentina-layout"/>
</mime-type>
</mime-info> </mime-info>

View File

@ -59,6 +59,7 @@ src_install() {
doman dist/debian/${PN}.1 doman dist/debian/${PN}.1
doman dist/debian/tape.1 doman dist/debian/tape.1
doman dist/debian/puzzle.1
cp dist/debian/valentina.sharedmimeinfo dist/debian/${PN}.xml || die cp dist/debian/valentina.sharedmimeinfo dist/debian/${PN}.xml || die
insinto /usr/share/mime/packages insinto /usr/share/mime/packages

BIN
dist/macx/layout.icns vendored Normal file

Binary file not shown.

View File

@ -9,9 +9,9 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>10.6</string> <string>10.7</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>© 2013-2020, Valentina project</string> <string>© 2013-2021, Valentina project</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>@TYPEINFO@</string> <string>@TYPEINFO@</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
@ -19,11 +19,53 @@
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>io.bitbucket.valentinaproject.@EXECUTABLE@</string> <string>io.bitbucket.valentinaproject.@EXECUTABLE@</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.7.0</string> <string>0.7.47</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.7.0.0</string> <string>0.7.47.0</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleTypeIconFile</key>
<string>layout.incs</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bitbucket.valentinaproject.vlt</string>
</array>
<key>CFBundleTypeName</key>
<string>Valentina layout</string>
<key>LSHandlerRank</key>
<string>Owner</string>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.text</string>
<string>public.xml</string>
</array>
<key>UTTypeDescription</key>
<string>Valentina layout</string>
<key>UTTypeIconFile</key>
<string>layout.icns</string>
<key>UTTypeIdentifier</key>
<string>io.bitbucket.valentinaproject.vlt</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>vlt</string>
</array>
<key>public.mime-type</key>
<string>text/xml</string>
</dict>
</dict>
</array>
<key>NSRequiresAquaSystemAppearance</key> <key>NSRequiresAquaSystemAppearance</key>
<true/> <true/>
</dict> </dict>

14
dist/puzzle.desktop vendored Normal file
View File

@ -0,0 +1,14 @@
[Desktop Entry]
Type=Application
Name=Puzzle
Exec=puzzle %F
Version=1.0
GenericName=Valentina's layout editor
Comment=Create and edit layouts
Comment[uk]=Створюйте і редагуйте розкладки
Comment[ru]=Создавайте и редактируйте раскладку
Icon=puzzle
Terminal=false
MimeType=application/x-valentina-layout;
Categories=Qt;Utility;FileTools;
TryExec=puzzle

View File

@ -151,6 +151,9 @@ gzip -9c dist/debian/%{name}.1 > dist/debian/%{name}.1.gz &&
gzip -9c dist/debian/tape.1 > dist/debian/tape.1.gz && gzip -9c dist/debian/tape.1 > dist/debian/tape.1.gz &&
%{__install} -Dm 644 dist/debian/tape.1.gz %{buildroot}%{_mandir}/man1/tape.1.gz %{__install} -Dm 644 dist/debian/tape.1.gz %{buildroot}%{_mandir}/man1/tape.1.gz
gzip -9c dist/debian/puzzle.1 > dist/debian/puzzle.1.gz &&
%{__install} -Dm 644 dist/debian/puzzle.1.gz %{buildroot}%{_mandir}/man1/puzzle.1.gz
cp dist/debian/valentina.sharedmimeinfo dist/debian/%{name}.xml && cp dist/debian/valentina.sharedmimeinfo dist/debian/%{name}.xml &&
%{__install} -Dm 644 dist/debian/%{name}.xml %{buildroot}%{_datadir}/mime/packages/%{name}.xml %{__install} -Dm 644 dist/debian/%{name}.xml %{buildroot}%{_datadir}/mime/packages/%{name}.xml
@ -160,6 +163,7 @@ cp dist/debian/valentina.mime dist/debian/%{name} &&
%if 0%{?suse_version} > 0 %if 0%{?suse_version} > 0
%suse_update_desktop_file -r %{name} Graphics VectorGraphics 2DGraphics %suse_update_desktop_file -r %{name} Graphics VectorGraphics 2DGraphics
%suse_update_desktop_file -r tape Utility Applet %suse_update_desktop_file -r tape Utility Applet
%suse_update_desktop_file -r puzzle Utility Applet
%endif %endif
%post %post
@ -194,8 +198,10 @@ fi
%license LICENSE_GPL.txt %license LICENSE_GPL.txt
%doc %{_mandir}/man1/%{name}.1* %doc %{_mandir}/man1/%{name}.1*
%doc %{_mandir}/man1/tape.1* %doc %{_mandir}/man1/tape.1*
%doc %{_mandir}/man1/puzzle.1*
%{_bindir}/valentina %{_bindir}/valentina
%{_bindir}/tape %{_bindir}/tape
%{_bindir}/puzzle
%{_libdir}/libvpropertyexplorer.so %{_libdir}/libvpropertyexplorer.so
%{_libdir}/libvpropertyexplorer.so.* %{_libdir}/libvpropertyexplorer.so.*
%{_libdir}/libqmuparser.so %{_libdir}/libqmuparser.so
@ -208,6 +214,7 @@ fi
%{_datadir}/mime/packages/%{name}.xml %{_datadir}/mime/packages/%{name}.xml
%{_datadir}/applications/%{name}.desktop %{_datadir}/applications/%{name}.desktop
%{_datadir}/applications/tape.desktop %{_datadir}/applications/tape.desktop
%{_datadir}/applications/puzzle.desktop
%dir %{_datadir}/icons/ %dir %{_datadir}/icons/
%dir %{_datadir}/icons/hicolor/ %dir %{_datadir}/icons/hicolor/
@ -242,7 +249,7 @@ fi
%{_datadir}/%{name}/labels/*.xml %{_datadir}/%{name}/labels/*.xml
%clean %clean
rm -f dist/debian/%{name}.1.gz dist/debian/tape.1.gz dist/debian/%{name}.xml dist/debian/%{name} rm -f dist/debian/%{name}.1.gz dist/debian/tape.1.gz dist/debian/puzzle.1.gz dist/debian/%{name}.xml dist/debian/%{name}
[ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot} [ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}

View File

@ -86,6 +86,7 @@ Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescrip
Name: "fileassoc1"; Description: "{cm:CreateFileAssocVal}"; GroupDescription: "{cm:FileAssoc}" Name: "fileassoc1"; Description: "{cm:CreateFileAssocVal}"; GroupDescription: "{cm:FileAssoc}"
Name: "fileassoc2"; Description: "{cm:CreateFileAssocVit}"; GroupDescription: "{cm:FileAssoc}" Name: "fileassoc2"; Description: "{cm:CreateFileAssocVit}"; GroupDescription: "{cm:FileAssoc}"
Name: "fileassoc3"; Description: "{cm:CreateFileAssocVst}"; GroupDescription: "{cm:FileAssoc}" Name: "fileassoc3"; Description: "{cm:CreateFileAssocVst}"; GroupDescription: "{cm:FileAssoc}"
Name: "fileassoc4"; Description: "{cm:CreateFileAssocVlt}"; GroupDescription: "{cm:FileAssoc}"
Name: "deletesettings"; Description: "{cm:RemoveAnyExistingSettings}"; GroupDescription: "{cm:ManageSettings}"; Flags: unchecked Name: "deletesettings"; Description: "{cm:RemoveAnyExistingSettings}"; GroupDescription: "{cm:ManageSettings}"; Flags: unchecked
[Types] [Types]
@ -161,6 +162,7 @@ Name: "lang_files\chinese"; Description: "Chinese (China)"; Types: full custom;
; Signing ; Signing
Source: ".\valentina\valentina.exe"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\valentina.exe"; DestDir: "{app}"; Flags: ignoreversion sign
Source: ".\valentina\tape.exe"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\tape.exe"; DestDir: "{app}"; Flags: ignoreversion sign
Source: ".\valentina\puzzle.exe"; DestDir: "{app}"; Flags: ignoreversion sign
Source: ".\valentina\vpropertyexplorer.dll"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\vpropertyexplorer.dll"; DestDir: "{app}"; Flags: ignoreversion sign
Source: ".\valentina\qmuparser2.dll"; DestDir: "{app}"; Flags: ignoreversion sign Source: ".\valentina\qmuparser2.dll"; DestDir: "{app}"; Flags: ignoreversion sign
; Localizations ; Localizations
@ -249,6 +251,7 @@ Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChang
Root: "HKCR"; Subkey: ".val"; ValueType: string; ValueName: ""; ValueData: "Valentina.Pattern"; Flags: uninsdeletevalue; Tasks: fileassoc1 Root: "HKCR"; Subkey: ".val"; ValueType: string; ValueName: ""; ValueData: "Valentina.Pattern"; Flags: uninsdeletevalue; Tasks: fileassoc1
Root: "HKCR"; Subkey: ".vit"; ValueType: string; ValueName: ""; ValueData: "Valentina.IndividualMeasurements"; Flags: uninsdeletevalue; Tasks: fileassoc2 Root: "HKCR"; Subkey: ".vit"; ValueType: string; ValueName: ""; ValueData: "Valentina.IndividualMeasurements"; Flags: uninsdeletevalue; Tasks: fileassoc2
Root: "HKCR"; Subkey: ".vst"; ValueType: string; ValueName: ""; ValueData: "Valentina.StandardMeasurements"; Flags: uninsdeletevalue; Tasks: fileassoc3 Root: "HKCR"; Subkey: ".vst"; ValueType: string; ValueName: ""; ValueData: "Valentina.StandardMeasurements"; Flags: uninsdeletevalue; Tasks: fileassoc3
Root: "HKCR"; Subkey: ".vlt"; ValueType: string; ValueName: ""; ValueData: "Valentina.Layout"; Flags: uninsdeletevalue; Tasks: fileassoc3
Root: "HKCR"; Subkey: "Valentina.Pattern"; ValueType: string; ValueData: "Valentina pattern file"; Flags: uninsdeletekey; Tasks: fileassoc1 Root: "HKCR"; Subkey: "Valentina.Pattern"; ValueType: string; ValueData: "Valentina pattern file"; Flags: uninsdeletekey; Tasks: fileassoc1
Root: "HKCR"; Subkey: "Valentina.Pattern\DefaultIcon"; ValueType: string; ValueData: "{app}\pattern.ico,0"; Tasks: fileassoc1 Root: "HKCR"; Subkey: "Valentina.Pattern\DefaultIcon"; ValueType: string; ValueData: "{app}\pattern.ico,0"; Tasks: fileassoc1
@ -262,6 +265,10 @@ Root: "HKCR"; Subkey: "Valentina.StandardMeasurements"; ValueType: string; Value
Root: "HKCR"; Subkey: "Valentina.StandardMeasurements\DefaultIcon"; ValueType: string; ValueData: "{app}\s-measurements.ico,0"; Tasks: fileassoc3 Root: "HKCR"; Subkey: "Valentina.StandardMeasurements\DefaultIcon"; ValueType: string; ValueData: "{app}\s-measurements.ico,0"; Tasks: fileassoc3
Root: "HKCR"; Subkey: "Valentina.StandardMeasurements\shell\open\command"; ValueType: string; ValueData: """{app}\tape.exe"" ""%1"""; Tasks: fileassoc3 Root: "HKCR"; Subkey: "Valentina.StandardMeasurements\shell\open\command"; ValueType: string; ValueData: """{app}\tape.exe"" ""%1"""; Tasks: fileassoc3
Root: "HKCR"; Subkey: "Valentina.Layout"; ValueType: string; ValueData: "Valentina layout file"; Flags: uninsdeletekey; Tasks: fileassoc1
Root: "HKCR"; Subkey: "Valentina.Layout\DefaultIcon"; ValueType: string; ValueData: "{app}\layout.ico,0"; Tasks: fileassoc1
Root: "HKCR"; Subkey: "Valentina.Layout\shell\open\command"; ValueType: string; ValueData: """{app}\puzzle.exe"" ""%1"""; Tasks: fileassoc1
[CustomMessages] [CustomMessages]
FileAssoc = Create file associations FileAssoc = Create file associations
english.FileAssoc = Create file associations english.FileAssoc = Create file associations
@ -287,6 +294,12 @@ russian.CreateFileAssocVst = *.vst (Мультиразмерный файл ме
ukrainian.CreateFileAssocVst = *.vst (Мультирозмірний файл мірок) ukrainian.CreateFileAssocVst = *.vst (Мультирозмірний файл мірок)
german.CreateFileAssocVst = *.vst (Multi-Size Maßdatei) german.CreateFileAssocVst = *.vst (Multi-Size Maßdatei)
CreateFileAssocVlt = *.vlt (Layout file)
english.CreateFileAssocVlt = *.vlt (Layout file)
russian.CreateFileAssocVlt = *.vlt (Файл раскладки)
ukrainian.CreateFileAssocVlt = *.vlt (Файл роскладки)
german.CreateFileAssocVlt = *.vlt (Layoutdatei)
WarnRemoveOld = is installed at the moment. Remove old version? WarnRemoveOld = is installed at the moment. Remove old version?
english.WarnRemoveOld = is installed at the moment. Remove old version? english.WarnRemoveOld = is installed at the moment. Remove old version?
russian.WarnRemoveOld = установлена на данный момент. Удалить старую версию? russian.WarnRemoveOld = установлена на данный момент. Удалить старую версию?

BIN
dist/win/layout.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -10,6 +10,7 @@ TEMPLATE = app
DEPENDPATH += \ DEPENDPATH += \
../../src/app/valentina \ ../../src/app/valentina \
../../src/app/tape \ ../../src/app/tape \
../../src/app/puzzle \
../../src/libs/qmuparser \ ../../src/libs/qmuparser \
../../src/libs/vpropertyexplorer \ ../../src/libs/vpropertyexplorer \
../../src/libs/ifc \ ../../src/libs/ifc \
@ -25,6 +26,7 @@ DEPENDPATH += \
include(../../src/app/valentina/valentina.pri) include(../../src/app/valentina/valentina.pri)
include(../../src/app/tape/tape.pri) include(../../src/app/tape/tape.pri)
include(../../src/app/puzzle/puzzle.pri)
include(../../src/libs/qmuparser/qmuparser.pri) include(../../src/libs/qmuparser/qmuparser.pri)
include(../../src/libs/vpropertyexplorer/vpropertyexplorer.pri) include(../../src/libs/vpropertyexplorer/vpropertyexplorer.pri)
include(../../src/libs/ifc/ifc.pri) include(../../src/libs/ifc/ifc.pri)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/************************************************************************
**
** @file puzzlepreferencesconfigurationpage.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 5, 2021
**
** @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) 2021 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 "puzzlepreferencesconfigurationpage.h"
#include "ui_puzzlepreferencesconfigurationpage.h"
#include "../../vpapplication.h"
//---------------------------------------------------------------------------------------------------------------------
PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::PuzzlePreferencesConfigurationPage)
{
ui->setupUi(this);
InitLanguages(ui->langCombo);
connect(ui->langCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]()
{
m_langChanged = true;
});
// Theme
ui->darkModeCheck->setChecked(VPApplication::VApp()->PuzzleSettings()->GetDarkMode());
// Native dialogs
ui->checkBoxDontUseNativeDialog->setChecked(VPApplication::VApp()->PuzzleSettings()->IsDontUseNativeDialog());
//----------------------- Toolbar
ui->toolBarStyleCheck->setChecked(VPApplication::VApp()->PuzzleSettings()->GetToolBarStyle());
}
//---------------------------------------------------------------------------------------------------------------------
PuzzlePreferencesConfigurationPage::~PuzzlePreferencesConfigurationPage()
{
delete ui;
}
//---------------------------------------------------------------------------------------------------------------------
QStringList PuzzlePreferencesConfigurationPage::Apply()
{
QStringList preferences;
VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
settings->SetToolBarStyle(ui->toolBarStyleCheck->isChecked());
if (settings->GetDarkMode() != ui->darkModeCheck->isChecked())
{
settings->SetDarkMode(ui->darkModeCheck->isChecked());
preferences.append(tr("dark mode"));
}
if (settings->IsDontUseNativeDialog() != ui->checkBoxDontUseNativeDialog->isChecked())
{
settings->SetDontUseNativeDialog(ui->checkBoxDontUseNativeDialog->isChecked());
}
if (m_langChanged)
{
const QString locale = qvariant_cast<QString>(ui->langCombo->currentData());
settings->SetLocale(locale);
m_langChanged = false;
VAbstractApplication::VApp()->LoadTranslation(locale);
qApp->processEvents();// force to call changeEvent
}
return preferences;
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesConfigurationPage::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
// retranslate designer form (single inheritance approach)
ui->retranslateUi(this);
}
// remember to call base class implementation
QWidget::changeEvent(event);
}

View File

@ -0,0 +1,57 @@
/************************************************************************
**
** @file puzzlepreferencesconfigurationpage.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 5, 2021
**
** @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) 2021 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 PUZZLEPREFERENCESCONFIGURATIONPAGE_H
#define PUZZLEPREFERENCESCONFIGURATIONPAGE_H
#include <QWidget>
namespace Ui
{
class PuzzlePreferencesConfigurationPage;
}
class PuzzlePreferencesConfigurationPage : public QWidget
{
Q_OBJECT
public:
explicit PuzzlePreferencesConfigurationPage(QWidget *parent = nullptr);
virtual ~PuzzlePreferencesConfigurationPage();
QStringList Apply();
protected:
virtual void changeEvent(QEvent* event) override;
private:
Q_DISABLE_COPY(PuzzlePreferencesConfigurationPage)
Ui::PuzzlePreferencesConfigurationPage *ui;
bool m_langChanged{false};
};
#endif // PUZZLEPREFERENCESCONFIGURATIONPAGE_H

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PuzzlePreferencesConfigurationPage</class>
<widget class="QWidget" name="PuzzlePreferencesConfigurationPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>505</width>
<height>548</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>494</width>
<height>514</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Language</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>GUI language:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="langCombo"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Toolbar</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="toolBarStyleCheck">
<property name="text">
<string>The text appears under the icon (recommended for beginners).</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>User Interface</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QCheckBox" name="darkModeCheck">
<property name="text">
<string>Activate dark mode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxDontUseNativeDialog">
<property name="text">
<string>Don't use the native file dialog</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,220 @@
/************************************************************************
**
** @file puzzlepreferencespathpage.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 5, 2021
**
** @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) 2021 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 "puzzlepreferencespathpage.h"
#include "ui_puzzlepreferencespathpage.h"
#include "../../vpapplication.h"
//---------------------------------------------------------------------------------------------------------------------
PuzzlePreferencesPathPage::PuzzlePreferencesPathPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::PuzzlePreferencesPathPage)
{
ui->setupUi(this);
InitTable();
connect(ui->pathTable, &QTableWidget::itemSelectionChanged, this, [this]()
{
ui->defaultButton->setEnabled(not ui->pathTable->selectedItems().isEmpty());
ui->defaultButton->setDefault(false);
ui->editButton->setEnabled(not ui->pathTable->selectedItems().isEmpty());
ui->editButton->setDefault(true);
});
connect(ui->defaultButton, &QPushButton::clicked, this, &PuzzlePreferencesPathPage::DefaultPath);
connect(ui->editButton, &QPushButton::clicked, this, &PuzzlePreferencesPathPage::EditPath);
}
//---------------------------------------------------------------------------------------------------------------------
PuzzlePreferencesPathPage::~PuzzlePreferencesPathPage()
{
delete ui;
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesPathPage::Apply()
{
VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
settings->SetPathIndividualMeasurements(ui->pathTable->item(0, 1)->text());
settings->SetPathMultisizeMeasurements(ui->pathTable->item(1, 1)->text());
settings->SetPathPattern(ui->pathTable->item(2, 1)->text());
settings->SetPathTemplate(ui->pathTable->item(3, 1)->text());
settings->SetPathManualLayouts(ui->pathTable->item(4, 1)->text());
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesPathPage::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
// retranslate designer form (single inheritance approach)
ui->retranslateUi(this);
InitTable();
}
// remember to call base class implementation
QWidget::changeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesPathPage::DefaultPath()
{
const int row = ui->pathTable->currentRow();
QTableWidgetItem *item = ui->pathTable->item(row, 1);
SCASSERT(item != nullptr)
QString path;
switch (row)
{
case 0: // individual measurements
path = VCommonSettings::GetDefPathIndividualMeasurements();
break;
case 1: // multisize measurements
path = VCommonSettings::GetDefPathMultisizeMeasurements();
break;
case 2: // pattern path
path = VCommonSettings::GetDefPathPattern();
break;
case 3: // templates
path = VCommonSettings::GetDefPathTemplate();
break;
case 4: // layouts
path = VCommonSettings::GetDefPathManualLayouts();
break;
default:
break;
}
item->setText(path);
item->setToolTip(path);
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesPathPage::EditPath()
{
const int row = ui->pathTable->currentRow();
QTableWidgetItem *item = ui->pathTable->item(row, 1);
SCASSERT(item != nullptr)
QString path;
switch (row)
{
case 0: // individual measurements
path = VPApplication::VApp()->PuzzleSettings()->GetPathIndividualMeasurements();
break;
case 1: // multisize measurements
path = VPApplication::VApp()->PuzzleSettings()->GetPathMultisizeMeasurements();
path = VCommonSettings::PrepareMultisizeTables(path);
break;
case 2: // pattern path
path = VPApplication::VApp()->PuzzleSettings()->GetPathPattern();
break;
case 3: // templates
path = VPApplication::VApp()->PuzzleSettings()->GetPathTemplate();
break;
case 4: // layouts
path = VPApplication::VApp()->PuzzleSettings()->GetPathManualLayouts();
break;
default:
break;
}
bool usedNotExistedDir = false;
QDir directory(path);
if (not directory.exists())
{
usedNotExistedDir = directory.mkpath(QChar('.'));
}
const QString dir = QFileDialog::getExistingDirectory(
this, tr("Open Directory"), path,
VAbstractApplication::VApp()->NativeFileDialog(QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks));
if (dir.isEmpty())
{
if (usedNotExistedDir)
{
QDir(path).rmpath(QChar('.'));
}
DefaultPath();
return;
}
item->setText(dir);
item->setToolTip(dir);
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzlePreferencesPathPage::InitTable()
{
ui->pathTable->clearContents();
ui->pathTable->setRowCount(5);
ui->pathTable->setColumnCount(2);
const VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
{
ui->pathTable->setItem(0, 0, new QTableWidgetItem(tr("My Individual Measurements")));
QTableWidgetItem *item = new QTableWidgetItem(settings->GetPathIndividualMeasurements());
item->setToolTip(settings->GetPathIndividualMeasurements());
ui->pathTable->setItem(0, 1, item);
}
{
ui->pathTable->setItem(1, 0, new QTableWidgetItem(tr("My Multisize Measurements")));
QTableWidgetItem *item = new QTableWidgetItem(settings->GetPathMultisizeMeasurements());
item->setToolTip(settings->GetPathMultisizeMeasurements());
ui->pathTable->setItem(1, 1, item);
}
{
ui->pathTable->setItem(2, 0, new QTableWidgetItem(tr("My Patterns")));
QTableWidgetItem *item = new QTableWidgetItem(settings->GetPathPattern());
item->setToolTip(settings->GetPathPattern());
ui->pathTable->setItem(2, 1, item);
}
{
ui->pathTable->setItem(3, 0, new QTableWidgetItem(tr("My Templates")));
QTableWidgetItem *item = new QTableWidgetItem(settings->GetPathTemplate());
item->setToolTip(settings->GetPathTemplate());
ui->pathTable->setItem(3, 1, item);
}
{
ui->pathTable->setItem(4, 0, new QTableWidgetItem(tr("My Layouts")));
QTableWidgetItem *item = new QTableWidgetItem(settings->GetPathManualLayouts());
item->setToolTip(settings->GetPathManualLayouts());
ui->pathTable->setItem(4, 1, item);
}
ui->pathTable->verticalHeader()->setDefaultSectionSize(20);
ui->pathTable->resizeColumnsToContents();
ui->pathTable->resizeRowsToContents();
ui->pathTable->horizontalHeader()->setStretchLastSection(true);
}

View File

@ -0,0 +1,62 @@
/************************************************************************
**
** @file puzzlepreferencespathpage.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 5, 2021
**
** @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) 2021 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 PUZZLEPREFERENCESPATHPAGE_H
#define PUZZLEPREFERENCESPATHPAGE_H
#include <QWidget>
namespace Ui
{
class PuzzlePreferencesPathPage;
}
class PuzzlePreferencesPathPage : public QWidget
{
Q_OBJECT
public:
explicit PuzzlePreferencesPathPage(QWidget *parent = nullptr);
virtual ~PuzzlePreferencesPathPage();
void Apply();
protected:
virtual void changeEvent(QEvent* event) override;
private slots:
void DefaultPath();
void EditPath();
private:
Q_DISABLE_COPY(PuzzlePreferencesPathPage)
Ui::PuzzlePreferencesPathPage *ui;
void InitTable();
};
#endif // PUZZLEPREFERENCESPATHPAGE_H

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PuzzlePreferencesPathPage</class>
<widget class="QWidget" name="PuzzlePreferencesPathPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>586</width>
<height>808</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Paths that Valentina uses</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableWidget" name="pathTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Path</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="defaultButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Default</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="editButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,160 @@
/************************************************************************
**
** @file dialogpuzzlepreferences.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 5, 2021
**
** @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) 2021 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 "dialogpuzzlepreferences.h"
#include "ui_dialogpuzzlepreferences.h"
#include "../vpapplication.h"
#include "configpages/puzzlepreferencesconfigurationpage.h"
#include "configpages/puzzlepreferencespathpage.h"
#include <QMessageBox>
#include <QPushButton>
#include <QShowEvent>
//---------------------------------------------------------------------------------------------------------------------
DialogPuzzlePreferences::DialogPuzzlePreferences(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogPuzzlePreferences),
m_configurationPage(new PuzzlePreferencesConfigurationPage),
m_pathPage(new PuzzlePreferencesPathPage)
{
ui->setupUi(this);
#if defined(Q_OS_MAC)
setWindowFlags(Qt::Window);
#endif
VAbstractApplication::VApp()->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c());
QPushButton *bOk = ui->buttonBox->button(QDialogButtonBox::Ok);
SCASSERT(bOk != nullptr)
connect(bOk, &QPushButton::clicked, this, &DialogPuzzlePreferences::Ok);
QPushButton *bApply = ui->buttonBox->button(QDialogButtonBox::Apply);
SCASSERT(bApply != nullptr)
connect(bApply, &QPushButton::clicked, this, &DialogPuzzlePreferences::Apply);
ui->pagesWidget->insertWidget(0, m_configurationPage);
ui->pagesWidget->insertWidget(1, m_pathPage);
connect(ui->contentsWidget, &QListWidget::currentItemChanged, this, &DialogPuzzlePreferences::PageChanged);
ui->pagesWidget->setCurrentIndex(0);
}
//---------------------------------------------------------------------------------------------------------------------
DialogPuzzlePreferences::~DialogPuzzlePreferences()
{
delete ui;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogPuzzlePreferences::showEvent(QShowEvent *event)
{
QDialog::showEvent( event );
if ( event->spontaneous() )
{
return;
}
if (m_isInitialized)
{
return;
}
// do your init stuff here
QSize sz = VAbstractApplication::VApp()->Settings()->GetPreferenceDialogSize();
if (not sz.isEmpty())
{
resize(sz);
}
m_isInitialized = true;//first show windows are held
}
//---------------------------------------------------------------------------------------------------------------------
void DialogPuzzlePreferences::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
// remember the size for the next time this dialog is opened, but only
// if widget was already initialized, which rules out the resize at
// dialog creating, which would
if (m_isInitialized)
{
VAbstractApplication::VApp()->Settings()->SetPreferenceDialogSize(size());
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogPuzzlePreferences::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
// retranslate designer form (single inheritance approach)
ui->retranslateUi(this);
}
// remember to call base class implementation
QDialog::changeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogPuzzlePreferences::Apply()
{
QStringList preferences;
preferences += m_configurationPage->Apply();
m_pathPage->Apply();
if (not preferences.isEmpty())
{
const QString text = tr("Followed %n option(s) require restart to take effect: %1.", "",
preferences.size()).arg(preferences.join(QStringLiteral(", ")));
QMessageBox::information(this, QCoreApplication::applicationName(), text);
}
VPApplication::VApp()->PuzzleSettings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c());
emit UpdateProperties();
setResult(QDialog::Accepted);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogPuzzlePreferences::Ok()
{
Apply();
done(QDialog::Accepted);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogPuzzlePreferences::PageChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
if (current == nullptr)
{
current = previous;
}
int rowIndex = ui->contentsWidget->row(current);
ui->pagesWidget->setCurrentIndex(rowIndex);
}

View File

@ -0,0 +1,71 @@
/************************************************************************
**
** @file dialogpuzzlepreferences.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 21 5, 2021
**
** @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) 2021 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 DIALOGPUZZLEPREFERENCES_H
#define DIALOGPUZZLEPREFERENCES_H
#include <QDialog>
namespace Ui
{
class DialogPuzzlePreferences;
}
class PuzzlePreferencesConfigurationPage;
class PuzzlePreferencesPathPage;
class QListWidgetItem;
class DialogPuzzlePreferences : public QDialog
{
Q_OBJECT
public:
explicit DialogPuzzlePreferences(QWidget *parent = nullptr);
virtual ~DialogPuzzlePreferences();
signals:
void UpdateProperties();
protected:
virtual void showEvent(QShowEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void changeEvent(QEvent* event) override;
private slots:
void Apply();
void Ok();
void PageChanged(QListWidgetItem *current, QListWidgetItem *previous);
private:
Q_DISABLE_COPY(DialogPuzzlePreferences)
Ui::DialogPuzzlePreferences *ui;
bool m_isInitialized{false};
PuzzlePreferencesConfigurationPage *m_configurationPage;
PuzzlePreferencesPathPage *m_pathPage;
};
#endif // DIALOGPUZZLEPREFERENCES_H

View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogPuzzlePreferences</class>
<widget class="QDialog" name="DialogPuzzlePreferences">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>851</width>
<height>551</height>
</rect>
</property>
<property name="windowTitle">
<string>Puzzle preferences</string>
</property>
<property name="windowIcon">
<iconset resource="../share/resources/puzzleicon.qrc">
<normaloff>:/puzzleicon/64x64/logo.png</normaloff>:/puzzleicon/64x64/logo.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListWidget" name="contentsWidget">
<property name="minimumSize">
<size>
<width>128</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>16777215</height>
</size>
</property>
<property name="iconSize">
<size>
<width>96</width>
<height>84</height>
</size>
</property>
<property name="textElideMode">
<enum>Qt::ElideMiddle</enum>
</property>
<property name="movement">
<enum>QListView::Static</enum>
</property>
<property name="spacing">
<number>12</number>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="currentRow">
<number>0</number>
</property>
<item>
<property name="text">
<string>Configuration</string>
</property>
<property name="textAlignment">
<set>AlignCenter</set>
</property>
<property name="icon">
<iconset resource="../../../libs/vmisc/share/resources/icon.qrc">
<normaloff>:/icon/config.png</normaloff>:/icon/config.png</iconset>
</property>
<property name="flags">
<set>ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled</set>
</property>
</item>
<item>
<property name="text">
<string>Paths</string>
</property>
<property name="textAlignment">
<set>AlignCenter</set>
</property>
<property name="icon">
<iconset resource="../../../libs/vmisc/share/resources/icon.qrc">
<normaloff>:/icon/path_config.png</normaloff>:/icon/path_config.png</iconset>
</property>
<property name="flags">
<set>ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled</set>
</property>
</item>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="pagesWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<widget class="QWidget" name="page_2"/>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../share/resources/puzzleicon.qrc"/>
<include location="../../../libs/vmisc/share/resources/icon.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DialogPuzzlePreferences</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>DialogPuzzlePreferences</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

@ -53,6 +53,11 @@ int main(int argc, char *argv[])
#endif // defined(APPIMAGE) && defined(Q_OS_LINUX) #endif // defined(APPIMAGE) && defined(Q_OS_LINUX)
Q_INIT_RESOURCE(puzzleicon); Q_INIT_RESOURCE(puzzleicon);
Q_INIT_RESOURCE(theme);
Q_INIT_RESOURCE(icon);
Q_INIT_RESOURCE(schema);
Q_INIT_RESOURCE(flags);
Q_INIT_RESOURCE(style);
QT_REQUIRE_VERSION(argc, argv, "5.4.0")// clazy:exclude=qstring-arg,qstring-allocations QT_REQUIRE_VERSION(argc, argv, "5.4.0")// clazy:exclude=qstring-arg,qstring-allocations

View File

@ -2,6 +2,9 @@
# This need for corect working file translations.pro # This need for corect working file translations.pro
SOURCES += \ SOURCES += \
$$PWD/dialogs/configpages/puzzlepreferencesconfigurationpage.cpp \
$$PWD/dialogs/configpages/puzzlepreferencespathpage.cpp \
$$PWD/dialogs/dialogpuzzlepreferences.cpp \
$$PWD/dialogs/vpdialogabout.cpp \ $$PWD/dialogs/vpdialogabout.cpp \
$$PWD/main.cpp \ $$PWD/main.cpp \
$$PWD/vpapplication.cpp \ $$PWD/vpapplication.cpp \
@ -30,6 +33,9 @@ SOURCES += \
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp
HEADERS += \ HEADERS += \
$$PWD/dialogs/configpages/puzzlepreferencesconfigurationpage.h \
$$PWD/dialogs/configpages/puzzlepreferencespathpage.h \
$$PWD/dialogs/dialogpuzzlepreferences.h \
$$PWD/dialogs/vpdialogabout.h \ $$PWD/dialogs/vpdialogabout.h \
$$PWD/stable.h \ $$PWD/stable.h \
$$PWD/vpapplication.h \ $$PWD/vpapplication.h \
@ -56,6 +62,9 @@ HEADERS += \
$$PWD/xml/vplayoutliterals.h $$PWD/xml/vplayoutliterals.h
FORMS += \ FORMS += \
$$PWD/dialogs/configpages/puzzlepreferencesconfigurationpage.ui \
$$PWD/dialogs/configpages/puzzlepreferencespathpage.ui \
$$PWD/dialogs/dialogpuzzlepreferences.ui \
$$PWD/dialogs/vpdialogabout.ui \ $$PWD/dialogs/vpdialogabout.ui \
$$PWD/vpcarrousel.ui \ $$PWD/vpcarrousel.ui \
$$PWD/vpmainwindow.ui $$PWD/vpmainwindow.ui

View File

@ -66,17 +66,9 @@ include(../translations.pri)
# Set "make install" command for Unix-like systems. # Set "make install" command for Unix-like systems.
unix{ unix{
# Prefix for binary file. !macx{
isEmpty(PREFIX){
PREFIX = $$DEFAULT_PREFIX
}
unix:!macx{
DATADIR =$$PREFIX/share
DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\"
# Path to bin file after installation # Path to bin file after installation
target.path = $$PREFIX/bin target.path = $$BINDIR
INSTALLS += \ INSTALLS += \
target target
@ -112,8 +104,7 @@ unix{
QMAKE_INFO_PLIST = $$PWD/../../../dist/macx/puzzle/Info.plist QMAKE_INFO_PLIST = $$PWD/../../../dist/macx/puzzle/Info.plist
format.path = $$RESOURCES_DIR/ format.path = $$RESOURCES_DIR/
format.files += $$PWD/../../../dist/macx/i-measurements.icns format.files += $$PWD/../../../dist/macx/layout.icns
format.files += $$PWD/../../../dist/macx/s-measurements.icns
QMAKE_BUNDLE_DATA += \ QMAKE_BUNDLE_DATA += \
#libraries \ #libraries \

View File

@ -61,7 +61,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
// writing a multithreaded application and the error happens on // writing a multithreaded application and the error happens on
// a non-GUI thread, you'll have to queue the message to the GUI // a non-GUI thread, you'll have to queue the message to the GUI
QCoreApplication *instance = QCoreApplication::instance(); QCoreApplication *instance = QCoreApplication::instance();
const bool isGuiThread = instance && (QThread::currentThread() == instance->thread()); const bool isGuiThread = (instance != nullptr) && (QThread::currentThread() == instance->thread());
if (not isGuiThread) if (not isGuiThread)
{ {
@ -199,7 +199,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg) if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
{ {
if (qApp->IsAppInGUIMode()) if (VPApplication::VApp()->IsAppInGUIMode())
{ {
if (topWinAllowsPop) if (topWinAllowsPop)
{ {
@ -234,9 +234,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPApplication::VPApplication(int &argc, char **argv) VPApplication::VPApplication(int &argc, char **argv)
:VAbstractApplication(argc, argv), :VAbstractApplication(argc, argv)
mainWindows(),
localServer(nullptr)
{ {
setApplicationDisplayName(VER_PRODUCTNAME_STR); setApplicationDisplayName(VER_PRODUCTNAME_STR);
setApplicationName(VER_INTERNALNAME_STR); setApplicationName(VER_INTERNALNAME_STR);
@ -264,7 +262,7 @@ VPApplication::~VPApplication()
* @return value that is returned from the receiver's event handler. * @return value that is returned from the receiver's event handler.
*/ */
// reimplemented from QApplication so we can throw exceptions in slots // reimplemented from QApplication so we can throw exceptions in slots
bool VPApplication::notify(QObject *receiver, QEvent *event) auto VPApplication::notify(QObject *receiver, QEvent *event) -> bool
{ {
try try
{ {
@ -325,26 +323,24 @@ bool VPApplication::notify(QObject *receiver, QEvent *event)
/** /**
* @brief IsAppInGUIMode little hack that allow to have access to application state from VAbstractApplication class. * @brief IsAppInGUIMode little hack that allow to have access to application state from VAbstractApplication class.
*/ */
bool VPApplication::IsAppInGUIMode() const auto VPApplication::IsAppInGUIMode() const -> bool
{ {
return CommandLine()->IsGuiEnabled(); return CommandLine()->IsGuiEnabled();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPMainWindow *VPApplication::MainWindow() auto VPApplication::MainWindow()-> VPMainWindow *
{ {
Clean(); Clean();
if (mainWindows.isEmpty()) if (mainWindows.isEmpty())
{ {
VPCommandLinePtr cmd; NewMainWindow();
VPCommandLine::ProcessInstance(cmd, QStringList());
NewMainWindow(VPCommandLinePtr());
} }
return mainWindows[0]; return mainWindows[0];
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QList<VPMainWindow *> VPApplication::MainWindows() auto VPApplication::MainWindows() -> QList<VPMainWindow *>
{ {
Clean(); Clean();
QList<VPMainWindow*> list; QList<VPMainWindow*> list;
@ -356,13 +352,22 @@ QList<VPMainWindow *> VPApplication::MainWindows()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPMainWindow *VPApplication::NewMainWindow(const VPCommandLinePtr &cmd) auto VPApplication::NewMainWindow() -> VPMainWindow *
{ {
VPMainWindow *puzzle = new VPMainWindow(cmd); VPCommandLinePtr cmd;
VPCommandLine::ProcessInstance(cmd, {ConstFirst<QString>(VPApplication::arguments())});
return NewMainWindow(cmd);
}
//---------------------------------------------------------------------------------------------------------------------
auto VPApplication::NewMainWindow(const VPCommandLinePtr &cmd) -> VPMainWindow *
{
auto *puzzle = new VPMainWindow(cmd);
mainWindows.prepend(puzzle); mainWindows.prepend(puzzle);
if (cmd->IsGuiEnabled()) if (not cmd->IsTestModeEnabled())
{ {
puzzle->show(); puzzle->show();
puzzle->UpdateWindowTitle();
} }
puzzle->InitZoom(); puzzle->InitZoom();
return puzzle; return puzzle;
@ -399,7 +404,7 @@ void VPApplication::InitOptions()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
const VTranslateVars *VPApplication::TrVars() auto VPApplication::TrVars() -> const VTranslateVars *
{ {
return nullptr; return nullptr;
} }
@ -412,7 +417,7 @@ void VPApplication::OpenSettings()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPSettings *VPApplication::PuzzleSettings() auto VPApplication::PuzzleSettings() -> VPSettings *
{ {
SCASSERT(settings != nullptr) SCASSERT(settings != nullptr)
return qobject_cast<VPSettings *>(settings); return qobject_cast<VPSettings *>(settings);
@ -421,7 +426,7 @@ VPSettings *VPApplication::PuzzleSettings()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPApplication::ActivateDarkMode() void VPApplication::ActivateDarkMode()
{ {
VPSettings *settings = qApp->PuzzleSettings(); VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
if (settings->GetDarkMode()) if (settings->GetDarkMode())
{ {
QFile f(":qdarkstyle/style.qss"); QFile f(":qdarkstyle/style.qss");
@ -498,14 +503,14 @@ void VPApplication::ProcessArguments(const VPCommandLinePtr &cmd)
cmd.get()->parser.showHelp(V_EX_USAGE); cmd.get()->parser.showHelp(V_EX_USAGE);
} }
if (args.count() > 1 && rawLayouts.size() > 0) if (args.count() > 1 && not rawLayouts.isEmpty())
{ {
qCCritical(pApp, "%s\n", qCCritical(pApp, "%s\n",
qPrintable(tr("Import raw layout data does not support penning several layout files."))); qPrintable(tr("Import raw layout data does not support openning several layout files.")));
cmd.get()->parser.showHelp(V_EX_USAGE); cmd.get()->parser.showHelp(V_EX_USAGE);
} }
for (auto &arg : args) for (const auto &arg : args)
{ {
NewMainWindow(cmd); NewMainWindow(cmd);
if (not MainWindow()->LoadFile(arg)) if (not MainWindow()->LoadFile(arg))
@ -518,7 +523,7 @@ void VPApplication::ProcessArguments(const VPCommandLinePtr &cmd)
continue; continue;
} }
if (rawLayouts.size() > 0) if (not rawLayouts.isEmpty())
{ {
MainWindow()->ImportRawLayouts(rawLayouts); MainWindow()->ImportRawLayouts(rawLayouts);
} }
@ -533,7 +538,7 @@ void VPApplication::ProcessArguments(const VPCommandLinePtr &cmd)
} }
NewMainWindow(cmd); NewMainWindow(cmd);
if (rawLayouts.size() > 0) if (not rawLayouts.isEmpty())
{ {
// MainWindow()->New(); // prepare layout settings // MainWindow()->New(); // prepare layout settings
MainWindow()->ImportRawLayouts(rawLayouts); MainWindow()->ImportRawLayouts(rawLayouts);
@ -553,7 +558,7 @@ void VPApplication::ProcessCMD()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPApplication::event(QEvent *e) auto VPApplication::event(QEvent *e) -> bool
{ {
switch(e->type()) switch(e->type())
{ {
@ -561,12 +566,12 @@ bool VPApplication::event(QEvent *e)
// Mac specific). // Mac specific).
case QEvent::FileOpen: case QEvent::FileOpen:
{ {
QFileOpenEvent *fileOpenEvent = static_cast<QFileOpenEvent *>(e); auto *fileOpenEvent = static_cast<QFileOpenEvent *>(e);
const QString macFileOpen = fileOpenEvent->file(); const QString macFileOpen = fileOpenEvent->file();
if(not macFileOpen.isEmpty()) if(not macFileOpen.isEmpty())
{ {
VPMainWindow *mw = MainWindow(); VPMainWindow *mw = MainWindow();
if (mw) if (mw != nullptr)
{ {
mw->LoadFile(macFileOpen); // open file in existing window mw->LoadFile(macFileOpen); // open file in existing window
} }
@ -639,8 +644,14 @@ void VPApplication::Clean()
} }
} }
//-------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPCommandLinePtr VPApplication::CommandLine() const auto VPApplication::CommandLine() -> VPCommandLinePtr
{ {
return VPCommandLine::instance; return VPCommandLine::instance;
} }
//---------------------------------------------------------------------------------------------------------------------
VPApplication *VPApplication::VApp()
{
return qobject_cast<VPApplication*>(QCoreApplication::instance());
}

View File

@ -35,15 +35,9 @@
#include <memory> #include <memory>
class VPApplication;// use in define
class VPMainWindow; class VPMainWindow;
class QLocalServer; class QLocalServer;
#if defined(qApp)
#undef qApp
#endif
#define qApp (static_cast<VPApplication*>(VAbstractApplication::instance()))
enum class SocketConnection : bool {Client = false, Server = true}; enum class SocketConnection : bool {Client = false, Server = true};
class VPApplication : public VAbstractApplication class VPApplication : public VAbstractApplication
@ -58,6 +52,7 @@ public:
virtual bool IsAppInGUIMode() const override; virtual bool IsAppInGUIMode() const override;
VPMainWindow *MainWindow(); VPMainWindow *MainWindow();
QList<VPMainWindow*> MainWindows(); QList<VPMainWindow*> MainWindows();
VPMainWindow *NewMainWindow();
VPMainWindow *NewMainWindow(const VPCommandLinePtr &cmd); VPMainWindow *NewMainWindow(const VPCommandLinePtr &cmd);
void InitOptions(); void InitOptions();
@ -70,7 +65,9 @@ public:
void ParseCommandLine(const SocketConnection &connection, const QStringList &arguments); void ParseCommandLine(const SocketConnection &connection, const QStringList &arguments);
void ProcessArguments(const VPCommandLinePtr &cmd); void ProcessArguments(const VPCommandLinePtr &cmd);
VPCommandLinePtr CommandLine() const;
static VPCommandLinePtr CommandLine();
static VPApplication *VApp();
public slots: public slots:
void ProcessCMD(); void ProcessCMD();
@ -86,8 +83,8 @@ private slots:
private: private:
Q_DISABLE_COPY(VPApplication) Q_DISABLE_COPY(VPApplication)
QList<QPointer<VPMainWindow> > mainWindows; QList<QPointer<VPMainWindow> > mainWindows{};
QLocalServer *localServer; QLocalServer *localServer{nullptr};
void Clean(); void Clean();
}; };

View File

@ -44,6 +44,13 @@
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../vwidgets/vmaingraphicsscene.h" #include "../vwidgets/vmaingraphicsscene.h"
#include "vpsheet.h" #include "vpsheet.h"
#include "dialogs/dialogpuzzlepreferences.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
#include "../vmisc/backport/qscopeguard.h"
#else
#include <QScopeGuard>
#endif
#include <QLoggingCategory> #include <QLoggingCategory>
@ -57,19 +64,18 @@ QT_WARNING_POP
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) : VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) :
QMainWindow(parent), VAbstractMainWindow(parent),
ui(new Ui::VPMainWindow), ui(new Ui::VPMainWindow),
m_cmd(cmd) m_cmd(cmd),
m_statusLabel(new QLabel(this))
{ {
m_layout = new VPLayout();
// create a standard sheet // create a standard sheet
VPSheet *sheet = new VPSheet(m_layout); auto *sheet = new VPSheet(m_layout);
sheet->SetName(QObject::tr("Sheet 1")); sheet->SetName(QObject::tr("Sheet 1"));
m_layout->AddSheet(sheet); m_layout->AddSheet(sheet);
m_layout->SetFocusedSheet(); m_layout->SetFocusedSheet();
// ----- for test purposes, to be removed------------------ // // ----- for test purposes, to be removed------------------
sheet->SetSheetMarginsConverted(1, 1, 1, 1); sheet->SetSheetMarginsConverted(1, 1, 1, 1);
sheet->SetSheetSizeConverted(84.1, 118.9); sheet->SetSheetSizeConverted(84.1, 118.9);
sheet->SetPiecesGapConverted(1); sheet->SetPiecesGapConverted(1);
@ -82,31 +88,42 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) :
m_layout->SetTilesSizeConverted(21,29.7); m_layout->SetTilesSizeConverted(21,29.7);
m_layout->SetTilesOrientation(PageOrientation::Portrait); m_layout->SetTilesOrientation(PageOrientation::Portrait);
m_layout->SetTilesMarginsConverted(1,1,1,1); m_layout->SetTilesMarginsConverted(1,1,1,1);
// m_layout->SetShowTiles(true); m_layout->SetShowTiles(true);
// -------------------------------------------------------- // --------------------------------------------------------
ui->setupUi(this); ui->setupUi(this);
// init the tile factory // init the tile factory
m_tileFactory = new VPTileFactory(m_layout, qApp->Settings()); m_tileFactory = new VPTileFactory(m_layout, VPApplication::VApp()->Settings());
m_tileFactory->refreshTileInfos(); m_tileFactory->refreshTileInfos();
// init the export tool // init the export tool
m_exporter = new VPExporter(m_layout, qApp->Settings()); m_exporter = new VPExporter(m_layout, qApp->Settings());
InitMenuBar(); // init status bar
statusBar()->addPermanentWidget(m_statusLabel, 1);
SetupMenu();
InitProperties(); InitProperties();
InitCarrousel(); InitCarrousel();
InitMainGraphics(); InitMainGraphics();
InitZoomToolBar(); InitZoomToolBar();
InitScaleToolBar();
SetPropertiesData(); SetPropertiesData();
ReadSettings(); ReadSettings();
#if defined(Q_OS_MAC)
// Mac OS Dock Menu
QMenu *menu = new QMenu(this);
connect(menu, &QMenu::aboutToShow, this, &VPMainWindow::AboutToShowDockMenu);
AboutToShowDockMenu();
menu->setAsDockMenu();
#endif //defined(Q_OS_MAC)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -117,11 +134,50 @@ VPMainWindow::~VPMainWindow()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPMainWindow::LoadFile(QString path) auto VPMainWindow::CurrentFile() const -> QString
{ {
return curFile;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPMainWindow::LoadFile(QString path) -> bool
{
if (not QFileInfo::exists(path))
{
qCCritical(pWindow, "%s", qUtf8Printable(tr("File '%1' doesn't exist!").arg(path)));
if (m_cmd->IsTestModeEnabled())
{
qApp->exit(V_EX_NOINPUT);
}
return false;
}
// Check if file already opened
QList<VPMainWindow*> list = VPApplication::VApp()->MainWindows();
auto w = std::find_if(list.begin(), list.end(),
[path](VPMainWindow *window) { return window->CurrentFile() == path; });
if (w != list.end())
{
(*w)->activateWindow();
close();
return false;
}
VlpCreateLock(lock, path);
if (not lock->IsLocked())
{
if (not IgnoreLocking(lock->GetLockError(), path, m_cmd->IsGuiEnabled()))
{
return false;
}
}
try try
{ {
VLayoutConverter converter(path); VLayoutConverter converter(path);
m_curFileFormatVersion = converter.GetCurrentFormatVersion();
m_curFileFormatVersionStr = converter.GetFormatVersionStr();
path = converter.Convert(); path = converter.Convert();
} }
catch (VException &e) catch (VException &e)
@ -134,31 +190,81 @@ bool VPMainWindow::LoadFile(QString path)
QFile file(path); QFile file(path);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
QScopedPointer<VPLayoutFileReader> fileReader(new VPLayoutFileReader()); VPLayoutFileReader fileReader;
if(m_layout == nullptr) if(m_layout == nullptr)
{ {
m_layout = new VPLayout(); m_layout = new VPLayout();
} }
fileReader->ReadFile(m_layout, &file); fileReader.ReadFile(m_layout, &file);
// TODO / FIXME : better return value and error handling if (fileReader.hasError())
{
qCCritical(pWindow, "%s\n\n%s", qUtf8Printable(tr("File error.")),
qUtf8Printable(tr("Unable to read a layout file")));
lock.reset();
if (m_cmd->IsTestModeEnabled())
{
qApp->exit(V_EX_NOINPUT);
}
return false;
}
// updates the properties with the loaded data
SetPropertiesData();
// TODO : update the Carrousel and the QGraphicView
return true; return true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPMainWindow::SaveFile(const QString &path) void VPMainWindow::LayoutWasSaved(bool saved)
{
setWindowModified(!saved);
not lIsReadOnly ? ui->actionSave->setEnabled(!saved): ui->actionSave->setEnabled(false);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::SetCurrentFile(const QString &fileName)
{
curFile = fileName;
if (not curFile.isEmpty())
{
auto *settings = VPApplication::VApp()->PuzzleSettings();
QStringList files = settings->GetRecentFileList();
files.removeAll(fileName);
files.prepend(fileName);
while (files.size() > MaxRecentFiles)
{
files.removeLast();
}
settings->SetRecentFileList(files);
UpdateRecentFileActions();
}
UpdateWindowTitle();
}
//---------------------------------------------------------------------------------------------------------------------
auto VPMainWindow::SaveLayout(const QString &path, QString &error) -> bool
{ {
QFile file(path); QFile file(path);
file.open(QIODevice::WriteOnly); file.open(QIODevice::WriteOnly);
VPLayoutFileWriter *fileWriter = new VPLayoutFileWriter(); VPLayoutFileWriter fileWriter;
fileWriter->WriteFile(m_layout, &file); fileWriter.WriteFile(m_layout, &file);
// TODO / FIXME : better return value and error handling if (fileWriter.hasError())
{
error = tr("Fail to create layout.");
return false;
}
SetCurrentFile(path);
LayoutWasSaved(true);
return true; return true;
} }
@ -207,7 +313,10 @@ void VPMainWindow::ImportRawLayouts(const QStringList &rawLayouts)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitZoom() void VPMainWindow::InitZoom()
{ {
if (m_graphicsView != nullptr)
{
m_graphicsView->ZoomFitBest(); m_graphicsView->ZoomFitBest();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -234,13 +343,17 @@ VPPiece* VPMainWindow::CreatePiece(const VLayoutPiece &rawPiece)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitMenuBar() void VPMainWindow::SetupMenu()
{ {
// most of the actions are connected through name convention (auto-connection) // most of the actions are connected through name convention (auto-connection)
// -------------------- connects the actions for the file menu // -------------------- connects the actions for the file menu
ui->actionNew->setShortcuts(QKeySequence::New);
ui->actionSave->setShortcuts(QKeySequence::Save);
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
connect(ui->actionExit, &QAction::triggered, this, &VPMainWindow::close); connect(ui->actionExit, &QAction::triggered, this, &VPMainWindow::close);
ui->actionExit->setShortcuts(QKeySequence::Quit);
// -------------------- connects the actions for the edit menu // -------------------- connects the actions for the edit menu
// TODO : initialise the undo / redo // TODO : initialise the undo / redo
@ -250,8 +363,43 @@ void VPMainWindow::InitMenuBar()
// Add dock properties action // Add dock properties action
QAction* actionDockWidgetToolOptions = ui->dockWidgetProperties->toggleViewAction(); QAction* actionDockWidgetToolOptions = ui->dockWidgetProperties->toggleViewAction();
ui->menuWindows->addAction(actionDockWidgetToolOptions); ui->menuEdit->addAction(actionDockWidgetToolOptions);
// File
m_recentFileActs.fill(nullptr);
for (auto & recentFileAct : m_recentFileActs)
{
auto *action = new QAction(this);
recentFileAct = action;
connect(action, &QAction::triggered, this, [this]()
{
if (auto *senderAction = qobject_cast<QAction *>(sender()))
{
const QString filePath = senderAction->data().toString();
if (not filePath.isEmpty())
{
LoadFile(filePath);
}
}
});
ui->menuFile->insertAction(ui->actionPreferences, recentFileAct);
recentFileAct->setVisible(false);
}
m_separatorAct = new QAction(this);
m_separatorAct->setSeparator(true);
m_separatorAct->setVisible(false);
ui->menuFile->insertAction(ui->actionPreferences, m_separatorAct);
// Actions for recent files loaded by a puzzle window application.
UpdateRecentFileActions();
// Window
connect(ui->menuWindow, &QMenu::aboutToShow, this, [this]()
{
ui->menuWindow->clear();
CreateWindowMenu(ui->menuWindow);
});
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -603,10 +751,7 @@ void VPMainWindow::InitZoomToolBar()
delete m_doubleSpinBoxScale; delete m_doubleSpinBoxScale;
} }
if (m_mouseCoordinate != nullptr)
{
delete m_mouseCoordinate; delete m_mouseCoordinate;
}
// connect the zoom buttons and shortcuts to the slots // connect the zoom buttons and shortcuts to the slots
QList<QKeySequence> zoomInShortcuts; QList<QKeySequence> zoomInShortcuts;
@ -631,27 +776,29 @@ void VPMainWindow::InitZoomToolBar()
zoomFitBestShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Equal)); zoomFitBestShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Equal));
ui->actionZoomFitBest->setShortcuts(zoomFitBestShortcuts); ui->actionZoomFitBest->setShortcuts(zoomFitBestShortcuts);
connect(ui->actionZoomFitBest, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomFitBest); connect(ui->actionZoomFitBest, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomFitBest);
}
// defined the scale //---------------------------------------------------------------------------------------------------------------------
ui->toolBarZoom->addSeparator(); void VPMainWindow::InitScaleToolBar()
QLabel* zoomScale = new QLabel(tr("Scale:"), this); {
ui->toolBarZoom->addWidget(zoomScale); auto* zoomScale = new QLabel(tr("Scale:"), this);
ui->toolBarScale->addWidget(zoomScale);
m_doubleSpinBoxScale = new QDoubleSpinBox(this); m_doubleSpinBoxScale = new QDoubleSpinBox(this);
m_doubleSpinBoxScale->setDecimals(1); m_doubleSpinBoxScale->setDecimals(1);
m_doubleSpinBoxScale->setSuffix("%"); m_doubleSpinBoxScale->setSuffix(QChar('%'));
on_ScaleChanged(m_graphicsView->transform().m11()); on_ScaleChanged(m_graphicsView->transform().m11());
connect(m_doubleSpinBoxScale.data(), QOverload<double>::of(&QDoubleSpinBox::valueChanged), connect(m_doubleSpinBoxScale.data(), QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this, [this](double d){m_graphicsView->Zoom(d/100.0);}); this, [this](double d){m_graphicsView->Zoom(d/100.0);});
ui->toolBarZoom->addWidget(m_doubleSpinBoxScale); ui->toolBarScale->addWidget(m_doubleSpinBoxScale);
// define the mouse position // define the mouse position
ui->toolBarZoom->addSeparator(); ui->toolBarScale->addSeparator();
m_mouseCoordinate = new QLabel(QString("0, 0 (%1)").arg(UnitsToStr(m_layout->GetUnit(), true))); m_mouseCoordinate = new QLabel(QStringLiteral("0, 0 (%1)").arg(UnitsToStr(m_layout->GetUnit(), true)));
ui->toolBarZoom->addWidget(m_mouseCoordinate); ui->toolBarScale->addWidget(m_mouseCoordinate);
ui->toolBarZoom->addSeparator(); ui->toolBarScale->addSeparator();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -670,11 +817,75 @@ void VPMainWindow::SetCheckBoxValue(QCheckBox *checkbox, bool value)
checkbox->blockSignals(false); checkbox->blockSignals(false);
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::UpdateWindowTitle()
{
QString showName;
bool isFileWritable = true;
if (not curFile.isEmpty())
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
isFileWritable = QFileInfo(curFile).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
showName = StrippedName(curFile);
}
else
{
int index = VPApplication::VApp()->MainWindows().indexOf(this);
if (index != -1)
{
showName = tr("untitled %1.vlt").arg(index+1);
}
else
{
showName = tr("untitled.vlt");
}
}
showName += QLatin1String("[*]");
if (lIsReadOnly || not isFileWritable)
{
showName += QStringLiteral(" (") + tr("read only") + QChar(')');
}
setWindowTitle(showName);
setWindowFilePath(curFile);
#if defined(Q_OS_MAC)
static QIcon fileIcon = QIcon(QCoreApplication::applicationDirPath() +
QLatin1String("/../Resources/layout.icns"));
QIcon icon;
if (not curFile.isEmpty())
{
if (not isWindowModified())
{
icon = fileIcon;
}
else
{
static QIcon darkIcon;
if (darkIcon.isNull())
{
darkIcon = QIcon(darkenPixmap(fileIcon.pixmap(16, 16)));
}
icon = darkIcon;
}
}
setWindowIcon(icon);
#endif //defined(Q_OS_MAC)
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::ReadSettings() void VPMainWindow::ReadSettings()
{ {
qCDebug(pWindow, "Reading settings."); qCDebug(pWindow, "Reading settings.");
const VPSettings *settings = qApp->PuzzleSettings(); const VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
if (settings->status() == QSettings::NoError) if (settings->status() == QSettings::NoError)
{ {
@ -682,6 +893,9 @@ void VPMainWindow::ReadSettings()
restoreState(settings->GetWindowState()); restoreState(settings->GetWindowState());
restoreState(settings->GetToolbarsState(), APP_VERSION); restoreState(settings->GetToolbarsState(), APP_VERSION);
// Text under tool buton icon
ToolBarStyles();
ui->dockWidgetProperties->setVisible(settings->IsDockWidgetPropertiesActive()); ui->dockWidgetProperties->setVisible(settings->IsDockWidgetPropertiesActive());
ui->dockWidgetPropertiesContents->setVisible(settings->IsDockWidgetPropertiesContentsActive()); ui->dockWidgetPropertiesContents->setVisible(settings->IsDockWidgetPropertiesContentsActive());
@ -700,7 +914,7 @@ void VPMainWindow::ReadSettings()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::WriteSettings() void VPMainWindow::WriteSettings()
{ {
VPSettings *settings = qApp->PuzzleSettings(); VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
settings->SetGeometry(saveGeometry()); settings->SetGeometry(saveGeometry());
settings->SetWindowState(saveState()); settings->SetWindowState(saveState());
settings->SetToolbarsState(saveState(APP_VERSION)); settings->SetToolbarsState(saveState(APP_VERSION));
@ -837,20 +1051,56 @@ void VPMainWindow::generateTiledPdf(QString fileName)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::CreateWindowMenu(QMenu *menu)
{
SCASSERT(menu != nullptr)
QAction *action = menu->addAction(tr("&New Window"));
connect(action, &QAction::triggered, this, []()
{
VPApplication::VApp()->NewMainWindow()->activateWindow();
});
action->setMenuRole(QAction::NoRole);
menu->addSeparator();
const QList<VPMainWindow*> windows = VPApplication::VApp()->MainWindows();
for (int i = 0; i < windows.count(); ++i)
{
VPMainWindow *window = windows.at(i);
QString title = QStringLiteral("%1. %2").arg(i+1).arg(window->windowTitle());
const int index = title.lastIndexOf(QLatin1String("[*]"));
if (index != -1)
{
window->isWindowModified() ? title.replace(index, 3, QChar('*')) : title.replace(index, 3, QString());
}
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
QAction *action = menu->addAction(title, this, SLOT(ShowWindow()));
#else
QAction *action = menu->addAction(title, this, &VPMainWindow::ShowWindow);
#endif //QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
action->setData(i);
action->setCheckable(true);
action->setMenuRole(QAction::NoRole);
if (window->isActiveWindow())
{
action->setChecked(true);
}
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionNew_triggered() void VPMainWindow::on_actionNew_triggered()
{ {
// just for test purpuses, to be removed: VPApplication::VApp()->NewMainWindow();
QMessageBox msgBox; }
msgBox.setText("TODO VPMainWindow::New");
int ret = msgBox.exec();
Q_UNUSED(ret);
// TODO
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::ShowToolTip(const QString &toolTip)
{
m_statusLabel->setText(toolTip);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -877,102 +1127,196 @@ void VPMainWindow::closeEvent(QCloseEvent *event)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
// retranslate designer form (single inheritance approach)
ui->retranslateUi(this);
WindowsLocale();
UpdateWindowTitle();
}
// remember to call base class implementation
QMainWindow::changeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
QStringList VPMainWindow::RecentFileList() const
{
return VPApplication::VApp()->PuzzleSettings()->GetRecentFileList();
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionOpen_triggered() void VPMainWindow::on_actionOpen_triggered()
{ {
qCDebug(pWindow, "Openning puzzle layout file."); qCDebug(pWindow, "Openning puzzle layout file.");
const QString filter(tr("Layout files") + QLatin1String(" (*.vlt)")); const QString filter(tr("Layout files") + QLatin1String(" (*.vlt)"));
//Use standard path to individual measurements
const QString pathTo = VPApplication::VApp()->PuzzleSettings()->GetPathManualLayouts();
//Get list last open files bool usedNotExistedDir = false;
QStringList recentFiles = qApp->PuzzleSettings()->GetRecentFileList(); QDir directory(pathTo);
QString dir; if (not directory.exists())
if (recentFiles.isEmpty())
{ {
dir = QDir::homePath(); usedNotExistedDir = directory.mkpath(QChar('.'));
}
else
{
//Absolute path to last open file
dir = QFileInfo(recentFiles.first()).absolutePath();
}
qCDebug(pWindow, "Run QFileDialog::getOpenFileName: dir = %s.", qUtf8Printable(dir));
const QString filePath = QFileDialog::getOpenFileName(this, tr("Open file"), dir, filter, nullptr);
if (filePath.isEmpty())
{
return;
} }
const QString mPath = QFileDialog::getOpenFileName(this, tr("Open file"), pathTo, filter, nullptr,
VAbstractApplication::VApp()->NativeFileDialog());
// TODO : if m_layout == nullptr, open in current window if (not mPath.isEmpty())
// otherwise open in new window
// TODO : if layout file has a lock, warning message
if(!LoadFile(filePath))
{ {
return; VPApplication::VApp()->NewMainWindow()->LoadFile(mPath);
} }
// Updates the list of recent files if (usedNotExistedDir)
recentFiles.removeAll(filePath);
recentFiles.prepend(filePath);
while (recentFiles.size() > MaxRecentFiles)
{ {
recentFiles.removeLast(); QDir(pathTo).rmpath(QChar('.'));
} }
qApp->PuzzleSettings()->SetRecentFileList(recentFiles);
// updates the properties with the loaded data
SetPropertiesData();
// TODO : update the Carrousel and the QGraphicView
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionSave_triggered() bool VPMainWindow::on_actionSave_triggered()
{ {
// just for test purpuses, to be removed: if (curFile.isEmpty() || lIsReadOnly)
QMessageBox msgBox; {
msgBox.setText("TODO VPMainWindow::Save"); return on_actionSaveAs_triggered();
int ret = msgBox.exec(); }
Q_UNUSED(ret); if (m_curFileFormatVersion < VLayoutConverter::LayoutMaxVer
&& not ContinueFormatRewrite(m_curFileFormatVersionStr, VLayoutConverter::LayoutMaxVerStr))
{
return false;
}
// TODO if (not CheckFilePermissions(curFile, this))
{
return false;
}
QString error;
if (not SaveLayout(curFile, error))
{
QMessageBox messageBox;
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Could not save the file"));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return false;
}
m_curFileFormatVersion = VLayoutConverter::LayoutMaxVer;
m_curFileFormatVersionStr = VLayoutConverter::LayoutMaxVerStr;
return true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionSaveAs_triggered() bool VPMainWindow::on_actionSaveAs_triggered()
{ {
// TODO / FIXME : See valentina how the save is done over there. we need to add the QString filters = tr("Layout files") + QStringLiteral(" (*.vlt)");
// extension .vlt, check for empty file names etc. QString suffix = QStringLiteral("vlt");
QString fName = tr("layout") + QChar('.') + suffix;
//Get list last open files
QStringList recentFiles = qApp->PuzzleSettings()->GetRecentFileList();
QString dir; QString dir;
if (recentFiles.isEmpty()) if (curFile.isEmpty())
{ {
dir = QDir::homePath(); dir = VPApplication::VApp()->PuzzleSettings()->GetPathManualLayouts();
} }
else else
{ {
//Absolute path to last open file dir = QFileInfo(curFile).absolutePath();
dir = QFileInfo(recentFiles.first()).absolutePath();
} }
QString filters(tr("Layout files") + QLatin1String("(*.vlt)")); bool usedNotExistedDir = false;
QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), QDir directory(dir);
dir + QLatin1String("/") + tr("Layout") + QLatin1String(".vlt"), if (not directory.exists())
filters, nullptr {
#ifdef Q_OS_LINUX usedNotExistedDir = directory.mkpath(QChar('.'));
, QFileDialog::DontUseNativeDialog }
#endif
);
SaveFile(fileName); QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), dir + QChar('/') + fName, filters, nullptr,
VAbstractApplication::VApp()->NativeFileDialog());
auto RemoveTempDir = qScopeGuard([usedNotExistedDir, dir]()
{
if (usedNotExistedDir)
{
QDir(dir).rmpath(QChar('.'));
}
});
if (fileName.isEmpty())
{
return false;
}
QFileInfo f( fileName );
if (f.suffix().isEmpty() && f.suffix() != suffix)
{
fileName += QChar('.') + suffix;
}
if (QFileInfo::exists(fileName) && curFile != fileName)
{
// Temporary try to lock the file before saving
VLockGuard<char> tmp(fileName);
if (not tmp.IsLocked())
{
qCCritical(pWindow, "%s",
qUtf8Printable(tr("Failed to lock. This file already opened in another window.")));
return false;
}
}
// Need for restoring previous state in case of failure
// const bool readOnly = m_layout->IsReadOnly();
// m_layout->SetReadOnly(false);
lIsReadOnly = false;
QString error;
bool result = SaveLayout(fileName, error);
if (not result)
{
QMessageBox messageBox;
messageBox.setIcon(QMessageBox::Warning);
messageBox.setInformativeText(tr("Could not save file"));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
// Restore previous state
// m_layout->SetReadOnly(readOnly);
// lIsReadOnly = readOnly;
return false;
}
m_curFileFormatVersion = VLayoutConverter::LayoutMaxVer;
m_curFileFormatVersionStr = VLayoutConverter::LayoutMaxVerStr;
// UpdatePadlock(false);
UpdateWindowTitle();
if (curFile == fileName && not lock.isNull())
{
lock->Unlock();
}
VlpCreateLock(lock, fileName);
if (not lock->IsLocked())
{
qCCritical(pWindow, "%s", qUtf8Printable(tr("Failed to lock. This file already opened in another window. "
"Expect collissions when run 2 copies of the program.")));
return false;
}
return true;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1004,19 +1348,6 @@ void VPMainWindow::on_actionImportRawLayout_triggered()
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionCloseLayout_triggered()
{
// just for test purpuses, to be removed:
QMessageBox msgBox;
msgBox.setText("TODO VPMainWindow::CloseLayout");
int ret = msgBox.exec();
Q_UNUSED(ret);
// TODO
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionAboutQt_triggered() void VPMainWindow::on_actionAboutQt_triggered()
{ {
@ -1509,3 +1840,64 @@ void VPMainWindow::on_MouseMoved(const QPointF &scenePos)
.arg(UnitsToStr(m_layout->GetUnit(), true))); .arg(UnitsToStr(m_layout->GetUnit(), true)));
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::ShowWindow() const
{
if (auto *action = qobject_cast<QAction*>(sender()))
{
const QVariant v = action->data();
if (v.canConvert<int>())
{
const int offset = qvariant_cast<int>(v);
const QList<VPMainWindow*> windows = VPApplication::VApp()->MainWindows();
windows.at(offset)->raise();
windows.at(offset)->activateWindow();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionPreferences_triggered()
{
// Calling constructor of the dialog take some time. Because of this user have time to call the dialog twice.
static QPointer<DialogPuzzlePreferences> guard;// Prevent any second run
if (guard.isNull())
{
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
auto *preferences = new DialogPuzzlePreferences(this);
// QScopedPointer needs to be sure any exception will never block guard
QScopedPointer<DialogPuzzlePreferences> dlg(preferences);
guard = preferences;
// Must be first
connect(dlg.data(), &DialogPuzzlePreferences::UpdateProperties, this, &VPMainWindow::WindowsLocale);
connect(dlg.data(), &DialogPuzzlePreferences::UpdateProperties, this, &VPMainWindow::ToolBarStyles);
QGuiApplication::restoreOverrideCursor();
dlg->exec();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::ToolBarStyles()
{
ToolBarStyle(ui->mainToolBar);
ToolBarStyle(ui->toolBarZoom);
}
//---------------------------------------------------------------------------------------------------------------------
#if defined(Q_OS_MAC)
void VPMainWindow::AboutToShowDockMenu()
{
if (QMenu *menu = qobject_cast<QMenu *>(sender()))
{
menu->clear();
CreateWindowMenu(menu);
menu->addSeparator();
QAction *actionPreferences = menu->addAction(tr("Preferences"));
actionPreferences->setMenuRole(QAction::NoRole);
connect(actionPreferences, &QAction::triggered, this, &VPMainWindow::Preferences);
}
}
#endif //defined(Q_OS_MAC)

View File

@ -43,13 +43,15 @@
#include "vpexporter.h" #include "vpexporter.h"
#include "vpcommandline.h" #include "vpcommandline.h"
#include "../vlayout/vlayoutdef.h" #include "../vlayout/vlayoutdef.h"
#include "../vwidgets/vabstractmainwindow.h"
#include "../vmisc/vlockguard.h"
namespace Ui namespace Ui
{ {
class VPMainWindow; class VPMainWindow;
} }
class VPMainWindow : public QMainWindow class VPMainWindow : public VAbstractMainWindow
{ {
Q_OBJECT Q_OBJECT
@ -57,6 +59,8 @@ public:
explicit VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent = nullptr); explicit VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent = nullptr);
virtual ~VPMainWindow(); virtual ~VPMainWindow();
QString CurrentFile() const;
/** /**
* @brief LoadFile Loads the layout file of given path in m_layout. * @brief LoadFile Loads the layout file of given path in m_layout.
* This function doesn't update the gui. * This function doesn't update the gui.
@ -65,12 +69,15 @@ public:
*/ */
bool LoadFile(QString path); bool LoadFile(QString path);
void LayoutWasSaved(bool saved);
void SetCurrentFile(const QString &fileName);
/** /**
* @brief SaveFile Saves the current layout to the layout file of given path * @brief SaveLayout Saves the current layout to the layout file of given path
* @param path path to layout file * @param path path to layout file
* @return true if success * @return true if success
*/ */
bool SaveFile(const QString &path); bool SaveLayout(const QString &path, QString &error);
/** /**
* @brief ImportRawLayouts The function imports the raw layouts of given paths * @brief ImportRawLayouts The function imports the raw layouts of given paths
@ -83,6 +90,8 @@ public:
*/ */
void InitZoom(); void InitZoom();
void UpdateWindowTitle();
public slots: public slots:
/** /**
* @brief on_actionNew_triggered When the menu action File > New * @brief on_actionNew_triggered When the menu action File > New
@ -90,146 +99,14 @@ public slots:
*/ */
void on_actionNew_triggered(); void on_actionNew_triggered();
virtual void ShowToolTip(const QString &toolTip) override;
protected: protected:
enum { MaxRecentFiles = 5 };
virtual void closeEvent(QCloseEvent *event) override; virtual void closeEvent(QCloseEvent *event) override;
virtual void changeEvent(QEvent* event) override;
virtual QStringList RecentFileList() const override;
private: private slots:
Q_DISABLE_COPY(VPMainWindow)
Ui::VPMainWindow *ui;
VPCarrousel *m_carrousel{nullptr};
VPMainGraphicsView *m_graphicsView{nullptr};
VPCommandLinePtr m_cmd;
VPLayout *m_layout{nullptr};
QList<VPPiece *>m_selectedPieces{QList<VPPiece *>()};
VPTileFactory *m_tileFactory{nullptr};
VPExporter *m_exporter{nullptr};
/**
* @brief spin box with the scale factor of the graphic view
*/
QPointer<QDoubleSpinBox> m_doubleSpinBoxScale{nullptr};
/**
* @brief mouseCoordinate pointer to label who show mouse coordinate.
*/
QLabel* m_mouseCoordinate{nullptr};
/**
* @brief CreatePiece creates a piece from the given VLayoutPiece data
* @param rawPiece the raw piece data
*/
VPPiece* CreatePiece(const VLayoutPiece &rawPiece);
/**
* @brief InitMenuBar Inits the menu bar (File, Edit, Help ...)
*/
void InitMenuBar();
/**
* @brief InitProperties Init the properties
*/
void InitProperties();
/**
* @brief InitPropertyTabCurrentPiece Inits the current piece tab in the properties
*/
void InitPropertyTabCurrentPiece();
/**
* @brief InitPropertyTabCurrentSheet Inits the current sheet tab in the properties;
*/
void InitPropertyTabCurrentSheet();
/**
* @brief InitPropertyTabLayout Inits the layout tab in the properties
*/
void InitPropertyTabLayout();
/**
* @brief InitPropertyTabTiles Inits the tiles tab in the properties
*/
void InitPropertyTabTiles();
/**
* @brief InitCarrousel Inits the carrousel
*/
void InitCarrousel();
/**
* @brief InitMainGraphics Initialises the puzzle main graphics
*/
void InitMainGraphics();
/**
* @brief InitToolBar Initialises the tool bar
*/
void InitZoomToolBar();
/**
* @brief SetPropertiesData Sets the values of UI elements
* in all the property tabs to the values saved in m_layout
*/
void SetPropertiesData();
/**
* @brief SetPropertyTabCurrentPieceData Sets the values of UI elements
* in the Current Piece Tab to the values saved in m_layout
*/
void SetPropertyTabCurrentPieceData();
/**
* @brief SetPropertyTabSheetData Sets the values of UI elements
* in the Sheet Tab to the values saved in focused sheet
*/
void SetPropertyTabSheetData();
/**
* @brief SetPropertyTabTilesData Sets the values of UI elements
* in the Tiles Tab to the values saved in m_layout
*/
void SetPropertyTabTilesData();
/**
* @brief SetPropertyTabLayoutData Sets the values of UI elements
* in the Layout Tab to the values saved in m_layout
*/
void SetPropertyTabLayoutData();
/**
* @brief SetDoubleSpinBoxValue sets the given spinbox to the given value.
* the signals are blocked before changing the value and unblocked after
* @param spinBox pointer to spinbox
* @param value spinbox value
*/
void SetDoubleSpinBoxValue(QDoubleSpinBox *spinBox, qreal value);
/**
* @brief SetCheckBoxValue sets the given checkbox to the given value.
* the signals are blocked before changing the value and unblocked after
* @param checkbox pointer to checkbox
* @param value checkbox value
*/
void SetCheckBoxValue(QCheckBox *checkbox, bool value);
void ReadSettings();
void WriteSettings();
bool MaybeSave();
/**
* @brief generateTiledPdf Generates the tiled Pdf in the given filename
* @param fileName output file name
*/
void generateTiledPdf(QString fileName);
private slots:
/** /**
* @brief on_actionOpen_triggered When the menu action File > Open is * @brief on_actionOpen_triggered When the menu action File > Open is
* triggered. * triggered.
@ -242,14 +119,14 @@ private slots:
* triggered. * triggered.
* The slot is automatically connected through name convention. * The slot is automatically connected through name convention.
*/ */
void on_actionSave_triggered(); bool on_actionSave_triggered();
/** /**
* @brief on_actionSaveAs_triggered When the menu action File > Save As * @brief on_actionSaveAs_triggered When the menu action File > Save As
* is triggered. * is triggered.
* The slot is automatically connected through name convention. * The slot is automatically connected through name convention.
*/ */
void on_actionSaveAs_triggered(); bool on_actionSaveAs_triggered();
/** /**
* @brief on_actionImportRawLayout_triggered When the menu action * @brief on_actionImportRawLayout_triggered When the menu action
@ -258,13 +135,6 @@ private slots:
*/ */
void on_actionImportRawLayout_triggered(); void on_actionImportRawLayout_triggered();
/**
* @brief on_actionCloseLayout_triggered When the menu action
* File > Close Layout is triggered.
* The slot is automatically connected through name convention.
*/
void on_actionCloseLayout_triggered();
/** /**
* @brief on_actionAboutQt_triggered When the menu action Help > About Qt * @brief on_actionAboutQt_triggered When the menu action Help > About Qt
* is triggered. * is triggered.
@ -523,6 +393,165 @@ private slots:
* @param scenePos position mouse. * @param scenePos position mouse.
*/ */
void on_MouseMoved(const QPointF &scenePos); void on_MouseMoved(const QPointF &scenePos);
void on_actionPreferences_triggered();
void ShowWindow() const;
void ToolBarStyles();
#if defined(Q_OS_MAC)
void AboutToShowDockMenu();
#endif //defined(Q_OS_MAC)
private:
Q_DISABLE_COPY(VPMainWindow)
Ui::VPMainWindow *ui;
VPCarrousel *m_carrousel{nullptr};
VPMainGraphicsView *m_graphicsView{nullptr};
VPCommandLinePtr m_cmd;
VPLayout *m_layout{new VPLayout()};
QList<VPPiece *>m_selectedPieces{QList<VPPiece *>()};
VPTileFactory *m_tileFactory{nullptr};
VPExporter *m_exporter{nullptr};
/**
* @brief spin box with the scale factor of the graphic view
*/
QPointer<QDoubleSpinBox> m_doubleSpinBoxScale{nullptr};
/**
* @brief mouseCoordinate pointer to label who show mouse coordinate.
*/
QLabel* m_mouseCoordinate{nullptr};
QLabel* m_statusLabel{nullptr};
QString curFile{};
bool isInitialized{false};
bool lIsReadOnly{false};
QSharedPointer<VLockGuard<char>> lock{nullptr};
/**
* @brief CreatePiece creates a piece from the given VLayoutPiece data
* @param rawPiece the raw piece data
*/
VPPiece* CreatePiece(const VLayoutPiece &rawPiece);
/**
* @brief InitMenuBar Inits the menu bar (File, Edit, Help ...)
*/
void SetupMenu();
/**
* @brief InitProperties Init the properties
*/
void InitProperties();
/**
* @brief InitPropertyTabCurrentPiece Inits the current piece tab in the properties
*/
void InitPropertyTabCurrentPiece();
/**
* @brief InitPropertyTabCurrentSheet Inits the current sheet tab in the properties;
*/
void InitPropertyTabCurrentSheet();
/**
* @brief InitPropertyTabLayout Inits the layout tab in the properties
*/
void InitPropertyTabLayout();
/**
* @brief InitPropertyTabTiles Inits the tiles tab in the properties
*/
void InitPropertyTabTiles();
/**
* @brief InitCarrousel Inits the carrousel
*/
void InitCarrousel();
/**
* @brief InitMainGraphics Initialises the puzzle main graphics
*/
void InitMainGraphics();
/**
* @brief InitToolBar Initialises the tool bar
*/
void InitZoomToolBar();
/**
* @brief InitScaleToolBar Initialises the scale tool bar
*/
void InitScaleToolBar();
/**
* @brief SetPropertiesData Sets the values of UI elements
* in all the property tabs to the values saved in m_layout
*/
void SetPropertiesData();
/**
* @brief SetPropertyTabCurrentPieceData Sets the values of UI elements
* in the Current Piece Tab to the values saved in m_layout
*/
void SetPropertyTabCurrentPieceData();
/**
* @brief SetPropertyTabSheetData Sets the values of UI elements
* in the Sheet Tab to the values saved in focused sheet
*/
void SetPropertyTabSheetData();
/**
* @brief SetPropertyTabTilesData Sets the values of UI elements
* in the Tiles Tab to the values saved in m_layout
*/
void SetPropertyTabTilesData();
/**
* @brief SetPropertyTabLayoutData Sets the values of UI elements
* in the Layout Tab to the values saved in m_layout
*/
void SetPropertyTabLayoutData();
/**
* @brief SetDoubleSpinBoxValue sets the given spinbox to the given value.
* the signals are blocked before changing the value and unblocked after
* @param spinBox pointer to spinbox
* @param value spinbox value
*/
void SetDoubleSpinBoxValue(QDoubleSpinBox *spinBox, qreal value);
/**
* @brief SetCheckBoxValue sets the given checkbox to the given value.
* the signals are blocked before changing the value and unblocked after
* @param checkbox pointer to checkbox
* @param value checkbox value
*/
void SetCheckBoxValue(QCheckBox *checkbox, bool value);
void ReadSettings();
void WriteSettings();
bool MaybeSave();
/**
* @brief generateTiledPdf Generates the tiled Pdf in the given filename
* @param fileName output file name
*/
void generateTiledPdf(QString fileName);
void CreateWindowMenu(QMenu *menu);
}; };
#endif // VPMAINWINDOW_H #endif // VPMAINWINDOW_H

View File

@ -14,7 +14,7 @@
<string>Puzzle</string> <string>Puzzle</string>
</property> </property>
<property name="windowIcon"> <property name="windowIcon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/logo.png</normaloff>:/puzzleicon/64x64/logo.png</iconset> <normaloff>:/puzzleicon/64x64/logo.png</normaloff>:/puzzleicon/64x64/logo.png</iconset>
</property> </property>
<property name="layoutDirection"> <property name="layoutDirection">
@ -53,6 +53,8 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionImportRawLayout"/> <addaction name="actionImportRawLayout"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionPreferences"/>
<addaction name="separator"/>
<addaction name="actionExit"/> <addaction name="actionExit"/>
</widget> </widget>
<widget class="QMenu" name="menuEdit"> <widget class="QMenu" name="menuEdit">
@ -61,11 +63,10 @@
</property> </property>
<addaction name="separator"/> <addaction name="separator"/>
</widget> </widget>
<widget class="QMenu" name="menuWindows"> <widget class="QMenu" name="menuWindow">
<property name="title"> <property name="title">
<string>&amp;Windows</string> <string>&amp;Window</string>
</property> </property>
<addaction name="actionCloseLayout"/>
<addaction name="separator"/> <addaction name="separator"/>
</widget> </widget>
<widget class="QMenu" name="menuHelp"> <widget class="QMenu" name="menuHelp">
@ -77,18 +78,29 @@
</widget> </widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
<addaction name="menuEdit"/> <addaction name="menuEdit"/>
<addaction name="menuWindows"/> <addaction name="menuWindow"/>
<addaction name="menuHelp"/> <addaction name="menuHelp"/>
</widget> </widget>
<widget class="QToolBar" name="mainToolBar"> <widget class="QToolBar" name="mainToolBar">
<property name="enabled">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>Menu</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<attribute name="toolBarArea"> <attribute name="toolBarArea">
<enum>TopToolBarArea</enum> <enum>TopToolBarArea</enum>
</attribute> </attribute>
<attribute name="toolBarBreak"> <attribute name="toolBarBreak">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
<addaction name="actionNew"/>
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
</widget> </widget>
<widget class="QStatusBar" name="statusBar"/>
<widget class="QDockWidget" name="dockWidgetCarrousel"> <widget class="QDockWidget" name="dockWidgetCarrousel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -163,6 +175,9 @@
</property> </property>
<item> <item>
<widget class="QTabWidget" name="tabWidgetProperties"> <widget class="QTabWidget" name="tabWidgetProperties">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding"> <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -192,7 +207,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<attribute name="icon"> <attribute name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconCurrentPiece.png</normaloff>:/puzzleicon/64x64/iconCurrentPiece.png</iconset> <normaloff>:/puzzleicon/64x64/iconCurrentPiece.png</normaloff>:/puzzleicon/64x64/iconCurrentPiece.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -216,6 +231,9 @@
</property> </property>
<item> <item>
<widget class="QScrollArea" name="scrollAreaCurrentPiece"> <widget class="QScrollArea" name="scrollAreaCurrentPiece">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true"/> <string notr="true"/>
</property> </property>
@ -390,7 +408,7 @@
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconRotate90Clockwise.png</normaloff>:/puzzleicon/64x64/iconRotate90Clockwise.png</iconset> <normaloff>:/puzzleicon/64x64/iconRotate90Clockwise.png</normaloff>:/puzzleicon/64x64/iconRotate90Clockwise.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -410,7 +428,7 @@
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconRotate90Anticlockwise.png</normaloff>:/puzzleicon/64x64/iconRotate90Anticlockwise.png</iconset> <normaloff>:/puzzleicon/64x64/iconRotate90Anticlockwise.png</normaloff>:/puzzleicon/64x64/iconRotate90Anticlockwise.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -430,7 +448,7 @@
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconRotateGrainlineVertical.png</normaloff>:/puzzleicon/64x64/iconRotateGrainlineVertical.png</iconset> <normaloff>:/puzzleicon/64x64/iconRotateGrainlineVertical.png</normaloff>:/puzzleicon/64x64/iconRotateGrainlineVertical.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -450,7 +468,7 @@
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconRotateGrainlineHorizontal.png</normaloff>:/puzzleicon/64x64/iconRotateGrainlineHorizontal.png</iconset> <normaloff>:/puzzleicon/64x64/iconRotateGrainlineHorizontal.png</normaloff>:/puzzleicon/64x64/iconRotateGrainlineHorizontal.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -610,7 +628,7 @@
</widget> </widget>
<widget class="QWidget" name="tabSheetProperty"> <widget class="QWidget" name="tabSheetProperty">
<attribute name="icon"> <attribute name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconLayout.png</normaloff>:/puzzleicon/64x64/iconLayout.png</iconset> <normaloff>:/puzzleicon/64x64/iconLayout.png</normaloff>:/puzzleicon/64x64/iconLayout.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -762,7 +780,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconPortrait.png</normaloff>:/puzzleicon/64x64/iconPortrait.png</iconset> <normaloff>:/puzzleicon/64x64/iconPortrait.png</normaloff>:/puzzleicon/64x64/iconPortrait.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -785,7 +803,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconLandscape.png</normaloff>:/puzzleicon/64x64/iconLandscape.png</iconset> <normaloff>:/puzzleicon/64x64/iconLandscape.png</normaloff>:/puzzleicon/64x64/iconLandscape.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -977,7 +995,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconGrainlineVertical.png</normaloff>:/puzzleicon/64x64/iconGrainlineVertical.png</iconset> <normaloff>:/puzzleicon/64x64/iconGrainlineVertical.png</normaloff>:/puzzleicon/64x64/iconGrainlineVertical.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -997,7 +1015,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconGrainlineHorizontal.png</normaloff>:/puzzleicon/64x64/iconGrainlineHorizontal.png</iconset> <normaloff>:/puzzleicon/64x64/iconGrainlineHorizontal.png</normaloff>:/puzzleicon/64x64/iconGrainlineHorizontal.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -1083,7 +1101,7 @@
</widget> </widget>
<widget class="QWidget" name="tabTilesProperty"> <widget class="QWidget" name="tabTilesProperty">
<attribute name="icon"> <attribute name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconTiles.png</normaloff>:/puzzleicon/64x64/iconTiles.png</iconset> <normaloff>:/puzzleicon/64x64/iconTiles.png</normaloff>:/puzzleicon/64x64/iconTiles.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -1125,7 +1143,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>356</width> <width>356</width>
<height>717</height> <height>700</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
@ -1193,7 +1211,7 @@
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconPortrait.png</normaloff>:/puzzleicon/64x64/iconPortrait.png</iconset> <normaloff>:/puzzleicon/64x64/iconPortrait.png</normaloff>:/puzzleicon/64x64/iconPortrait.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -1213,7 +1231,7 @@
<string/> <string/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconLandscape.png</normaloff>:/puzzleicon/64x64/iconLandscape.png</iconset> <normaloff>:/puzzleicon/64x64/iconLandscape.png</normaloff>:/puzzleicon/64x64/iconLandscape.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -1371,7 +1389,7 @@
</widget> </widget>
<widget class="QWidget" name="tabLayoutProperty"> <widget class="QWidget" name="tabLayoutProperty">
<attribute name="icon"> <attribute name="icon">
<iconset resource="share/resources/puzzleicon.qrc"> <iconset>
<normaloff>:/puzzleicon/64x64/iconProperties.png</normaloff>:/puzzleicon/64x64/iconProperties.png</iconset> <normaloff>:/puzzleicon/64x64/iconProperties.png</normaloff>:/puzzleicon/64x64/iconProperties.png</iconset>
</attribute> </attribute>
<attribute name="title"> <attribute name="title">
@ -1413,7 +1431,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>356</width> <width>356</width>
<height>717</height> <height>700</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
@ -1539,7 +1557,7 @@
</widget> </widget>
<widget class="QToolBar" name="toolBarZoom"> <widget class="QToolBar" name="toolBarZoom">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>zoom</string>
</property> </property>
<property name="toolButtonStyle"> <property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum> <enum>Qt::ToolButtonTextUnderIcon</enum>
@ -1555,7 +1573,26 @@
<addaction name="actionZoomOriginal"/> <addaction name="actionZoomOriginal"/>
<addaction name="actionZoomFitBest"/> <addaction name="actionZoomFitBest"/>
</widget> </widget>
<widget class="QStatusBar" name="statusBar"/>
<widget class="QToolBar" name="toolBarScale">
<property name="windowTitle">
<string>Scale</string>
</property>
<property name="allowedAreas">
<set>Qt::AllToolBarAreas</set>
</property>
<attribute name="toolBarArea">
<enum>BottomToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<action name="actionOpen"> <action name="actionOpen">
<property name="icon">
<iconset theme="document-open">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text"> <property name="text">
<string>&amp;Open</string> <string>&amp;Open</string>
</property> </property>
@ -1564,6 +1601,13 @@
</property> </property>
</action> </action>
<action name="actionSave"> <action name="actionSave">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="document-save">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text"> <property name="text">
<string>&amp;Save</string> <string>&amp;Save</string>
</property> </property>
@ -1572,6 +1616,13 @@
</property> </property>
</action> </action>
<action name="actionSaveAs"> <action name="actionSaveAs">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset theme="document-save-as">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text"> <property name="text">
<string>Save &amp;As</string> <string>Save &amp;As</string>
</property> </property>
@ -1579,12 +1630,10 @@
<string>Ctrl+Shift+S</string> <string>Ctrl+Shift+S</string>
</property> </property>
</action> </action>
<action name="actionCloseLayout">
<property name="text">
<string>&amp;Close Layout</string>
</property>
</action>
<action name="actionImportRawLayout"> <action name="actionImportRawLayout">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text"> <property name="text">
<string>&amp;Import Raw Layout Data</string> <string>&amp;Import Raw Layout Data</string>
</property> </property>
@ -1603,8 +1652,15 @@
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+Q</string> <string>Ctrl+Q</string>
</property> </property>
<property name="menuRole">
<enum>QAction::QuitRole</enum>
</property>
</action> </action>
<action name="actionNew"> <action name="actionNew">
<property name="icon">
<iconset theme="document-new">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text"> <property name="text">
<string>&amp;New</string> <string>&amp;New</string>
</property> </property>
@ -1616,11 +1672,21 @@
<property name="text"> <property name="text">
<string>About &amp;Qt</string> <string>About &amp;Qt</string>
</property> </property>
<property name="menuRole">
<enum>QAction::AboutQtRole</enum>
</property>
</action> </action>
<action name="actionAboutPuzzle"> <action name="actionAboutPuzzle">
<property name="icon">
<iconset theme="help-about">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text"> <property name="text">
<string>About &amp;Puzzle</string> <string>About &amp;Puzzle</string>
</property> </property>
<property name="menuRole">
<enum>QAction::AboutRole</enum>
</property>
</action> </action>
<action name="actionProperties"> <action name="actionProperties">
<property name="checkable"> <property name="checkable">
@ -1629,11 +1695,20 @@
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="text"> <property name="text">
<string>Properties</string> <string>Properties</string>
</property> </property>
<property name="menuRole">
<enum>QAction::PreferencesRole</enum>
</property>
</action> </action>
<action name="actionZoomIn"> <action name="actionZoomIn">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-in"> <iconset theme="zoom-in">
<normaloff>.</normaloff>.</iconset> <normaloff>.</normaloff>.</iconset>
@ -1643,6 +1718,9 @@
</property> </property>
</action> </action>
<action name="actionZoomOut"> <action name="actionZoomOut">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-out"> <iconset theme="zoom-out">
<normaloff>.</normaloff>.</iconset> <normaloff>.</normaloff>.</iconset>
@ -1652,6 +1730,9 @@
</property> </property>
</action> </action>
<action name="actionZoomOriginal"> <action name="actionZoomOriginal">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-original"> <iconset theme="zoom-original">
<normaloff>.</normaloff>.</iconset> <normaloff>.</normaloff>.</iconset>
@ -1661,6 +1742,9 @@
</property> </property>
</action> </action>
<action name="actionZoomFitBest"> <action name="actionZoomFitBest">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-fit-best"> <iconset theme="zoom-fit-best">
<normaloff>.</normaloff>.</iconset> <normaloff>.</normaloff>.</iconset>
@ -1672,6 +1756,11 @@
<string>Zoom sheet</string> <string>Zoom sheet</string>
</property> </property>
</action> </action>
<action name="actionPreferences">
<property name="text">
<string>Preferences</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<tabstops> <tabstops>
@ -1721,9 +1810,6 @@
<tabstop>checkBoxLayoutWarningPiecesSuperposition</tabstop> <tabstop>checkBoxLayoutWarningPiecesSuperposition</tabstop>
<tabstop>checkBoxLayoutWarningPiecesOutOfBound</tabstop> <tabstop>checkBoxLayoutWarningPiecesOutOfBound</tabstop>
</tabstops> </tabstops>
<resources> <resources/>
<include location="share/resources/puzzleicon.qrc"/>
<include location="share/resources/puzzleicon.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -70,8 +70,6 @@ class VPSheet : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit VPSheet(VPLayout* layout); explicit VPSheet(VPLayout* layout);
~VPSheet(); ~VPSheet();

View File

@ -33,19 +33,6 @@
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionconversionerror.h" #include "../ifc/exception/vexceptionconversionerror.h"
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileReader::VPLayoutFileReader()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileReader::~VPLayoutFileReader()
{
// TODO
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file) bool VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file)
{ {
@ -56,7 +43,7 @@ bool VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file)
ReadLayout(layout); ReadLayout(layout);
} }
return !error(); return hasError();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -39,8 +39,8 @@ class VPLayoutFileReader : public QXmlStreamReader
{ {
Q_DECLARE_TR_FUNCTIONS(VPLayoutFileReader) Q_DECLARE_TR_FUNCTIONS(VPLayoutFileReader)
public: public:
VPLayoutFileReader(); VPLayoutFileReader()=default;
~VPLayoutFileReader(); ~VPLayoutFileReader()=default;
bool ReadFile(VPLayout *layout, QFile *file); bool ReadFile(VPLayout *layout, QFile *file);

View File

@ -34,18 +34,6 @@
#include "vplayoutliterals.h" #include "vplayoutliterals.h"
#include "../ifc/xml/vlayoutconverter.h" #include "../ifc/xml/vlayoutconverter.h"
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileWriter::VPLayoutFileWriter()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileWriter::~VPLayoutFileWriter()
{
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteFile(VPLayout *layout, QFile *file) void VPLayoutFileWriter::WriteFile(VPLayout *layout, QFile *file)
{ {

View File

@ -31,6 +31,7 @@
#include <QLocale> #include <QLocale>
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QCoreApplication>
#include "../vmisc/literals.h" #include "../vmisc/literals.h"
@ -43,14 +44,14 @@ class QMarginsF;
class VPLayoutFileWriter : public QXmlStreamWriter class VPLayoutFileWriter : public QXmlStreamWriter
{ {
Q_DECLARE_TR_FUNCTIONS(VPLayoutFileWriter)
public: public:
VPLayoutFileWriter(); VPLayoutFileWriter()= default;
~VPLayoutFileWriter(); ~VPLayoutFileWriter()= default;
void WriteFile(VPLayout *layout, QFile *file); void WriteFile(VPLayout *layout, QFile *file);
private: private:
void WriteLayout(VPLayout *layout); void WriteLayout(VPLayout *layout);
void WriteProperties(VPLayout *layout); void WriteProperties(VPLayout *layout);
void WriteUnplacePiecesList(VPLayout *layout); void WriteUnplacePiecesList(VPLayout *layout);
@ -69,7 +70,6 @@ private:
template <size_t N> template <size_t N>
void SetAttribute(const QString &name, const char (&value)[N]); void SetAttribute(const QString &name, const char (&value)[N]);
}; };
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -70,6 +70,7 @@ void TapePreferencesPathPage::Apply()
settings->SetPathMultisizeMeasurements(ui->pathTable->item(1, 1)->text()); settings->SetPathMultisizeMeasurements(ui->pathTable->item(1, 1)->text());
settings->SetPathPattern(ui->pathTable->item(2, 1)->text()); settings->SetPathPattern(ui->pathTable->item(2, 1)->text());
settings->SetPathTemplate(ui->pathTable->item(3, 1)->text()); settings->SetPathTemplate(ui->pathTable->item(3, 1)->text());
settings->SetPathManualLayouts(ui->pathTable->item(4, 1)->text());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -107,6 +108,9 @@ void TapePreferencesPathPage::DefaultPath()
case 3: // templates case 3: // templates
path = VCommonSettings::GetDefPathTemplate(); path = VCommonSettings::GetDefPathTemplate();
break; break;
case 4: // layouts
path = VCommonSettings::GetDefPathManualLayouts();
break;
default: default:
break; break;
} }
@ -138,6 +142,9 @@ void TapePreferencesPathPage::EditPath()
case 3: // templates case 3: // templates
path = MApplication::VApp()->TapeSettings()->GetPathTemplate(); path = MApplication::VApp()->TapeSettings()->GetPathTemplate();
break; break;
case 4: // layouts
path = MApplication::VApp()->TapeSettings()->GetPathManualLayouts();
break;
default: default:
break; break;
} }
@ -171,7 +178,7 @@ void TapePreferencesPathPage::EditPath()
void TapePreferencesPathPage::InitTable() void TapePreferencesPathPage::InitTable()
{ {
ui->pathTable->clearContents(); ui->pathTable->clearContents();
ui->pathTable->setRowCount(4); ui->pathTable->setRowCount(5);
ui->pathTable->setColumnCount(2); ui->pathTable->setColumnCount(2);
const VTapeSettings *settings = MApplication::VApp()->TapeSettings(); const VTapeSettings *settings = MApplication::VApp()->TapeSettings();
@ -204,6 +211,13 @@ void TapePreferencesPathPage::InitTable()
ui->pathTable->setItem(3, 1, item); ui->pathTable->setItem(3, 1, item);
} }
{
ui->pathTable->setItem(4, 0, new QTableWidgetItem(tr("My Layouts")));
QTableWidgetItem *item = new QTableWidgetItem(settings->GetPathManualLayouts());
item->setToolTip(settings->GetPathManualLayouts());
ui->pathTable->setItem(4, 1, item);
}
ui->pathTable->verticalHeader()->setDefaultSectionSize(20); ui->pathTable->verticalHeader()->setDefaultSectionSize(20);
ui->pathTable->resizeColumnsToContents(); ui->pathTable->resizeColumnsToContents();
ui->pathTable->resizeRowsToContents(); ui->pathTable->resizeRowsToContents();

View File

@ -89,7 +89,7 @@ void DialogTapePreferences::showEvent(QShowEvent *event)
// do your init stuff here // do your init stuff here
QSize sz = VAbstractApplication::VApp()->Settings()->GetPreferenceDialogSize(); QSize sz = VAbstractApplication::VApp()->Settings()->GetPreferenceDialogSize();
if (sz.isEmpty() == false) if (not sz.isEmpty())
{ {
resize(sz); resize(sz);
} }

View File

@ -374,7 +374,7 @@ bool MApplication::IsTestMode() const
*/ */
bool MApplication::IsAppInGUIMode() const bool MApplication::IsAppInGUIMode() const
{ {
return IsTestMode(); return not IsTestMode();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -854,6 +854,7 @@ TMainWindow *MApplication::NewMainWindow()
if (not MApplication::VApp()->IsTestMode()) if (not MApplication::VApp()->IsTestMode())
{ {
tape->show(); tape->show();
tape->UpdateWindowTitle();
} }
return tape; return tape;
} }

View File

@ -35,7 +35,6 @@
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "dialogs/dialogmdatabase.h" #include "dialogs/dialogmdatabase.h"
class MApplication;// use in define
class TMainWindow; class TMainWindow;
class QLocalServer; class QLocalServer;

View File

@ -133,7 +133,7 @@ TMainWindow::TMainWindow(QWidget *parent)
connect(gradation, &QTimer::timeout, this, &TMainWindow::GradationChanged); connect(gradation, &QTimer::timeout, this, &TMainWindow::GradationChanged);
SetupMenu(); SetupMenu();
UpdateWindowTitle();
ReadSettings(); ReadSettings();
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
@ -278,21 +278,20 @@ bool TMainWindow::LoadFile(const QString &path)
// Check if file already opened // Check if file already opened
const QList<TMainWindow*> list = MApplication::VApp()->MainWindows(); const QList<TMainWindow*> list = MApplication::VApp()->MainWindows();
for (auto w : list) auto w = std::find_if(list.begin(), list.end(),
[path](TMainWindow *window) { return window->CurrentFile() == path; });
if (w != list.end())
{ {
if (w->CurrentFile() == path) (*w)->activateWindow();
{
w->activateWindow();
close(); close();
return false; return false;
} }
}
VlpCreateLock(lock, path); VlpCreateLock(lock, path);
if (not lock->IsLocked()) if (not lock->IsLocked())
{ {
if (not IgnoreLocking(lock->GetLockError(), path)) if (not IgnoreLocking(lock->GetLockError(), path, MApplication::VApp()->IsAppInGUIMode()))
{ {
return false; return false;
} }
@ -388,13 +387,6 @@ bool TMainWindow::LoadFile(const QString &path)
return true; return true;
} }
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::ShowToolTip(const QString &toolTip)
{
Q_UNUSED(toolTip)
// do nothing
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void TMainWindow::FileNew() void TMainWindow::FileNew()
{ {
@ -597,11 +589,13 @@ void TMainWindow::changeEvent(QEvent *event)
{ {
if (event->type() == QEvent::LanguageChange) if (event->type() == QEvent::LanguageChange)
{ {
VAbstractApplication::VApp()->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c()); WindowsLocale();
// retranslate designer form (single inheritance approach) // retranslate designer form (single inheritance approach)
ui->retranslateUi(this); ui->retranslateUi(this);
UpdateWindowTitle();
InitMeasurementUnits(); InitMeasurementUnits();
if (mType == MeasurementsType::Multisize) if (mType == MeasurementsType::Multisize)
@ -782,49 +776,10 @@ bool TMainWindow::FileSave()
return false; return false;
} }
#ifdef Q_OS_WIN32 if (not CheckFilePermissions(curFile, this))
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
const bool isFileWritable = QFileInfo(curFile).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not isFileWritable)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The measurements document has no write permissions."));
messageBox.setInformativeText(tr("Do you want to change the premissions?"));
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
messageBox.setDefaultButton(QMessageBox::Yes);
if (messageBox.exec() == QMessageBox::Yes)
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
bool changed = QFile::setPermissions(curFile,
QFileInfo(curFile).permissions() | QFileDevice::WriteUser);
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not changed)
{
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Cannot set permissions for %1 to writable.").arg(curFile));
messageBox.setInformativeText(tr("Could not save the file."));
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{ {
return false; return false;
} }
}
QString error; QString error;
if (not SaveMeasurements(curFile, error)) if (not SaveMeasurements(curFile, error))
@ -2410,7 +2365,6 @@ void TMainWindow::SetupMenu()
m_separatorAct->setVisible(false); m_separatorAct->setVisible(false);
ui->menuFile->insertAction(ui->actionPreferences, m_separatorAct ); ui->menuFile->insertAction(ui->actionPreferences, m_separatorAct );
connect(ui->actionQuit, &QAction::triggered, this, &TMainWindow::close); connect(ui->actionQuit, &QAction::triggered, this, &TMainWindow::close);
ui->actionQuit->setShortcuts(QKeySequence::Quit); ui->actionQuit->setShortcuts(QKeySequence::Quit);
@ -3289,7 +3243,15 @@ void TMainWindow::UpdateWindowTitle()
} }
else else
{ {
showName = tr("untitled %1").arg(MApplication::VApp()->MainWindows().size()+1); int index = MApplication::VApp()->MainWindows().indexOf(this);
if (index != -1)
{
showName = tr("untitled %1").arg(index+1);
}
else
{
showName = tr("untitled");
}
mType == MeasurementsType::Multisize ? showName += QLatin1String(".vst") : showName += QLatin1String(".vit"); mType == MeasurementsType::Multisize ? showName += QLatin1String(".vst") : showName += QLatin1String(".vit");
} }
@ -3525,21 +3487,20 @@ bool TMainWindow::LoadFromExistingFile(const QString &path)
// Check if file already opened // Check if file already opened
const QList<TMainWindow*> list = MApplication::VApp()->MainWindows(); const QList<TMainWindow*> list = MApplication::VApp()->MainWindows();
for (auto w : list) auto w = std::find_if(list.begin(), list.end(),
[path](TMainWindow *window) { return window->CurrentFile() == path; });
if (w != list.end())
{ {
if (w->CurrentFile() == path) (*w)->activateWindow();
{
w->activateWindow();
close(); close();
return false; return false;
} }
}
VlpCreateLock(lock, path); VlpCreateLock(lock, path);
if (not lock->IsLocked()) if (not lock->IsLocked())
{ {
if (not IgnoreLocking(lock->GetLockError(), path)) if (not IgnoreLocking(lock->GetLockError(), path, MApplication::VApp()->IsAppInGUIMode()))
{ {
return false; return false;
} }
@ -3653,7 +3614,11 @@ void TMainWindow::CreateWindowMenu(QMenu *menu)
window->isWindowModified() ? title.replace(index, 3, QChar('*')) : title.replace(index, 3, QString()); window->isWindowModified() ? title.replace(index, 3, QChar('*')) : title.replace(index, 3, QString());
} }
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
QAction *action = menu->addAction(title, this, SLOT(ShowWindow())); QAction *action = menu->addAction(title, this, SLOT(ShowWindow()));
#else
QAction *action = menu->addAction(title, this, &TMainWindow::ShowWindow);
#endif //QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
action->setData(i); action->setData(i);
action->setCheckable(true); action->setCheckable(true);
action->setMenuRole(QAction::NoRole); action->setMenuRole(QAction::NoRole);
@ -3664,72 +3629,6 @@ void TMainWindow::CreateWindowMenu(QMenu *menu)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
bool TMainWindow::IgnoreLocking(int error, const QString &path)
{
QMessageBox::StandardButton answer = QMessageBox::Abort;
if (not MApplication::VApp()->IsTestMode())
{
switch(error)
{
case QLockFile::LockFailedError:
answer = QMessageBox::warning(this, tr("Locking file"),
tr("This file already opened in another window. Ignore if you want "
"to continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::PermissionError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("The lock file could not be created, for lack of permissions. "
"Ignore if you want to continue (not recommended, can cause "
"a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::UnknownError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file. Ignore if you want to "
"continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
default:
answer = QMessageBox::Abort;
break;
}
}
if (answer == QMessageBox::Abort)
{
qCDebug(tMainWindow, "Failed to lock %s", qUtf8Printable(path));
qCDebug(tMainWindow, "Error type: %d", error);
if (MApplication::VApp()->IsTestMode())
{
switch(error)
{
case QLockFile::LockFailedError:
qCCritical(tMainWindow, "%s",
qUtf8Printable(tr("This file already opened in another window.")));
break;
case QLockFile::PermissionError:
qCCritical(tMainWindow, "%s",
qUtf8Printable(tr("The lock file could not be created, for lack of permissions.")));
break;
case QLockFile::UnknownError:
qCCritical(tMainWindow, "%s",
qUtf8Printable(tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file.")));
break;
default:
break;
}
qApp->exit(V_EX_NOINPUT);
}
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void TMainWindow::HackDimensionBaseValue() void TMainWindow::HackDimensionBaseValue()
{ {

View File

@ -65,8 +65,7 @@ public:
bool LoadFile(const QString &path); bool LoadFile(const QString &path);
public slots: void UpdateWindowTitle();
virtual void ShowToolTip(const QString &toolTip) override;
protected: protected:
virtual void closeEvent(QCloseEvent *event) override; virtual void closeEvent(QCloseEvent *event) override;
@ -218,7 +217,6 @@ private:
void MeasurementGUI(); void MeasurementGUI();
void Controls(); void Controls();
void MFields(bool enabled); void MFields(bool enabled);
void UpdateWindowTitle();
void ReadSettings(); void ReadSettings();
void WriteSettings(); void WriteSettings();
@ -231,8 +229,6 @@ private:
void CreateWindowMenu(QMenu *menu); void CreateWindowMenu(QMenu *menu);
bool IgnoreLocking(int error, const QString &path);
template <class T> template <class T>
void HackWidget(T **widget); void HackWidget(T **widget);
void HackDimensionBaseValue(); void HackDimensionBaseValue();

View File

@ -3253,53 +3253,10 @@ bool MainWindow::on_actionSave_triggered()
return false; return false;
} }
#ifdef Q_OS_WIN32 if (not CheckFilePermissions(VAbstractValApplication::VApp()->GetPatternPath(), this))
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
const bool isFileWritable = QFileInfo(VAbstractValApplication::VApp()->GetPatternPath()).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not isFileWritable)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The document has no write permissions."));
messageBox.setInformativeText(tr("Do you want to change the premissions?"));
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
messageBox.setDefaultButton(QMessageBox::Yes);
if (messageBox.exec() == QMessageBox::Yes)
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
bool changed =
QFile::setPermissions(VAbstractValApplication::VApp()->GetPatternPath(),
QFileInfo(VAbstractValApplication::VApp()
->GetPatternPath()).permissions() | QFileDevice::WriteUser);
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not changed)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Cannot set permissions for %1 to writable.")
.arg(VAbstractValApplication::VApp()->GetPatternPath()));
messageBox.setInformativeText(tr("Could not save the file."));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{ {
return false; return false;
} }
}
QString error; QString error;
bool result = SavePattern(VAbstractValApplication::VApp()->GetPatternPath(), error); bool result = SavePattern(VAbstractValApplication::VApp()->GetPatternPath(), error);
@ -5325,7 +5282,7 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile)
} }
else else
{ {
if (not IgnoreLocking(lock->GetLockError(), fileName)) if (not IgnoreLocking(lock->GetLockError(), fileName, VApplication::IsGUIMode()))
{ {
return false; return false;
} }
@ -6433,73 +6390,6 @@ void MainWindow::UpdateWindowTitle()
#endif //defined(Q_OS_MAC) #endif //defined(Q_OS_MAC)
} }
//---------------------------------------------------------------------------------------------------------------------
bool MainWindow::IgnoreLocking(int error, const QString &path)
{
QMessageBox::StandardButton answer = QMessageBox::Abort;
if (VApplication::IsGUIMode())
{
switch(error)
{
case QLockFile::LockFailedError:
answer = QMessageBox::warning(this, tr("Locking file"),
tr("This file already opened in another window. Ignore if you want "
"to continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::PermissionError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("The lock file could not be created, for lack of permissions. "
"Ignore if you want to continue (not recommended, can cause "
"a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::UnknownError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("Unknown error happened, for instance a full partition prevented "
"writing out the lock file. Ignore if you want to continue (not "
"recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
default:
answer = QMessageBox::Abort;
break;
}
}
if (answer == QMessageBox::Abort)
{
qCDebug(vMainWindow, "Failed to lock %s", qUtf8Printable(path));
qCDebug(vMainWindow, "Error type: %d", error);
Clear();
if (not VApplication::IsGUIMode())
{
switch(error)
{
case QLockFile::LockFailedError:
qCCritical(vMainWindow, "%s",
qUtf8Printable(tr("This file already opened in another window.")));
break;
case QLockFile::PermissionError:
qCCritical(vMainWindow, "%s",
qUtf8Printable(tr("The lock file could not be created, for lack of permissions.")));
break;
case QLockFile::UnknownError:
qCCritical(vMainWindow, "%s",
qUtf8Printable(tr("Unknown error happened, for instance a full partition prevented "
"writing out the lock file.")));
break;
default:
break;
}
qApp->exit(V_EX_NOINPUT);
}
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void MainWindow::ToolSelectPoint() void MainWindow::ToolSelectPoint()
{ {

View File

@ -392,8 +392,6 @@ private:
void UpdateWindowTitle(); void UpdateWindowTitle();
bool IgnoreLocking(int error, const QString &path);
void ToolSelectPoint(); void ToolSelectPoint();
void ToolSelectPointByPress(); void ToolSelectPointByPress();
void ToolSelectPointByRelease(); void ToolSelectPointByRelease();

View File

@ -149,66 +149,80 @@ unix{
tape.path = $$BINDIR tape.path = $$BINDIR
tape.files += $${OUT_PWD}/../tape/$${DESTDIR}/tape tape.files += $${OUT_PWD}/../tape/$${DESTDIR}/tape
puzzle.path = $$BINDIR
puzzle.files += $${OUT_PWD}/../puzzle/$${DESTDIR}/puzzle
# .desktop file # .desktop file
desktop.path = $$DATADIR/applications/ desktop.path = $$DATADIR/applications/
desktop.files += ../../../dist/$${TARGET}.desktop \ desktop.files += ../../../dist/$${TARGET}.desktop \
desktop.files += ../../../dist/tape.desktop desktop.files += ../../../dist/tape.desktop \
desktop.files += ../../../dist/puzzle.desktop
# logo # logo
hicolor_48_apps.path = $$DATADIR/icons/hicolor/48x48/apps/ hicolor_48_apps.path = $$DATADIR/icons/hicolor/48x48/apps/
hicolor_48_apps.files += \ hicolor_48_apps.files += \
../../../share/icons/48x48/apps/$${TARGET}.png \ ../../../share/icons/48x48/apps/$${TARGET}.png \
../../../share/icons/48x48/apps/tape.png ../../../share/icons/48x48/apps/tape.png \
../../../share/icons/48x48/apps/puzzle.png
hicolor_48_mimetypes.path = $$DATADIR/icons/hicolor/48x48/mimetypes/ hicolor_48_mimetypes.path = $$DATADIR/icons/hicolor/48x48/mimetypes/
hicolor_48_mimetypes.files += \ hicolor_48_mimetypes.files += \
../../../share/icons/48x48/mimetypes/application-x-valentina-pattern.png \ ../../../share/icons/48x48/mimetypes/application-x-valentina-pattern.png \
../../../share/icons/48x48/mimetypes/application-x-valentina-i-measurements.png \ ../../../share/icons/48x48/mimetypes/application-x-valentina-i-measurements.png \
../../../share/icons/48x48/mimetypes/application-x-valentina-s-measurements.png ../../../share/icons/48x48/mimetypes/application-x-valentina-s-measurements.png \
../../../share/icons/48x48/mimetypes/application-x-valentina-layout.png
hicolor_64_apps.path = $$DATADIR/icons/hicolor/64x64/apps/ hicolor_64_apps.path = $$DATADIR/icons/hicolor/64x64/apps/
hicolor_64_apps.files += \ hicolor_64_apps.files += \
../../../share/icons/64x64/apps/$${TARGET}.png \ ../../../share/icons/64x64/apps/$${TARGET}.png \
../../../share/icons/64x64/apps/tape.png ../../../share/icons/64x64/apps/tape.png \
../../../share/icons/64x64/apps/puzzle.png
hicolor_64_mimetypes.path = $$DATADIR/icons/hicolor/64x64/mimetypes/ hicolor_64_mimetypes.path = $$DATADIR/icons/hicolor/64x64/mimetypes/
hicolor_64_mimetypes.files += \ hicolor_64_mimetypes.files += \
../../../share/icons/64x64/mimetypes/application-x-valentina-pattern.png \ ../../../share/icons/64x64/mimetypes/application-x-valentina-pattern.png \
../../../share/icons/64x64/mimetypes/application-x-valentina-i-measurements.png \ ../../../share/icons/64x64/mimetypes/application-x-valentina-i-measurements.png \
../../../share/icons/64x64/mimetypes/application-x-valentina-s-measurements.png ../../../share/icons/64x64/mimetypes/application-x-valentina-s-measurements.png \
../../../share/icons/64x64/mimetypes/application-x-valentina-layout.png
hicolor_128_apps.path = $$DATADIR/icons/hicolor/128x128/apps/ hicolor_128_apps.path = $$DATADIR/icons/hicolor/128x128/apps/
hicolor_128_apps.files += \ hicolor_128_apps.files += \
../../../share/icons/128x128/apps/$${TARGET}.png \ ../../../share/icons/128x128/apps/$${TARGET}.png \
../../../share/icons/128x128/apps/tape.png ../../../share/icons/128x128/apps/tape.png \
../../../share/icons/128x128/apps/puzzle.png
hicolor_128_mimetypes.path = $$DATADIR/icons/hicolor/128x128/mimetypes/ hicolor_128_mimetypes.path = $$DATADIR/icons/hicolor/128x128/mimetypes/
hicolor_128_mimetypes.files += \ hicolor_128_mimetypes.files += \
../../../share/icons/128x128/mimetypes/application-x-valentina-pattern.png \ ../../../share/icons/128x128/mimetypes/application-x-valentina-pattern.png \
../../../share/icons/128x128/mimetypes/application-x-valentina-i-measurements.png \ ../../../share/icons/128x128/mimetypes/application-x-valentina-i-measurements.png \
../../../share/icons/128x128/mimetypes/application-x-valentina-s-measurements.png ../../../share/icons/128x128/mimetypes/application-x-valentina-s-measurements.png \
../../../share/icons/128x128/mimetypes/application-x-valentina-layout.png
hicolor_256_apps.path = $$DATADIR/icons/hicolor/256x256/apps/ hicolor_256_apps.path = $$DATADIR/icons/hicolor/256x256/apps/
hicolor_256_apps.files += \ hicolor_256_apps.files += \
../../../share/icons/256x256/apps/$${TARGET}.png \ ../../../share/icons/256x256/apps/$${TARGET}.png \
../../../share/icons/256x256/apps/tape.png ../../../share/icons/256x256/apps/tape.png \
../../../share/icons/256x256/apps/puzzle.png
hicolor_256_mimetypes.path = $$DATADIR/icons/hicolor/256x256/mimetypes/ hicolor_256_mimetypes.path = $$DATADIR/icons/hicolor/256x256/mimetypes/
hicolor_256_mimetypes.files += \ hicolor_256_mimetypes.files += \
../../../share/icons/256x256/mimetypes/application-x-valentina-pattern.png \ ../../../share/icons/256x256/mimetypes/application-x-valentina-pattern.png \
../../../share/icons/256x256/mimetypes/application-x-valentina-i-measurements.png \ ../../../share/icons/256x256/mimetypes/application-x-valentina-i-measurements.png \
../../../share/icons/256x256/mimetypes/application-x-valentina-s-measurements.png ../../../share/icons/256x256/mimetypes/application-x-valentina-s-measurements.png \
../../../share/icons/256x256/mimetypes/application-x-valentina-layout.png
hicolor_512_apps.path = $$DATADIR/icons/hicolor/512x512/apps/ hicolor_512_apps.path = $$DATADIR/icons/hicolor/512x512/apps/
hicolor_512_apps.files += \ hicolor_512_apps.files += \
../../../share/icons/512x512/apps/$${TARGET}.png \ ../../../share/icons/512x512/apps/$${TARGET}.png \
../../../share/icons/512x512/apps/tape.png ../../../share/icons/512x512/apps/tape.png \
../../../share/icons/512x512/apps/puzzle.png
hicolor_512_mimetypes.path = $$DATADIR/icons/hicolor/512x512/mimetypes/ hicolor_512_mimetypes.path = $$DATADIR/icons/hicolor/512x512/mimetypes/
hicolor_512_mimetypes.files += \ hicolor_512_mimetypes.files += \
../../../share/icons/512x512/mimetypes/application-x-valentina-pattern.png \ ../../../share/icons/512x512/mimetypes/application-x-valentina-pattern.png \
../../../share/icons/512x512/mimetypes/application-x-valentina-i-measurements.png \ ../../../share/icons/512x512/mimetypes/application-x-valentina-i-measurements.png \
../../../share/icons/512x512/mimetypes/application-x-valentina-s-measurements.png ../../../share/icons/512x512/mimetypes/application-x-valentina-s-measurements.png \
../../../share/icons/512x512/mimetypes/application-x-valentina-layout.png
# Path to translation files after installation # Path to translation files after installation
translations.path = $$PKGDATADIR/translations/ translations.path = $$PKGDATADIR/translations/
@ -229,6 +243,7 @@ unix{
INSTALLS += \ INSTALLS += \
target \ target \
tape \ tape \
puzzle \
desktop \ desktop \
hicolor_48_apps \ hicolor_48_apps \
hicolor_48_mimetypes \ hicolor_48_mimetypes \
@ -273,6 +288,9 @@ unix{
tape.path = $$MACOS_DIR tape.path = $$MACOS_DIR
tape.files += $${OUT_PWD}/../tape/$${DESTDIR}/tape.app/$$MACOS_DIR/tape tape.files += $${OUT_PWD}/../tape/$${DESTDIR}/tape.app/$$MACOS_DIR/tape
puzzle.path = $$MACOS_DIR
puzzle.files += $${OUT_PWD}/../puzzle/$${DESTDIR}/puzzle.app/$$MACOS_DIR/puzzle
# Utility pdftops need for saving a layout image to PS and EPS formates. # Utility pdftops need for saving a layout image to PS and EPS formates.
xpdf.path = $$MACOS_DIR xpdf.path = $$MACOS_DIR
xpdf.files += $${PWD}/../../../dist/macx/bin64/pdftops xpdf.files += $${PWD}/../../../dist/macx/bin64/pdftops
@ -298,6 +316,7 @@ unix{
icns_resources.files += $$PWD/../../../dist/macx/i-measurements.icns icns_resources.files += $$PWD/../../../dist/macx/i-measurements.icns
icns_resources.files += $$PWD/../../../dist/macx/s-measurements.icns icns_resources.files += $$PWD/../../../dist/macx/s-measurements.icns
icns_resources.files += $$PWD/../../../dist/macx/pattern.icns icns_resources.files += $$PWD/../../../dist/macx/pattern.icns
icns_resources.files += $$PWD/../../../dist/macx/layout.icns
# Copy to bundle multisize measurements files # Copy to bundle multisize measurements files
# We cannot add none exist files to bundle through QMAKE_BUNDLE_DATA. That's why we must do this manually. # We cannot add none exist files to bundle through QMAKE_BUNDLE_DATA. That's why we must do this manually.
@ -309,6 +328,7 @@ unix{
label \ label \
libraries \ libraries \
tape \ tape \
puzzle \
xpdf \ xpdf \
icns_resources icns_resources
} }
@ -322,11 +342,13 @@ win32:*g++* {
package.files += \ package.files += \
$${OUT_PWD}/$${DESTDIR}/valentina.exe \ $${OUT_PWD}/$${DESTDIR}/valentina.exe \
$${OUT_PWD}/../tape/$${DESTDIR}/tape.exe \ $${OUT_PWD}/../tape/$${DESTDIR}/tape.exe \
$${OUT_PWD}/../puzzle/$${DESTDIR}/puzzle.exe \
$${OUT_PWD}/../tape/$${DESTDIR}/diagrams.rcc \ $${OUT_PWD}/../tape/$${DESTDIR}/diagrams.rcc \
$$PWD/../../../dist/win/valentina.ico \ $$PWD/../../../dist/win/valentina.ico \
$$PWD/../../../dist/win/i-measurements.ico \ $$PWD/../../../dist/win/i-measurements.ico \
$$PWD/../../../dist/win/s-measurements.ico \ $$PWD/../../../dist/win/s-measurements.ico \
$$PWD/../../../dist/win/pattern.ico \ $$PWD/../../../dist/win/pattern.ico \
$$PWD/../../../dist/win/layout.ico \
$$PWD/../../../dist/win/pdftops.exe \ $$PWD/../../../dist/win/pdftops.exe \
$$PWD/../../../dist/win/EUDC.TTE \ $$PWD/../../../dist/win/EUDC.TTE \
$$PWD/../../../AUTHORS.txt \ $$PWD/../../../AUTHORS.txt \

View File

@ -153,16 +153,14 @@ QString VAbstractApplication::translationsPath(const QString &locale) const
{ {
return dir.absolutePath(); return dir.absolutePath();
} }
else
{
#if defined(APPIMAGE) && defined(Q_OS_LINUX) #if defined(APPIMAGE) && defined(Q_OS_LINUX)
/* Fix path to trasnaltions when run inside AppImage. */ /* Fix path to trasnaltions when run inside AppImage. */
return AppImageRoot() + PKGDATADIR + trPath; return AppImageRoot() + PKGDATADIR + trPath;
#else #else
return PKGDATADIR + trPath; return PKGDATADIR + trPath;
#endif // defined(APPIMAGE) && defined(Q_OS_LINUX) #endif // defined(APPIMAGE) && defined(Q_OS_LINUX)
} #endif // Unix
#endif
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/************************************************************************ /************************************************************************
** **
** @file vcommonsettings.h ** @file vcommonsettings.h
** @author Roman Telezhynskyi <dismine(at)gmail.com> ** @author Roman Telezhynskyi <dismine(at)gmail.com>

View File

@ -831,12 +831,20 @@ QVector<QLineF> VPassmark::BuiltInSAPassmarkBaseLine(const VPiece &piece) const
} }
else else
{ {
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2' with built in " if (m_data.globalPassmarkLength > accuracyPointOnLine)
"seam allowance. User must manually provide length.") {
length = m_data.globalPassmarkLength;
}
else
{
const QString errorMsg = QObject::tr("Cannot calculate a notch for point '%1' in piece '%2' with built "
"in seam allowance. User must manually provide length.")
.arg(m_data.nodeName, m_data.pieceName); .arg(m_data.nodeName, m_data.pieceName);
VAbstractApplication::VApp()->IsPedantic() ? throw VExceptionInvalidNotch(errorMsg) : VAbstractApplication::VApp()->IsPedantic()
qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg; ? throw VExceptionInvalidNotch(errorMsg)
return QVector<QLineF>(); : qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
return {};
}
} }
} }

View File

@ -31,18 +31,31 @@
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vmisc/vsysexits.h"
#include "dialogs/dialogexporttocsv.h" #include "dialogs/dialogexporttocsv.h"
#include "../vwidgets/vmaingraphicsview.h"
#include <QStyle> #include <QStyle>
#include <QToolBar> #include <QToolBar>
#include <QFileDialog> #include <QFileDialog>
#include <QAction> #include <QAction>
#include <QLockFile>
#include <QMessageBox>
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
#include "../vwidgets/vmaingraphicsview.h"
#include <QStyleFactory> #include <QStyleFactory>
#endif #endif
#include <QLoggingCategory>
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes")
QT_WARNING_DISABLE_INTEL(1418)
Q_LOGGING_CATEGORY(abstactMainWindow, "abs.MainWindow")
QT_WARNING_POP
namespace namespace
{ {
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -134,6 +147,13 @@ VAbstractMainWindow::VAbstractMainWindow(QWidget *parent)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::ShowToolTip(const QString &toolTip)
{
Q_UNUSED(toolTip)
// do nothing
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VAbstractMainWindow::ContinueFormatRewrite(const QString &currentFormatVersion, bool VAbstractMainWindow::ContinueFormatRewrite(const QString &currentFormatVersion,
const QString &maxFormatVersion) const QString &maxFormatVersion)
@ -197,6 +217,16 @@ QString VAbstractMainWindow::CSVFilePath()
return fileName; return fileName;
} }
//---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)
{
Q_UNUSED(fileName)
Q_UNUSED(withHeader)
Q_UNUSED(mib)
Q_UNUSED(separator)
// do nothing
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::UpdateRecentFileActions() void VAbstractMainWindow::UpdateRecentFileActions()
{ {
@ -219,6 +249,121 @@ void VAbstractMainWindow::UpdateRecentFileActions()
m_separatorAct->setVisible(numRecentFiles>0); m_separatorAct->setVisible(numRecentFiles>0);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractMainWindow::CheckFilePermissions(const QString &path, QWidget *messageBoxParent) -> bool
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
// cppcheck-suppress unreadVariable
const bool isFileWritable = QFileInfo(path).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not isFileWritable)
{
QMessageBox messageBox(messageBoxParent);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The measurements document has no write permissions."));
messageBox.setInformativeText(tr("Do you want to change the premissions?"));
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
messageBox.setDefaultButton(QMessageBox::Yes);
if (messageBox.exec() == QMessageBox::Yes)
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
bool changed = QFile::setPermissions(path, QFileInfo(path).permissions() | QFileDevice::WriteUser);
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not changed)
{
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Cannot set permissions for %1 to writable.").arg(path));
messageBox.setInformativeText(tr("Could not save the file."));
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{
return false;
}
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractMainWindow::IgnoreLocking(int error, const QString &path, bool guiMode)
{
QMessageBox::StandardButton answer = QMessageBox::Abort;
if (guiMode)
{
switch(error)
{
case QLockFile::LockFailedError:
answer = QMessageBox::warning(this, tr("Locking file"),
tr("This file already opened in another window. Ignore if you want "
"to continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::PermissionError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("The lock file could not be created, for lack of permissions. "
"Ignore if you want to continue (not recommended, can cause "
"a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::UnknownError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file. Ignore if you want to "
"continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
default:
answer = QMessageBox::Abort;
break;
}
}
if (answer == QMessageBox::Abort)
{
qCDebug(abstactMainWindow, "Failed to lock %s", qUtf8Printable(path));
qCDebug(abstactMainWindow, "Error type: %d", error);
if (not guiMode)
{
switch(error)
{
case QLockFile::LockFailedError:
qCCritical(abstactMainWindow, "%s",
qUtf8Printable(tr("This file already opened in another window.")));
break;
case QLockFile::PermissionError:
qCCritical(abstactMainWindow, "%s",
qUtf8Printable(tr("The lock file could not be created, for lack of permissions.")));
break;
case QLockFile::UnknownError:
qCCritical(abstactMainWindow, "%s",
qUtf8Printable(tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file.")));
break;
default:
break;
}
qApp->exit(V_EX_NOINPUT);
}
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::WindowsLocale() void VAbstractMainWindow::WindowsLocale()
{ {

View File

@ -45,7 +45,7 @@ public:
virtual ~VAbstractMainWindow() Q_DECL_EQ_DEFAULT; virtual ~VAbstractMainWindow() Q_DECL_EQ_DEFAULT;
public slots: public slots:
virtual void ShowToolTip(const QString &toolTip)=0; virtual void ShowToolTip(const QString &toolTip);
virtual void UpdateVisibilityGroups(); virtual void UpdateVisibilityGroups();
virtual void UpdateDetailsList(); virtual void UpdateDetailsList();
virtual void ZoomFitBestCurrent(); virtual void ZoomFitBestCurrent();
@ -66,11 +66,15 @@ protected:
QString CSVFilePath(); QString CSVFilePath();
virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)=0; virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator);
virtual QStringList RecentFileList() const =0; virtual QStringList RecentFileList() const =0;
void UpdateRecentFileActions(); void UpdateRecentFileActions();
static bool CheckFilePermissions(const QString &path, QWidget *messageBoxParent=nullptr);
bool IgnoreLocking(int error, const QString &path, bool guiMode);
private: private:
Q_DISABLE_COPY(VAbstractMainWindow) Q_DISABLE_COPY(VAbstractMainWindow)
}; };