From c8526f2eb007ea72aa1f9c2b84d436743e3c62d5 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sat, 21 Mar 2020 18:15:29 +0200 Subject: [PATCH] Setting scale factor for export and print. --- ChangeLog.txt | 1 + dist/OBS_debian/debian.valentina.1 | 6 +- dist/debian/valentina.1 | 6 +- src/app/valentina/core/vcmdexport.cpp | 28 ++ src/app/valentina/core/vcmdexport.h | 3 + .../valentina/dialogs/dialoglayoutscale.cpp | 214 ++++++++ src/app/valentina/dialogs/dialoglayoutscale.h | 74 +++ .../valentina/dialogs/dialoglayoutscale.ui | 334 +++++++++++++ src/app/valentina/dialogs/dialogs.h | 1 + src/app/valentina/dialogs/dialogs.pri | 3 + .../valentina/dialogs/dialogsavelayout.cpp | 84 +++- src/app/valentina/dialogs/dialogsavelayout.h | 10 + src/app/valentina/dialogs/dialogsavelayout.ui | 456 +++++++++++++----- src/app/valentina/mainwindow.cpp | 4 + src/app/valentina/mainwindowsnogui.cpp | 84 +++- src/app/valentina/mainwindowsnogui.h | 3 + src/libs/vdxf/vdxfengine.cpp | 37 +- src/libs/vdxf/vdxfengine.h | 8 + src/libs/vdxf/vdxfpaintdevice.cpp | 34 ++ src/libs/vdxf/vdxfpaintdevice.h | 6 + src/libs/vlayout/vlayoutpiece.cpp | 8 + src/libs/vlayout/vlayoutpiece.h | 1 + src/libs/vmisc/commandoptions.cpp | 4 + src/libs/vmisc/commandoptions.h | 2 + src/libs/vmisc/share/resources/icon.qrc | 4 + .../resources/icon/32x32/broken_link.png | Bin 0 -> 1561 bytes .../resources/icon/32x32/broken_link@2x.png | Bin 0 -> 4495 bytes .../vmisc/share/resources/icon/32x32/link.png | Bin 0 -> 1219 bytes .../share/resources/icon/32x32/link@2x.png | Bin 0 -> 3673 bytes 29 files changed, 1257 insertions(+), 158 deletions(-) create mode 100644 src/app/valentina/dialogs/dialoglayoutscale.cpp create mode 100644 src/app/valentina/dialogs/dialoglayoutscale.h create mode 100644 src/app/valentina/dialogs/dialoglayoutscale.ui create mode 100644 src/libs/vmisc/share/resources/icon/32x32/broken_link.png create mode 100644 src/libs/vmisc/share/resources/icon/32x32/broken_link@2x.png create mode 100644 src/libs/vmisc/share/resources/icon/32x32/link.png create mode 100644 src/libs/vmisc/share/resources/icon/32x32/link@2x.png diff --git a/ChangeLog.txt b/ChangeLog.txt index c3367696f..5eedaf2d4 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -44,6 +44,7 @@ - Tool Point at distance and angle now allows negative length. - Export pattern to DXF-ASTM. - [smart-pattern/valentina#18] Auto-created Visibility Group for group operation. +- Setting scale factor for export and print. # Version 0.6.2 (unreleased) - [#903] Bug in tool Cut Spline path. diff --git a/dist/OBS_debian/debian.valentina.1 b/dist/OBS_debian/debian.valentina.1 index b84655a61..5e9da11b5 100644 --- a/dist/OBS_debian/debian.valentina.1 +++ b/dist/OBS_debian/debian.valentina.1 @@ -1,6 +1,6 @@ .\" Manpage for valentina. .\" Contact dismine@gmail.com to correct errors. -.TH valentina 1 "15 March, 2020" "valentina man page" +.TH valentina 1 "21 March, 2020" "valentina man page" .SH NAME Valentina \- Pattern making program. .SH SYNOPSIS @@ -213,6 +213,10 @@ The path to output destination folder. By default the directory at which the app .RB "Page top margin in current units like 3.0 (" "export mode" "). If not set will be used value from default printer. Or 0 if none printers was found." .IP "-B, --bmargin " .RB "Page bottom margin in current units like 3.0 (" "export mode" "). If not set will be used value from default printer. Or 0 if none printers was found." +.IP "--xscale " +.RB "Set horizontal scale factor from 0.01 to 3.0 (default = 1.0, " "export mode" ")." +.IP "--yscale " +.RB "Set vertical scale factor from 0.01 to 3.0 (default = 1.0, " "export mode" ")." .IP "--followGrainline" .RB "Order detail to follow grainline direction (" "export mode" "). .IP "--manualPriority" diff --git a/dist/debian/valentina.1 b/dist/debian/valentina.1 index b84655a61..5e9da11b5 100644 --- a/dist/debian/valentina.1 +++ b/dist/debian/valentina.1 @@ -1,6 +1,6 @@ .\" Manpage for valentina. .\" Contact dismine@gmail.com to correct errors. -.TH valentina 1 "15 March, 2020" "valentina man page" +.TH valentina 1 "21 March, 2020" "valentina man page" .SH NAME Valentina \- Pattern making program. .SH SYNOPSIS @@ -213,6 +213,10 @@ The path to output destination folder. By default the directory at which the app .RB "Page top margin in current units like 3.0 (" "export mode" "). If not set will be used value from default printer. Or 0 if none printers was found." .IP "-B, --bmargin " .RB "Page bottom margin in current units like 3.0 (" "export mode" "). If not set will be used value from default printer. Or 0 if none printers was found." +.IP "--xscale " +.RB "Set horizontal scale factor from 0.01 to 3.0 (default = 1.0, " "export mode" ")." +.IP "--yscale " +.RB "Set vertical scale factor from 0.01 to 3.0 (default = 1.0, " "export mode" ")." .IP "--followGrainline" .RB "Order detail to follow grainline direction (" "export mode" "). .IP "--manualPriority" diff --git a/src/app/valentina/core/vcmdexport.cpp b/src/app/valentina/core/vcmdexport.cpp index b58f8f33e..84a6956b0 100644 --- a/src/app/valentina/core/vcmdexport.cpp +++ b/src/app/valentina/core/vcmdexport.cpp @@ -408,6 +408,28 @@ bool VCommandLine::IsCSVWithHeader() const return IsOptionSet(LONG_OPTION_CSVWITHHEADER); } +//--------------------------------------------------------------------------------------------------------------------- +qreal VCommandLine::ExportXScale() const +{ + qreal xs = 0; + if (IsOptionSet(LONG_OPTION_EXPXSCALE)) + { + xs = OptionValue(LONG_OPTION_EXPXSCALE).toDouble(); + } + return xs; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VCommandLine::ExportYScale() const +{ + qreal ys = 0; + if (IsOptionSet(LONG_OPTION_EXPYSCALE)) + { + ys = OptionValue(LONG_OPTION_EXPYSCALE).toDouble(); + } + return ys; +} + //--------------------------------------------------------------------------------------------------------------------- QString VCommandLine::OptExportSuchDetails() const { @@ -664,6 +686,12 @@ void VCommandLine::InitCommandLineOptions() translate("VCommandLine", "Page bottom margin in current units like 3.0 (export mode). If not set will be " "used value from default printer. Or 0 if none printers was found."), translate("VCommandLine", "The bottom margin")}, + {LONG_OPTION_EXPXSCALE, + translate("VCommandLine", "Set horizontal scale factor from 0.01 to 3.0 (default = 1.0, export mode)."), + translate("VCommandLine", "Horizontal scale")}, + {LONG_OPTION_EXPYSCALE, + translate("VCommandLine", "Set vertical scale factor from 0.01 to 3.0 (default = 1.0, export mode)."), + translate("VCommandLine", "Vertical scale")}, //================================================================================================================= {LONG_OPTION_FOLLOW_GRAINLINE, translate("VCommandLine", "Order detail to follow grainline direction (export mode).")}, diff --git a/src/app/valentina/core/vcmdexport.h b/src/app/valentina/core/vcmdexport.h index a89f0bf4c..b4b8057b7 100644 --- a/src/app/valentina/core/vcmdexport.h +++ b/src/app/valentina/core/vcmdexport.h @@ -88,6 +88,9 @@ public: bool IsExportOnlyDetails() const; bool IsCSVWithHeader() const; + qreal ExportXScale() const; + qreal ExportYScale() const; + //@brief returns the piece name regex or empty string if not set QString OptExportSuchDetails() const; diff --git a/src/app/valentina/dialogs/dialoglayoutscale.cpp b/src/app/valentina/dialogs/dialoglayoutscale.cpp new file mode 100644 index 000000000..256c66f14 --- /dev/null +++ b/src/app/valentina/dialogs/dialoglayoutscale.cpp @@ -0,0 +1,214 @@ +/************************************************************************ + ** + ** @file dialoglayoutscale.cpp + ** @author Roman Telezhynskyi + ** @date 21 3, 2020 + ** + ** @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) 2020 Valentina project + ** 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 . + ** + *************************************************************************/ + +#include "dialoglayoutscale.h" +#include "ui_dialoglayoutscale.h" +#include "../core/vapplication.h" +#include "../vmisc/vsettings.h" + +#include + +//--------------------------------------------------------------------------------------------------------------------- +DialogLayoutScale::DialogLayoutScale(bool printTiled, QWidget *parent) + :QDialog(parent), + ui(new Ui::DialogLayoutScale) +{ + ui->setupUi(this); + + qApp->ValentinaSettings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c()); + + QPushButton *bOk = ui->buttonBox->button(QDialogButtonBox::Ok); + SCASSERT(bOk != nullptr) + connect(bOk, &QPushButton::clicked, this, &DialogLayoutScale::Save); + + if (not printTiled) + { + ui->groupBoxMargins->setVisible(false); + } + + connect(ui->toolButtonScaleConnected, &QToolButton::clicked, this, &DialogLayoutScale::ToggleScaleConnection); + + connect(ui->doubleSpinBoxHorizontalScale, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &DialogLayoutScale::HorizontalScaleChanged); + connect(ui->doubleSpinBoxVerticalScale, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &DialogLayoutScale::VerticalScaleChanged); + + ReadSettings(); +} + +//--------------------------------------------------------------------------------------------------------------------- +DialogLayoutScale::~DialogLayoutScale() +{ + delete ui; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::SetTiledMargins(QMarginsF margins) +{ + // read Margins top, right, bottom, left + margins = UnitConvertor(margins, Unit::Mm, qApp->patternUnit()); + + ui->doubleSpinBoxLeftField->setValue(margins.left()); + ui->doubleSpinBoxTopField->setValue(margins.top()); + ui->doubleSpinBoxRightField->setValue(margins.right()); + ui->doubleSpinBoxBottomField->setValue(margins.bottom()); +} + +//--------------------------------------------------------------------------------------------------------------------- +QMarginsF DialogLayoutScale::GetTiledMargins() const +{ + QMarginsF margins = QMarginsF( + ui->doubleSpinBoxLeftField->value(), + ui->doubleSpinBoxTopField->value(), + ui->doubleSpinBoxRightField->value(), + ui->doubleSpinBoxBottomField->value() + ); + + return UnitConvertor(margins, qApp->patternUnit(), Unit::Mm); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::SetXScale(qreal scale) +{ + ui->doubleSpinBoxHorizontalScale->setValue(scale * 100.); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal DialogLayoutScale::GetXScale() const +{ + return ui->doubleSpinBoxHorizontalScale->value() / 100.; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::SetYScale(qreal scale) +{ + ui->doubleSpinBoxVerticalScale->setValue(scale * 100.); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal DialogLayoutScale::GetYScale() const +{ + return ui->doubleSpinBoxVerticalScale->value() / 100.; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::showEvent(QShowEvent *event) +{ + QDialog::showEvent( event ); + if ( event->spontaneous() ) + { + return; + } + + if (isInitialized) + { + return; + } + // do your init stuff here + + setFixedSize(size()); + + isInitialized = true;//first show windows are held +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::Save() +{ + WriteSettings(); + + accept(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::ToggleScaleConnection() +{ + m_scaleConnected = not m_scaleConnected; + + QIcon icon; + icon.addFile(m_scaleConnected ? QStringLiteral(":/icon/32x32/link.png") + : QStringLiteral(":/icon/32x32/broken_link.png")); + ui->toolButtonScaleConnected->setIcon(icon); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::HorizontalScaleChanged(double d) +{ + if (m_scaleConnected) + { + ui->doubleSpinBoxVerticalScale->blockSignals(true); + ui->doubleSpinBoxVerticalScale->setValue(d); + ui->doubleSpinBoxVerticalScale->blockSignals(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::VerticalScaleChanged(double d) +{ + if (m_scaleConnected) + { + ui->doubleSpinBoxHorizontalScale->blockSignals(true); + ui->doubleSpinBoxHorizontalScale->setValue(d); + ui->doubleSpinBoxHorizontalScale->blockSignals(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::ReadSettings() +{ + VSettings *settings = qApp->ValentinaSettings(); + const Unit unit = qApp->patternUnit(); + + // read Margins top, right, bottom, left + const QMarginsF margins = settings->GetTiledPDFMargins(unit); + + ui->doubleSpinBoxLeftField->setValue(margins.left()); + ui->doubleSpinBoxTopField->setValue(margins.top()); + ui->doubleSpinBoxRightField->setValue(margins.right()); + ui->doubleSpinBoxBottomField->setValue(margins.bottom()); + + ui->doubleSpinBoxLeftField->setSuffix(UnitsToStr(unit, true)); + ui->doubleSpinBoxTopField->setSuffix(UnitsToStr(unit, true)); + ui->doubleSpinBoxRightField->setSuffix(UnitsToStr(unit, true)); + ui->doubleSpinBoxBottomField->setSuffix(UnitsToStr(unit, true)); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogLayoutScale::WriteSettings() const +{ + VSettings *settings = qApp->ValentinaSettings(); + const Unit unit = qApp->patternUnit(); + + // write Margins top, right, bottom, left + QMarginsF margins = QMarginsF( + ui->doubleSpinBoxLeftField->value(), + ui->doubleSpinBoxTopField->value(), + ui->doubleSpinBoxRightField->value(), + ui->doubleSpinBoxBottomField->value() + ); + settings->SetTiledPDFMargins(margins,unit); +} diff --git a/src/app/valentina/dialogs/dialoglayoutscale.h b/src/app/valentina/dialogs/dialoglayoutscale.h new file mode 100644 index 000000000..757f9c6e6 --- /dev/null +++ b/src/app/valentina/dialogs/dialoglayoutscale.h @@ -0,0 +1,74 @@ +/************************************************************************ + ** + ** @file dialoglayoutscale.h + ** @author Roman Telezhynskyi + ** @date 21 3, 2020 + ** + ** @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) 2020 Valentina project + ** 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 . + ** + *************************************************************************/ +#ifndef DIALOGLAYOUTSCALE_H +#define DIALOGLAYOUTSCALE_H + +#include + +namespace Ui +{ + class DialogLayoutScale; +} + +class DialogLayoutScale : public QDialog +{ + Q_OBJECT + +public: + explicit DialogLayoutScale(bool printTiled, QWidget *parent = nullptr); + ~DialogLayoutScale(); + + void SetTiledMargins(QMarginsF margins); + QMarginsF GetTiledMargins() const; + + void SetXScale(qreal scale); + qreal GetXScale() const; + + void SetYScale(qreal scale); + qreal GetYScale() const; + +protected: + virtual void showEvent(QShowEvent *event) override; + +private slots: + void Save(); + void ToggleScaleConnection(); + void HorizontalScaleChanged(double d); + void VerticalScaleChanged(double d); + +private: + Q_DISABLE_COPY(DialogLayoutScale) + Ui::DialogLayoutScale *ui; + bool isInitialized{false}; + bool m_scaleConnected{true}; + + void ReadSettings(); + void WriteSettings() const; +}; + +#endif // DIALOGLAYOUTSCALE_H diff --git a/src/app/valentina/dialogs/dialoglayoutscale.ui b/src/app/valentina/dialogs/dialoglayoutscale.ui new file mode 100644 index 000000000..6a0c99c37 --- /dev/null +++ b/src/app/valentina/dialogs/dialoglayoutscale.ui @@ -0,0 +1,334 @@ + + + DialogLayoutScale + + + + 0 + 0 + 404 + 211 + + + + Layout scale + + + + :/icon/64x64/icon64x64.png:/icon/64x64/icon64x64.png + + + + + + + + true + + + Margins + + + false + + + + + + + 0 + 0 + + + + Left: + + + + + + + cm + + + 0.100000000000000 + + + + + + + + 0 + 0 + + + + Right: + + + + + + + cm + + + 0.100000000000000 + + + + + + + + 0 + 0 + + + + Top: + + + + + + + cm + + + 0.100000000000000 + + + + + + + + 0 + 0 + + + + Bottom: + + + + + + + cm + + + 0.100000000000000 + + + + + + + + + + + + Scale + + + + + + + + Horizontal: + + + + + + + Vertical: + + + + + + + + + + + % + + + 1 + + + 1.000000000000000 + + + 300.000000000000000 + + + 0.100000000000000 + + + 100.000000000000000 + + + + + + + % + + + 1 + + + 1.000000000000000 + + + 300.000000000000000 + + + 0.100000000000000 + + + 100.000000000000000 + + + + + + + + + 1 + + + 0 + + + 0 + + + + + + 10 + + + + <html><head/><body><p><span style=" font-size:16pt;">┐</span></p></body></html> + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + ... + + + + :/icon/32x32/link.png:/icon/32x32/link.png + + + + 32 + 32 + + + + QToolButton::DelayedPopup + + + + + + + <html><head/><body><p><span style=" font-size:16pt; font-weight:600;">┘</span></p></body></html> + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + DialogLayoutScale + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogLayoutScale + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/app/valentina/dialogs/dialogs.h b/src/app/valentina/dialogs/dialogs.h index 122665410..2ca4e9ca3 100644 --- a/src/app/valentina/dialogs/dialogs.h +++ b/src/app/valentina/dialogs/dialogs.h @@ -36,5 +36,6 @@ #include "dialogaboutapp.h" #include "dialogpreferences.h" #include "dialogfinalmeasurements.h" +#include "dialoglayoutscale.h" #endif // DIALOGS_H diff --git a/src/app/valentina/dialogs/dialogs.pri b/src/app/valentina/dialogs/dialogs.pri index 2bb72de56..af53d7952 100644 --- a/src/app/valentina/dialogs/dialogs.pri +++ b/src/app/valentina/dialogs/dialogs.pri @@ -2,6 +2,7 @@ # This need for corect working file translations.pro HEADERS += \ + $$PWD/dialoglayoutscale.h \ $$PWD/dialogs.h \ $$PWD/dialogincrements.h \ $$PWD/dialoghistory.h \ @@ -26,6 +27,7 @@ HEADERS += \ SOURCES += \ $$PWD/dialogincrements.cpp \ $$PWD/dialoghistory.cpp \ + $$PWD/dialoglayoutscale.cpp \ $$PWD/dialogpatternproperties.cpp \ $$PWD/dialognewpattern.cpp \ $$PWD/dialogaboutapp.cpp \ @@ -47,6 +49,7 @@ SOURCES += \ FORMS += \ $$PWD/dialogincrements.ui \ $$PWD/dialoghistory.ui \ + $$PWD/dialoglayoutscale.ui \ $$PWD/dialogpatternproperties.ui \ $$PWD/dialognewpattern.ui \ $$PWD/dialogaboutapp.ui \ diff --git a/src/app/valentina/dialogs/dialogsavelayout.cpp b/src/app/valentina/dialogs/dialogsavelayout.cpp index f04ce78de..ecac7451b 100644 --- a/src/app/valentina/dialogs/dialogsavelayout.cpp +++ b/src/app/valentina/dialogs/dialogsavelayout.cpp @@ -151,26 +151,15 @@ DialogSaveLayout::DialogSaveLayout(int count, Draw mode, const QString &fileName InitTemplates(ui->comboBoxTemplates); + connect(ui->toolButtonScaleConnected, &QToolButton::clicked, this, &DialogSaveLayout::ToggleScaleConnection); + + connect(ui->doubleSpinBoxHorizontalScale, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &DialogSaveLayout::HorizontalScaleChanged); + connect(ui->doubleSpinBoxVerticalScale, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &DialogSaveLayout::VerticalScaleChanged); + ReadSettings(); - // connect for the template drop down box of the tiled pds - connect(ui->comboBoxTemplates, QOverload::of(&QComboBox::currentIndexChanged), - this, &DialogSaveLayout::WriteSettings); - - // connects for the margins of the tiled pdf - connect(ui->doubleSpinBoxLeftField, QOverload::of(&QDoubleSpinBox::valueChanged), - this, &DialogSaveLayout::WriteSettings); - connect(ui->doubleSpinBoxTopField, QOverload::of(&QDoubleSpinBox::valueChanged), - this, &DialogSaveLayout::WriteSettings); - connect(ui->doubleSpinBoxRightField, QOverload::of(&QDoubleSpinBox::valueChanged), - this, &DialogSaveLayout::WriteSettings); - connect(ui->doubleSpinBoxBottomField, QOverload::of(&QDoubleSpinBox::valueChanged), - this, &DialogSaveLayout::WriteSettings); - - // connects for the orientation buttons for the tiled pdf - connect(ui->toolButtonPortrait, &QToolButton::toggled, this, &DialogSaveLayout::WriteSettings); - connect(ui->toolButtonLandscape, &QToolButton::toggled, this, &DialogSaveLayout::WriteSettings); - ShowExample();//Show example for current format. } @@ -520,6 +509,8 @@ LayoutExportFormats DialogSaveLayout::Format() const //--------------------------------------------------------------------------------------------------------------------- void DialogSaveLayout::Save() { + WriteSettings(); + for (int i=0; i < count; ++i) { const QString name = Path()+'/'+FileName()+QString::number(i+1)+ExportFormatSuffix(Format()); @@ -623,6 +614,39 @@ void DialogSaveLayout::ShowExample() } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSaveLayout::ToggleScaleConnection() +{ + m_scaleConnected = not m_scaleConnected; + + QIcon icon; + icon.addFile(m_scaleConnected ? QStringLiteral(":/icon/32x32/link.png") + : QStringLiteral(":/icon/32x32/broken_link.png")); + ui->toolButtonScaleConnected->setIcon(icon); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSaveLayout::HorizontalScaleChanged(double d) +{ + if (m_scaleConnected) + { + ui->doubleSpinBoxVerticalScale->blockSignals(true); + ui->doubleSpinBoxVerticalScale->setValue(d); + ui->doubleSpinBoxVerticalScale->blockSignals(false); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSaveLayout::VerticalScaleChanged(double d) +{ + if (m_scaleConnected) + { + ui->doubleSpinBoxHorizontalScale->blockSignals(true); + ui->doubleSpinBoxHorizontalScale->setValue(d); + ui->doubleSpinBoxHorizontalScale->blockSignals(false); + } +} + //--------------------------------------------------------------------------------------------------------------------- bool DialogSaveLayout::IsTextAsPaths() const { @@ -719,6 +743,30 @@ PageOrientation DialogSaveLayout::GetTiledPageOrientation() const } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogSaveLayout::SetXScale(qreal scale) +{ + ui->doubleSpinBoxHorizontalScale->setValue(scale * 100.); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal DialogSaveLayout::GetXScale() const +{ + return ui->doubleSpinBoxHorizontalScale->value() / 100.; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogSaveLayout::SetYScale(qreal scale) +{ + ui->doubleSpinBoxVerticalScale->setValue(scale * 100.); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal DialogSaveLayout::GetYScale() const +{ + return ui->doubleSpinBoxVerticalScale->value() / 100.; +} + //--------------------------------------------------------------------------------------------------------------------- void DialogSaveLayout::showEvent(QShowEvent *event) { diff --git a/src/app/valentina/dialogs/dialogsavelayout.h b/src/app/valentina/dialogs/dialogsavelayout.h index 462c2330e..8f6d480f7 100644 --- a/src/app/valentina/dialogs/dialogsavelayout.h +++ b/src/app/valentina/dialogs/dialogsavelayout.h @@ -86,6 +86,12 @@ public: void SetTiledPageOrientation(PageOrientation orientation); PageOrientation GetTiledPageOrientation() const; + void SetXScale(qreal scale); + qreal GetXScale() const; + + void SetYScale(qreal scale); + qreal GetYScale() const; + protected: virtual void showEvent(QShowEvent *event) override; void InitTemplates(QComboBox *comboBoxTemplates); @@ -94,6 +100,9 @@ private slots: void Save(); void PathChanged(const QString &text); void ShowExample(); + void ToggleScaleConnection(); + void HorizontalScaleChanged(double d); + void VerticalScaleChanged(double d); private: Q_DISABLE_COPY(DialogSaveLayout) Ui::DialogSaveLAyout *ui; @@ -101,6 +110,7 @@ private: bool isInitialized; Draw m_mode; bool m_tiledExportMode; + bool m_scaleConnected{true}; static bool havePdf; static bool tested; diff --git a/src/app/valentina/dialogs/dialogsavelayout.ui b/src/app/valentina/dialogs/dialogsavelayout.ui index c9440ace0..b86e47a78 100644 --- a/src/app/valentina/dialogs/dialogsavelayout.ui +++ b/src/app/valentina/dialogs/dialogsavelayout.ui @@ -6,8 +6,8 @@ 0 0 - 719 - 314 + 493 + 391 @@ -17,20 +17,20 @@ :/icon/64x64/icon64x64.png:/icon/64x64/icon64x64.png - - - - - Path: - - - - + + + + + + Path: + + + - + 0 0 @@ -46,7 +46,7 @@ - + 0 0 @@ -61,44 +61,229 @@ - - - - File format: - - + + + + + + + 0 + 0 + + + + File format: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - - 0 - 0 - - - + + + + + + Options + + + + + + false + + + Binary form + + + + + + + true + + + Text as paths + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Scale + + + + + + + + Horizontal: + + + + + + + Vertical: + + + + + + + + + + + % + + + 1 + + + 1.000000000000000 + + + 300.000000000000000 + + + 0.100000000000000 + + + 100.000000000000000 + + + + + + + % + + + 1 + + + 1.000000000000000 + + + 300.000000000000000 + + + 0.100000000000000 + + + 100.000000000000000 + + + + + + + + + 1 + + + 0 + + + 0 + + + + + + 10 + + + + <html><head/><body><p><span style=" font-size:16pt;">┐</span></p></body></html> + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + ... + + + + :/icon/32x32/link.png:/icon/32x32/link.png + + + + 32 + 32 + + + + QToolButton::DelayedPopup + + + + + + + <html><head/><body><p><span style=" font-size:16pt; font-weight:600;">┘</span></p></body></html> + + + + + + + + + - - - - false - - - Binary form - - - - - - - true - - - Text as paths - - - - + @@ -148,6 +333,9 @@ cm + + 0.100000000000000 + @@ -164,6 +352,9 @@ cm + + 0.100000000000000 + @@ -204,6 +395,9 @@ cm + + 0.100000000000000 + @@ -224,6 +418,9 @@ cm + + 0.100000000000000 + @@ -239,79 +436,75 @@ Paper format - - - - - + + + + + Templates: + + + + + + + + + + Orientation: + + + + + + + - Templates: + ... + + + + :/icon/16x16/portrait.png:/icon/16x16/portrait.png + + + true + + + true + + + true - - - - - + + - Orientation: + ... + + + + :/icon/16x16/landscape.png:/icon/16x16/landscape.png + + + true + + + true - - - - - - ... - - - - :/icon/16x16/portrait.png:/icon/16x16/portrait.png - - - true - - - true - - - true - - - - - - - ... - - - - :/icon/16x16/landscape.png:/icon/16x16/landscape.png - - - true - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + Qt::Horizontal + + + + 40 + 20 + + + @@ -320,19 +513,28 @@ - - - - File name: - - - - + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + File name: + + + - + 0 0 @@ -347,6 +549,12 @@ + + + 0 + 0 + + 130 @@ -363,7 +571,7 @@ - + Qt::Horizontal diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 00eca97a4..8dc9b5c75 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -5527,6 +5527,8 @@ bool MainWindow::DoExport(const VCommandLinePtr &expParams) m_dialogSaveLayout->SelectFormat(static_cast(expParams->OptExportType())); m_dialogSaveLayout->SetBinaryDXFFormat(expParams->IsBinaryDXF()); m_dialogSaveLayout->SetTextAsPaths(expParams->IsTextAsPaths()); + m_dialogSaveLayout->SetXScale(expParams->ExportXScale()); + m_dialogSaveLayout->SetYScale(expParams->ExportYScale()); if (static_cast(expParams->OptExportType()) == LayoutExportFormats::PDFTiled) { @@ -5562,6 +5564,8 @@ bool MainWindow::DoExport(const VCommandLinePtr &expParams) m_dialogSaveLayout->SetDestinationPath(expParams->OptDestinationPath()); m_dialogSaveLayout->SelectFormat(static_cast(expParams->OptExportType())); m_dialogSaveLayout->SetBinaryDXFFormat(expParams->IsBinaryDXF()); + m_dialogSaveLayout->SetXScale(expParams->ExportXScale()); + m_dialogSaveLayout->SetYScale(expParams->ExportYScale()); if (static_cast(expParams->OptExportType()) == LayoutExportFormats::PDFTiled) { diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index 74c946e94..7eac97fc7 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -41,6 +41,7 @@ #include "../vlayout/vlayoutgenerator.h" #include "dialogs/dialoglayoutprogress.h" #include "dialogs/dialogsavelayout.h" +#include "dialogs/dialoglayoutscale.h" #include "../vlayout/vposter.h" #include "../vpatterndb/floatItemData/vpiecelabeldata.h" #include "../vpatterndb/floatItemData/vpatternlabeldata.h" @@ -868,7 +869,9 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer) auto *paper = qgraphicsitem_cast(papers.at(i)); if (paper) { - *poster += posterazor->Calc(paper->rect().toRect(), i, orientation); + QRectF paperRect = paper->rect(); + QSizeF image(paperRect.width() * m_xscale, paperRect.height() * m_yscale); + *poster += posterazor->Calc(image.toSize(), i, orientation); } } @@ -1213,8 +1216,8 @@ void MainWindowsNoGUI::SvgFile(const QString &name, QGraphicsRectItem *paper, QG const QRectF r = paper->rect(); QSvgGenerator generator; generator.setFileName(name); - generator.setSize(QSize(qFloor(r.width() + margins.left() + margins.right()), - qFloor(r.height() + margins.top() + margins.bottom()))); + generator.setSize(QSize(qFloor(r.width() * m_dialogSaveLayout->GetXScale() + margins.left() + margins.right()), + qFloor(r.height() * m_dialogSaveLayout->GetYScale() + margins.top() + margins.bottom()))); generator.setViewBox(QRectF(0, 0, r.width() + margins.left() + margins.right(), r.height() + margins.top() + margins.bottom())); generator.setTitle(tr("Pattern")); @@ -1226,6 +1229,7 @@ void MainWindowsNoGUI::SvgFile(const QString &name, QGraphicsRectItem *paper, QG painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(Qt::black, qApp->Settings()->WidthHairLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter.setBrush ( QBrush ( Qt::NoBrush ) ); + painter.scale(m_dialogSaveLayout->GetXScale(), m_dialogSaveLayout->GetYScale()); scene->render(&painter, r, r, Qt::IgnoreAspectRatio); painter.end(); } @@ -1240,8 +1244,8 @@ void MainWindowsNoGUI::PngFile(const QString &name, QGraphicsRectItem *paper, QG { const QRectF r = paper->rect(); // Create the image with the exact size of the shrunk scene - QImage image(QSize(qFloor(r.width() + margins.left() + margins.right()), - qFloor(r.height() + margins.top() + margins.bottom())), + QImage image(QSize(qFloor(r.width() * m_dialogSaveLayout->GetXScale() + margins.left() + margins.right()), + qFloor(r.height() * m_dialogSaveLayout->GetYScale() + margins.top() + margins.bottom())), QImage::Format_ARGB32); image.fill(Qt::white); QPainter painter(&image); @@ -1249,6 +1253,7 @@ void MainWindowsNoGUI::PngFile(const QString &name, QGraphicsRectItem *paper, QG painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(Qt::black, qApp->Settings()->WidthMainLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter.setBrush ( QBrush ( Qt::NoBrush ) ); + painter.scale(m_dialogSaveLayout->GetXScale(), m_dialogSaveLayout->GetYScale()); scene->render(&painter, r, r, Qt::IgnoreAspectRatio); image.save(name); } @@ -1271,9 +1276,11 @@ void MainWindowsNoGUI::PdfFile(const QString &name, QGraphicsRectItem *paper, QG printer.setResolution(static_cast(PrintDPI)); printer.setOrientation(QPrinter::Portrait); printer.setFullPage(ignorePrinterFields); - if (not printer.setPageSize(QPageSize(QSizeF(FromPixel(r.width() + margins.left() + margins.right(), Unit::Mm), - FromPixel(r.height() + margins.top() + margins.bottom(), Unit::Mm)), - QPageSize::Millimeter))) + + qreal width = FromPixel(r.width() * m_dialogSaveLayout->GetXScale() + margins.left() + margins.right(), Unit::Mm); + qreal height = FromPixel(r.height() * m_dialogSaveLayout->GetYScale() + margins.top() + margins.bottom(), Unit::Mm); + + if (not printer.setPageSize(QPageSize(QSizeF(width, height), QPageSize::Millimeter))) { qWarning() << tr("Cannot set printer page size"); } @@ -1298,6 +1305,7 @@ void MainWindowsNoGUI::PdfFile(const QString &name, QGraphicsRectItem *paper, QG painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(Qt::black, qApp->Settings()->WidthMainLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter.setBrush ( QBrush ( Qt::NoBrush ) ); + painter.scale(m_dialogSaveLayout->GetXScale(), m_dialogSaveLayout->GetYScale()); scene->render(&painter, r, r, Qt::IgnoreAspectRatio); painter.end(); } @@ -1323,6 +1331,9 @@ void MainWindowsNoGUI::PdfTiledFile(const QString &name) qWarning()<GetXScale(); + m_yscale = m_dialogSaveLayout->GetYScale(); + printer.setOutputFileName(name); printer.setResolution(static_cast(PrintDPI)); PrintPages(&printer); @@ -1421,13 +1432,18 @@ void MainWindowsNoGUI::FlatDxfFile(const QString &name, int version, bool binary PrepareTextForDXF(endStringPlaceholder, details); VDxfPaintDevice generator; generator.setFileName(name); - generator.setSize(paper->rect().size().toSize()); + + const QRectF r = paper->rect(); + generator.setSize(QSize(qFloor(r.width() * m_dialogSaveLayout->GetXScale()), + qFloor(r.height() * m_dialogSaveLayout->GetYScale()))); + generator.setResolution(PrintDPI); generator.SetVersion(static_cast(version)); generator.SetBinaryFormat(binary); generator.setInsunits(VarInsunits::Millimeters);// Decided to always use mm. See issue #745 QPainter painter; + painter.scale(m_dialogSaveLayout->GetXScale(), m_dialogSaveLayout->GetYScale()); if (painter.begin(&generator)) { scene->render(&painter, paper->rect(), paper->rect(), Qt::IgnoreAspectRatio); @@ -1442,11 +1458,14 @@ void MainWindowsNoGUI::AAMADxfFile(const QString &name, int version, bool binary { VDxfPaintDevice generator; generator.setFileName(name); - generator.setSize(size); + generator.setSize(QSize(qCeil(size.width() * m_dialogSaveLayout->GetXScale()), + qCeil(size.height() * m_dialogSaveLayout->GetYScale()))); generator.setResolution(PrintDPI); generator.SetVersion(static_cast(version)); generator.SetBinaryFormat(binary); generator.setInsunits(VarInsunits::Millimeters);// Decided to always use mm. See issue #745 + generator.SetXScale(m_dialogSaveLayout->GetXScale()); + generator.SetYScale(m_dialogSaveLayout->GetYScale()); generator.ExportToAAMA(details); } @@ -1461,6 +1480,8 @@ void MainWindowsNoGUI::ASTMDxfFile(const QString &name, int version, bool binary generator.SetVersion(static_cast(version)); generator.SetBinaryFormat(binary); generator.setInsunits(VarInsunits::Millimeters);// Decided to always use mm. See issue #745 + generator.SetXScale(m_dialogSaveLayout->GetXScale()); + generator.SetYScale(m_dialogSaveLayout->GetYScale()); generator.ExportToASTM(details); } @@ -1477,6 +1498,17 @@ void MainWindowsNoGUI::PreparePaper(int index) const shadows.at(index)->setVisible(false); paper->setPen(QPen(Qt::white, 0.1, Qt::NoPen));// border } + + QTransform matrix; + matrix.scale(m_xscale, m_yscale); + + QList paperDetails = details.at(index); + for (auto detail : paperDetails) + { + QTransform m = detail->transform(); + m *= matrix; + detail->setTransform(m); + } } //--------------------------------------------------------------------------------------------------------------------- @@ -1491,6 +1523,17 @@ void MainWindowsNoGUI::RestorePaper(int index) const scenes.at(index)->setBackgroundBrush(brush); shadows.at(index)->setVisible(true); } + + QTransform matrix; + matrix.scale(1./m_xscale, 1./m_yscale); + + QList paperDetails = details.at(index); + for (auto detail : paperDetails) + { + QTransform m = detail->transform(); + m *= matrix; + detail->setTransform(m); + } } //--------------------------------------------------------------------------------------------------------------------- @@ -1581,8 +1624,19 @@ void MainWindowsNoGUI::PrintPreview() return; } + { + DialogLayoutScale layoutScale(isTiled, this); + layoutScale.SetXScale(1); + layoutScale.SetYScale(1); + layoutScale.exec(); + + m_xscale = layoutScale.GetXScale(); + m_yscale = layoutScale.GetYScale(); + } + SetPrinterSettings(printer.data(), PrintType::PrintPreview); printer->setResolution(static_cast(PrintDPI)); + // display print preview dialog QPrintPreviewDialog preview(printer.data()); connect(&preview, &QPrintPreviewDialog::paintRequested, this, &MainWindowsNoGUI::PrintPages); @@ -1613,6 +1667,16 @@ void MainWindowsNoGUI::LayoutPrint() return; } + { + DialogLayoutScale layoutScale(isTiled, this); + layoutScale.SetXScale(1); + layoutScale.SetYScale(1); + layoutScale.exec(); + + m_xscale = layoutScale.GetXScale(); + m_yscale = layoutScale.GetYScale(); + } + SetPrinterSettings(printer.data(), PrintType::PrintNative); QPrintDialog dialog(printer.data(), this ); // If only user couldn't change page margins we could use method setMinMax(); diff --git a/src/app/valentina/mainwindowsnogui.h b/src/app/valentina/mainwindowsnogui.h index 1137d725b..77a69eb86 100644 --- a/src/app/valentina/mainwindowsnogui.h +++ b/src/app/valentina/mainwindowsnogui.h @@ -162,6 +162,9 @@ private: QString layoutPrinterName; + qreal m_xscale{1}; + qreal m_yscale{1}; + static QList CreateShadows(const QList &papers); static QList CreateScenes(const QList &papers, const QList &shadows, diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp index bec63c1c8..f023ea186 100644 --- a/src/libs/vdxf/vdxfengine.cpp +++ b/src/libs/vdxf/vdxfengine.cpp @@ -587,6 +587,30 @@ void VDxfEngine::setInsunits(const VarInsunits &var) varInsunits = var; } +//--------------------------------------------------------------------------------------------------------------------- +qreal VDxfEngine::GetXScale() const +{ + return m_xscale; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::SetXScale(const qreal &xscale) +{ + m_xscale = xscale; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VDxfEngine::GetYScale() const +{ + return m_yscale; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfEngine::SetYScale(const qreal &yscale) +{ + m_yscale = yscale; +} + //--------------------------------------------------------------------------------------------------------------------- QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wswitch-default") @@ -642,7 +666,7 @@ bool VDxfEngine::ExportToAAMA(const QVector &details) ExportStyleSystemText(input, details); - for(auto &detail : details) + for(auto detail : details) { dx_ifaceBlock *detailBlock = new dx_ifaceBlock(); @@ -655,6 +679,8 @@ bool VDxfEngine::ExportToAAMA(const QVector &details) detailBlock->name = blockName.toStdString(); detailBlock->layer = '1'; + detail.Scale(m_xscale, m_yscale); + ExportAAMAOutline(detailBlock, detail); ExportAAMADraw(detailBlock, detail); ExportAAMAIntcut(detailBlock, detail); @@ -775,7 +801,7 @@ void VDxfEngine::ExportPieceText(dx_ifaceBlock *detailBlock, const VLayoutPiece for (int i = 0; i < list.size(); ++i) { - QPointF pos(startPos.x(), startPos.y() - ToPixel(AAMATextHeight, varInsunits)*(list.size() - i-1)); + QPointF pos(startPos.x(), startPos.y() - ToPixel(AAMATextHeight * m_yscale, varInsunits)*(list.size() - i-1)); detailBlock->ent.push_back(AAMAText(pos, list.at(i), QChar('1'))); } } @@ -790,7 +816,8 @@ void VDxfEngine::ExportStyleSystemText(const QSharedPointer &input, co { for (int j = 0; j < strings.size(); ++j) { - QPointF pos(0, getSize().height() - ToPixel(AAMATextHeight, varInsunits)*(strings.size() - j-1)); + QPointF pos(0, getSize().height() - + ToPixel(AAMATextHeight * m_yscale, varInsunits)*(strings.size() - j-1)); input->AddEntity(AAMAText(pos, strings.at(j), QChar('1'))); } return; @@ -840,7 +867,7 @@ bool VDxfEngine::ExportToASTM(const QVector &details) ExportStyleSystemText(input, details); - for(auto &detail : details) + for(auto detail : details) { dx_ifaceBlock *detailBlock = new dx_ifaceBlock(); @@ -853,6 +880,8 @@ bool VDxfEngine::ExportToASTM(const QVector &details) detailBlock->name = blockName.toStdString(); detailBlock->layer = '1'; + detail.Scale(m_xscale, m_yscale); + ExportASTMPieceBoundary(detailBlock, detail); ExportASTMSewLine(detailBlock, detail); ExportASTMInternalLine(detailBlock, detail); diff --git a/src/libs/vdxf/vdxfengine.h b/src/libs/vdxf/vdxfengine.h index 945f965de..de1e8d0bf 100644 --- a/src/libs/vdxf/vdxfengine.h +++ b/src/libs/vdxf/vdxfengine.h @@ -92,6 +92,12 @@ public: void setMeasurement(const VarMeasurement &var); void setInsunits(const VarInsunits &var); + qreal GetXScale() const; + void SetXScale(const qreal &xscale); + + qreal GetYScale() const; + void SetYScale(const qreal &yscale); + private: Q_DISABLE_COPY(VDxfEngine) QSize size; @@ -104,6 +110,8 @@ private: VarMeasurement varMeasurement; VarInsunits varInsunits; DRW_Text *textBuffer; + qreal m_xscale{1}; + qreal m_yscale{1}; Q_REQUIRED_RESULT double FromPixel(double pix, const VarInsunits &unit) const; Q_REQUIRED_RESULT double ToPixel(double val, const VarInsunits &unit) const; diff --git a/src/libs/vdxf/vdxfpaintdevice.cpp b/src/libs/vdxf/vdxfpaintdevice.cpp index d425e98e5..23622d211 100644 --- a/src/libs/vdxf/vdxfpaintdevice.cpp +++ b/src/libs/vdxf/vdxfpaintdevice.cpp @@ -162,6 +162,40 @@ void VDxfPaintDevice::setInsunits(const VarInsunits &var) engine->setInsunits(var); } +//--------------------------------------------------------------------------------------------------------------------- +qreal VDxfPaintDevice::GetXScale() const +{ + return engine->GetYScale(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfPaintDevice::SetXScale(const qreal &xscale) +{ + if (engine->isActive()) + { + qWarning("VDxfPaintDevice::SetXScale(), cannot set x scale while Dxf is being generated"); + return; + } + engine->SetXScale(xscale); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VDxfPaintDevice::GetYScale() const +{ + return engine->GetXScale(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VDxfPaintDevice::SetYScale(const qreal &yscale) +{ + if (engine->isActive()) + { + qWarning("VDxfPaintDevice::SetYScale(), cannot set y scale while Dxf is being generated"); + return; + } + engine->SetYScale(yscale); +} + //--------------------------------------------------------------------------------------------------------------------- bool VDxfPaintDevice::ExportToAAMA(const QVector &details) const { diff --git a/src/libs/vdxf/vdxfpaintdevice.h b/src/libs/vdxf/vdxfpaintdevice.h index 1488da069..a78f762f8 100644 --- a/src/libs/vdxf/vdxfpaintdevice.h +++ b/src/libs/vdxf/vdxfpaintdevice.h @@ -66,6 +66,12 @@ public: void setMeasurement(const VarMeasurement &var); void setInsunits(const VarInsunits &var); + qreal GetXScale() const; + void SetXScale(const qreal &xscale); + + qreal GetYScale() const; + void SetYScale(const qreal &yscale); + bool ExportToAAMA(const QVector &details) const; bool ExportToASTM(const QVector &details) const; diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index a0d959641..7d4fbb5cb 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -830,6 +830,14 @@ void VLayoutPiece::Translate(qreal dx, qreal dy) d->matrix *= m; } +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutPiece::Scale(qreal sx, qreal sy) +{ + QTransform m; + m.scale(sx, sy); + d->matrix *= m; +} + //--------------------------------------------------------------------------------------------------------------------- void VLayoutPiece::Rotate(const QPointF &originPoint, qreal degrees) { diff --git a/src/libs/vlayout/vlayoutpiece.h b/src/libs/vlayout/vlayoutpiece.h index f0471e84f..509bf18ac 100644 --- a/src/libs/vlayout/vlayoutpiece.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -126,6 +126,7 @@ public: void SetMirror(bool value); void Translate(qreal dx, qreal dy); + void Scale(qreal sx, qreal sy); void Rotate(const QPointF &originPoint, qreal degrees); void Mirror(const QLineF &edge); void Mirror(); diff --git a/src/libs/vmisc/commandoptions.cpp b/src/libs/vmisc/commandoptions.cpp index 1a2eefe37..47e637f5b 100644 --- a/src/libs/vmisc/commandoptions.cpp +++ b/src/libs/vmisc/commandoptions.cpp @@ -53,6 +53,8 @@ const QString LONG_OPTION_BINARYDXF = QStringLiteral("bdxf"); const QString LONG_OPTION_TEXT2PATHS = QStringLiteral("text2paths"); const QString LONG_OPTION_EXPORTONLYDETAILS = QStringLiteral("exportOnlyDetails"); const QString LONG_OPTION_EXPORTSUCHDETAILS = QStringLiteral("exportSuchDetails"); +const QString LONG_OPTION_EXPXSCALE = QStringLiteral("xscale"); +const QString LONG_OPTION_EXPYSCALE = QStringLiteral("yscale"); const QString LONG_OPTION_CROP_LENGTH = QStringLiteral("crop"); const QString SINGLE_OPTION_CROP_LENGTH = QStringLiteral("c"); @@ -153,6 +155,8 @@ QStringList AllKeys() LONG_OPTION_TEXT2PATHS, LONG_OPTION_EXPORTONLYDETAILS, LONG_OPTION_EXPORTSUCHDETAILS, + LONG_OPTION_EXPXSCALE, + LONG_OPTION_EXPYSCALE, LONG_OPTION_CROP_LENGTH, SINGLE_OPTION_CROP_LENGTH, LONG_OPTION_CROP_WIDTH, LONG_OPTION_UNITE, SINGLE_OPTION_UNITE, diff --git a/src/libs/vmisc/commandoptions.h b/src/libs/vmisc/commandoptions.h index cd8c57ed5..1f4758455 100644 --- a/src/libs/vmisc/commandoptions.h +++ b/src/libs/vmisc/commandoptions.h @@ -50,6 +50,8 @@ extern const QString LONG_OPTION_BINARYDXF; extern const QString LONG_OPTION_TEXT2PATHS; extern const QString LONG_OPTION_EXPORTONLYDETAILS; extern const QString LONG_OPTION_EXPORTSUCHDETAILS; +extern const QString LONG_OPTION_EXPXSCALE; +extern const QString LONG_OPTION_EXPYSCALE; extern const QString LONG_OPTION_CROP_LENGTH; extern const QString SINGLE_OPTION_CROP_LENGTH; diff --git a/src/libs/vmisc/share/resources/icon.qrc b/src/libs/vmisc/share/resources/icon.qrc index ebd7ae48f..f4cff9ed5 100644 --- a/src/libs/vmisc/share/resources/icon.qrc +++ b/src/libs/vmisc/share/resources/icon.qrc @@ -85,5 +85,9 @@ icon/32x32/font_preferences.png icon/24x24/font_preferences@2x.png icon/24x24/font_preferences.png + icon/32x32/broken_link.png + icon/32x32/broken_link@2x.png + icon/32x32/link.png + icon/32x32/link@2x.png diff --git a/src/libs/vmisc/share/resources/icon/32x32/broken_link.png b/src/libs/vmisc/share/resources/icon/32x32/broken_link.png new file mode 100644 index 0000000000000000000000000000000000000000..e9eda1311efa3275fef208bf4f341fd2f3f2e259 GIT binary patch literal 1561 zcmV+!2Il#RP)0`ZQ7VfmCC4bDHxS?gj&=nwXvuy$^gSKfWvI}-qVMInrf2{de76%fB*ZR z?|$ce|3WZ@rGEDyHEW`Z1jbScVPgWQwQhfLkEQG^tb6loe115cPW0Zp_wC8gmT$I{oq=_4zBB*|cb!Pr>!)8!OG|;%>BPW*10f+HNJuci z?RMkxQp2M6N+ymf1d&DPqbQmK$QbA}~v z$1jT|0Z_2rs+k@Y`H~JP$z>UC)JqHlqIJHy&oJ$uTI9W>GfpF02a5j zV3ymx-IkM6f8o%fC;)JcjC^Px=tpw$3u+2+JpjDAwJIc9AGKDi)1vEc*ZtEKmMQ>f zFqt-yg$um^(2$W4{1IF*ne^)L@O`t5MslaMwYM=V>#fWROC>2io<1Wn{vARmq$tRl z$K%DNORdA>9?#;o6)SXs(b1};B}?+N-pb5|hHXJJppeUn+v(hW^TLH|nurLc zQmeH#W@oEU?OU<&ZdY$UA@p|u2*?>mM@B!W+Vfh(sS3+|zsvQBe%`!%M|ZdTkGi@; zoLp|hv#!RaOA{K+=C%K}XKgNOGZ@#)UqUIbh&bw+dZ zcz$V(g%YATRbe^u%GM*wP)*3k!@jYPn!i}%Zp_a9DtgYGEuPU)JQx}}NEka}Jb(Vz zpc#+}0yL44pU%(DPJiHZdc7kfmW<}+@z-}+4<;qftYHjk05I+c3DfCHll1We#bu{c zC@0(H=<2dYCM004$+STbgyJd5(A3mqcRQWCZ`9RYboKNYvYMKX7nE2xrlcmXHyGl; zz&HR`_VwBKIUEkmo}CmErJuVF0J55!zaG4P-7w`u zWNK)D>F7}aK<57aSoVHROn5}tbdSf2;bGTTXZNqX2LSVP52CN%Q`Tqi4}?z(gG|nu zCSxq`>l2?_E#QfulyNc$f&egff6{)lb^`$T7o;`1IT;s538#~$9CP$xSz>rf&q0_t zp)08xl8JtVk^j&x0b>9Gkp=*Go=vn~U?B7<2}MCEg~&uma|BG}CaEWcu_xcdFNy*P zk*FgYAN6$meSWA^D#&Dt9017NSr5h-mhGrc2n`L5@cDcQ1o$3F0JMC+P8b{*4E2Ie!m~Fv9ZwUG`Ms74%)9={qbaZ z(W?AiC#0Q@0l>KF2TrTjSqPBA7#=W?6SW6ccINN2;!K4ls91jkP!dr*{oQUr00000 LNkvXXu0mjfw71;L literal 0 HcmV?d00001 diff --git a/src/libs/vmisc/share/resources/icon/32x32/broken_link@2x.png b/src/libs/vmisc/share/resources/icon/32x32/broken_link@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7c709416c84348331a43d97f31bc71c668a60cf3 GIT binary patch literal 4495 zcmV;A5peE_P)Op?iGL!h-^)Y?*@v`O1do3ucoE%;**WkHtZV;2?0 z6|GhT>Y@U=tgf<)2nq;-MOO&4^uv}mX$%OZ71z?x+LAUOZSyf{GT--}^X?y$bg5$e zsZDgwKlA(Dx#!$7&wbzLJnzR4#$nWb>Sx&Ttq%eK>i^;ULY0;W*>dw`hJ~@%=!AX3 zEAhv7+}*%u&AI~1KKn4fcWv=_Yz>5Q8dI-(+L~M$I)@BhD!>a3FhK|*3~NnH?FQJ! zj4dzSzj6=8af~SdtJZ8l<5w@iC7)}YAc<}eO5Wl3`>kNmffEeC?{kn!B@mA%kw_$v zN~JPd>n}@XKl=PV7ahIy^Dkiiy(@Fu0xtXFOI2EXuZ8kLku%RYLlsAgL3HY4nE@ik zv12{x=;-ib@%Rp7_?8X#t=d1<`x9gJ<^f>E>c)v$dyV06xP1Dwsj4`V^=qv)5{V>Y zu^1AGB#hBu21-jKc>l~9DnFFhKoFZQyJKS|09^j1O}S?QtJZ7?F!OVvP;l9~=glE7 zLkNN6$9vG--Hli*4%c;I+ctv1Aj&JsQC3<4V+@SZ*uDErj>qFa@`nnpfA))u+?=t1 z^KNd;B1^bPO0jh6)X4+@mZi}CPCNGPYeQdO^d}k5yNZOkJe|p0)z{zuleT?rc&Gg^ zm>EJSOq_TYDXFeX3=Y&>_1Jctck_401OR!u7wq2kG#1|aeAtrw)kq{VwW6XN0C4zl z2M!%-k9nTCDSFuan_CrrbIaXJ+sZEb*lz}-iAKl9{u2X(%PdRU;cx*Q$3bsjpGc)r zg+1-Pjj#Uq_1;(jpvGd+up{yqJgcNM0wDyn_R!sZ6b%0N4fo&i1n?{1ne4sIUs?zN zX@nm6;i^woysxYC*qs#>6_8S*tgIA+LqqTPE4vUtGG|DT8Pj||JKqTe0009g29Zu@ zdOhuJ1XAxkDfR_+U2lCllfux@5CFh&92O)Zmd`p10C3k`IRXHoP$^|8l{K(*Dh&hO zk@UnNpzROL>H##hv*A67coNJE%eKg}lqG-y0KnR{IRk(Mh=>S81j8CIoc6h?)M)b( z#!iu-kYNKNf+PVD5rZVgXpEH$ND^7K!_32{EwQ$Oqt3JKq+n)SN(CZ7S_+<<2}+^j zIR$`V2E9vSuwgKP5l@b)J5*XoX7m{2!5F~JWMEl#%w_G%DF8@7FtTrc#0`j{+3)C4 zT|jvngaRQIgdq5AA6(CK6gZk&E?`(umIA=cFor=OhD?s?%YIi&0`ipJB88Fc8d09hAr!%l^JCQaV$Sn>q1R`;g5t$7DkSQ!0 z)dC7shzO{%ENhq)ZKTsF$5I%|F%BRJFl7yZKoDSt*VoxOYEa`E17=Pdqd`Ovf}oVe zWMofH0pKwVKs<5`GHVc#EIy-PR15Inifpccz|6>GTrk6Bt;=%D0*DgE7{kLnpt2_I zNMuHhJv{Pxb zFjq**bDSWU8Hsot+S73l)*Y2m`M?_F@gDGHBV zx5sn6*N^oahv#{)eKsacsD$5VT`iUSwfY+y^G5ES3t;iB&ldZXbx$Z5xVXBi3Pgl- zI*sVS0Ep4J`)KT>1+>=JXFu!e%Bw3XB7ZdiUaP4INZ=l6S&zTpaq3@~F~b`9?#Q9; z1Vj8FHWWKLFfagSMp01_s;jF>kyt@_90C3l0MK#89SHdCQX*VfRaHrO`FS8B96R2F zbUGaimIv=V{OA=Y6=cn}ZD_5pUk0VN19as-P*5-pL>I?h_w0A?Ys>*y)Y5|Hnwk;_ zu_iAPDLHe_98^r7KF#v`@5!_6N1E&EW;HHagqI($cTaHg?qnjlzU{3x6OBgUxh}vg z6q7{qTUoxm<_f?_Vq++scG1<v#66=QI?*3|5&*0&pk={=^IPldeP9{{#iS4;SOmrE%ZIE95oLZG<18fTqedE}2Yy_wBd$_jeyX1_Nehc)+b$tGM%Cu<#5Mp|i6S2M@lJ zOlLCRwk>P*_J``y0PxDPWw*e#pK`+CD<;pMFUqD)h2L=yE-xoi>OwmhTrqweaK;&s zfMH`^Ikta)=fPKBbvyU&1#6AU>C;hAQ85?H-_TN?3jka0y>zf+-@tA0c;@3nvDi*9 zqFNaR|97%{(J%$fEZOk!cr3oz0E_&<8rL&v0BCJ!sAbRlc5!v})QR)v0Yuo}+KOLq z+TWlUuDli3Q*XSfM*6sb=D0HV(ZF?gFg5|-}Ou8WQ>_pLl7^wq9= zL`eC+@o04RZ(Cd4R6O2eJa0EKzoavnt*$X$zZ@L=vtxzRQW)7YZmOIz?(KR*lre45t%WkW+=>yjm>WQA^-IPq^!3ir4!r0Wvo>C0ih0iZvTkQrkF z4^&m1wAjy_1{HYPTwv$ixp~6xpUy;!Nr;Oh@o`-ZIk!EA|0C*J4n_=5swVOBp*~Qa8`4reNcdlZ`xj_nXwNh%bFAyjR zMIu%~SsA2KIDYUTGJ}JaFs2GX*CXqm!xNjf+o8z7b%N+-2^A+Wk^vgD~)CiCR7mKJZ!IiUR5F&2PDQqC)%GNp3Tym?mT*=K`S~(D^^O zu=+U%0K80QHxbK_IC#(LZdI5$k6HnpIvtOSA} zNJF9XZU8{#(lY^1De#C)q`{j4MWY^u^lBs?9<)@kGvRGeVvv^6&)9gFo6^FIN=&fze5%mJv` zv12&%Yg*WKpHB`9Y;;qpkNZxXcwo^RZzP6O!N@R+}SFT zEr4$V047u=U_2w38OdZSn?MN$@xDnDp_ID5NTKH4&mYqIZV=s==UmdWZxjDhW=QD}Kbw`?-w$I(O=Oh8uefEF+fW9dhbgGI9!yqE`_4T8@{V;1| z)}>?dZs1b@fX;Pmk?9|5XJa0F=bd)1r>B>R2!(}VI6a3qL+t7g*NR-6uLaJIV7r_@J zp8)_ncB}<(7xrzr(e*SQPbL!mL$Pcw(Fr(^QU+a}`M`TUf5~YOS*N*0hKBipOQe(m z%d!{%rBZ2lp6=$T`8B@xFn0akytTuTpWdr&btIKc7aYM4IzZqjNIxEfFMl-9w~8UQDGP*Mhz1!PAeu7hRw;&5+X1NI=28|R@ooG?*_%B zGpSL3NRn8Obd-)1M~yL(0FzSy2qDaHU(hff3^0?0(JdgLT?rB*TT(ySVZsEFTL7>b zdGiJ%)n0(uCizFAwU7oIkB7NKYXg9^0oys|0>)%}#ONd~G9Xg+A8E}^M~O(3N||*5 zpU;Ntx&hmgIo2QnBL3Yg092a($Y%V+Y>sPfV2l}Vk+D)4?dFXY0Aq5#YGTSVAfGA^ zB#-LLmi8MSHkXm(lZTJQoU#C=jbS!y42Ij^1&Cm$HTy>e&KL6wz>&jUV$2K%vtV*_ z3IN*{d)&0^AL;aP90!1y=>!60C-Z&pH7^(}hY;01Ulu3NbK!Z~)y6%MQveJlSupW$ zdwcs}48!O1AruN~&v@6)yy1tw_iB1pGZzcP{NbPzC<+E0Ff(GY1dKLauED{a;s8&$ zJ)VcQ{%HS{($W&xwuREth>XQzH&sW9_Ju#!^pqD*#2hOQ4h9f2ef|=JuM`lUEG>;l zpU($l4Ep=~;d<_G2F!^u>l8ihUD)$Ky$(AcxH5hAqH6~-8TaaNI81>+0HII_mTlSb z*x(Z3#TEp89I`EYrp4YohkbY1()!q>NoR#BD=Q#`Kr|XfXJ=Pj8}BQ|p1sFDXDa%C zxp53mtT7t(pZRHF(6YaiUr=z>^yyQj-|vSp2GM8~$9sAai^W_o;~8Zu5ef#al9C9D zi;IWz2Pw3*wdsNA;4?a{KECl=%g2lZ#sq+iKKmRtef@G=y84AlAgn74htHclc@l!b zAV$Jt*LC4}9;8&TZ3|LLfPr`-jsph{A{rgorGYCq-na75@_${Ammat@cK~?zSoOIV z&o%LO6^qQ37hQ_a~cx$ZpC&zN} zm8)OG3-_<+omThJ&52}E4Gs)U8XSrR6Nxxd=`@mwB!-3t(bLn5&dx6G?mpU+Os5~x zhF7n@ch!NFYhJ|L%|9Ab0LJal)Act!Wc!LL&lAKe39^=%D}^9wjL}4*gV}61EH_EX zZ@l=m74CTLYg_=h@YCzC`9HEL)H$DcN`~1E1wwW{j26>ulo>9{Eg-b1N)1U<(^h4WTM<)?P18&I2aIBEOlqs4 zhL%fsY0@-(XwY8*N{d|5AFo6>aCs4Dm4|!Ec_vg0RkG zq9pNpN=iz;!x0N2V0LyEV`JmpVXhV`g7UPbrfBm8yjuM|ghjg?@3f2*6ug|Msu}`; z2>^i0l?YK3@n=u3f9!7|O%%uU?#B1m#Vf8?fWNC5*?W(ClD~Ub+2UdtJvVzhCMG8< z9?v}aYGPs{Ek53vnUIiRpBW#XyU}>Gd%e7ZkrKp2N530mkHI~kZ@R6vtk@do9B^)p zyW3VqU+wh>OrNU*F(F`A|$vKa0IfYvi_Ji`_i!hM{RM^WTtBb$;5pI!wL8h36IuviA+&JSlu`WNc^!e7=FHUO6kl%c4&3+oV6j-hIftsM zNKa40?c4o&FgWFste9%AsoeZs004z2nyZrBt_x151CdAs#0gt0Q3wVnwczATiMOG` zYuYkeIi6!br!yIiIoVm|oD=TdAN)ZiwYt6Gt$$Eu)Mq}t4kbPNp*W5hpNw={bJzu$j$aBv728R>|! z$~Eh~+^`3%HtQ>jq98aCyyb1E{K!8t`q$Xlc)z#t@Mpo`N+MO&>G$$1`r4U3FglMTJztMBN*f6y$9Gz;}Bcx zy+(MJ26F^(5CH@RVXY?_v8573nI=FDN2VELux+)y2ml?k9+ZD@bfrUfGA1AriHsOB zwvpg%dk)(j4#&Q@xL8|E=Kg|TufNo<+VY;u+5677xjVA+!{G=Xjf~Vi=(^Cg>67sF z55I#LXH{Ztu@83V?@H!eM<5UY0dTuq5CsuEH~U8C=U7H((}9R7yP)*cWiS%#q9R>O zNpa^p91Z}$?CcZx{iD6QrtKFv{nPU0`X`~`W#l<|6`gfO@SJFVjer6MA_Du}+i>W& hl8@VPrMA=%-+w6Lx0{>t(>(wH002ovPDHLkV1mbSD~JF9 literal 0 HcmV?d00001 diff --git a/src/libs/vmisc/share/resources/icon/32x32/link@2x.png b/src/libs/vmisc/share/resources/icon/32x32/link@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..46527dab9127e6cbd7fbabf202a33777e50fd8b5 GIT binary patch literal 3673 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 literal 0 HcmV?d00001