Resolved issue #761. New feature. Export final measurements.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2017-09-28 17:09:43 +03:00
commit fed167aea4
42 changed files with 3806 additions and 278 deletions

View File

@ -20,6 +20,7 @@
- [#755] New feature. Toggle point label.
- Fixed bug. After full parse undocommand Move labe losts connection to tool.
- [#756] New feature. Select pieces from command line.
- [#761] New feature. Export final measurements.
# Version 0.5.1
- [#683] Tool Seam allowance's dialog is off screen on small resolutions.

View File

@ -1,6 +1,6 @@
.\" Manpage for valentina.
.\" Contact dismine@gmail.com to correct errors.
.TH valentina 1 "10 March, 2017" "valentina man page"
.TH valentina 1 "28 September, 2017" "valentina man page"
.SH NAME
Valentina \- Pattern making program.
.SH SYNOPSIS
@ -106,6 +106,8 @@ The path to output destination folder. By default the directory at which the app
.RB "Export text as paths."
.IP "--exportOnlyDetails"
.RB "Export only details. Export details as they positioned in the details mode. Any layout related options will be ignored."
.IP "--exportSuchDetails <The name regex>"
.RB "Export only details that match a piece name regex."
.IP "-x, --gsize <The size value>"
.RB "Set size value a pattern file, that was opened with multisize measurements " "(export mode)" ". Valid values: 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56cm."
.IP "-e, --gheight <The height value>"
@ -193,14 +195,366 @@ The path to output destination folder. By default the directory at which the app
Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq.
.IP "--no-scaling"
.RB "Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). Alternatively you can use the QT_AUTO_SCREEN_SCALE_FACTOR=0 environment variable."
.IP "--csvWithHeader"
.RB "Export to csv with header. By default disabled."
.IP "--csvCodec <Codec name>"
.RB "Specify codec that will be used to save data. List of supported codecs provided by Qt. Default value depend from system. On Windows, the codec will be based on a system locale. On Unix systems, the codec will might fall back to using the iconv library if no builtin codec for the locale can be found. Valid values usually these:"
.RS
.BR "*" " US-ASCII,"
.RE
.RS
.BR "*" " US-ASCII,"
.RE
.RS
.BR "*" " ISO-8859-1,"
.RE
.RS
.BR "*" " ISO-8859-2,"
.RE
.RS
.BR "*" " ISO-8859-3,"
.RE
.RS
.BR "*" " ISO-8859-4,"
.RE
.RS
.BR "*" " ISO-8859-5,"
.RE
.RS
.BR "*" " ISO-8859-6,"
.RE
.RS
.BR "*" " ISO-8859-7,"
.RE
.RS
.BR "*" " ISO-8859-8,"
.RE
.RS
.BR "*" " ISO-8859-9,"
.RE
.RS
.BR "*" " ISO-8859-10,"
.RE
.RS
.BR "*" " ISO-2022-JP-1,"
.RE
.RS
.BR "*" " Shift_JIS,"
.RE
.RS
.BR "*" " EUC-JP,"
.RE
.RS
.BR "*" " US-ASCII,"
.RE
.RS
.BR "*" " windows-949,"
.RE
.RS
.BR "*" " ISO-2022-KR,"
.RE
.RS
.BR "*" " windows-949,"
.RE
.RS
.BR "*" " ISO-2022-JP,"
.RE
.RS
.BR "*" " ISO-2022-JP-2,"
.RE
.RS
.BR "*" " GBK,"
.RE
.RS
.BR "*" " ISO-8859-6,"
.RE
.RS
.BR "*" " ISO-8859-6,"
.RE
.RS
.BR "*" " ISO-8859-8,"
.RE
.RS
.BR "*" " ISO-8859-8,"
.RE
.RS
.BR "*" " ISO-2022-CN,"
.RE
.RS
.BR "*" " ISO-2022-CN-EXT,"
.RE
.RS
.BR "*" " UTF-8,"
.RE
.RS
.BR "*" " ISO-8859-13,"
.RE
.RS
.BR "*" " ISO-8859-14,"
.RE
.RS
.BR "*" " ISO-8859-15,"
.RE
.RS
.BR "*" " GBK,"
.RE
.RS
.BR "*" " GB18030,"
.RE
.RS
.BR "*" " UTF-16,"
.RE
.RS
.BR "*" " UTF-32,"
.RE
.RS
.BR "*" " SCSU,"
.RE
.RS
.BR "*" " UTF-7,"
.RE
.RS
.BR "*" " UTF-16BE,"
.RE
.RS
.BR "*" " UTF-16LE,"
.RE
.RS
.BR "*" " UTF-16,"
.RE
.RS
.BR "*" " CESU-8,"
.RE
.RS
.BR "*" " UTF-32,"
.RE
.RS
.BR "*" " UTF-32BE,"
.RE
.RS
.BR "*" " UTF-32LE,"
.RE
.RS
.BR "*" " BOCU-1,"
.RE
.RS
.BR "*" " hp-roman8,"
.RE
.RS
.BR "*" " Adobe-Standard-Encoding,"
.RE
.RS
.BR "*" " IBM850,"
.RE
.RS
.BR "*" " IBM862,"
.RE
.RS
.BR "*" " IBM-Thai,"
.RE
.RS
.BR "*" " Shift_JIS,"
.RE
.RS
.BR "*" " GBK,"
.RE
.RS
.BR "*" " Big5,"
.RE
.RS
.BR "*" " macintosh,"
.RE
.RS
.BR "*" " IBM037,"
.RE
.RS
.BR "*" " IBM273,"
.RE
.RS
.BR "*" " IBM277,"
.RE
.RS
.BR "*" " IBM278,"
.RE
.RS
.BR "*" " IBM280,"
.RE
.RS
.BR "*" " IBM284,"
.RE
.RS
.BR "*" " IBM285,"
.RE
.RS
.BR "*" " IBM290,"
.RE
.RS
.BR "*" " IBM297,"
.RE
.RS
.BR "*" " IBM420,"
.RE
.RS
.BR "*" " IBM424,"
.RE
.RS
.BR "*" " IBM437,"
.RE
.RS
.BR "*" " IBM500,"
.RE
.RS
.BR "*" " cp851,"
.RE
.RS
.BR "*" " IBM852,"
.RE
.RS
.BR "*" " IBM855,"
.RE
.RS
.BR "*" " IBM857,"
.RE
.RS
.BR "*" " IBM860,"
.RE
.RS
.BR "*" " IBM861,"
.RE
.RS
.BR "*" " IBM863,"
.RE
.RS
.BR "*" " IBM864,"
.RE
.RS
.BR "*" " IBM865,"
.RE
.RS
.BR "*" " IBM868,"
.RE
.RS
.BR "*" " IBM869,"
.RE
.RS
.BR "*" " IBM870,"
.RE
.RS
.BR "*" " IBM871,"
.RE
.RS
.BR "*" " IBM918,"
.RE
.RS
.BR "*" " IBM1026,"
.RE
.RS
.BR "*" " KOI8-R,"
.RE
.RS
.BR "*" " HZ-GB-2312,"
.RE
.RS
.BR "*" " IBM866,"
.RE
.RS
.BR "*" " IBM775,"
.RE
.RS
.BR "*" " KOI8-U,"
.RE
.RS
.BR "*" " IBM00858,"
.RE
.RS
.BR "*" " IBM01140,"
.RE
.RS
.BR "*" " IBM01141,"
.RE
.RS
.BR "*" " IBM01142,"
.RE
.RS
.BR "*" " IBM01143,"
.RE
.RS
.BR "*" " IBM01144,"
.RE
.RS
.BR "*" " IBM01145,"
.RE
.RS
.BR "*" " IBM01146,"
.RE
.RS
.BR "*" " IBM01147,"
.RE
.RS
.BR "*" " IBM01148,"
.RE
.RS
.BR "*" " IBM01149,"
.RE
.RS
.BR "*" " Big5-HKSCS,"
.RE
.RS
.BR "*" " IBM1047,"
.RE
.RS
.BR "*" " windows-1250,"
.RE
.RS
.BR "*" " windows-1251,"
.RE
.RS
.BR "*" " windows-1252,"
.RE
.RS
.BR "*" " windows-1253,"
.RE
.RS
.BR "*" " windows-1254,"
.RE
.RS
.BR "*" " windows-1255,"
.RE
.RS
.BR "*" " windows-1256,"
.RE
.RS
.BR "*" " windows-1257,"
.RE
.RS
.BR "*" " windows-1258,"
.RE
.RS
.BR "*" " TIS-620,"
.RE
.RS
.BR "*" " TSCII."
.RE
.IP "--csvSeparator <Separator character>"
.RB "Specify csv separator character. Default value is ','. Valid characters:"
.RS
.BR "*" " 'Tab',"
.RE
.RS
.BR "*" " ';',"
.RE
.RS
.BR "*" " 'Space',"
.RE
.RS
.BR "*" " ','."
.RE
.IP "--csvExportFM <Path to csv file>"
.RB "Calling this command enable exporting final measurements. Specify path to csv file with final measurements. The path must contain path to directory and name of file. It can be absolute or relatetive. In case of relative path will be used current working directory to calc a destination path."
.IP Arguments:
.I filename
\- a pattern file.
.SH AUTHOR
.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 tape (1)

View File

@ -1,6 +1,6 @@
.\" Manpage for valentina.
.\" Contact dismine@gmail.com to correct errors.
.TH valentina 1 "22 September, 2017" "valentina man page"
.TH valentina 1 "28 September, 2017" "valentina man page"
.SH NAME
Valentina \- Pattern making program.
.SH SYNOPSIS
@ -195,6 +195,362 @@ The path to output destination folder. By default the directory at which the app
Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq.
.IP "--no-scaling"
.RB "Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). Alternatively you can use the QT_AUTO_SCREEN_SCALE_FACTOR=0 environment variable."
.IP "--csvWithHeader"
.RB "Export to csv with header. By default disabled."
.IP "--csvCodec <Codec name>"
.RB "Specify codec that will be used to save data. List of supported codecs provided by Qt. Default value depend from system. On Windows, the codec will be based on a system locale. On Unix systems, the codec will might fall back to using the iconv library if no builtin codec for the locale can be found. Valid values usually these:"
.RS
.BR "*" " US-ASCII,"
.RE
.RS
.BR "*" " US-ASCII,"
.RE
.RS
.BR "*" " ISO-8859-1,"
.RE
.RS
.BR "*" " ISO-8859-2,"
.RE
.RS
.BR "*" " ISO-8859-3,"
.RE
.RS
.BR "*" " ISO-8859-4,"
.RE
.RS
.BR "*" " ISO-8859-5,"
.RE
.RS
.BR "*" " ISO-8859-6,"
.RE
.RS
.BR "*" " ISO-8859-7,"
.RE
.RS
.BR "*" " ISO-8859-8,"
.RE
.RS
.BR "*" " ISO-8859-9,"
.RE
.RS
.BR "*" " ISO-8859-10,"
.RE
.RS
.BR "*" " ISO-2022-JP-1,"
.RE
.RS
.BR "*" " Shift_JIS,"
.RE
.RS
.BR "*" " EUC-JP,"
.RE
.RS
.BR "*" " US-ASCII,"
.RE
.RS
.BR "*" " windows-949,"
.RE
.RS
.BR "*" " ISO-2022-KR,"
.RE
.RS
.BR "*" " windows-949,"
.RE
.RS
.BR "*" " ISO-2022-JP,"
.RE
.RS
.BR "*" " ISO-2022-JP-2,"
.RE
.RS
.BR "*" " GBK,"
.RE
.RS
.BR "*" " ISO-8859-6,"
.RE
.RS
.BR "*" " ISO-8859-6,"
.RE
.RS
.BR "*" " ISO-8859-8,"
.RE
.RS
.BR "*" " ISO-8859-8,"
.RE
.RS
.BR "*" " ISO-2022-CN,"
.RE
.RS
.BR "*" " ISO-2022-CN-EXT,"
.RE
.RS
.BR "*" " UTF-8,"
.RE
.RS
.BR "*" " ISO-8859-13,"
.RE
.RS
.BR "*" " ISO-8859-14,"
.RE
.RS
.BR "*" " ISO-8859-15,"
.RE
.RS
.BR "*" " GBK,"
.RE
.RS
.BR "*" " GB18030,"
.RE
.RS
.BR "*" " UTF-16,"
.RE
.RS
.BR "*" " UTF-32,"
.RE
.RS
.BR "*" " SCSU,"
.RE
.RS
.BR "*" " UTF-7,"
.RE
.RS
.BR "*" " UTF-16BE,"
.RE
.RS
.BR "*" " UTF-16LE,"
.RE
.RS
.BR "*" " UTF-16,"
.RE
.RS
.BR "*" " CESU-8,"
.RE
.RS
.BR "*" " UTF-32,"
.RE
.RS
.BR "*" " UTF-32BE,"
.RE
.RS
.BR "*" " UTF-32LE,"
.RE
.RS
.BR "*" " BOCU-1,"
.RE
.RS
.BR "*" " hp-roman8,"
.RE
.RS
.BR "*" " Adobe-Standard-Encoding,"
.RE
.RS
.BR "*" " IBM850,"
.RE
.RS
.BR "*" " IBM862,"
.RE
.RS
.BR "*" " IBM-Thai,"
.RE
.RS
.BR "*" " Shift_JIS,"
.RE
.RS
.BR "*" " GBK,"
.RE
.RS
.BR "*" " Big5,"
.RE
.RS
.BR "*" " macintosh,"
.RE
.RS
.BR "*" " IBM037,"
.RE
.RS
.BR "*" " IBM273,"
.RE
.RS
.BR "*" " IBM277,"
.RE
.RS
.BR "*" " IBM278,"
.RE
.RS
.BR "*" " IBM280,"
.RE
.RS
.BR "*" " IBM284,"
.RE
.RS
.BR "*" " IBM285,"
.RE
.RS
.BR "*" " IBM290,"
.RE
.RS
.BR "*" " IBM297,"
.RE
.RS
.BR "*" " IBM420,"
.RE
.RS
.BR "*" " IBM424,"
.RE
.RS
.BR "*" " IBM437,"
.RE
.RS
.BR "*" " IBM500,"
.RE
.RS
.BR "*" " cp851,"
.RE
.RS
.BR "*" " IBM852,"
.RE
.RS
.BR "*" " IBM855,"
.RE
.RS
.BR "*" " IBM857,"
.RE
.RS
.BR "*" " IBM860,"
.RE
.RS
.BR "*" " IBM861,"
.RE
.RS
.BR "*" " IBM863,"
.RE
.RS
.BR "*" " IBM864,"
.RE
.RS
.BR "*" " IBM865,"
.RE
.RS
.BR "*" " IBM868,"
.RE
.RS
.BR "*" " IBM869,"
.RE
.RS
.BR "*" " IBM870,"
.RE
.RS
.BR "*" " IBM871,"
.RE
.RS
.BR "*" " IBM918,"
.RE
.RS
.BR "*" " IBM1026,"
.RE
.RS
.BR "*" " KOI8-R,"
.RE
.RS
.BR "*" " HZ-GB-2312,"
.RE
.RS
.BR "*" " IBM866,"
.RE
.RS
.BR "*" " IBM775,"
.RE
.RS
.BR "*" " KOI8-U,"
.RE
.RS
.BR "*" " IBM00858,"
.RE
.RS
.BR "*" " IBM01140,"
.RE
.RS
.BR "*" " IBM01141,"
.RE
.RS
.BR "*" " IBM01142,"
.RE
.RS
.BR "*" " IBM01143,"
.RE
.RS
.BR "*" " IBM01144,"
.RE
.RS
.BR "*" " IBM01145,"
.RE
.RS
.BR "*" " IBM01146,"
.RE
.RS
.BR "*" " IBM01147,"
.RE
.RS
.BR "*" " IBM01148,"
.RE
.RS
.BR "*" " IBM01149,"
.RE
.RS
.BR "*" " Big5-HKSCS,"
.RE
.RS
.BR "*" " IBM1047,"
.RE
.RS
.BR "*" " windows-1250,"
.RE
.RS
.BR "*" " windows-1251,"
.RE
.RS
.BR "*" " windows-1252,"
.RE
.RS
.BR "*" " windows-1253,"
.RE
.RS
.BR "*" " windows-1254,"
.RE
.RS
.BR "*" " windows-1255,"
.RE
.RS
.BR "*" " windows-1256,"
.RE
.RS
.BR "*" " windows-1257,"
.RE
.RS
.BR "*" " windows-1258,"
.RE
.RS
.BR "*" " TIS-620,"
.RE
.RS
.BR "*" " TSCII."
.RE
.IP "--csvSeparator <Separator character>"
.RB "Specify csv separator character. Default value is ','. Valid characters:"
.RS
.BR "*" " 'Tab',"
.RE
.RS
.BR "*" " ';',"
.RE
.RS
.BR "*" " 'Space',"
.RE
.RS
.BR "*" " ','."
.RE
.IP "--csvExportFM <Path to csv file>"
.RB "Calling this command enable exporting final measurements. Specify path to csv file with final measurements. The path must contain path to directory and name of file. It can be absolute or relatetive. In case of relative path will be used current working directory to calc a destination path."
.IP Arguments:
.I filename
\- a pattern file.

View File

@ -32,7 +32,6 @@
#include "dialogs/dialognewmeasurements.h"
#include "dialogs/dialogmdatabase.h"
#include "dialogs/dialogtapepreferences.h"
#include "dialogs/dialogexporttocsv.h"
#include "../vpatterndb/calculator.h"
#include "../vpatterndb/pmsystems.h"
#include "../ifc/ifcdef.h"
@ -663,7 +662,7 @@ bool TMainWindow::eventFilter(QObject *object, QEvent *event)
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog)
void TMainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)
{
QxtCsvModel csv;
const int columns = ui->tableWidget->columnCount();
@ -678,7 +677,7 @@ void TMainWindow::ExportToCSVData(const QString &fileName, const DialogExportToC
}
}
if (dialog.WithHeader())
if (withHeader)
{
int colCount = 0;
for (int column = 0; column < columns; ++column)
@ -708,7 +707,8 @@ void TMainWindow::ExportToCSVData(const QString &fileName, const DialogExportToC
}
}
csv.toCSV(fileName, dialog.WithHeader(), dialog.Separator(), QTextCodec::codecForMib(dialog.SelectedMib()));
QString error;
csv.toCSV(fileName, error, withHeader, separator, QTextCodec::codecForMib(mib));
}
//---------------------------------------------------------------------------------------------------------------------
@ -1506,16 +1506,7 @@ void TMainWindow::ShowNewMData(bool fresh)
ui->plainTextEditFormula->blockSignals(true);
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
formula = meash->GetFormula();
}
QString formula = VTranslateVars::TryFormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator());
ui->plainTextEditFormula->setPlainText(formula);
ui->plainTextEditFormula->blockSignals(false);
@ -1895,7 +1886,7 @@ void TMainWindow::SetupMenu()
connect(ui->actionSaveAs, &QAction::triggered, this, &TMainWindow::FileSaveAs);
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportToCSV);
connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportDataToCSV);
connect(ui->actionReadOnly, &QAction::triggered, this, [this](bool ro)
{
if (not mIsReadOnly)
@ -2416,16 +2407,7 @@ void TMainWindow::RefreshTable(bool freshCall)
AddCell(locale().toString(value), currentRow, ColumnCalcValue, Qt::AlignHCenter | Qt::AlignVCenter,
meash->IsFormulaOk()); // calculated value
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
formula = meash->GetFormula();
}
QString formula = VTranslateVars::TryFormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator());
AddCell(formula, currentRow, ColumnFormula, Qt::AlignVCenter); // formula
}

View File

@ -70,7 +70,8 @@ protected:
virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE;
virtual void ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog) Q_DECL_FINAL;
virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib,
const QChar &separator) Q_DECL_FINAL;
private slots:
void FileNew();

View File

@ -33,8 +33,10 @@
#include "../vformat/vmeasurements.h"
#include "../vmisc/commandoptions.h"
#include "../vmisc/vsettings.h"
#include "../vmisc/dialogs/dialogexporttocsv.h"
#include "../vlayout/vlayoutgenerator.h"
#include <QDebug>
#include <QTextCodec>
VCommandLinePtr VCommandLine::instance = nullptr;
@ -278,6 +280,46 @@ void VCommandLine::InitOptions(VCommandLineOptions &options, QMap<QString, int>
"enabled). Alternatively you can use the "
"%1 environment variable.")
.arg("QT_AUTO_SCREEN_SCALE_FACTOR=0")));
//=================================================================================================================
optionsIndex.insert(LONG_OPTION_CSVWITHHEADER, index++);
options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVWITHHEADER,
translate("VCommandLine", "Export to csv with header. By default "
"disabled.")));
optionsIndex.insert(LONG_OPTION_CSVCODEC, index++);
options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVCODEC,
translate("VCommandLine", "Specify codec that will be used to save data. List"
" of supported codecs provided by Qt. Default "
"value depend from system. On Windows, the codec "
"will be based on a system locale. On Unix "
"systems, the codec will might fall back to using "
"the iconv library if no builtin codec for the "
"locale can be found. Valid values for this "
"installation:")
+ DialogExportToCSV::MakeHelpCodecsList(),
translate("VCommandLine", "Codec name"), QString("%1")
.arg(QString(QTextCodec::codecForLocale()->name()))));
optionsIndex.insert(LONG_OPTION_CSVSEPARATOR, index++);
options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVSEPARATOR,
translate("VCommandLine", "Specify csv separator character. Default value "
"is '%1'. Valid characters:")
.arg(VCommonSettings::GetDefCSVSeparator()) +
DialogExportToCSV::MakeHelpSeparatorList(),
translate("VCommandLine", "Separator character"), QString("%1")
.arg(VCommonSettings::GetDefCSVSeparator())));
optionsIndex.insert(LONG_OPTION_CSVEXPORTFM, index++);
options.append(new QCommandLineOption(QStringList() << LONG_OPTION_CSVEXPORTFM,
translate("VCommandLine", "Calling this command enable exporting final "
"measurements. Specify path to csv file with "
"final measurements. The path must contain path "
"to directory and name of file. It can be "
"absolute or relatetive. In case of "
"relative path will be used current working "
"directory to calc a destination path."),
translate("VCommandLine", "Path to csv file")));
}
//------------------------------------------------------------------------------------------------------
@ -499,7 +541,9 @@ VCommandLinePtr VCommandLine::Get(const QCoreApplication& app)
instance->parser.process(app);
//fixme: in case of additional options/modes which will need to disable GUI - add it here too
instance->isGuiEnabled = not (instance->IsExportEnabled() || instance->IsTestModeEnabled());
instance->isGuiEnabled = not (instance->IsExportEnabled()
|| instance->IsTestModeEnabled()
|| instance->IsExportFMEnabled());
return instance;
}
@ -547,6 +591,18 @@ bool VCommandLine::IsExportEnabled() const
return r;
}
//---------------------------------------------------------------------------------------------------------------------
bool VCommandLine::IsExportFMEnabled() const
{
const bool r = parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVEXPORTFM)));
if (r && parser.positionalArguments().size() != 1)
{
qCritical() << translate("VCommandLine", "Export options can be used with single input file only.") << "/n";
const_cast<VCommandLine*>(this)->parser.showHelp(V_EX_USAGE);
}
return r;
}
//------------------------------------------------------------------------------------------------------
DialogLayoutSettings::PaperSizeTemplate VCommandLine::OptPaperSize() const
{
@ -655,6 +711,12 @@ int VCommandLine::IsExportOnlyDetails() const
return parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_EXPORTONLYDETAILS)));
}
//---------------------------------------------------------------------------------------------------------------------
int VCommandLine::IsCSVWithHeader() const
{
return parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVWITHHEADER)));
}
//---------------------------------------------------------------------------------------------------------------------
QString VCommandLine::OptExportSuchDetails() const
{
@ -667,6 +729,32 @@ QString VCommandLine::OptExportSuchDetails() const
return path;
}
//---------------------------------------------------------------------------------------------------------------------
QString VCommandLine::OptCSVCodecName() const
{
return parser.value(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVCODEC)));
}
//---------------------------------------------------------------------------------------------------------------------
QChar VCommandLine::OptCSVSeparator() const
{
const QString value = parser.value(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVSEPARATOR)));
if (not value.isEmpty())
{
return value.at(0);
}
else
{
return QChar();
}
}
//---------------------------------------------------------------------------------------------------------------------
QString VCommandLine::OptExportFMTo() const
{
return parser.value(*optionsUsed.value(optionsIndex.value(LONG_OPTION_CSVEXPORTFM)));
}
//---------------------------------------------------------------------------------------------------------------------
QStringList VCommandLine::OptInputFileNames() const
{

View File

@ -62,6 +62,10 @@ public:
//export enabled
bool IsExportEnabled() const;
//@brief tests if user enabled export final measurements from cmd, throws exception if not exactly 1 input VAL
//file supplied in case export enabled
bool IsExportFMEnabled() const;
//@brief returns path to custom measure file or empty string
QString OptMeasurePath() const;
@ -78,10 +82,20 @@ public:
int IsBinaryDXF() const;
int IsTextAsPaths() const;
int IsExportOnlyDetails() const;
int IsCSVWithHeader() const;
//@brief returns the piece name regex or empty string if not set
QString OptExportSuchDetails() const;
//@brief returns user selected csv codec or empty string if not set
QString OptCSVCodecName() const;
//@brief returns user selected csv separator or empty string if not set
QChar OptCSVSeparator() const;
//@brief returns the destination path for export final measurements or empty string if not set
QString OptExportFMTo() const;
//generator creation is moved here ... because most options are for it only, so no need to create extra getters...
//@brief creates VLayoutGenerator
VLayoutGeneratorPtr DefaultGenerator() const;

View File

@ -0,0 +1,741 @@
/************************************************************************
**
** @file dialogfinalmeasurements.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 26 9, 2017
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2017 Valentina project
** <https://bitbucket.org/dismine/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 "dialogfinalmeasurements.h"
#include "ui_dialogfinalmeasurements.h"
#include "../vmisc/vsettings.h"
#include "../qmuparser/qmudef.h"
#include "../qmuparser/qmutokenparser.h"
#include "../vpatterndb/vtranslatevars.h"
#include "../vpatterndb/calculator.h"
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
#define DIALOG_MAX_FORMULA_HEIGHT 64
namespace
{
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
template <typename T>
void Move(QVector<T> &vector, int from, int to)
{
Q_ASSERT_X(from >= 0 && from < vector.size(), "QVector::move(int,int)", "'from' is out-of-range");
Q_ASSERT_X(to >= 0 && to < vector.size(), "QVector::move(int,int)", "'to' is out-of-range");
if (from == to) // don't detach when no-op
{
return;
}
T * const b = vector.begin();
if (from < to)
{
std::rotate(b + from, b + from + 1, b + to + 1);
}
else
{
std::rotate(b + to, b + from, b + from + 1);
}
}
#endif // QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
}
//---------------------------------------------------------------------------------------------------------------------
DialogFinalMeasurements::DialogFinalMeasurements(VPattern *doc, QWidget *parent)
: QDialog(parent),
ui(new Ui::DialogFinalMeasurements),
m_doc(doc),
m_data(doc->GetCompleteData()),
m_measurements(doc->GetFinalMeasurements()),
m_search(),
formulaBaseHeight(0),
m_isInitialized(false)
{
ui->setupUi(this);
ui->lineEditName->setClearButtonEnabled(true);
ui->lineEditFind->setClearButtonEnabled(true);
ui->lineEditFind->installEventFilter(this);
m_search = QSharedPointer<VTableSearch>(new VTableSearch(ui->tableWidget));
formulaBaseHeight = ui->plainTextEditFormula->height();
ui->plainTextEditFormula->installEventFilter(this);
qApp->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c());
qCDebug(vDialog, "Showing variables.");
ShowUnits();
const bool freshCall = true;
FillFinalMeasurements(freshCall);
connect(m_doc, &VPattern::FullUpdateFromFile, this, &DialogFinalMeasurements::FullUpdateFromFile);
ui->lineEditName->setValidator( new QRegularExpressionValidator(QRegularExpression(
QLatin1String("^$|")+NameRegExp()), this));
connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this,
&DialogFinalMeasurements::ShowFinalMeasurementDetails);
connect(ui->toolButtonAdd, &QToolButton::clicked, this, &DialogFinalMeasurements::Add);
connect(ui->toolButtonRemove, &QToolButton::clicked, this, &DialogFinalMeasurements::Remove);
connect(ui->toolButtonUp, &QToolButton::clicked, this, &DialogFinalMeasurements::MoveUp);
connect(ui->toolButtonDown, &QToolButton::clicked, this, &DialogFinalMeasurements::MoveDown);
connect(ui->pushButtonGrow, &QPushButton::clicked, this, &DialogFinalMeasurements::DeployFormula);
connect(ui->toolButtonExpr, &QToolButton::clicked, this, &DialogFinalMeasurements::Fx);
connect(ui->lineEditName, &QLineEdit::textEdited, this, &DialogFinalMeasurements::SaveName);
connect(ui->plainTextEditDescription, &QPlainTextEdit::textChanged, this,
&DialogFinalMeasurements::SaveDescription);
connect(ui->plainTextEditFormula, &QPlainTextEdit::textChanged, this, &DialogFinalMeasurements::SaveFormula);
connect(ui->lineEditFind, &QLineEdit::textEdited, this, [this](const QString &term){m_search->Find(term);});
connect(ui->toolButtonFindPrevious, &QToolButton::clicked, this, [this](){m_search->FindPrevious();});
connect(ui->toolButtonFindNext, &QToolButton::clicked, this, [this](){m_search->FindNext();});
connect(m_search.data(), &VTableSearch::HasResult, this, [this] (bool state)
{
ui->toolButtonFindPrevious->setEnabled(state);
});
connect(m_search.data(), &VTableSearch::HasResult, this, [this] (bool state)
{
ui->toolButtonFindNext->setEnabled(state);
});
if (ui->tableWidget->rowCount() > 0)
{
ui->tableWidget->selectRow(0);
}
}
//---------------------------------------------------------------------------------------------------------------------
DialogFinalMeasurements::~DialogFinalMeasurements()
{
delete ui;
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::closeEvent(QCloseEvent *event)
{
ui->plainTextEditFormula->blockSignals(true);
ui->lineEditName->blockSignals(true);
ui->plainTextEditDescription->blockSignals(true);
QDialog::closeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
// retranslate designer form (single inheritance approach)
ui->retranslateUi(this);
FullUpdateFromFile();
}
// remember to call base class implementation
QDialog::changeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
bool DialogFinalMeasurements::eventFilter(QObject *object, QEvent *event)
{
if (QLineEdit *textEdit = qobject_cast<QLineEdit *>(object))
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if ((keyEvent->key() == Qt::Key_Period) && (keyEvent->modifiers() & Qt::KeypadModifier))
{
if (qApp->Settings()->GetOsSeparator())
{
textEdit->insert(QLocale().decimalPoint());
}
else
{
textEdit->insert(QLocale::c().decimalPoint());
}
return true;
}
}
}
else
{
// pass the event on to the parent class
return QDialog::eventFilter(object, event);
}
return false;// pass the event to the widget
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::showEvent(QShowEvent *event)
{
QDialog::showEvent(event);
if ( event->spontaneous() )
{
return;
}
if (m_isInitialized)
{
return;
}
// do your init stuff here
const QSize sz = qApp->Settings()->GetFinalMeasurementsDialogSize();
if (not sz.isEmpty())
{
resize(sz);
}
m_isInitialized = true;//first show windows are held
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::resizeEvent(QResizeEvent *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)
{
qApp->Settings()->SetFinalMeasurementsDialogSize(size());
}
QDialog::resizeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::ShowFinalMeasurementDetails()
{
if (ui->tableWidget->rowCount() > 0 && m_measurements.size() == ui->tableWidget->rowCount())
{
EnableDetails(true);
const VFinalMeasurement &m = m_measurements.at(ui->tableWidget->currentRow());
ui->lineEditName->blockSignals(true);
ui->lineEditName->setText(m.name);
ui->lineEditName->blockSignals(false);
ui->plainTextEditDescription->blockSignals(true);
ui->plainTextEditDescription->setPlainText(m.description);
ui->plainTextEditDescription->blockSignals(false);
EvalUserFormula(m.formula, false);
ui->plainTextEditFormula->blockSignals(true);
const QString formula = VTranslateVars::TryFormulaToUser(m.formula, qApp->Settings()->GetOsSeparator());
ui->plainTextEditFormula->setPlainText(formula);
ui->plainTextEditFormula->blockSignals(false);
}
else
{
EnableDetails(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::Add()
{
const int currentRow = ui->tableWidget->currentRow()+1;
VFinalMeasurement m;
m.name = tr("measurement");
m.formula = "0";
m_measurements.append(m);
UpdateTree();
ui->tableWidget->selectRow(currentRow);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::Remove()
{
const int row = ui->tableWidget->currentRow();
if (row == -1 || row >= m_measurements.size())
{
return;
}
m_measurements.remove(row);
UpdateTree();
if (ui->tableWidget->rowCount() > 0)
{
ui->tableWidget->selectRow(0);
}
else
{
EnableDetails(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::MoveUp()
{
const int row = ui->tableWidget->currentRow();
if (row == -1 || row == 0 || row >= m_measurements.size())
{
return;
}
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
Move(m_measurements, row, row-1);
#else
m_measurements.move(row, row-1);
#endif
UpdateTree();
ui->tableWidget->selectRow(row-1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::MoveDown()
{
const int row = ui->tableWidget->currentRow();
if (row == -1 || row == ui->tableWidget->rowCount()-1 || row >= m_measurements.size())
{
return;
}
#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
Move(m_measurements, row, row+1);
#else
m_measurements.move(row, row+1);
#endif
UpdateTree();
ui->tableWidget->selectRow(row+1);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::SaveName(const QString &text)
{
const int row = ui->tableWidget->currentRow();
if (row == -1 || row >= m_measurements.size())
{
return;
}
m_measurements[row].name = text.isEmpty() ? tr("measurement") : text;
UpdateTree();
ui->tableWidget->blockSignals(true);
ui->tableWidget->selectRow(row);
ui->tableWidget->blockSignals(false);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::SaveDescription()
{
const int row = ui->tableWidget->currentRow();
if (row == -1 || row >= m_measurements.size())
{
return;
}
const QTextCursor cursor = ui->plainTextEditDescription->textCursor();
m_measurements[row].description = ui->plainTextEditDescription->toPlainText();
UpdateTree();
ui->tableWidget->blockSignals(true);
ui->tableWidget->selectRow(row);
ui->tableWidget->blockSignals(false);
ui->plainTextEditDescription->setTextCursor(cursor);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::SaveFormula()
{
const int row = ui->tableWidget->currentRow();
if (row == -1 || row >= m_measurements.size())
{
return;
}
// Replace line return character with spaces for calc if exist
QString text = ui->plainTextEditFormula->toPlainText();
text.replace("\n", " ");
QTableWidgetItem *formulaField = ui->tableWidget->item(row, 2);
if (formulaField->text() == text)
{
QTableWidgetItem *result = ui->tableWidget->item(row, 1);
//Show unit in dialog lable (cm, mm or inch)
const QString postfix = UnitsToStr(qApp->patternUnit());
ui->labelCalculatedValue->setText(result->text() + " " +postfix);
return;
}
if (text.isEmpty())
{
//Show unit in dialog lable (cm, mm or inch)
const QString postfix = UnitsToStr(qApp->patternUnit());
ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + "). " + tr("Empty field."));
return;
}
if (not EvalUserFormula(text, true))
{
return;
}
try
{
m_measurements[row].formula = qApp->TrVars()->FormulaFromUser(text, qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e) // Just in case something bad will happen
{
Q_UNUSED(e)
return;
}
const QTextCursor cursor = ui->plainTextEditFormula->textCursor();
UpdateTree();
ui->tableWidget->blockSignals(true);
ui->tableWidget->selectRow(row);
ui->tableWidget->blockSignals(false);
ui->plainTextEditFormula->setTextCursor(cursor);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::DeployFormula()
{
const QTextCursor cursor = ui->plainTextEditFormula->textCursor();
if (ui->plainTextEditFormula->height() < DIALOG_MAX_FORMULA_HEIGHT)
{
ui->plainTextEditFormula->setFixedHeight(DIALOG_MAX_FORMULA_HEIGHT);
//Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme("go-next",
QIcon(":/icons/win.icon.theme/16x16/actions/go-next.png")));
}
else
{
ui->plainTextEditFormula->setFixedHeight(formulaBaseHeight);
//Set icon from theme (internal for Windows system)
ui->pushButtonGrow->setIcon(QIcon::fromTheme("go-down",
QIcon(":/icons/win.icon.theme/16x16/actions/go-down.png")));
}
// I found that after change size of formula field, it was filed for angle formula, field for formula became black.
// This code prevent this.
setUpdatesEnabled(false);
repaint();
setUpdatesEnabled(true);
ui->plainTextEditFormula->setFocus();
ui->plainTextEditFormula->setTextCursor(cursor);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::Fx()
{
const int row = ui->tableWidget->currentRow();
if (row == -1 || row >= m_measurements.size())
{
return;
}
QScopedPointer<DialogEditWrongFormula> dialog(new DialogEditWrongFormula(&m_data, NULL_ID, this));
dialog->setWindowTitle(tr("Edit measurement"));
dialog->SetFormula(qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditFormula->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator()));
const QString postfix = UnitsToStr(qApp->patternUnit(), true);
dialog->setPostfix(postfix);//Show unit in dialog lable (cm, mm or inch)
if (dialog->exec() == QDialog::Accepted)
{
m_measurements[row].formula = dialog->GetFormula();
UpdateTree();
ui->tableWidget->selectRow(row);
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::FullUpdateFromFile()
{
m_data = m_doc->GetCompleteData();
m_measurements = m_doc->GetFinalMeasurements();
FillFinalMeasurements();
m_search->RefreshList(ui->lineEditFind->text());
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::FillFinalMeasurements(bool freshCall)
{
ui->tableWidget->blockSignals(true);
ui->tableWidget->clearContents();
ui->tableWidget->setRowCount(m_measurements.size());
for (int i=0; i < m_measurements.size(); ++i)
{
const VFinalMeasurement &m = m_measurements.at(i);
AddCell(m.name, i, 0, Qt::AlignVCenter); // name
bool ok = true;
const qreal result = EvalFormula(m.formula, ok);
AddCell(qApp->LocaleToString(result), i, 1, Qt::AlignHCenter | Qt::AlignVCenter, ok); // calculated value
const QString formula = VTranslateVars::TryFormulaFromUser(m.formula, qApp->Settings()->GetOsSeparator());
AddCell(formula, i, 2, Qt::AlignVCenter); // formula
}
if (freshCall)
{
ui->tableWidget->resizeColumnsToContents();
ui->tableWidget->resizeRowsToContents();
}
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
ui->tableWidget->blockSignals(false);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::ShowUnits()
{
const QString unit = UnitsToStr(qApp->patternUnit());
{
// calculated value
const QString header = ui->tableWidget->horizontalHeaderItem(1)->text();
const QString unitHeader = QString("%1 (%2)").arg(header).arg(unit);
ui->tableWidget->horizontalHeaderItem(1)->setText(unitHeader);
}
{
// formula
const QString header = ui->tableWidget->horizontalHeaderItem(2)->text();
const QString unitHeader = QString("%1 (%2)").arg(header).arg(unit);
ui->tableWidget->horizontalHeaderItem(2)->setText(unitHeader);
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::AddCell(const QString &text, int row, int column, int aligment, bool ok)
{
QTableWidgetItem *item = new QTableWidgetItem(text);
item->setTextAlignment(aligment);
// set the item non-editable (view only), and non-selectable
Qt::ItemFlags flags = item->flags();
flags &= ~(Qt::ItemIsEditable); // reset/clear the flag
item->setFlags(flags);
if (not ok)
{
QBrush brush = item->foreground();
brush.setColor(Qt::red);
item->setForeground(brush);
}
ui->tableWidget->setItem(row, column, item);
}
//---------------------------------------------------------------------------------------------------------------------
bool DialogFinalMeasurements::EvalUserFormula(const QString &formula, bool fromUser)
{
const QString postfix = UnitsToStr(qApp->patternUnit());//Show unit in dialog lable (cm, mm or inch)
if (formula.isEmpty())
{
ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + "). " + tr("Empty field."));
ui->labelCalculatedValue->setToolTip(tr("Empty field"));
return false;
}
else
{
try
{
QString f;
// Replace line return character with spaces for calc if exist
if (fromUser)
{
f = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
else
{
f = formula;
}
f.replace("\n", " ");
QScopedPointer<Calculator> cal(new Calculator());
const qreal result = cal->EvalFormula(m_data.DataVariables(), f);
if (qIsInf(result) || qIsNaN(result))
{
ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + ").");
ui->labelCalculatedValue->setToolTip(tr("Invalid result. Value is infinite or NaN. Please, check your "
"calculations."));
return false;
}
ui->labelCalculatedValue->setText(qApp->LocaleToString(result) + " " + postfix);
ui->labelCalculatedValue->setToolTip(tr("Value"));
return true;
}
catch (qmu::QmuParserError &e)
{
ui->labelCalculatedValue->setText(tr("Error") + " (" + postfix + "). " +
tr("Parser error: %1").arg(e.GetMsg()));
ui->labelCalculatedValue->setToolTip(tr("Parser error: %1").arg(e.GetMsg()));
return false;
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::Controls()
{
ui->toolButtonRemove->setEnabled(ui->tableWidget->rowCount() > 0);
if (ui->tableWidget->rowCount() >= 2)
{
if (ui->tableWidget->currentRow() == 0)
{
ui->toolButtonUp->setEnabled(false);
ui->toolButtonDown->setEnabled(true);
}
else if (ui->tableWidget->currentRow() == ui->tableWidget->rowCount()-1)
{
ui->toolButtonUp->setEnabled(true);
ui->toolButtonDown->setEnabled(false);
}
else
{
ui->toolButtonUp->setEnabled(true);
ui->toolButtonDown->setEnabled(true);
}
}
else
{
ui->toolButtonUp->setEnabled(false);
ui->toolButtonDown->setEnabled(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::EnableDetails(bool enabled)
{
if (enabled)
{
Controls();
}
else
{
ui->toolButtonRemove->setEnabled(enabled);
ui->toolButtonUp->setEnabled(enabled);
ui->toolButtonDown->setEnabled(enabled);
}
if (not enabled)
{ // Clear
ui->lineEditName->blockSignals(true);
ui->lineEditName->clear();
ui->lineEditName->blockSignals(false);
ui->plainTextEditDescription->blockSignals(true);
ui->plainTextEditDescription->clear();
ui->plainTextEditDescription->blockSignals(false);
ui->labelCalculatedValue->blockSignals(true);
ui->labelCalculatedValue->clear();
ui->labelCalculatedValue->blockSignals(false);
ui->plainTextEditFormula->blockSignals(true);
ui->plainTextEditFormula->clear();
ui->plainTextEditFormula->blockSignals(false);
}
ui->pushButtonGrow->setEnabled(enabled);
ui->toolButtonExpr->setEnabled(enabled);
ui->lineEditName->setEnabled(enabled);
ui->plainTextEditDescription->setEnabled(enabled);
ui->plainTextEditFormula->setEnabled(enabled);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogFinalMeasurements::UpdateTree()
{
int row = ui->tableWidget->currentRow();
FillFinalMeasurements();
ui->tableWidget->selectRow(row);
m_search->RefreshList(ui->lineEditFind->text());
}
//---------------------------------------------------------------------------------------------------------------------
qreal DialogFinalMeasurements::EvalFormula(const QString &formula, bool &ok)
{
qreal result = 0;
if (formula.isEmpty())
{
ok = false;
return result;
}
else
{
try
{
QString f = formula;
// Replace line return character with spaces for calc if exist
f.replace("\n", " ");
QScopedPointer<Calculator> cal(new Calculator());
result = cal->EvalFormula(m_data.DataVariables(), f);
if (qIsInf(result) || qIsNaN(result))
{
ok = false;
return 0;
}
}
catch (qmu::QmuParserError &)
{
ok = false;
return 0;
}
}
ok = true;
return result;
}

View File

@ -0,0 +1,102 @@
/************************************************************************
**
** @file dialogfinalmeasurements.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 26 9, 2017
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2017 Valentina project
** <https://bitbucket.org/dismine/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 DIALOGFINALMEASUREMENTS_H
#define DIALOGFINALMEASUREMENTS_H
#include <QDialog>
#include "../vmisc/vtablesearch.h"
#include "../vpatterndb/vcontainer.h"
#include "../xml/vpattern.h"
namespace Ui
{
class DialogFinalMeasurements;
}
class DialogFinalMeasurements : public QDialog
{
Q_OBJECT
public:
DialogFinalMeasurements(VPattern *doc, QWidget *parent = nullptr);
virtual ~DialogFinalMeasurements();
QVector<VFinalMeasurement> FinalMeasurements() const;
protected:
virtual void closeEvent ( QCloseEvent * event ) Q_DECL_OVERRIDE;
virtual void changeEvent ( QEvent * event) Q_DECL_OVERRIDE;
virtual bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE;
virtual void showEvent( QShowEvent *event ) Q_DECL_OVERRIDE;
virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
private slots:
void ShowFinalMeasurementDetails();
void Add();
void Remove();
void MoveUp();
void MoveDown();
void SaveName(const QString &text);
void SaveDescription();
void SaveFormula();
void DeployFormula();
void Fx();
void FullUpdateFromFile();
private:
Q_DISABLE_COPY(DialogFinalMeasurements)
Ui::DialogFinalMeasurements *ui;
/** @brief doc dom document container */
VPattern *m_doc;
VContainer m_data;
QVector<VFinalMeasurement> m_measurements;
QSharedPointer<VTableSearch> m_search;
int formulaBaseHeight;
bool m_isInitialized;
void FillFinalMeasurements(bool freshCall = false);
void ShowUnits();
void AddCell(const QString &text, int row, int column, int aligment, bool ok = true);
bool EvalUserFormula(const QString &formula, bool fromUser);
void Controls();
void EnableDetails(bool enabled);
void UpdateTree();
qreal EvalFormula(const QString &formula, bool &ok);
};
//---------------------------------------------------------------------------------------------------------------------
inline QVector<VFinalMeasurement> DialogFinalMeasurements::FinalMeasurements() const
{
return m_measurements;
}
#endif // DIALOGFINALMEASUREMENTS_H

View File

@ -0,0 +1,469 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogFinalMeasurements</class>
<widget class="QDialog" name="DialogFinalMeasurements">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>717</width>
<height>518</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelFind">
<property name="text">
<string>Find:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditFind">
<property name="placeholderText">
<string>Search</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButtonFindPrevious">
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="go-previous" resource="../../../libs/vmisc/share/resources/theme.qrc">
<normaloff>:/icons/win.icon.theme/16x16/actions/go-previous.png</normaloff>:/icons/win.icon.theme/16x16/actions/go-previous.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButtonFindNext">
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="go-next" resource="../../../libs/vmisc/share/resources/theme.qrc">
<normaloff>:/icons/win.icon.theme/16x16/actions/go-next.png</normaloff>:/icons/win.icon.theme/16x16/actions/go-next.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTableWidget" name="tableWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>8</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>150</height>
</size>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>120</number>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>70</number>
</attribute>
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>25</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>8</number>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>The calculated value</string>
</property>
</column>
<column>
<property name="text">
<string>Formula</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxDetails">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>4</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>236</height>
</size>
</property>
<property name="toolTip">
<string>Details</string>
</property>
<property name="title">
<string>Details</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>6</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5000</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item alignment="Qt::AlignRight">
<widget class="QToolButton" name="toolButtonAdd">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="list-add">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<widget class="QToolButton" name="toolButtonRemove">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="list-remove">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEditName">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelCalculated">
<property name="text">
<string>Calculated value:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="labelCalculatedValue">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="labelFormula">
<property name="text">
<string>Formula:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayoutValue">
<item>
<widget class="QPlainTextEdit" name="plainTextEditFormula">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>28</height>
</size>
</property>
<property name="toolTip">
<string>Calculation</string>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonGrow">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show full calculation in message box&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset theme="go-down">
<normaloff>../../../libs/vtools/dialogs/support</normaloff>../../../libs/vtools/dialogs/support</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButtonExpr">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Formula wizard</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset resource="../../../libs/vmisc/share/resources/icon.qrc">
<normaloff>:/icon/24x24/fx.png</normaloff>:/icon/24x24/fx.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QPlainTextEdit" name="plainTextEditDescription">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item alignment="Qt::AlignLeft">
<widget class="QToolButton" name="toolButtonUp">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Move measurement up</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="go-up">
<normaloff>../../tape</normaloff>../../tape</iconset>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<widget class="QToolButton" name="toolButtonDown">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Move measurement down</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="go-down">
<normaloff>../../tape</normaloff>../../tape</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5000</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../libs/vmisc/share/resources/icon.qrc"/>
<include location="../../../libs/vmisc/share/resources/theme.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DialogFinalMeasurements</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>227</x>
<y>523</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DialogFinalMeasurements</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>295</x>
<y>529</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -713,16 +713,7 @@ void DialogIncrements::FillIncrementsTable(QTableWidget *table,
AddCell(table, qApp->LocaleToString(*incr->GetValue()), currentRow, 1,
Qt::AlignHCenter | Qt::AlignVCenter, incr->IsFormulaOk()); // calculated value
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
formula = incr->GetFormula();
}
QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator());
AddCell(table, formula, currentRow, 2, Qt::AlignVCenter); // formula
}
@ -1394,16 +1385,7 @@ void DialogIncrements::ShowIncrementDetails()
EvalIncrementFormula(incr->GetFormula(), false, incr->GetData(), labelCalculatedValue);
plainTextEditFormula->blockSignals(true);
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
formula = incr->GetFormula();
}
QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator());
plainTextEditFormula->setPlainText(formula);
plainTextEditFormula->blockSignals(false);

View File

@ -825,11 +825,20 @@ QString DialogLayoutSettings::MakeHelpTemplateList()
QString out = "\n";
auto cntr = static_cast<VIndexType>(PaperSizeTemplate::A0);
foreach(const auto& v, pageFormatNames)
for (int i = 0; i < pageFormatNames.size(); ++i)
{
if (cntr <= static_cast<int>(PaperSizeTemplate::Roll44in))// Don't include custom template
{
out += "\t"+v+" = "+ QString::number(cntr++)+"\n";
out += "\t* "+pageFormatNames.at(i)+" = "+ QString::number(cntr++);
if (i < pageFormatNames.size() - 1)
{
out += ",\n";
}
else
{
out += ".\n";
}
}
}
return out;

View File

@ -35,5 +35,6 @@
#include "dialognewpattern.h"
#include "dialogaboutapp.h"
#include "dialogpreferences.h"
#include "dialogfinalmeasurements.h"
#endif // DIALOGS_H

View File

@ -19,7 +19,8 @@ HEADERS += \
$$PWD/configpages/preferencespathpage.h \
$$PWD/dialogdatetimeformats.h \
$$PWD/dialogknownmaterials.h \
$$PWD/dialogpatternmaterials.h
$$PWD/dialogpatternmaterials.h \
$$PWD/dialogfinalmeasurements.h
SOURCES += \
$$PWD/dialogincrements.cpp \
@ -38,7 +39,8 @@ SOURCES += \
$$PWD/configpages/preferencespathpage.cpp \
$$PWD/dialogdatetimeformats.cpp \
$$PWD/dialogknownmaterials.cpp \
$$PWD/dialogpatternmaterials.cpp
$$PWD/dialogpatternmaterials.cpp \
$$PWD/dialogfinalmeasurements.cpp
FORMS += \
$$PWD/dialogincrements.ui \
@ -57,4 +59,5 @@ FORMS += \
$$PWD/configpages/preferencespathpage.ui \
$$PWD/dialogdatetimeformats.ui \
$$PWD/dialogknownmaterials.ui \
$$PWD/dialogpatternmaterials.ui
$$PWD/dialogpatternmaterials.ui \
$$PWD/dialogfinalmeasurements.ui

View File

@ -250,10 +250,20 @@ bool DialogSaveLayout::IsBinaryDXFFormat() const
QString DialogSaveLayout::MakeHelpFormatList()
{
QString out("\n");
foreach(auto& v, InitFormats())
const auto formats = InitFormats();
for(int i = 0; i < formats.size(); ++i)
{
out += QLatin1String("\t") + v.first + QLatin1String(" = ") + QString::number(static_cast<int>(v.second))
+ QLatin1String("\n");
out += QLatin1String("\t* ") + formats.at(i).first + QLatin1String(" = ")
+ QString::number(static_cast<int>(formats.at(i).second));
if (i < formats.size() - 1)
{
out += QLatin1String(",\n");
}
else
{
out += QLatin1String(".\n");
}
}
return out;
}

View File

@ -40,7 +40,6 @@
#include "../vmisc/vsettings.h"
#include "../vmisc/def.h"
#include "../vmisc/qxtcsvmodel.h"
#include "../vmisc/dialogs/dialogexporttocsv.h"
#include "undocommands/renamepp.h"
#include "core/vtooloptionspropertybrowser.h"
#include "options.h"
@ -117,7 +116,9 @@ MainWindow::MainWindow(QWidget *parent)
patternReadOnly(false),
dialogTable(nullptr),
dialogTool(),
dialogHistory(nullptr), comboBoxDraws(nullptr), patternPieceLabel(nullptr), mode(Draw::Calculation),
dialogHistory(nullptr),
dialogFMeasurements(nullptr),
comboBoxDraws(nullptr), patternPieceLabel(nullptr), mode(Draw::Calculation),
currentDrawIndex(0), currentToolBoxIndex(0),
isDockToolOptionsVisible(true),
isDockGroupsVisible(true),
@ -1481,7 +1482,7 @@ void MainWindow::PrepareSceneList()
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog)
void MainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)
{
QxtCsvModel csv;
@ -1489,7 +1490,7 @@ void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCS
csv.insertColumn(1);
csv.insertColumn(2);
if (dialog.WithHeader())
if (withHeader)
{
csv.setHeaderText(0, tr("Name"));
csv.setHeaderText(1, tr("The calculated value"));
@ -1497,16 +1498,23 @@ void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCS
}
const QMap<QString, QSharedPointer<VIncrement> > increments = pattern->DataIncrements();
qint32 currentRow = -1;
auto SavePreviewCalculation = [&currentRow, &csv, increments](bool save)
{
QMap<QString, QSharedPointer<VIncrement> >::const_iterator i;
QMap<quint32, QString> map;
//Sorting QHash by id
for (i = increments.constBegin(); i != increments.constEnd(); ++i)
{
QSharedPointer<VIncrement> incr = i.value();
const QSharedPointer<VIncrement> incr = i.value();
if (incr->IsPreviewCalculation() == save)
{
map.insert(incr->getIndex(), i.key());
}
}
qint32 currentRow = -1;
QMapIterator<quint32, QString> iMap(map);
while (iMap.hasNext())
{
@ -1518,21 +1526,17 @@ void MainWindow::ExportToCSVData(const QString &fileName, const DialogExportToCS
csv.setText(currentRow, 0, incr->GetName()); // name
csv.setText(currentRow, 1, qApp->LocaleToString(*incr->GetValue())); // calculated value
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
formula = incr->GetFormula();
}
QString formula = VTranslateVars::TryFormulaToUser(incr->GetFormula(),
qApp->Settings()->GetOsSeparator());
csv.setText(currentRow, 2, formula); // formula
}
};
csv.toCSV(fileName, dialog.WithHeader(), dialog.Separator(), QTextCodec::codecForMib(dialog.SelectedMib()));
SavePreviewCalculation(false);
SavePreviewCalculation(true);
QString error;
csv.toCSV(fileName, error, withHeader, separator, QTextCodec::codecForMib(mib));
}
//---------------------------------------------------------------------------------------------------------------------
@ -2833,6 +2837,9 @@ void MainWindow::Clear()
ui->actionZoomOriginal->setEnabled(false);
ui->actionHistory->setEnabled(false);
ui->actionTable->setEnabled(false);
ui->actionExportIncrementsToCSV->setEnabled(false);
ui->actionExportFinalMeasurementsToCSV->setEnabled(false);
ui->actionFinalMeasurements->setEnabled(false);
ui->actionLast_tool->setEnabled(false);
ui->actionShowCurveDetails->setEnabled(false);
ui->actionLoadIndividual->setEnabled(false);
@ -3078,6 +3085,9 @@ void MainWindow::SetEnableWidgets(bool enable)
ui->actionDetails->setEnabled(enable);
ui->actionLayout->setEnabled(enable);
ui->actionTable->setEnabled(enable && drawStage);
ui->actionExportIncrementsToCSV->setEnabled(enable);
ui->actionExportFinalMeasurementsToCSV->setEnabled(enable);
ui->actionFinalMeasurements->setEnabled(enable);
ui->actionZoomFitBest->setEnabled(enable);
ui->actionZoomFitBestCurrent->setEnabled(enable && drawStage);
ui->actionZoomOriginal->setEnabled(enable);
@ -3970,7 +3980,8 @@ void MainWindow::CreateActions()
connect(ui->actionSave, &QAction::triggered, this, &MainWindow::Save);
connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::Open);
connect(ui->actionNew, &QAction::triggered, this, &MainWindow::New);
connect(ui->actionExportIncrementsToCSV, &QAction::triggered, this, &MainWindow::ExportToCSV);
connect(ui->actionExportIncrementsToCSV, &QAction::triggered, this, &MainWindow::ExportDataToCSV);
connect(ui->actionExportFinalMeasurementsToCSV, &QAction::triggered, this, &MainWindow::ExportFMeasurementsToCSV);
connect(ui->actionTable, &QAction::triggered, this, [this](bool checked)
{
@ -3993,6 +4004,27 @@ void MainWindow::CreateActions()
}
});
connect(ui->actionFinalMeasurements, &QAction::triggered, this, [this]()
{
if (dialogFMeasurements.isNull())
{
dialogFMeasurements = new DialogFinalMeasurements(doc, this);
connect(dialogFMeasurements.data(), &DialogFinalMeasurements::finished, this, [this](int result)
{
if (result == QDialog::Accepted)
{
doc->SetFinalMeasurements(dialogFMeasurements->FinalMeasurements());
}
delete dialogFMeasurements;
});
dialogFMeasurements->show();
}
else
{
dialogFMeasurements->activateWindow();
}
});
connect(ui->actionAbout_Qt, &QAction::triggered, this, [this]()
{
QMessageBox::aboutQt(this, tr("About Qt"));
@ -4177,11 +4209,11 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile)
{
qCDebug(vMainWindow, "Loading new file %s.", qUtf8Printable(fileName));
{ // Convert to absolute path is need
{ // Convert to absolute path if need
QFileInfo info(fileName);
if (info.isRelative())
if (info.exists() && info.isRelative())
{
fileName = QDir::currentPath() + QLatin1Char('/') + fileName;
fileName = QFileInfo(QDir::currentPath() + QLatin1Char('/') + fileName).canonicalFilePath();
}
}
@ -4810,7 +4842,7 @@ void MainWindow::ZoomFirstShow()
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::DoExport(const VCommandLinePtr &expParams)
bool MainWindow::DoExport(const VCommandLinePtr &expParams)
{
QHash<quint32, VPiece> details;
if(not qApp->getOpeningPattern())
@ -4820,7 +4852,7 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams)
{
qCCritical(vMainWindow, "%s", qUtf8Printable(tr("You can't export empty scene.")));
qApp->exit(V_EX_DATAERR);
return;
return false;
}
else
{
@ -4856,7 +4888,7 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams)
qCCritical(vMainWindow, "%s", qUtf8Printable(tr("You can't export empty scene. Please, "
"include at least one detail in layout.")));
qApp->exit(V_EX_DATAERR);
return;
return false;
}
}
}
@ -4879,7 +4911,7 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams)
{
qCCritical(vMainWindow, "%s\n\n%s", qUtf8Printable(tr("Export error.")), qUtf8Printable(e.ErrorMessage()));
qApp->exit(V_EX_DATAERR);
return;
return false;
}
}
else
@ -4903,16 +4935,61 @@ void MainWindow::DoExport(const VCommandLinePtr &expParams)
qCCritical(vMainWindow, "%s\n\n%s", qUtf8Printable(tr("Export error.")),
qUtf8Printable(e.ErrorMessage()));
qApp->exit(V_EX_DATAERR);
return;
return false;
}
}
else
{
return;
qApp->exit(V_EX_DATAERR);
return false;
}
}
qApp->exit(V_EX_OK);
return true;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief DoFMExport process export final measurements
* @param expParams command line options
* @return true if succesfull
*/
bool MainWindow::DoFMExport(const VCommandLinePtr &expParams)
{
QString filePath = expParams->OptExportFMTo();
if (filePath.isEmpty())
{
qCCritical(vMainWindow, "%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")),
qUtf8Printable(tr("Destination path is empty.")));
qApp->exit(V_EX_DATAERR);
return false;
}
QFileInfo info(filePath);
if (info.isRelative())
{
filePath = QDir::currentPath() + QLatin1Char('/') + filePath;
}
const QString codecName = expParams->OptCSVCodecName();
int mib = QTextCodec::codecForLocale()->mibEnum();
if (not codecName.isEmpty())
{
if (QTextCodec *codec = QTextCodec::codecForName(codecName.toLatin1()))
{
mib = codec->mibEnum();
}
}
QChar separator = expParams->OptCSVSeparator();
if (separator.isNull())
{
separator = VCommonSettings::GetDefCSVSeparator();
}
return ExportFMeasurementsToCSVData(filePath, expParams->IsCSVWithHeader(), mib, separator);
}
//---------------------------------------------------------------------------------------------------------------------
@ -5012,6 +5089,11 @@ void MainWindow::ProcessCMD()
if (VApplication::IsGUIMode())
{
ReopenFilesAfterCrash(args);
for (int i=0, sz = args.size(); i < sz; ++i)
{
LoadPattern(args.at(i));
}
}
else
{
@ -5021,21 +5103,16 @@ void MainWindow::ProcessCMD()
qApp->exit(V_EX_NOINPUT);
return;
}
}
for (int i=0, sz = args.size(); i < sz; ++i)
{
const bool loaded = LoadPattern(args.at(static_cast<int>(i)), cmd->OptMeasurePath());
const bool loaded = LoadPattern(args.first(), cmd->OptMeasurePath());
if (not loaded && not VApplication::IsGUIMode())
if (not loaded)
{
return; // process only one input file
}
bool hSetted = true;
bool sSetted = true;
if (loaded && (cmd->IsTestModeEnabled() || cmd->IsExportEnabled()))
{
if (cmd->IsSetGradationSize())
{
sSetted = SetSize(cmd->OptGradationSize());
@ -5045,29 +5122,26 @@ void MainWindow::ProcessCMD()
{
hSetted = SetHeight(cmd->OptGradationHeight());
}
}
if (not cmd->IsTestModeEnabled())
{
if (cmd->IsExportEnabled())
{
if (loaded && hSetted && sSetted)
{
DoExport(cmd);
return; // process only one input file
}
else
if (not (hSetted && sSetted))
{
qApp->exit(V_EX_DATAERR);
return;
}
break;
if (not cmd->IsTestModeEnabled())
{
if (cmd->IsExportEnabled() && not DoExport(cmd))
{
return;
}
if (cmd->IsExportFMEnabled() && not DoFMExport(cmd))
{
return;
}
}
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_OK);// close program after processing in console mode
}
}

View File

@ -47,6 +47,7 @@ class QLabel;
class DialogIncrements;
class DialogTool;
class DialogHistory;
class DialogFinalMeasurements;
class VWidgetGroups;
class VWidgetDetails;
class QToolButton;
@ -102,7 +103,8 @@ protected:
virtual void customEvent(QEvent * event) Q_DECL_OVERRIDE;
virtual void CleanLayout() Q_DECL_OVERRIDE;
virtual void PrepareSceneList() Q_DECL_OVERRIDE;
virtual void ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog) Q_DECL_FINAL;
virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib,
const QChar &separator) Q_DECL_FINAL;
private slots:
void MouseMove(const QPointF &scenePos);
void Clear();
@ -229,6 +231,7 @@ private:
QPointer<DialogIncrements> dialogTable;
QSharedPointer<DialogTool> dialogTool;
QPointer<DialogHistory> dialogHistory;
QPointer<DialogFinalMeasurements> dialogFMeasurements;
/** @brief comboBoxDraws comboc who show name of pattern peaces. */
QComboBox *comboBoxDraws;
@ -348,7 +351,8 @@ private:
void CheckRequiredMeasurements(const VMeasurements *m);
void ReopenFilesAfterCrash(QStringList &args);
void DoExport(const VCommandLinePtr& expParams);
bool DoExport(const VCommandLinePtr& expParams);
bool DoFMExport(const VCommandLinePtr& expParams);
bool SetSize(const QString &text);
bool SetHeight(const QString & text);

View File

@ -1699,12 +1699,17 @@
</property>
<addaction name="actionOpenTape"/>
<addaction name="actionEditCurrent"/>
<addaction name="separator"/>
<addaction name="actionUnloadMeasurements"/>
<addaction name="actionLoadIndividual"/>
<addaction name="actionLoadMultisize"/>
<addaction name="actionSyncMeasurements"/>
<addaction name="separator"/>
<addaction name="actionTable"/>
<addaction name="actionExportIncrementsToCSV"/>
<addaction name="separator"/>
<addaction name="actionFinalMeasurements"/>
<addaction name="actionExportFinalMeasurementsToCSV"/>
</widget>
<widget class="QMenu" name="menuWindow">
<property name="title">
@ -2649,6 +2654,9 @@
</property>
</action>
<action name="actionExportIncrementsToCSV">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Export increments to CSV</string>
</property>
@ -2657,6 +2665,9 @@
</property>
</action>
<action name="actionZoomFitBestCurrent">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Zoom fit best current</string>
</property>
@ -2675,6 +2686,22 @@
<string>Label template editor</string>
</property>
</action>
<action name="actionFinalMeasurements">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Final measurements</string>
</property>
</action>
<action name="actionExportFinalMeasurementsToCSV">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Export Final Measurements to CSV</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -33,6 +33,8 @@
#include "../vdxf/vdxfpaintdevice.h"
#include "dialogs/dialoglayoutsettings.h"
#include "../vwidgets/vmaingraphicsscene.h"
#include "../vmisc/dialogs/dialogexporttocsv.h"
#include "../vmisc/qxtcsvmodel.h"
#include "../vlayout/vlayoutgenerator.h"
#include "dialogs/dialoglayoutprogress.h"
#include "dialogs/dialogsavelayout.h"
@ -41,6 +43,7 @@
#include "../vpatterndb/floatItemData/vpatternlabeldata.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h"
#include "../vpatterndb/measurements.h"
#include "../vpatterndb/calculator.h"
#include "../vtools/tools/vabstracttool.h"
#include "../vtools/tools/vtoolseamallowance.h"
@ -224,6 +227,31 @@ void MainWindowsNoGUI::ErrorConsoleMode(const LayoutErrors &state)
qApp->exit(V_EX_DATAERR);
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindowsNoGUI::ExportFMeasurementsToCSV()
{
QString fileName = CSVFilePath();
if (fileName.isEmpty())
{
return;
}
DialogExportToCSV dialog(this);
dialog.SetWithHeader(qApp->Settings()->GetCSVWithHeader());
dialog.SetSelectedMib(qApp->Settings()->GetCSVCodec());
dialog.SetSeparator(qApp->Settings()->GetCSVSeparator());
if (dialog.exec() == QDialog::Accepted)
{
ExportFMeasurementsToCSVData(fileName, dialog.IsWithHeader(), dialog.GetSelectedMib(), dialog.GetSeparator());
qApp->Settings()->SetCSVSeparator(dialog.GetSeparator());
qApp->Settings()->SetCSVCodec(dialog.GetSelectedMib());
qApp->Settings()->SetCSVWithHeader(dialog.IsWithHeader());
}
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindowsNoGUI::ExportData(const QVector<VLayoutPiece> &listDetails, const DialogSaveLayout &dialog)
{
@ -1543,6 +1571,84 @@ void MainWindowsNoGUI::SetSizeHeightForIndividualM() const
emit doc->UpdatePatternLabel();
}
//---------------------------------------------------------------------------------------------------------------------
bool MainWindowsNoGUI::ExportFMeasurementsToCSVData(const QString &fileName, bool withHeader, int mib,
const QChar &separator) const
{
QxtCsvModel csv;
csv.insertColumn(0);
csv.insertColumn(1);
if (withHeader)
{
csv.setHeaderText(0, tr("Name"));
csv.setHeaderText(1, tr("Value"));
}
const QVector<VFinalMeasurement> measurements = doc->GetFinalMeasurements();
const VContainer completeData = doc->GetCompleteData();
for (int i=0; i < measurements.size(); ++i)
{
const VFinalMeasurement &m = measurements.at(i);
csv.insertRow(i);
csv.setText(i, 0, m.name); // name
if (not m.formula.isEmpty())
{
try
{
QString f = m.formula;
// Replace line return character with spaces for calc if exist
f.replace("\n", " ");
QScopedPointer<Calculator> cal(new Calculator());
const qreal result = cal->EvalFormula(completeData.DataVariables(), f);
csv.setText(i, 1, qApp->LocaleToString(result)); // value
if (qIsInf(result) || qIsNaN(result))
{
qCritical("%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")),
qUtf8Printable(tr("Value in line %1 is infinite or NaN. Please, check your calculations.")
.arg(i+1)));
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_DATAERR);
}
return false;
}
}
catch (qmu::QmuParserError &e)
{
qCritical("%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")),
qUtf8Printable(tr("Parser error at line %1: %2.").arg(i+1).arg(e.GetMsg())));
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_DATAERR);
}
return false;
}
}
}
QString error;
const bool success = csv.toCSV(fileName, error, withHeader, separator, QTextCodec::codecForMib(mib));
if (not success)
{
qCritical("%s\n\n%s", qUtf8Printable(tr("Export final measurements error.")),
qUtf8Printable(tr("File error %1.").arg(error)));
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_CANTCREAT);
}
}
return success;
}
//---------------------------------------------------------------------------------------------------------------------
int MainWindowsNoGUI::ContinueIfLayoutStale()
{

View File

@ -56,6 +56,8 @@ public slots:
void PrintOrigin();
void PrintTiled();
void RefreshDetailsLabel();
protected slots:
void ExportFMeasurementsToCSV();
protected:
QVector<VLayoutPiece> listDetails;
@ -100,6 +102,9 @@ protected:
int ContinueIfLayoutStale();
QString FileName() const;
void SetSizeHeightForIndividualM() const;
bool ExportFMeasurementsToCSVData(const QString &fileName,
bool withHeader, int mib, const QChar &separator) const;
private slots:
void PrintPages (QPrinter *printer);
void ErrorConsoleMode(const LayoutErrors &state);

View File

@ -152,7 +152,8 @@ void VPattern::Parse(const Document &parse)
QStringList tags = QStringList() << TagDraw << TagIncrements << TagDescription << TagNotes
<< TagMeasurements << TagVersion << TagGradation << TagImage << TagUnit
<< TagPatternName << TagPatternNum << TagCompanyName << TagCustomerName
<< TagPatternLabel << TagPatternMaterials << TagPreviewCalculations;
<< TagPatternLabel << TagPatternMaterials << TagPreviewCalculations
<< TagFinalMeasurements;
PrepareForParse(parse);
QDomNode domNode = documentElement().firstChild();
while (domNode.isNull() == false)
@ -231,6 +232,9 @@ void VPattern::Parse(const Document &parse)
qCDebug(vXML, "Tag prewiew calculations.");
ParseIncrementsElement(domElement);
break;
case 16: // TagFinalMeasurements
qCDebug(vXML, "Tag final measurements.");
break;
default:
qCDebug(vXML, "Wrong tag name %s", qUtf8Printable(domElement.tagName()));
break;
@ -3128,9 +3132,9 @@ qreal VPattern::EvalFormula(VContainer *data, const QString &formula, bool *ok)
QDomElement VPattern::MakeEmptyIncrement(const QString &name)
{
QDomElement element = createElement(TagIncrement);
SetAttribute(element, IncrementName, name);
SetAttribute(element, IncrementFormula, QString("0"));
SetAttribute(element, IncrementDescription, QString(""));
SetAttribute(element, AttrName, name);
SetAttribute(element, AttrFormula, QString("0"));
SetAttribute(element, AttrDescription, QString(""));
return element;
}
@ -3144,7 +3148,7 @@ QDomElement VPattern::FindIncrement(const QString &name) const
const QDomElement domElement = list.at(i).toElement();
if (domElement.isNull() == false)
{
const QString parameter = domElement.attribute(IncrementName);
const QString parameter = domElement.attribute(AttrName);
if (parameter == name)
{
return domElement;
@ -3573,19 +3577,19 @@ void VPattern::ParseIncrementsElement(const QDomNode &node)
{
if (domElement.tagName() == TagIncrement)
{
const QString name = GetParametrString(domElement, IncrementName, "");
const QString name = GetParametrString(domElement, AttrName, "");
QString desc;
try
{
desc = GetParametrString(domElement, IncrementDescription);
desc = GetParametrString(domElement, AttrDescription);
}
catch (VExceptionEmptyParameter &e)
{
Q_UNUSED(e)
}
const QString formula = GetParametrString(domElement, IncrementFormula, "0");
const QString formula = GetParametrString(domElement, AttrFormula, "0");
bool ok = false;
const qreal value = EvalFormula(data, formula, &ok);
@ -3664,19 +3668,19 @@ void VPattern::MoveDownPreviewCalculation(const QString &name)
//---------------------------------------------------------------------------------------------------------------------
void VPattern::SetIncrementName(const QString &name, const QString &text)
{
SetIncrementAttribute(name, IncrementName, text);
SetIncrementAttribute(name, AttrName, text);
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::SetIncrementFormula(const QString &name, const QString &text)
{
SetIncrementAttribute(name, IncrementFormula, text);
SetIncrementAttribute(name, AttrFormula, text);
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::SetIncrementDescription(const QString &name, const QString &text)
{
SetIncrementAttribute(name, IncrementDescription, text);
SetIncrementAttribute(name, AttrDescription, text);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -38,6 +38,7 @@
<file>schema/pattern/v0.6.1.xsd</file>
<file>schema/pattern/v0.6.2.xsd</file>
<file>schema/pattern/v0.6.3.xsd</file>
<file>schema/pattern/v0.6.4.xsd</file>
<file>schema/standard_measurements/v0.3.0.xsd</file>
<file>schema/standard_measurements/v0.4.0.xsd</file>
<file>schema/standard_measurements/v0.4.1.xsd</file>

View File

@ -0,0 +1,985 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document-->
<xs:element name="pattern">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="version" type="formatVersion"/>
<xs:element name="unit" type="units"/>
<xs:element name="image" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="extension" type="imageExtension"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="gradation" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="heights">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"/>
<xs:attribute name="h50" type="xs:boolean"/>
<xs:attribute name="h56" type="xs:boolean"/>
<xs:attribute name="h62" type="xs:boolean"/>
<xs:attribute name="h68" type="xs:boolean"/>
<xs:attribute name="h74" type="xs:boolean"/>
<xs:attribute name="h80" type="xs:boolean"/>
<xs:attribute name="h86" type="xs:boolean"/>
<xs:attribute name="h92" type="xs:boolean"/>
<xs:attribute name="h98" type="xs:boolean"/>
<xs:attribute name="h104" type="xs:boolean"/>
<xs:attribute name="h110" type="xs:boolean"/>
<xs:attribute name="h116" type="xs:boolean"/>
<xs:attribute name="h122" type="xs:boolean"/>
<xs:attribute name="h128" type="xs:boolean"/>
<xs:attribute name="h134" type="xs:boolean"/>
<xs:attribute name="h140" type="xs:boolean"/>
<xs:attribute name="h146" type="xs:boolean"/>
<xs:attribute name="h152" type="xs:boolean"/>
<xs:attribute name="h158" type="xs:boolean"/>
<xs:attribute name="h164" type="xs:boolean"/>
<xs:attribute name="h170" type="xs:boolean"/>
<xs:attribute name="h176" type="xs:boolean"/>
<xs:attribute name="h182" type="xs:boolean"/>
<xs:attribute name="h188" type="xs:boolean"/>
<xs:attribute name="h194" type="xs:boolean"/>
<xs:attribute name="h200" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="sizes">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"/>
<xs:attribute name="s22" type="xs:boolean"/>
<xs:attribute name="s24" type="xs:boolean"/>
<xs:attribute name="s26" type="xs:boolean"/>
<xs:attribute name="s28" type="xs:boolean"/>
<xs:attribute name="s30" type="xs:boolean"/>
<xs:attribute name="s32" type="xs:boolean"/>
<xs:attribute name="s34" type="xs:boolean"/>
<xs:attribute name="s36" type="xs:boolean"/>
<xs:attribute name="s38" type="xs:boolean"/>
<xs:attribute name="s40" type="xs:boolean"/>
<xs:attribute name="s42" type="xs:boolean"/>
<xs:attribute name="s44" type="xs:boolean"/>
<xs:attribute name="s46" type="xs:boolean"/>
<xs:attribute name="s48" type="xs:boolean"/>
<xs:attribute name="s50" type="xs:boolean"/>
<xs:attribute name="s52" type="xs:boolean"/>
<xs:attribute name="s54" type="xs:boolean"/>
<xs:attribute name="s56" type="xs:boolean"/>
<xs:attribute name="s58" type="xs:boolean"/>
<xs:attribute name="s60" type="xs:boolean"/>
<xs:attribute name="s62" type="xs:boolean"/>
<xs:attribute name="s64" type="xs:boolean"/>
<xs:attribute name="s66" type="xs:boolean"/>
<xs:attribute name="s68" type="xs:boolean"/>
<xs:attribute name="s70" type="xs:boolean"/>
<xs:attribute name="s72" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="custom" type="xs:boolean"/>
<xs:attribute name="defHeight" type="baseHeight"/>
<xs:attribute name="defSize" type="baseSize"/>
</xs:complexType>
</xs:element>
<xs:element name="patternName" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="patternNumber" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="company" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="customer" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="patternLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="text" type="xs:string" use="required"/>
<xs:attribute name="bold" type="xs:boolean"/>
<xs:attribute name="italic" type="xs:boolean"/>
<xs:attribute name="alignment" type="alignmentType"/>
<xs:attribute name="sfIncrement" type="xs:unsignedInt"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="dateFormat" type="xs:string"/>
<xs:attribute name="timeFormat" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="patternMaterials" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="material" minOccurs="0" maxOccurs="9">
<xs:complexType>
<xs:attribute name="number" type="userMaterialType" use="required"/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="finalMeasurements" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="finalMeasurment" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="description" type="xs:string"/>
<xs:attribute name="name" type="shortName" use="required"/>
<xs:attribute name="formula" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="measurements" type="xs:string"/>
<xs:element name="increments">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="increment" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="description" type="xs:string" use="required"/>
<xs:attribute name="name" type="shortName" use="required"/>
<xs:attribute name="formula" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="previewCalculations">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="increment" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="description" type="xs:string" use="required"/>
<xs:attribute name="name" type="shortName" use="required"/>
<xs:attribute name="formula" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="draw" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="calculation" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="x" type="xs:double"/>
<xs:attribute name="y" type="xs:double"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="name" type="shortName"/>
<xs:attribute name="firstPoint" type="xs:unsignedInt"/>
<xs:attribute name="secondPoint" type="xs:unsignedInt"/>
<xs:attribute name="thirdPoint" type="xs:unsignedInt"/>
<xs:attribute name="basePoint" type="xs:unsignedInt"/>
<xs:attribute name="pShoulder" type="xs:unsignedInt"/>
<xs:attribute name="p1Line" type="xs:unsignedInt"/>
<xs:attribute name="p2Line" type="xs:unsignedInt"/>
<xs:attribute name="length" type="xs:string"/>
<xs:attribute name="angle" type="xs:string"/>
<xs:attribute name="typeLine" type="linePenStyle"/>
<xs:attribute name="splinePath" type="xs:unsignedInt"/>
<xs:attribute name="spline" type="xs:unsignedInt"/>
<xs:attribute name="p1Line1" type="xs:unsignedInt"/>
<xs:attribute name="p1Line2" type="xs:unsignedInt"/>
<xs:attribute name="p2Line1" type="xs:unsignedInt"/>
<xs:attribute name="p2Line2" type="xs:unsignedInt"/>
<xs:attribute name="center" type="xs:unsignedInt"/>
<xs:attribute name="radius" type="xs:string"/>
<xs:attribute name="axisP1" type="xs:unsignedInt"/>
<xs:attribute name="axisP2" type="xs:unsignedInt"/>
<xs:attribute name="arc" type="xs:unsignedInt"/>
<xs:attribute name="elArc" type="xs:unsignedInt"/>
<xs:attribute name="curve" type="xs:unsignedInt"/>
<xs:attribute name="curve1" type="xs:unsignedInt"/>
<xs:attribute name="curve2" type="xs:unsignedInt"/>
<xs:attribute name="lineColor" type="colors"/>
<xs:attribute name="color" type="colors"/>
<xs:attribute name="firstArc" type="xs:unsignedInt"/>
<xs:attribute name="secondArc" type="xs:unsignedInt"/>
<xs:attribute name="crossPoint" type="crossType"/>
<xs:attribute name="vCrossPoint" type="crossType"/>
<xs:attribute name="hCrossPoint" type="crossType"/>
<xs:attribute name="c1Center" type="xs:unsignedInt"/>
<xs:attribute name="c2Center" type="xs:unsignedInt"/>
<xs:attribute name="c1Radius" type="xs:string"/>
<xs:attribute name="c2Radius" type="xs:string"/>
<xs:attribute name="cRadius" type="xs:string"/>
<xs:attribute name="tangent" type="xs:unsignedInt"/>
<xs:attribute name="cCenter" type="xs:unsignedInt"/>
<xs:attribute name="name1" type="shortName"/>
<xs:attribute name="mx1" type="xs:double"/>
<xs:attribute name="my1" type="xs:double"/>
<xs:attribute name="name2" type="shortName"/>
<xs:attribute name="mx2" type="xs:double"/>
<xs:attribute name="my2" type="xs:double"/>
<xs:attribute name="point1" type="xs:unsignedInt"/>
<xs:attribute name="point2" type="xs:unsignedInt"/>
<xs:attribute name="dartP1" type="xs:unsignedInt"/>
<xs:attribute name="dartP2" type="xs:unsignedInt"/>
<xs:attribute name="dartP3" type="xs:unsignedInt"/>
<xs:attribute name="baseLineP1" type="xs:unsignedInt"/>
<xs:attribute name="baseLineP2" type="xs:unsignedInt"/>
<xs:attribute name="showLabel" type="xs:boolean"/>
<xs:attribute name="showLabel1" type="xs:boolean"/>
<xs:attribute name="showLabel2" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="firstPoint" type="xs:unsignedInt"/>
<xs:attribute name="secondPoint" type="xs:unsignedInt"/>
<xs:attribute name="typeLine" type="linePenStyle"/>
<xs:attribute name="lineColor" type="colors"/>
</xs:complexType>
</xs:element>
<xs:element name="operation" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="source" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="idObject" type="xs:unsignedInt" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="destination" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="idObject" type="xs:unsignedInt" use="required"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="showLabel" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="center" type="xs:unsignedInt"/>
<xs:attribute name="angle" type="xs:string"/>
<xs:attribute name="length" type="xs:string"/>
<xs:attribute name="suffix" type="xs:string"/>
<xs:attribute name="type" type="xs:string" use="required"/>
<xs:attribute name="p1Line" type="xs:unsignedInt"/>
<xs:attribute name="p2Line" type="xs:unsignedInt"/>
<xs:attribute name="axisType" type="axisType"/>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="angle1" type="xs:string"/>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="angle2" type="xs:string"/>
<xs:attribute name="radius" type="xs:string"/>
<xs:attribute name="center" type="xs:unsignedInt"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="color" type="colors"/>
<xs:attribute name="penStyle" type="curvePenStyle"/>
<xs:attribute name="length" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="elArc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="angle1" type="xs:string"/>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="angle2" type="xs:string"/>
<xs:attribute name="rotationAngle" type="xs:string"/>
<xs:attribute name="radius1" type="xs:string"/>
<xs:attribute name="radius2" type="xs:string"/>
<xs:attribute name="center" type="xs:unsignedInt"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="color" type="colors"/>
<xs:attribute name="penStyle" type="curvePenStyle"/>
<xs:attribute name="length" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="pathPoint" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="kAsm2" type="xs:string"/>
<xs:attribute name="pSpline" type="xs:unsignedInt"/>
<xs:attribute name="angle" type="xs:string"/>
<xs:attribute name="angle1" type="xs:string"/>
<xs:attribute name="angle2" type="xs:string"/>
<xs:attribute name="length1" type="xs:string"/>
<xs:attribute name="length2" type="xs:string"/>
<xs:attribute name="kAsm1" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="kCurve" type="xs:double"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="kAsm1" type="xs:double"/>
<xs:attribute name="kAsm2" type="xs:double"/>
<xs:attribute name="angle1" type="xs:string"/>
<xs:attribute name="angle2" type="xs:string"/>
<xs:attribute name="length1" type="xs:string"/>
<xs:attribute name="length2" type="xs:string"/>
<xs:attribute name="point1" type="xs:unsignedInt"/>
<xs:attribute name="point2" type="xs:unsignedInt"/>
<xs:attribute name="point3" type="xs:unsignedInt"/>
<xs:attribute name="point4" type="xs:unsignedInt"/>
<xs:attribute name="color" type="colors"/>
<xs:attribute name="penStyle" type="curvePenStyle"/>
<xs:attribute name="duplicate" type="xs:unsignedInt"/>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="modeling" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="idObject" type="xs:unsignedInt"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="idTool" type="xs:unsignedInt"/>
<xs:attribute name="inUse" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="idObject" type="xs:unsignedInt"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="idTool" type="xs:unsignedInt"/>
<xs:attribute name="inUse" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="elArc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="idObject" type="xs:unsignedInt"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="idTool" type="xs:unsignedInt"/>
<xs:attribute name="inUse" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="idObject" type="xs:unsignedInt"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="idTool" type="xs:unsignedInt"/>
<xs:attribute name="inUse" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="path" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="nodes" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="node" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="type" type="xs:string" use="required"/>
<xs:attribute name="idObject" type="xs:unsignedInt" use="required"/>
<xs:attribute name="reverse" type="xs:unsignedInt"/>
<xs:attribute name="excluded" type="xs:boolean"/>
<xs:attribute name="before" type="xs:double"/>
<xs:attribute name="after" type="xs:double"/>
<xs:attribute name="angle" type="nodeAngle"/>
<xs:attribute name="passmark" type="xs:boolean"/>
<xs:attribute name="passmarkLine" type="passmarkLineType"/>
<xs:attribute name="passmarkAngle" type="passmarkAngleType"/>
<xs:attribute name="showSecondPassmark" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="type" type="piecePathType"/>
<xs:attribute name="idTool" type="xs:unsignedInt"/>
<xs:attribute name="inUse" type="xs:boolean"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="typeLine" type="curvePenStyle"/>
<xs:attribute name="cut" type="xs:boolean"/>
</xs:complexType>
</xs:element>
<xs:element name="tools" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="det" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="nodes" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="node" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="type" type="xs:string" use="required"/>
<xs:attribute name="idObject" type="xs:unsignedInt" use="required"/>
<xs:attribute name="reverse" type="xs:unsignedInt"/>
<xs:attribute name="excluded" type="xs:boolean"/>
<xs:attribute name="before" type="xs:string"/>
<xs:attribute name="after" type="xs:string"/>
<xs:attribute name="angle" type="nodeAngle"/>
<xs:attribute name="passmark" type="xs:boolean"/>
<xs:attribute name="passmarkLine" type="passmarkLineType"/>
<xs:attribute name="passmarkAngle" type="passmarkAngleType"/>
<xs:attribute name="showSecondPassmark" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="csa" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="record" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="start" type="xs:unsignedInt"/>
<xs:attribute name="path" type="xs:unsignedInt" use="required"/>
<xs:attribute name="end" type="xs:unsignedInt"/>
<xs:attribute name="reverse" type="xs:boolean"/>
<xs:attribute name="includeAs" type="piecePathIncludeType"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="iPaths" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="record" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="path" type="xs:unsignedInt" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="pins" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="record" type="xs:unsignedInt" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="children" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="nodes" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="child" type="xs:unsignedInt" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="csa" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="child" type="xs:unsignedInt" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="iPaths" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="child" type="xs:unsignedInt" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="pins" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="child" type="xs:unsignedInt" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="indexD1" type="xs:unsignedInt"/>
<xs:attribute name="indexD2" type="xs:unsignedInt"/>
<xs:attribute name="inUse" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="details" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="detail" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="data" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="text" type="xs:string" use="required"/>
<xs:attribute name="bold" type="xs:boolean"/>
<xs:attribute name="italic" type="xs:boolean"/>
<xs:attribute name="alignment" type="alignmentType"/>
<xs:attribute name="sfIncrement" type="xs:unsignedInt"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="letter" type="xs:string"/>
<xs:attribute name="annotation" type="xs:string"/>
<xs:attribute name="orientation" type="xs:string"/>
<xs:attribute name="rotationWay" type="xs:string"/>
<xs:attribute name="tilt" type="xs:string"/>
<xs:attribute name="foldPosition" type="xs:string"/>
<xs:attribute name="visible" type="xs:boolean"/>
<xs:attribute name="onFold" type="xs:boolean"/>
<xs:attribute name="fontSize" type="xs:unsignedInt"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="width" type="xs:string"/>
<xs:attribute name="height" type="xs:string"/>
<xs:attribute name="rotation" type="xs:string"/>
<xs:attribute name="centerPin" type="xs:unsignedInt"/>
<xs:attribute name="topLeftPin" type="xs:unsignedInt"/>
<xs:attribute name="quantity" type="xs:unsignedInt"/>
<xs:attribute name="bottomRightPin" type="xs:unsignedInt"/>
</xs:complexType>
</xs:element>
<xs:element name="patternInfo" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="visible" type="xs:boolean"/>
<xs:attribute name="fontSize" type="xs:unsignedInt"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="width" type="xs:string"/>
<xs:attribute name="height" type="xs:string"/>
<xs:attribute name="rotation" type="xs:string"/>
<xs:attribute name="centerPin" type="xs:unsignedInt"/>
<xs:attribute name="topLeftPin" type="xs:unsignedInt"/>
<xs:attribute name="bottomRightPin" type="xs:unsignedInt"/>
</xs:complexType>
</xs:element>
<xs:element name="grainline" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="visible" type="xs:boolean"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="length" type="xs:string"/>
<xs:attribute name="rotation" type="xs:string"/>
<xs:attribute name="arrows" type="arrowType"/>
<xs:attribute name="centerPin" type="xs:unsignedInt"/>
<xs:attribute name="topPin" type="xs:unsignedInt"/>
<xs:attribute name="bottomPin" type="xs:unsignedInt"/>
</xs:complexType>
</xs:element>
<xs:element name="nodes" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="node" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="type" type="xs:string" use="required"/>
<xs:attribute name="idObject" type="xs:unsignedInt" use="required"/>
<xs:attribute name="reverse" type="xs:unsignedInt"/>
<xs:attribute name="excluded" type="xs:boolean"/>
<xs:attribute name="before" type="xs:string"/>
<xs:attribute name="after" type="xs:string"/>
<xs:attribute name="angle" type="nodeAngle"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="passmark" type="xs:boolean"/>
<xs:attribute name="passmarkLine" type="passmarkLineType"/>
<xs:attribute name="passmarkAngle" type="passmarkAngleType"/>
<xs:attribute name="showSecondPassmark" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="csa" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="record" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="start" type="xs:unsignedInt"/>
<xs:attribute name="path" type="xs:unsignedInt" use="required"/>
<xs:attribute name="end" type="xs:unsignedInt"/>
<xs:attribute name="reverse" type="xs:boolean"/>
<xs:attribute name="includeAs" type="piecePathIncludeType"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="iPaths" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="record" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="path" type="xs:unsignedInt" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="pins" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="record" type="xs:unsignedInt" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="version" type="pieceVersion"/>
<xs:attribute name="mx" type="xs:double"/>
<xs:attribute name="my" type="xs:double"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="inLayout" type="xs:boolean"/>
<xs:attribute name="forbidFlipping" type="xs:boolean"/>
<xs:attribute name="width" type="xs:string"/>
<xs:attribute name="seamAllowance" type="xs:boolean"/>
<xs:attribute name="seamAllowanceBuiltIn" type="xs:boolean"/>
<xs:attribute name="united" type="xs:boolean"/>
<xs:attribute name="closed" type="xs:unsignedInt"/>
<xs:attribute name="hideMainPath" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="groups" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="group" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="object" type="xs:unsignedInt"/>
<xs:attribute name="tool" type="xs:unsignedInt"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="visible" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="readOnly" type="xs:boolean"/>
</xs:complexType>
<xs:unique name="incrementName">
<xs:selector xpath=".//increment"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:simpleType name="shortName">
<xs:restriction base="xs:string">
<xs:pattern value="^([^\p{Nd}\p{Zs}*/&amp;|!&lt;&gt;^\()\-+.,٫, ٬.=?:;'\&quot;]){1,1}([^\p{Zs}*/&amp;|!&lt;&gt;^\()\-+.,٫, ٬.=?:;\&quot;]){0,}$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="units">
<xs:restriction base="xs:string">
<xs:enumeration value="mm"/>
<xs:enumeration value="cm"/>
<xs:enumeration value="inch"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="measurementsTypes">
<xs:restriction base="xs:string">
<xs:enumeration value="standard"/>
<xs:enumeration value="individual"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="formatVersion">
<xs:restriction base="xs:string">
<xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="imageExtension">
<xs:restriction base="xs:string">
<xs:enumeration value="PNG"/>
<xs:enumeration value="JPG"/>
<xs:enumeration value="BMP"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="colors">
<xs:restriction base="xs:string">
<xs:enumeration value="black"/>
<xs:enumeration value="green"/>
<xs:enumeration value="blue"/>
<xs:enumeration value="darkRed"/>
<xs:enumeration value="darkGreen"/>
<xs:enumeration value="darkBlue"/>
<xs:enumeration value="yellow"/>
<xs:enumeration value="lightsalmon"/>
<xs:enumeration value="goldenrod"/>
<xs:enumeration value="orange"/>
<xs:enumeration value="deeppink"/>
<xs:enumeration value="violet"/>
<xs:enumeration value="darkviolet"/>
<xs:enumeration value="mediumseagreen"/>
<xs:enumeration value="lime"/>
<xs:enumeration value="deepskyblue"/>
<xs:enumeration value="cornflowerblue"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="linePenStyle">
<xs:restriction base="xs:string">
<xs:enumeration value="none"/>
<xs:enumeration value="hair"/>
<xs:enumeration value="dashLine"/>
<xs:enumeration value="dotLine"/>
<xs:enumeration value="dashDotLine"/>
<xs:enumeration value="dashDotDotLine"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="curvePenStyle">
<xs:restriction base="xs:string">
<xs:enumeration value="hair"/>
<xs:enumeration value="dashLine"/>
<xs:enumeration value="dotLine"/>
<xs:enumeration value="dashDotLine"/>
<xs:enumeration value="dashDotDotLine"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="baseHeight">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="50"/>
<xs:enumeration value="56"/>
<xs:enumeration value="62"/>
<xs:enumeration value="68"/>
<xs:enumeration value="74"/>
<xs:enumeration value="80"/>
<xs:enumeration value="86"/>
<xs:enumeration value="92"/>
<xs:enumeration value="98"/>
<xs:enumeration value="104"/>
<xs:enumeration value="110"/>
<xs:enumeration value="116"/>
<xs:enumeration value="122"/>
<xs:enumeration value="128"/>
<xs:enumeration value="134"/>
<xs:enumeration value="140"/>
<xs:enumeration value="146"/>
<xs:enumeration value="152"/>
<xs:enumeration value="158"/>
<xs:enumeration value="164"/>
<xs:enumeration value="170"/>
<xs:enumeration value="176"/>
<xs:enumeration value="182"/>
<xs:enumeration value="188"/>
<xs:enumeration value="194"/>
<xs:enumeration value="200"/>
<xs:enumeration value="500"/>
<xs:enumeration value="560"/>
<xs:enumeration value="620"/>
<xs:enumeration value="680"/>
<xs:enumeration value="740"/>
<xs:enumeration value="800"/>
<xs:enumeration value="860"/>
<xs:enumeration value="920"/>
<xs:enumeration value="980"/>
<xs:enumeration value="1040"/>
<xs:enumeration value="1100"/>
<xs:enumeration value="1160"/>
<xs:enumeration value="1220"/>
<xs:enumeration value="1280"/>
<xs:enumeration value="1340"/>
<xs:enumeration value="1400"/>
<xs:enumeration value="1460"/>
<xs:enumeration value="1520"/>
<xs:enumeration value="1580"/>
<xs:enumeration value="1640"/>
<xs:enumeration value="1700"/>
<xs:enumeration value="1760"/>
<xs:enumeration value="1820"/>
<xs:enumeration value="1880"/>
<xs:enumeration value="1940"/>
<xs:enumeration value="2000"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="baseSize">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="22"/>
<xs:enumeration value="24"/>
<xs:enumeration value="26"/>
<xs:enumeration value="28"/>
<xs:enumeration value="30"/>
<xs:enumeration value="32"/>
<xs:enumeration value="34"/>
<xs:enumeration value="36"/>
<xs:enumeration value="38"/>
<xs:enumeration value="40"/>
<xs:enumeration value="42"/>
<xs:enumeration value="44"/>
<xs:enumeration value="46"/>
<xs:enumeration value="48"/>
<xs:enumeration value="50"/>
<xs:enumeration value="52"/>
<xs:enumeration value="54"/>
<xs:enumeration value="56"/>
<xs:enumeration value="58"/>
<xs:enumeration value="60"/>
<xs:enumeration value="62"/>
<xs:enumeration value="64"/>
<xs:enumeration value="66"/>
<xs:enumeration value="68"/>
<xs:enumeration value="70"/>
<xs:enumeration value="72"/>
<xs:enumeration value="220"/>
<xs:enumeration value="240"/>
<xs:enumeration value="260"/>
<xs:enumeration value="280"/>
<xs:enumeration value="300"/>
<xs:enumeration value="320"/>
<xs:enumeration value="340"/>
<xs:enumeration value="360"/>
<xs:enumeration value="380"/>
<xs:enumeration value="400"/>
<xs:enumeration value="420"/>
<xs:enumeration value="440"/>
<xs:enumeration value="460"/>
<xs:enumeration value="480"/>
<xs:enumeration value="500"/>
<xs:enumeration value="520"/>
<xs:enumeration value="540"/>
<xs:enumeration value="560"/>
<xs:enumeration value="580"/>
<xs:enumeration value="600"/>
<xs:enumeration value="620"/>
<xs:enumeration value="640"/>
<xs:enumeration value="660"/>
<xs:enumeration value="680"/>
<xs:enumeration value="700"/>
<xs:enumeration value="720"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="crossType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="axisType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="arrowType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/>
<!--Both-->
<xs:enumeration value="1"/>
<!--Front-->
<xs:enumeration value="2"/>
<!--Rear-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="pieceVersion">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="1"/>
<!--Old version-->
<xs:enumeration value="2"/>
<!--New version-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="nodeAngle">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/>
<!--by length-->
<xs:enumeration value="1"/>
<!--by points intersections-->
<xs:enumeration value="2"/>
<!--by second edge symmetry-->
<xs:enumeration value="3"/>
<!--by first edge symmetry-->
<xs:enumeration value="4"/>
<!--by first edge right angle-->
<xs:enumeration value="5"/>
<!--by first edge right angle-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="piecePathType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="1"/>
<!--custom seam allowance-->
<xs:enumeration value="2"/>
<!--internal path-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="piecePathIncludeType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/>
<!--as main path-->
<xs:enumeration value="1"/>
<!--as custom seam allowance-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="passmarkLineType">
<xs:restriction base="xs:string">
<xs:enumeration value="one"/>
<xs:enumeration value="two"/>
<xs:enumeration value="three"/>
<xs:enumeration value="tMark"/>
<xs:enumeration value="vMark"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="passmarkAngleType">
<xs:restriction base="xs:string">
<xs:enumeration value="straightforward"/>
<xs:enumeration value="bisector"/>
<xs:enumeration value="intersection"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="alignmentType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/><!--default (no aligns)-->
<xs:enumeration value="1"/><!--aligns with the left edge-->
<xs:enumeration value="2"/><!--aligns with the right edge-->
<xs:enumeration value="4"/><!--Centers horizontally in the available space-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="userMaterialType">
<xs:restriction base="xs:unsignedInt">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="9"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@ -88,7 +88,9 @@ const QString VAbstractPattern::TagCustomerName = QStringLiteral("customer")
const QString VAbstractPattern::TagCompanyName = QStringLiteral("company");
const QString VAbstractPattern::TagPatternLabel = QStringLiteral("patternLabel");
const QString VAbstractPattern::TagPatternMaterials = QStringLiteral("patternMaterials");
const QString VAbstractPattern::TagFinalMeasurements= QStringLiteral("finalMeasurements");
const QString VAbstractPattern::TagMaterial = QStringLiteral("material");
const QString VAbstractPattern::TagFMeasurement = QStringLiteral("finalMeasurment");
const QString VAbstractPattern::TagGrainline = QStringLiteral("grainline");
const QString VAbstractPattern::TagPath = QStringLiteral("path");
const QString VAbstractPattern::TagNodes = QStringLiteral("nodes");
@ -187,9 +189,8 @@ const QString VAbstractPattern::AttrDefHeight = QStringLiteral("defHeight"
const QString VAbstractPattern::AttrDefSize = QStringLiteral("defSize");
const QString VAbstractPattern::AttrExtension = QStringLiteral("extension");
const QString VAbstractPattern::IncrementName = QStringLiteral("name");
const QString VAbstractPattern::IncrementFormula = QStringLiteral("formula");
const QString VAbstractPattern::IncrementDescription = QStringLiteral("description");
const QString VAbstractPattern::AttrFormula = QStringLiteral("formula");
const QString VAbstractPattern::AttrDescription = QStringLiteral("description");
const QString VAbstractPattern::NodeArc = QStringLiteral("NodeArc");
const QString VAbstractPattern::NodeElArc = QStringLiteral("NodeElArc");
@ -1444,6 +1445,28 @@ QMap<int, QString> VAbstractPattern::GetPatternMaterials() const
return patternMaterials;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<VFinalMeasurement> VAbstractPattern::GetFinalMeasurements() const
{
const QDomNodeList list = elementsByTagName(TagFinalMeasurements);
if (list.isEmpty() || list.at(0).childNodes().count() == 0)
{
return QVector<VFinalMeasurement>();
}
return GetFMeasurements(list.at(0).toElement());
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPattern::SetFinalMeasurements(const QVector<VFinalMeasurement> &measurements)
{
QDomElement tag = CheckTagExists(TagFinalMeasurements);
RemoveAllChildren(tag);
SetFMeasurements(tag, measurements);
modified = true;
emit patternChanged(false);
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPattern::SetPatternWasChanged(bool changed)
{
@ -1598,7 +1621,8 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag)
{
const QStringList tags = QStringList() << TagUnit << TagImage << TagDescription << TagNotes
<< TagGradation << TagPatternName << TagPatternNum << TagCompanyName
<< TagCustomerName << TagPatternLabel << TagPatternMaterials;
<< TagCustomerName << TagPatternLabel << TagPatternMaterials
<< TagFinalMeasurements;
switch (tags.indexOf(tag))
{
case 1: //TagImage
@ -1641,6 +1665,9 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag)
case 10: // TagPatternMaterials
element = createElement(TagPatternMaterials);
break;
case 11: // TagFinalMeasurements
element = createElement(TagFinalMeasurements);
break;
case 0: //TagUnit (Mandatory tag)
default:
return QDomElement();
@ -1703,7 +1730,7 @@ QStringList VAbstractPattern::ListIncrements() const
try
{
increments.append(GetParametrString(dom, IncrementName));
increments.append(GetParametrString(dom, AttrName));
}
catch (VExceptionEmptyParameter &e)
{
@ -1734,6 +1761,7 @@ QVector<VFormulaField> VAbstractPattern::ListExpressions() const
list << ListOperationExpressions();
list << ListPathExpressions();
list << ListPieceExpressions();
list << ListFinalMeasurementsExpressions();
return list;
}
@ -1853,7 +1881,7 @@ QVector<VFormulaField> VAbstractPattern::ListIncrementExpressions() const
{
const QDomElement dom = list.at(i).toElement();
ReadExpressionAttribute(expressions, dom, IncrementFormula);
ReadExpressionAttribute(expressions, dom, AttrFormula);
}
return expressions;
@ -1970,6 +1998,26 @@ QVector<VFormulaField> VAbstractPattern::ListPieceExpressions() const
return expressions;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<VFormulaField> VAbstractPattern::ListFinalMeasurementsExpressions() const
{
QVector<VFormulaField> expressions;
const QDomNodeList list = elementsByTagName(TagFMeasurement);
for (int i=0; i < list.size(); ++i)
{
const QDomElement dom = list.at(i).toElement();
if (dom.isNull())
{
continue;
}
// Each tag can contains several attributes.
ReadExpressionAttribute(expressions, dom, AttrFormula);
}
return expressions;
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractPattern::IsVariable(const QString &token) const
{
@ -2103,6 +2151,51 @@ void VAbstractPattern::SetMaterials(QDomElement &element, const QMap<int, QStrin
}
}
//---------------------------------------------------------------------------------------------------------------------
QVector<VFinalMeasurement> VAbstractPattern::GetFMeasurements(const QDomElement &element) const
{
QVector<VFinalMeasurement> measurements;
if (not element.isNull())
{
QDomElement tagFMeasurement = element.firstChildElement();
while (not tagFMeasurement.isNull())
{
if (tagFMeasurement.tagName() == TagFMeasurement)
{
VFinalMeasurement m;
m.name = GetParametrString(tagFMeasurement, AttrName, tr("measurement"));
m.formula = GetParametrString(tagFMeasurement, AttrFormula, "0");
m.description = GetParametrEmptyString(tagFMeasurement, AttrDescription);
measurements.append(m);
}
tagFMeasurement = tagFMeasurement.nextSiblingElement(TagFMeasurement);
}
}
return measurements;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPattern::SetFMeasurements(QDomElement &element, const QVector<VFinalMeasurement> &measurements)
{
if (not element.isNull())
{
for (int i=0; i < measurements.size(); ++i)
{
QDomElement tagFMeasurement = createElement(TagFMeasurement);
SetAttribute(tagFMeasurement, AttrName, measurements.at(i).name);
SetAttribute(tagFMeasurement, AttrFormula, measurements.at(i).formula);
SetAttribute(tagFMeasurement, AttrDescription, measurements.at(i).description);
element.appendChild(tagFMeasurement);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief IsModified state of the document for cases that do not cover QUndoStack.

View File

@ -70,6 +70,13 @@ struct VFormulaField
QString attribute;
};
struct VFinalMeasurement
{
QString name;
QString formula;
QString description;
};
QT_WARNING_POP
class VAbstractPattern : public QObject, public VDomDocument
@ -163,6 +170,9 @@ public:
void SetPatternMaterials(const QMap<int, QString> &materials);
QMap<int, QString> GetPatternMaterials() const;
QVector<VFinalMeasurement> GetFinalMeasurements() const;
void SetFinalMeasurements(const QVector<VFinalMeasurement> &measurements);
void SetPatternWasChanged(bool changed);
bool GetPatternWasChanged() const;
@ -221,7 +231,9 @@ public:
static const QString TagCustomerName;
static const QString TagPatternLabel;
static const QString TagPatternMaterials;
static const QString TagFinalMeasurements;
static const QString TagMaterial;
static const QString TagFMeasurement;
static const QString TagGrainline;
static const QString TagPath;
static const QString TagNodes;
@ -320,9 +332,8 @@ public:
static const QString AttrDefSize;
static const QString AttrExtension;
static const QString IncrementName;
static const QString IncrementFormula;
static const QString IncrementDescription;
static const QString AttrFormula;
static const QString AttrDescription;
static const QString NodeArc;
static const QString NodeElArc;
@ -435,6 +446,7 @@ private:
QVector<VFormulaField> ListPathExpressions() const;
QVector<VFormulaField> ListGrainlineExpressions(const QDomElement &element) const;
QVector<VFormulaField> ListPieceExpressions() const;
QVector<VFormulaField> ListFinalMeasurementsExpressions() const;
bool IsVariable(const QString& token) const;
bool IsPostfixOperator(const QString& token) const;
@ -444,6 +456,9 @@ private:
QMap<int, QString> GetMaterials(const QDomElement &element) const;
void SetMaterials(QDomElement &element, const QMap<int, QString> &materials);
QVector<VFinalMeasurement> GetFMeasurements(const QDomElement &element) const;
void SetFMeasurements(QDomElement &element, const QVector<VFinalMeasurement> &measurements);
};
//---------------------------------------------------------------------------------------------------------------------

View File

@ -58,8 +58,8 @@ class QDomElement;
*/
const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.6.3");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.6.3.xsd");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.6.4");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.6.4.xsd");
//VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
//VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
@ -250,6 +250,8 @@ QString VPatternConverter::XSDSchema(int ver) const
case (0x000602):
return QStringLiteral("://schema/pattern/v0.6.2.xsd");
case (0x000603):
return QStringLiteral("://schema/pattern/v0.6.3.xsd");
case (0x000604):
return CurrentSchema;
default:
InvalidVersion(ver);
@ -412,6 +414,10 @@ void VPatternConverter::ApplyPatches()
ValidateXML(XSDSchema(0x000603), m_convertedFileName);
V_FALLTHROUGH
case (0x000603):
ToV0_6_4();
ValidateXML(XSDSchema(0x000604), m_convertedFileName);
V_FALLTHROUGH
case (0x000604):
break;
default:
InvalidVersion(m_ver);
@ -430,7 +436,7 @@ void VPatternConverter::DowngradeToCurrentMaxVersion()
bool VPatternConverter::IsReadOnly() const
{
// Check if attribute readOnly was not changed in file format
Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 6, 3),
Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 6, 4),
"Check attribute readOnly.");
// Possibly in future attribute readOnly will change position etc.
@ -864,6 +870,16 @@ void VPatternConverter::ToV0_6_3()
Save();
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ToV0_6_4()
{
// TODO. Delete if minimal supported version is 0.6.4
Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < CONVERTER_VERSION_CHECK(0, 6, 4),
"Time to refactor the code.");
SetVersion(QStringLiteral("0.6.4"));
Save();
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::TagUnitToV0_2_0()
{

View File

@ -53,7 +53,7 @@ public:
static const QString PatternMaxVerStr;
static const QString CurrentSchema;
static Q_DECL_CONSTEXPR const int PatternMinVer = CONVERTER_VERSION_CHECK(0, 1, 0);
static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 6, 3);
static Q_DECL_CONSTEXPR const int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 6, 4);
protected:
virtual int MinVer() const Q_DECL_OVERRIDE;
@ -109,6 +109,7 @@ private:
void ToV0_6_1();
void ToV0_6_2();
void ToV0_6_3();
void ToV0_6_4();
void TagUnitToV0_2_0();
void TagIncrementToV0_2_0();

View File

@ -111,6 +111,11 @@ const QString SINGLE_OPTION_TOP_MARGIN = QStringLiteral("T");
const QString LONG_OPTION_BOTTOM_MARGIN = QStringLiteral("bmargin");
const QString SINGLE_OPTION_BOTTOM_MARGIN = QStringLiteral("B");
const QString LONG_OPTION_CSVWITHHEADER = QStringLiteral("csvWithHeader");
const QString LONG_OPTION_CSVCODEC = QStringLiteral("csvCodec");
const QString LONG_OPTION_CSVSEPARATOR = QStringLiteral("csvSeparator");
const QString LONG_OPTION_CSVEXPORTFM = QStringLiteral("csvExportFM");
//---------------------------------------------------------------------------------------------------------------------
QStringList AllKeys()
{
@ -143,7 +148,11 @@ QStringList AllKeys()
<< LONG_OPTION_RIGHT_MARGIN << SINGLE_OPTION_RIGHT_MARGIN
<< LONG_OPTION_TOP_MARGIN << SINGLE_OPTION_TOP_MARGIN
<< LONG_OPTION_BOTTOM_MARGIN << SINGLE_OPTION_BOTTOM_MARGIN
<< LONG_OPTION_NO_HDPI_SCALING;
<< LONG_OPTION_NO_HDPI_SCALING
<< LONG_OPTION_CSVWITHHEADER
<< LONG_OPTION_CSVCODEC
<< LONG_OPTION_CSVSEPARATOR
<< LONG_OPTION_CSVEXPORTFM;
return list;
}

View File

@ -108,6 +108,11 @@ extern const QString SINGLE_OPTION_TOP_MARGIN;
extern const QString LONG_OPTION_BOTTOM_MARGIN;
extern const QString SINGLE_OPTION_BOTTOM_MARGIN;
extern const QString LONG_OPTION_CSVWITHHEADER;
extern const QString LONG_OPTION_CSVCODEC;
extern const QString LONG_OPTION_CSVSEPARATOR;
extern const QString LONG_OPTION_CSVEXPORTFM;
QStringList AllKeys();
#endif // COMMANDOPTIONS_H

View File

@ -44,25 +44,23 @@ DialogExportToCSV::DialogExportToCSV(QWidget *parent)
{
ui->setupUi(this);
ui->checkBoxWithHeader->setChecked(qApp->Settings()->GetCSVWithHeader());
foreach (int mib, QTextCodec::availableMibs())
{
ui->comboBoxCodec->addItem(QTextCodec::codecForMib(mib)->name(), mib);
}
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(qApp->Settings()->GetCSVCodec()));
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec()));
SetSeparator(qApp->Settings()->GetCSVSeparator());
SetSeparator(VCommonSettings::GetDefCSVSeparator());
QPushButton *bDefaults = ui->buttonBox->button(QDialogButtonBox::RestoreDefaults);
SCASSERT(bDefaults != nullptr)
connect(bDefaults, &QPushButton::clicked, this, [this]()
{
ui->checkBoxWithHeader->setChecked(qApp->Settings()->GetDefCSVWithHeader());
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(qApp->Settings()->GetDefCSVCodec()));
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec()));
SetSeparator(qApp->Settings()->GetDefCSVSeparator());
SetSeparator(VCommonSettings::GetDefCSVSeparator());
});
}
@ -73,19 +71,46 @@ DialogExportToCSV::~DialogExportToCSV()
}
//---------------------------------------------------------------------------------------------------------------------
bool DialogExportToCSV::WithHeader() const
bool DialogExportToCSV::IsWithHeader() const
{
return ui->checkBoxWithHeader->isChecked();
}
//---------------------------------------------------------------------------------------------------------------------
int DialogExportToCSV::SelectedMib() const
void DialogExportToCSV::SetWithHeader(bool value)
{
return ui->comboBoxCodec->currentData().toInt();
ui->checkBoxWithHeader->setChecked(value);
}
//---------------------------------------------------------------------------------------------------------------------
QChar DialogExportToCSV::Separator() const
int DialogExportToCSV::GetSelectedMib() const
{
if (ui->comboBoxCodec->currentIndex() != -1)
{
return ui->comboBoxCodec->currentData().toInt();
}
else
{
return VCommonSettings::GetDefCSVCodec();
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogExportToCSV::SetSelectedMib(int value)
{
const int index = ui->comboBoxCodec->findData(value);
if (index != -1)
{
ui->comboBoxCodec->setCurrentIndex(index);
}
else
{
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(VCommonSettings::GetDefCSVCodec()));
}
}
//---------------------------------------------------------------------------------------------------------------------
QChar DialogExportToCSV::GetSeparator() const
{
if (ui->radioButtonTab->isChecked())
{
@ -101,7 +126,7 @@ QChar DialogExportToCSV::Separator() const
}
else
{
return QChar(',');
return VCommonSettings::GetDefCSVSeparator();
}
}
@ -159,3 +184,34 @@ void DialogExportToCSV::SetSeparator(const QChar &separator)
break;
}
}
//---------------------------------------------------------------------------------------------------------------------
QString DialogExportToCSV::MakeHelpCodecsList()
{
QString out("\n");
const QList<int> list = QTextCodec::availableMibs();
for (int i = 0; i < list.size(); ++i)
{
out += QLatin1String("\t* ") + QTextCodec::codecForMib(list.at(i))->name();
if (i < list.size()-1)
{
out += QLatin1String(",\n");
}
else
{
out += QLatin1String(".\n");
}
}
return out;
}
//---------------------------------------------------------------------------------------------------------------------
QString DialogExportToCSV::MakeHelpSeparatorList()
{
QString out("\n");
out += QLatin1String("\t* 'Tab',\n");
out += QLatin1String("\t* ';',\n");
out += QLatin1String("\t* 'Space',\n");
out += QLatin1String("\t* ','.\n");
return out;
}

View File

@ -31,7 +31,8 @@
#include <QDialog>
namespace Ui {
namespace Ui
{
class DialogExportToCSV;
}
@ -43,9 +44,17 @@ public:
explicit DialogExportToCSV(QWidget *parent = nullptr);
virtual ~DialogExportToCSV();
bool WithHeader() const;
int SelectedMib() const;
QChar Separator() const;
bool IsWithHeader() const;
void SetWithHeader(bool value);
int GetSelectedMib() const;
void SetSelectedMib(int value);
QChar GetSeparator() const;
void SetSeparator(const QChar &separator);
static QString MakeHelpCodecsList();
static QString MakeHelpSeparatorList();
protected:
virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
@ -55,8 +64,6 @@ private:
Q_DISABLE_COPY(DialogExportToCSV)
Ui::DialogExportToCSV *ui;
bool isInitialized;
void SetSeparator(const QChar &separator);
};
#endif // DIALOGEXPORTTOCSV_H

View File

@ -591,7 +591,7 @@ static QString qxt_addCsvQuotes(QxtCsvModel::QuoteMode mode, QString field)
to output a row of headers at the top of the file.
*/
// cppcheck-suppress funcArgNamesDifferent
void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QTextCodec* codec) const
bool QxtCsvModel::toCSV(QIODevice* dest, QString &error, bool withHeader, QChar separator, QTextCodec* codec) const
{
const QxtCsvModelPrivate& d_ptr = qxt_d();
int row, col, rows, cols;
@ -600,7 +600,11 @@ void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QText
QString data;
if (not dest->isOpen())
{
dest->open(QIODevice::WriteOnly | QIODevice::Truncate);
if ( not dest->open(QIODevice::WriteOnly | QIODevice::Truncate))
{
error = dest->errorString();
return false;
}
}
QTextStream stream(dest);
if (codec)
@ -643,6 +647,7 @@ void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QText
}
stream << flush;
dest->close();
return true;
}
/*!
@ -653,10 +658,11 @@ void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QText
Fields in the output file will be separated by \a separator. Set \a withHeader to true
to output a row of headers at the top of the file.
*/
void QxtCsvModel::toCSV(const QString &filename, bool withHeader, QChar separator, QTextCodec* codec) const
bool QxtCsvModel::toCSV(const QString &filename, QString &error, bool withHeader, QChar separator,
QTextCodec* codec) const
{
QFile dest(filename);
toCSV(&dest, withHeader, separator, codec);
return toCSV(&dest, error, withHeader, separator, codec);
}
/*!

View File

@ -93,8 +93,9 @@ public:
void setSource(const QString &filename, bool withHeader = false, QChar separator = ',',
QTextCodec* codec = nullptr);
void toCSV(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr) const;
void toCSV(const QString &filename, bool withHeader = false, QChar separator = ',',
bool toCSV(QIODevice *file, QString &error, bool withHeader = false, QChar separator = ',',
QTextCodec* codec = nullptr) const;
bool toCSV(const QString &filename, QString &error, bool withHeader = false, QChar separator = ',',
QTextCodec* codec = nullptr) const;
enum QuoteOption { NoQuotes = 0,

View File

@ -78,6 +78,7 @@ const QString settingPreferenceDialogSize = QStringLiteral("preferenceDia
const QString settingToolSeamAllowanceDialogSize = QStringLiteral("toolSeamAllowanceDialogSize");
const QString settingIncrementsDialogSize = QStringLiteral("toolIncrementsDialogSize");
const QString settingFormulaWizardDialogSize = QStringLiteral("formulaWizardDialogSize");
const QString settingFinalMeasurementsDialogSize = QStringLiteral("finalMeasurementsDialogSize");
const QString settingLatestSkippedVersion = QStringLiteral("lastestSkippedVersion");
const QString settingDateOfLastRemind = QStringLiteral("dateOfLastRemind");
@ -616,6 +617,18 @@ void VCommonSettings::SetIncrementsDialogSize(const QSize &sz)
setValue(settingIncrementsDialogSize, sz);
}
//---------------------------------------------------------------------------------------------------------------------
QSize VCommonSettings::GetFinalMeasurementsDialogSize() const
{
return value(settingFinalMeasurementsDialogSize, QSize(0, 0)).toSize();
}
//---------------------------------------------------------------------------------------------------------------------
void VCommonSettings::SetFinalMeasurementsDialogSize(const QSize &sz)
{
setValue(settingFinalMeasurementsDialogSize, sz);
}
//---------------------------------------------------------------------------------------------------------------------
int VCommonSettings::GetLatestSkippedVersion() const
{
@ -697,7 +710,7 @@ bool VCommonSettings::GetCSVWithHeader() const
}
//---------------------------------------------------------------------------------------------------------------------
bool VCommonSettings::GetDefCSVWithHeader() const
bool VCommonSettings::GetDefCSVWithHeader()
{
return false;
}
@ -717,7 +730,7 @@ int VCommonSettings::GetCSVCodec() const
}
//---------------------------------------------------------------------------------------------------------------------
int VCommonSettings::GetDefCSVCodec() const
int VCommonSettings::GetDefCSVCodec()
{
return QTextCodec::codecForLocale()->mibEnum();
}
@ -762,7 +775,7 @@ QChar VCommonSettings::GetCSVSeparator() const
}
//---------------------------------------------------------------------------------------------------------------------
QChar VCommonSettings::GetDefCSVSeparator() const
QChar VCommonSettings::GetDefCSVSeparator()
{
return QChar(',');
}

View File

@ -129,6 +129,9 @@ public:
QSize GetIncrementsDialogSize() const;
void SetIncrementsDialogSize(const QSize& sz);
QSize GetFinalMeasurementsDialogSize() const;
void SetFinalMeasurementsDialogSize(const QSize& sz);
int GetLatestSkippedVersion() const;
void SetLatestSkippedVersion(int value);
@ -146,15 +149,15 @@ public:
void SetCSVWithHeader(bool withHeader);
bool GetCSVWithHeader() const;
bool GetDefCSVWithHeader() const;
static bool GetDefCSVWithHeader();
void SetCSVCodec(int mib);
int GetCSVCodec() const;
int GetDefCSVCodec() const;
static int GetDefCSVCodec();
void SetCSVSeparator(const QChar &separator);
QChar GetCSVSeparator() const;
QChar GetDefCSVSeparator() const;
static QChar GetDefCSVSeparator();
void SetDefaultSeamAllowance(double value);
double GetDefaultSeamAllowance();

View File

@ -80,7 +80,8 @@ VIncrement::~VIncrement()
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief getIndex return index of row
* @brief getIndex return index of row. Row index for increments and preview calucalations is unique. Check type before
* using.
* @return index
*/
quint32 VIncrement::getIndex() const

View File

@ -1069,6 +1069,20 @@ QString VTranslateVars::FormulaToUser(const QString &formula, bool osSeparator)
return newFormula;
}
//---------------------------------------------------------------------------------------------------------------------
QString VTranslateVars::TryFormulaToUser(const QString &formula, bool osSeparator)
{
try
{
return qApp->TrVars()->FormulaToUser(formula, osSeparator);
}
catch (qmu::QmuParserError &e)// In case something bad will happen
{
Q_UNUSED(e)
return formula;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VTranslateVars::Retranslate()
{

View File

@ -62,7 +62,9 @@ public:
QString FormulaFromUser(const QString &formula, bool osSeparator) const;
static QString TryFormulaFromUser(const QString &formula, bool osSeparator);
QString FormulaToUser(const QString &formula, bool osSeparator) const;
static QString TryFormulaToUser(const QString &formula, bool osSeparator);
virtual void Retranslate() Q_DECL_OVERRIDE;

View File

@ -326,16 +326,7 @@ void DialogSplinePath::Angle1Changed()
const QString angle1F = ui->plainTextEditAngle1F->toPlainText().replace("\n", " ");
const qreal angle1 = Visualization::FindVal(angle1F, data->DataVariables());
try
{
p.SetAngle1(angle1, qApp->TrVars()->FormulaFromUser(angle1F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetAngle1(angle1, angle1F);
}
p.SetAngle1(angle1, VTranslateVars::TryFormulaFromUser(angle1F, qApp->Settings()->GetOsSeparator()));
item->setData(Qt::UserRole, QVariant::fromValue(p));
@ -369,16 +360,7 @@ void DialogSplinePath::Angle2Changed()
const QString angle2F = ui->plainTextEditAngle2F->toPlainText().replace("\n", " ");
const qreal angle2 = Visualization::FindVal(angle2F, data->DataVariables());
try
{
p.SetAngle2(angle2, qApp->TrVars()->FormulaFromUser(angle2F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetAngle2(angle2, angle2F);
}
p.SetAngle2(angle2, VTranslateVars::TryFormulaFromUser(angle2F, qApp->Settings()->GetOsSeparator()));
item->setData(Qt::UserRole, QVariant::fromValue(p));
@ -412,16 +394,7 @@ void DialogSplinePath::Length1Changed()
const QString length1F = ui->plainTextEditLength1F->toPlainText().replace("\n", " ");
const qreal length1 = Visualization::FindLength(length1F, data->DataVariables());
try
{
p.SetLength1(length1, qApp->TrVars()->FormulaFromUser(length1F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetLength1(length1, length1F);
}
p.SetLength1(length1, VTranslateVars::TryFormulaFromUser(length1F, qApp->Settings()->GetOsSeparator()));
item->setData(Qt::UserRole, QVariant::fromValue(p));
@ -446,16 +419,7 @@ void DialogSplinePath::Length2Changed()
const QString length2F = ui->plainTextEditLength2F->toPlainText().replace("\n", " ");
const qreal length2 = Visualization::FindLength(length2F, data->DataVariables());
try
{
p.SetLength2(length2, qApp->TrVars()->FormulaFromUser(length2F, qApp->Settings()->GetOsSeparator()));
}
catch (qmu::QmuParserError &e)
{
Q_UNUSED(e)
p.SetLength2(length2, length2F);
}
p.SetLength2(length2, VTranslateVars::TryFormulaFromUser(length2F, qApp->Settings()->GetOsSeparator()));
item->setData(Qt::UserRole, QVariant::fromValue(p));
@ -469,14 +433,14 @@ void DialogSplinePath::FXAngle1()
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit first control point angle"));
QString angle1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle1F->toPlainText().replace("\n", " "),
QString angle1F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditAngle1F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(angle1F);
dialog->setPostfix(degreeSymbol);
if (dialog->exec() == QDialog::Accepted)
{
angle1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
angle1F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (angle1F.length() > 80)
{
@ -494,14 +458,14 @@ void DialogSplinePath::FXAngle2()
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit second control point angle"));
QString angle2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditAngle2F->toPlainText().replace("\n", " "),
QString angle2F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditAngle2F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(angle2F);
dialog->setPostfix(degreeSymbol);
if (dialog->exec() == QDialog::Accepted)
{
angle2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
angle2F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (angle2F.length() > 80)
{
@ -519,14 +483,14 @@ void DialogSplinePath::FXLength1()
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit first control point length"));
QString length1F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength1F->toPlainText().replace("\n", " "),
QString length1F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditLength1F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(length1F);
dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
{
length1F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
length1F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (length1F.length() > 80)
{
@ -544,14 +508,14 @@ void DialogSplinePath::FXLength2()
auto dialog = new DialogEditWrongFormula(data, toolId, this);
dialog->setWindowTitle(tr("Edit second control point length"));
QString length2F = qApp->TrVars()->TryFormulaFromUser(ui->plainTextEditLength2F->toPlainText().replace("\n", " "),
QString length2F = VTranslateVars::TryFormulaFromUser(ui->plainTextEditLength2F->toPlainText().replace("\n", " "),
qApp->Settings()->GetOsSeparator());
dialog->SetFormula(length2F);
dialog->setPostfix(UnitsToStr(qApp->patternUnit(), true));
if (dialog->exec() == QDialog::Accepted)
{
length2F = qApp->TrVars()->FormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
length2F = VTranslateVars::TryFormulaToUser(dialog->GetFormula(), qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (length2F.length() > 80)
{

View File

@ -30,6 +30,7 @@
#include "../vpropertyexplorer/checkablemessagebox.h"
#include "../vmisc/vabstractapplication.h"
#include "dialogs/dialogexporttocsv.h"
#include "../ifc/xml/vabstractpattern.h"
#include <QStyle>
#include <QToolBar>
@ -87,13 +88,7 @@ void VAbstractMainWindow::ToolBarStyle(QToolBar *bar)
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::WindowsLocale()
{
qApp->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c());
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::ExportToCSV()
QString VAbstractMainWindow::CSVFilePath()
{
const QString filters = tr("Comma-Separated Values") + QLatin1String(" (*.csv)");
const QString suffix("csv");
@ -104,7 +99,7 @@ void VAbstractMainWindow::ExportToCSV()
if (fileName.isEmpty())
{
return;
return fileName;
}
QFileInfo f( fileName );
@ -113,13 +108,36 @@ void VAbstractMainWindow::ExportToCSV()
fileName += QLatin1String(".") + suffix;
}
return fileName;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::WindowsLocale()
{
qApp->Settings()->GetOsSeparator() ? setLocale(QLocale()) : setLocale(QLocale::c());
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::ExportDataToCSV()
{
QString fileName = CSVFilePath();
if (fileName.isEmpty())
{
return;
}
DialogExportToCSV dialog(this);
dialog.SetWithHeader(qApp->Settings()->GetCSVWithHeader());
dialog.SetSelectedMib(qApp->Settings()->GetCSVCodec());
dialog.SetSeparator(qApp->Settings()->GetCSVSeparator());
if (dialog.exec() == QDialog::Accepted)
{
ExportToCSVData(fileName, dialog);
ExportToCSVData(fileName, dialog.IsWithHeader(), dialog.GetSelectedMib(), dialog.GetSeparator());
qApp->Settings()->SetCSVSeparator(dialog.Separator());
qApp->Settings()->SetCSVCodec(dialog.SelectedMib());
qApp->Settings()->SetCSVWithHeader(dialog.WithHeader());
qApp->Settings()->SetCSVSeparator(dialog.GetSeparator());
qApp->Settings()->SetCSVCodec(dialog.GetSelectedMib());
qApp->Settings()->SetCSVWithHeader(dialog.IsWithHeader());
}
}

View File

@ -35,7 +35,7 @@
#include <QObject>
#include <QString>
class DialogExportToCSV;
class VFinalMeasurement;
class VAbstractMainWindow : public QMainWindow
{
@ -49,7 +49,7 @@ public slots:
protected slots:
void WindowsLocale();
void ExportToCSV();
void ExportDataToCSV();
protected:
int m_curFileFormatVersion;
@ -58,7 +58,10 @@ protected:
bool ContinueFormatRewrite(const QString &currentFormatVersion, const QString &maxFormatVersion);
void ToolBarStyle(QToolBar *bar);
virtual void ExportToCSVData(const QString &fileName, const DialogExportToCSV &dialog)=0;
QString CSVFilePath();
virtual void ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)=0;
private:
Q_DISABLE_COPY(VAbstractMainWindow)
};

View File

@ -72,16 +72,7 @@ void TST_VTranslateVars::TestFormulaFromUser()
QLocale::setDefault(locale);
QString result;
try
{
result = m_trMs->FormulaFromUser(input, true);
}
catch (qmu::QmuParserError &e)// In case something bad will happen
{
Q_UNUSED(e)
result = input;
}
const QString result = VTranslateVars::TryFormulaFromUser(input, true);
QCOMPARE(result, output);
}
@ -111,16 +102,7 @@ void TST_VTranslateVars::TestFormulaToUser()
QLocale::setDefault(locale);
QString result;
try
{
result = m_trMs->FormulaToUser(input, true);
}
catch (qmu::QmuParserError &e)// In case something bad will happen
{
Q_UNUSED(e)
result = input;
}
const QString result = VTranslateVars::TryFormulaToUser(input, true);
QCOMPARE(result, output);
}