diff --git a/src/app/valentina/dialogs/dialogfinalmeasurements.cpp b/src/app/valentina/dialogs/dialogfinalmeasurements.cpp new file mode 100644 index 000000000..a2edafc6c --- /dev/null +++ b/src/app/valentina/dialogs/dialogfinalmeasurements.cpp @@ -0,0 +1,741 @@ +/************************************************************************ + ** + ** @file dialogfinalmeasurements.cpp + ** @author Roman Telezhynskyi + ** @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 + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "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 +void Move(QVector &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(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(object)) + { + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(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 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 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 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; +} diff --git a/src/app/valentina/dialogs/dialogfinalmeasurements.h b/src/app/valentina/dialogs/dialogfinalmeasurements.h new file mode 100644 index 000000000..a4aa725be --- /dev/null +++ b/src/app/valentina/dialogs/dialogfinalmeasurements.h @@ -0,0 +1,102 @@ +/************************************************************************ + ** + ** @file dialogfinalmeasurements.h + ** @author Roman Telezhynskyi + ** @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 + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef DIALOGFINALMEASUREMENTS_H +#define DIALOGFINALMEASUREMENTS_H + +#include + +#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 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 m_measurements; + QSharedPointer 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 DialogFinalMeasurements::FinalMeasurements() const +{ + return m_measurements; +} + +#endif // DIALOGFINALMEASUREMENTS_H diff --git a/src/app/valentina/dialogs/dialogfinalmeasurements.ui b/src/app/valentina/dialogs/dialogfinalmeasurements.ui new file mode 100644 index 000000000..074a08f00 --- /dev/null +++ b/src/app/valentina/dialogs/dialogfinalmeasurements.ui @@ -0,0 +1,469 @@ + + + DialogFinalMeasurements + + + + 0 + 0 + 717 + 518 + + + + Dialog + + + + + + 0 + + + + + Find: + + + + + + + Search + + + + + + + ... + + + + :/icons/win.icon.theme/16x16/actions/go-previous.png:/icons/win.icon.theme/16x16/actions/go-previous.png + + + + + + + ... + + + + :/icons/win.icon.theme/16x16/actions/go-next.png:/icons/win.icon.theme/16x16/actions/go-next.png + + + + + + + + + + 0 + 8 + + + + + 0 + 150 + + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + true + + + false + + + 120 + + + 70 + + + false + + + true + + + false + + + false + + + 25 + + + 8 + + + false + + + + Name + + + + + The calculated value + + + + + Formula + + + + + + + + + 0 + 4 + + + + + 0 + 236 + + + + Details + + + Details + + + + + + 6 + + + + + Qt::Horizontal + + + + 5000 + 20 + + + + + + + + + 0 + 0 + + + + ... + + + + .. + + + + + + + false + + + ... + + + + .. + + + + + + + + + Name: + + + + + + + false + + + + + + + Calculated value: + + + + + + + + + + + + + + Formula: + + + + + + + + + false + + + + 0 + 0 + + + + + 16777215 + 28 + + + + Calculation + + + true + + + + + + + false + + + + 18 + 18 + + + + + 0 + 0 + + + + Qt::StrongFocus + + + <html><head/><body><p>Show full calculation in message box</p></body></html> + + + + + + + ../../../libs/vtools/dialogs/support../../../libs/vtools/dialogs/support + + + + 16 + 16 + + + + false + + + true + + + + + + + false + + + + 24 + 24 + + + + Formula wizard + + + ... + + + + :/icon/24x24/fx.png:/icon/24x24/fx.png + + + + 24 + 24 + + + + + + + + + + Description: + + + + + + + false + + + + 0 + 1 + + + + + + + + + + false + + + Move measurement up + + + ... + + + + ../../tape../../tape + + + + + + + false + + + Move measurement down + + + ... + + + + ../../tape../../tape + + + + + + + Qt::Horizontal + + + + 5000 + 20 + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + buttonBox + accepted() + DialogFinalMeasurements + accept() + + + 227 + 523 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogFinalMeasurements + reject() + + + 295 + 529 + + + 286 + 274 + + + + + diff --git a/src/app/valentina/dialogs/dialogs.h b/src/app/valentina/dialogs/dialogs.h index 5ab889460..d91458e6c 100644 --- a/src/app/valentina/dialogs/dialogs.h +++ b/src/app/valentina/dialogs/dialogs.h @@ -35,5 +35,6 @@ #include "dialognewpattern.h" #include "dialogaboutapp.h" #include "dialogpreferences.h" +#include "dialogfinalmeasurements.h" #endif // DIALOGS_H diff --git a/src/app/valentina/dialogs/dialogs.pri b/src/app/valentina/dialogs/dialogs.pri index 7962f91dc..61c91e73c 100644 --- a/src/app/valentina/dialogs/dialogs.pri +++ b/src/app/valentina/dialogs/dialogs.pri @@ -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 diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 2f86f60e9..c1d1567e8 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -117,7 +117,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), @@ -2833,6 +2835,8 @@ void MainWindow::Clear() ui->actionZoomOriginal->setEnabled(false); ui->actionHistory->setEnabled(false); ui->actionTable->setEnabled(false); + ui->actionExportIncrementsToCSV->setEnabled(false); + ui->actionFinalMeasurements->setEnabled(false); ui->actionLast_tool->setEnabled(false); ui->actionShowCurveDetails->setEnabled(false); ui->actionLoadIndividual->setEnabled(false); @@ -3078,6 +3082,8 @@ void MainWindow::SetEnableWidgets(bool enable) ui->actionDetails->setEnabled(enable); ui->actionLayout->setEnabled(enable); ui->actionTable->setEnabled(enable && drawStage); + ui->actionExportIncrementsToCSV->setEnabled(enable); + ui->actionFinalMeasurements->setEnabled(enable); ui->actionZoomFitBest->setEnabled(enable); ui->actionZoomFitBestCurrent->setEnabled(enable && drawStage); ui->actionZoomOriginal->setEnabled(enable); @@ -3993,6 +3999,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")); diff --git a/src/app/valentina/mainwindow.h b/src/app/valentina/mainwindow.h index 47a5d651c..38a6bfeeb 100644 --- a/src/app/valentina/mainwindow.h +++ b/src/app/valentina/mainwindow.h @@ -47,6 +47,7 @@ class QLabel; class DialogIncrements; class DialogTool; class DialogHistory; +class DialogFinalMeasurements; class VWidgetGroups; class VWidgetDetails; class QToolButton; @@ -226,9 +227,10 @@ private: bool patternReadOnly; - QPointer dialogTable; - QSharedPointer dialogTool; - QPointer dialogHistory; + QPointer dialogTable; + QSharedPointer dialogTool; + QPointer dialogHistory; + QPointer dialogFMeasurements; /** @brief comboBoxDraws comboc who show name of pattern peaces. */ QComboBox *comboBoxDraws; diff --git a/src/app/valentina/mainwindow.ui b/src/app/valentina/mainwindow.ui index 64be47238..dad8e7a57 100644 --- a/src/app/valentina/mainwindow.ui +++ b/src/app/valentina/mainwindow.ui @@ -1699,12 +1699,16 @@ + + + + @@ -2649,6 +2653,9 @@ + + false + Export increments to CSV @@ -2657,6 +2664,9 @@ + + false + Zoom fit best current @@ -2675,6 +2685,14 @@ Label template editor + + + false + + + Final measurements + + @@ -2685,8 +2703,8 @@ - + diff --git a/src/libs/vmisc/vcommonsettings.cpp b/src/libs/vmisc/vcommonsettings.cpp index 063423140..b7a97d3d9 100644 --- a/src/libs/vmisc/vcommonsettings.cpp +++ b/src/libs/vmisc/vcommonsettings.cpp @@ -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 { diff --git a/src/libs/vmisc/vcommonsettings.h b/src/libs/vmisc/vcommonsettings.h index 2232d0ec5..231c44527 100644 --- a/src/libs/vmisc/vcommonsettings.h +++ b/src/libs/vmisc/vcommonsettings.h @@ -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); diff --git a/src/libs/vpatterndb/vtranslatevars.cpp b/src/libs/vpatterndb/vtranslatevars.cpp index 95aed8c2c..5224b5a5f 100644 --- a/src/libs/vpatterndb/vtranslatevars.cpp +++ b/src/libs/vpatterndb/vtranslatevars.cpp @@ -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() { diff --git a/src/libs/vpatterndb/vtranslatevars.h b/src/libs/vpatterndb/vtranslatevars.h index 0596c0f58..22a0034bc 100644 --- a/src/libs/vpatterndb/vtranslatevars.h +++ b/src/libs/vpatterndb/vtranslatevars.h @@ -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;