Import/Export known measurements to CSV.
This commit is contained in:
parent
84cc3a1393
commit
6336a94bd5
550
src/app/tape/dialogs/dialogknownmeasurementscsvcolumns.cpp
Normal file
550
src/app/tape/dialogs/dialogknownmeasurementscsvcolumns.cpp
Normal file
|
@ -0,0 +1,550 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file dialogknownmeasurementscsvcolumns.cpp
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 7 11, 2023
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2023 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#include "dialogknownmeasurementscsvcolumns.h"
|
||||
#include "ui_dialogknownmeasurementscsvcolumns.h"
|
||||
|
||||
#include "../vmisc/qxtcsvmodel.h"
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||
#include "../vmisc/backport/qoverload.h"
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||
#include "../vtools/dialogs/dialogtoolbox.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QShowEvent>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
|
||||
#include "../vmisc/compatibility.h"
|
||||
#endif
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogKnownMeasurementsCSVColumns::DialogKnownMeasurementsCSVColumns(const QString &filename, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::DialogKnownMeasurementsCSVColumns),
|
||||
m_fileName{filename}
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogKnownMeasurementsCSVColumns::~DialogKnownMeasurementsCSVColumns()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::changeEvent(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::LanguageChange)
|
||||
{
|
||||
// retranslate designer form (single inheritance approach)
|
||||
ui->retranslateUi(this);
|
||||
|
||||
RetranslateLabels();
|
||||
InitColumnsControls();
|
||||
InitImportHeaders();
|
||||
ShowImportPreview();
|
||||
CheckStatus();
|
||||
}
|
||||
|
||||
// remember to call base class implementation
|
||||
QDialog::changeEvent(event);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::showEvent(QShowEvent *event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
if (event->spontaneous())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_isInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// do your init stuff here
|
||||
|
||||
if (not m_fileName.isEmpty())
|
||||
{
|
||||
InitColumnsMap();
|
||||
ShowInputPreview();
|
||||
InitColumnsControls();
|
||||
RetranslateLabels();
|
||||
SetDefaultColumns();
|
||||
InitImportHeaders();
|
||||
ShowImportPreview();
|
||||
|
||||
connect(ui->comboBoxName, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogKnownMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxGroup, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogKnownMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxFullName, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogKnownMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxFormula, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogKnownMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxDescription, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogKnownMeasurementsCSVColumns::ColumnChanged);
|
||||
|
||||
CheckStatus();
|
||||
}
|
||||
|
||||
m_isInitialized = true; // first show windows are held
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::ColumnChanged()
|
||||
{
|
||||
auto *control = qobject_cast<QComboBox *>(sender());
|
||||
|
||||
if (control == ui->comboBoxName)
|
||||
{
|
||||
SaveColum(control, KnownMeasurementsColumns::Name);
|
||||
}
|
||||
else if (control == ui->comboBoxGroup)
|
||||
{
|
||||
SaveColum(control, KnownMeasurementsColumns::Group);
|
||||
}
|
||||
else if (control == ui->comboBoxFullName)
|
||||
{
|
||||
SaveColum(control, KnownMeasurementsColumns::FullName);
|
||||
}
|
||||
else if (control == ui->comboBoxFormula)
|
||||
{
|
||||
SaveColum(control, KnownMeasurementsColumns::Formula);
|
||||
}
|
||||
else if (control == ui->comboBoxDescription)
|
||||
{
|
||||
SaveColum(control, KnownMeasurementsColumns::Description);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool DialogKnownMeasurementsCSVColumns::ColumnMandatory(int column) const
|
||||
{
|
||||
return column < static_cast<int>(KnownMeasurementsColumns::Group);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QString DialogKnownMeasurementsCSVColumns::ColumnHeader(int column) const
|
||||
{
|
||||
const auto individualColumn = static_cast<KnownMeasurementsColumns>(column);
|
||||
switch (individualColumn)
|
||||
{
|
||||
case KnownMeasurementsColumns::Name:
|
||||
return tr("Name", "measurement column");
|
||||
case KnownMeasurementsColumns::Group:
|
||||
return tr("Group", "measurement column");
|
||||
case KnownMeasurementsColumns::FullName:
|
||||
return tr("Full name", "measurement column");
|
||||
case KnownMeasurementsColumns::Formula:
|
||||
return tr("Formula", "measurement column");
|
||||
case KnownMeasurementsColumns::Description:
|
||||
return tr("Description", "measurement column");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
int DialogKnownMeasurementsCSVColumns::ImportColumnCount() const
|
||||
{
|
||||
return static_cast<int>(KnownMeasurementsColumns::LAST_DO_NOT_USE);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
int DialogKnownMeasurementsCSVColumns::MinimumColumns() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
bool DialogKnownMeasurementsCSVColumns::ColumnsValid()
|
||||
{
|
||||
ClearColumnCollor();
|
||||
|
||||
bool columnNameFlag = true;
|
||||
bool columnGroupFlag = true;
|
||||
bool columnFullNameFlag = true;
|
||||
bool columnFormulaFlag = true;
|
||||
bool columnDescriptionFlag = true;
|
||||
|
||||
const QColor errorColor = Qt::red;
|
||||
|
||||
auto ChangeColumnColor = [this, errorColor](QLabel *label, bool &columnFlag, KnownMeasurementsColumns column)
|
||||
{
|
||||
if (not ColumnValid(column))
|
||||
{
|
||||
ChangeColor(label, errorColor);
|
||||
columnFlag = false;
|
||||
}
|
||||
};
|
||||
|
||||
ChangeColumnColor(ui->labelName, columnNameFlag, KnownMeasurementsColumns::Name);
|
||||
ChangeColumnColor(ui->labelGroup, columnGroupFlag, KnownMeasurementsColumns::Group);
|
||||
ChangeColumnColor(ui->labelFullName, columnFullNameFlag, KnownMeasurementsColumns::FullName);
|
||||
ChangeColumnColor(ui->labelFormula, columnFormulaFlag, KnownMeasurementsColumns::Formula);
|
||||
ChangeColumnColor(ui->labelDescription, columnDescriptionFlag, KnownMeasurementsColumns::Description);
|
||||
|
||||
return columnNameFlag && columnGroupFlag && columnFullNameFlag && columnFormulaFlag && columnDescriptionFlag;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::ClearColumnCollor()
|
||||
{
|
||||
ChangeColor(ui->labelName, OkColor(this));
|
||||
ChangeColor(ui->labelGroup, OkColor(this));
|
||||
ChangeColor(ui->labelFullName, OkColor(this));
|
||||
ChangeColor(ui->labelFormula, OkColor(this));
|
||||
ChangeColor(ui->labelDescription, OkColor(this));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::InitColumnsMap()
|
||||
{
|
||||
QSharedPointer<QxtCsvModel> csv = DialogKnownMeasurementsCSVColumns::CSVModel();
|
||||
m_columnsMap.clear();
|
||||
|
||||
auto InitColumn = [this, csv](int column, int &index)
|
||||
{
|
||||
++index;
|
||||
if (ColumnMandatory(column))
|
||||
{
|
||||
m_columnsMap[column] = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_columnsMap[column] = csv->columnCount() >= index ? index : -1;
|
||||
}
|
||||
};
|
||||
|
||||
m_columnsMap.resize(static_cast<int>(KnownMeasurementsColumns::LAST_DO_NOT_USE));
|
||||
int index = -1;
|
||||
|
||||
for (int column = 0; column < static_cast<int>(KnownMeasurementsColumns::LAST_DO_NOT_USE); ++column)
|
||||
{
|
||||
InitColumn(column, index);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::InitColumnsControls()
|
||||
{
|
||||
const int inputColumnCount = CSVModel()->columnCount();
|
||||
|
||||
auto InitControl = [this, inputColumnCount](QComboBox *control, int column)
|
||||
{
|
||||
SCASSERT(control != nullptr)
|
||||
|
||||
int currentColumn = -2;
|
||||
int index = control->currentIndex();
|
||||
if (index != -1)
|
||||
{
|
||||
currentColumn = control->currentData().toInt();
|
||||
}
|
||||
|
||||
control->blockSignals(true);
|
||||
control->clear();
|
||||
|
||||
for (int i = 0; i < inputColumnCount; ++i)
|
||||
{
|
||||
control->addItem(QString::number(i + 1), i);
|
||||
}
|
||||
|
||||
if (not ColumnMandatory(column))
|
||||
{
|
||||
control->addItem(tr("Skip"), -1);
|
||||
}
|
||||
|
||||
control->setCurrentIndex(-1);
|
||||
|
||||
index = control->findData(currentColumn);
|
||||
if (index != -1)
|
||||
{
|
||||
control->setCurrentIndex(index);
|
||||
control->blockSignals(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
control->blockSignals(false);
|
||||
|
||||
if (not ColumnMandatory(column))
|
||||
{
|
||||
control->setCurrentIndex(control->findData(-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
control->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InitControl(ui->comboBoxName, static_cast<int>(KnownMeasurementsColumns::Name));
|
||||
InitControl(ui->comboBoxGroup, static_cast<int>(KnownMeasurementsColumns::Group));
|
||||
InitControl(ui->comboBoxFullName, static_cast<int>(KnownMeasurementsColumns::FullName));
|
||||
InitControl(ui->comboBoxFormula, static_cast<int>(KnownMeasurementsColumns::Formula));
|
||||
InitControl(ui->comboBoxDescription, static_cast<int>(KnownMeasurementsColumns::Description));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::InitImportHeaders()
|
||||
{
|
||||
if (m_fileName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int columns = ImportColumnCount();
|
||||
|
||||
ui->tableWidgetImport->clear();
|
||||
ui->tableWidgetImport->setColumnCount(columns);
|
||||
|
||||
auto AddHeader = [this](int column, bool visible = true)
|
||||
{
|
||||
auto *header = new QTableWidgetItem(ColumnHeader(column));
|
||||
ui->tableWidgetImport->setHorizontalHeaderItem(column, header);
|
||||
ui->tableWidgetImport->setColumnHidden(column, not visible);
|
||||
};
|
||||
|
||||
AddHeader(static_cast<int>(KnownMeasurementsColumns::Name));
|
||||
AddHeader(static_cast<int>(KnownMeasurementsColumns::Group));
|
||||
AddHeader(static_cast<int>(KnownMeasurementsColumns::FullName));
|
||||
AddHeader(static_cast<int>(KnownMeasurementsColumns::Formula));
|
||||
AddHeader(static_cast<int>(KnownMeasurementsColumns::Description));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QSharedPointer<QxtCsvModel> DialogKnownMeasurementsCSVColumns::CSVModel() const
|
||||
{
|
||||
return QSharedPointer<QxtCsvModel>::create(m_fileName, nullptr, m_withHeader, m_separator, m_codec);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::ShowInputPreview()
|
||||
{
|
||||
if (m_fileName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QSharedPointer<QxtCsvModel> csv = DialogKnownMeasurementsCSVColumns::CSVModel();
|
||||
|
||||
const int columns = csv->columnCount();
|
||||
const int rows = csv->rowCount();
|
||||
|
||||
ui->tableWidgetInput->clear();
|
||||
ui->tableWidgetInput->setColumnCount(columns);
|
||||
ui->tableWidgetInput->setRowCount(rows);
|
||||
|
||||
ui->tableWidgetInput->horizontalHeader()->setVisible(m_withHeader);
|
||||
if (m_withHeader)
|
||||
{
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
auto *header = new QTableWidgetItem(csv->headerText(column));
|
||||
header->setToolTip(QString::number(column + 1));
|
||||
ui->tableWidgetInput->setHorizontalHeaderItem(column, header);
|
||||
}
|
||||
}
|
||||
|
||||
for (int row = 0; row < rows; ++row)
|
||||
{
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
const QString text = csv->text(row, column);
|
||||
auto *item = new QTableWidgetItem(text);
|
||||
item->setToolTip(text);
|
||||
|
||||
// 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);
|
||||
|
||||
ui->tableWidgetInput->setItem(row, column, item);
|
||||
}
|
||||
}
|
||||
|
||||
ui->tableWidgetInput->resizeColumnsToContents();
|
||||
ui->tableWidgetInput->resizeRowsToContents();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::ShowImportPreview()
|
||||
{
|
||||
if (m_fileName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QSharedPointer<QxtCsvModel> csv = DialogKnownMeasurementsCSVColumns::CSVModel();
|
||||
|
||||
const int importColumns = ImportColumnCount();
|
||||
const int columns = csv->columnCount();
|
||||
const int rows = csv->rowCount();
|
||||
|
||||
ui->tableWidgetImport->clearContents();
|
||||
ui->tableWidgetImport->setRowCount(rows);
|
||||
|
||||
for (int row = 0; row < rows; ++row)
|
||||
{
|
||||
for (int column = 0; column < importColumns; ++column)
|
||||
{
|
||||
const int tableColumn = m_columnsMap.at(column);
|
||||
if (tableColumn >= 0 && tableColumn < columns)
|
||||
{
|
||||
const QString text = csv->text(row, tableColumn);
|
||||
auto *item = new QTableWidgetItem(text);
|
||||
item->setToolTip(text);
|
||||
|
||||
// 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);
|
||||
|
||||
ui->tableWidgetImport->setItem(row, column, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->tableWidgetImport->resizeColumnsToContents();
|
||||
ui->tableWidgetImport->resizeRowsToContents();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::RetranslateLabels()
|
||||
{
|
||||
ui->labelName->setText(tr("Name") + "*:"_L1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::SetDefaultColumns()
|
||||
{
|
||||
auto SetDefault = [this](QComboBox *control, int column)
|
||||
{
|
||||
SCASSERT(control != nullptr)
|
||||
|
||||
int index = control->findData(m_columnsMap.at(column));
|
||||
if (index != -1)
|
||||
{
|
||||
control->setCurrentIndex(index);
|
||||
}
|
||||
};
|
||||
|
||||
SetDefault(ui->comboBoxName, static_cast<int>(KnownMeasurementsColumns::Name));
|
||||
SetDefault(ui->comboBoxGroup, static_cast<int>(KnownMeasurementsColumns::Group));
|
||||
SetDefault(ui->comboBoxFullName, static_cast<int>(KnownMeasurementsColumns::FullName));
|
||||
SetDefault(ui->comboBoxFormula, static_cast<int>(KnownMeasurementsColumns::Formula));
|
||||
SetDefault(ui->comboBoxDescription, static_cast<int>(KnownMeasurementsColumns::Description));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogKnownMeasurementsCSVColumns::CheckStatus()
|
||||
{
|
||||
auto SetStatus = [this](bool status)
|
||||
{
|
||||
QPushButton *bOk = ui->buttonBox->button(QDialogButtonBox::Ok);
|
||||
// cppcheck-suppress unknownMacro
|
||||
SCASSERT(bOk != nullptr)
|
||||
bOk->setEnabled(status);
|
||||
};
|
||||
|
||||
if (m_fileName.isEmpty())
|
||||
{
|
||||
SetStatus(false);
|
||||
ui->labelStatus->setText(tr("File path is empty"));
|
||||
return;
|
||||
}
|
||||
|
||||
QSharedPointer<QxtCsvModel> csv = DialogKnownMeasurementsCSVColumns::CSVModel();
|
||||
|
||||
const int columns = csv->columnCount();
|
||||
if (columns < MinimumColumns())
|
||||
{
|
||||
SetStatus(false);
|
||||
ui->labelStatus->setText(tr("Not enough columns"));
|
||||
return;
|
||||
}
|
||||
|
||||
const int rows = csv->rowCount();
|
||||
if (rows < 1)
|
||||
{
|
||||
SetStatus(false);
|
||||
ui->labelStatus->setText(tr("Not enough data to import"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (not ColumnsValid())
|
||||
{
|
||||
SetStatus(false);
|
||||
ui->labelStatus->setText(tr("Please, select unique number for each column"));
|
||||
return;
|
||||
}
|
||||
|
||||
SetStatus(true);
|
||||
ui->labelStatus->setText(tr("Ready"));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template <class T> bool DialogKnownMeasurementsCSVColumns::ColumnValid(T column) const
|
||||
{
|
||||
const int columnNumber = static_cast<int>(column);
|
||||
int value = m_columnsMap.at(columnNumber);
|
||||
|
||||
if (value == -1 && not ColumnMandatory(columnNumber))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int c = 0; c < m_columnsMap.size(); ++c)
|
||||
{
|
||||
if (c == columnNumber)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value == m_columnsMap.at(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template <class T> void DialogKnownMeasurementsCSVColumns::SaveColum(QComboBox *control, T column)
|
||||
{
|
||||
SCASSERT(control != nullptr)
|
||||
|
||||
const int columnNumber = static_cast<int>(column);
|
||||
m_columnsMap[columnNumber] = control->currentData().toInt();
|
||||
ShowImportPreview();
|
||||
CheckStatus();
|
||||
}
|
138
src/app/tape/dialogs/dialogknownmeasurementscsvcolumns.h
Normal file
138
src/app/tape/dialogs/dialogknownmeasurementscsvcolumns.h
Normal file
|
@ -0,0 +1,138 @@
|
|||
/************************************************************************
|
||||
**
|
||||
** @file dialogknownmeasurementscsvcolumns.h
|
||||
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||
** @date 7 11, 2023
|
||||
**
|
||||
** @brief
|
||||
** @copyright
|
||||
** This source code is part of the Valentina project, a pattern making
|
||||
** program, whose allow create and modeling patterns of clothing.
|
||||
** Copyright (C) 2023 Valentina project
|
||||
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||
**
|
||||
** Valentina is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Valentina is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*************************************************************************/
|
||||
#ifndef DIALOGKNOWNMEASUREMENTSCSVCOLUMNS_H
|
||||
#define DIALOGKNOWNMEASUREMENTSCSVCOLUMNS_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QxtCsvModel;
|
||||
class QComboBox;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
class VTextCodec;
|
||||
#endif
|
||||
|
||||
enum class KnownMeasurementsColumns : qint8
|
||||
{
|
||||
Name = 0,
|
||||
Group = 1, // optional
|
||||
FullName = 2, // optional
|
||||
Formula = 3, // optional
|
||||
Description = 4, // optional
|
||||
LAST_DO_NOT_USE = 5
|
||||
};
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class DialogKnownMeasurementsCSVColumns;
|
||||
}
|
||||
|
||||
class DialogKnownMeasurementsCSVColumns : public QDialog
|
||||
{
|
||||
Q_OBJECT // NOLINT
|
||||
|
||||
public:
|
||||
explicit DialogKnownMeasurementsCSVColumns(const QString &filename, QWidget *parent = nullptr);
|
||||
~DialogKnownMeasurementsCSVColumns() override;
|
||||
|
||||
auto ColumnsMap() const -> QVector<int>;
|
||||
|
||||
void SetWithHeader(bool withHeader);
|
||||
void SetSeparator(const QChar &separator);
|
||||
void SetCodec(VTextCodec *codec);
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *event) override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void ColumnChanged();
|
||||
|
||||
private:
|
||||
// cppcheck-suppress unknownMacro
|
||||
Q_DISABLE_COPY_MOVE(DialogKnownMeasurementsCSVColumns) // NOLINT
|
||||
Ui::DialogKnownMeasurementsCSVColumns *ui;
|
||||
bool m_isInitialized{false};
|
||||
QString m_fileName;
|
||||
bool m_withHeader{false};
|
||||
QChar m_separator{','};
|
||||
VTextCodec *m_codec{nullptr};
|
||||
QVector<int> m_columnsMap{};
|
||||
|
||||
auto ColumnMandatory(int column) const -> bool;
|
||||
auto ColumnHeader(int column) const -> QString;
|
||||
auto ImportColumnCount() const -> int;
|
||||
auto MinimumColumns() const -> int;
|
||||
auto ColumnsValid() -> bool;
|
||||
void ClearColumnCollor();
|
||||
|
||||
void InitColumnsMap();
|
||||
void InitColumnsControls();
|
||||
void InitImportHeaders();
|
||||
|
||||
auto CSVModel() const -> QSharedPointer<QxtCsvModel>;
|
||||
|
||||
void ShowInputPreview();
|
||||
void ShowImportPreview();
|
||||
|
||||
void RetranslateLabels();
|
||||
|
||||
void SetDefaultColumns();
|
||||
|
||||
void CheckStatus();
|
||||
|
||||
template <class T> auto ColumnValid(T column) const -> bool;
|
||||
|
||||
template <class T> void SaveColum(QComboBox *control, T column);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline auto DialogKnownMeasurementsCSVColumns::ColumnsMap() const -> QVector<int>
|
||||
{
|
||||
return m_columnsMap;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline void DialogKnownMeasurementsCSVColumns::SetWithHeader(bool withHeader)
|
||||
{
|
||||
m_withHeader = withHeader;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline void DialogKnownMeasurementsCSVColumns::SetSeparator(const QChar &separator)
|
||||
{
|
||||
m_separator = separator;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline void DialogKnownMeasurementsCSVColumns::SetCodec(VTextCodec *codec)
|
||||
{
|
||||
m_codec = codec;
|
||||
}
|
||||
|
||||
#endif // DIALOGKNOWNMEASUREMENTSCSVCOLUMNS_H
|
187
src/app/tape/dialogs/dialogknownmeasurementscsvcolumns.ui
Normal file
187
src/app/tape/dialogs/dialogknownmeasurementscsvcolumns.ui
Normal file
|
@ -0,0 +1,187 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DialogKnownMeasurementsCSVColumns</class>
|
||||
<widget class="QDialog" name="DialogKnownMeasurementsCSVColumns">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1036</width>
|
||||
<height>713</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Preview</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Input</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidgetInput">
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Import</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidgetImport">
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Columns</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string notr="true">Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxName"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelGroup">
|
||||
<property name="text">
|
||||
<string notr="true">Group:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxGroup"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelFullName">
|
||||
<property name="text">
|
||||
<string>Full name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxFullName"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelFormula">
|
||||
<property name="text">
|
||||
<string notr="true">Formula:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="comboBoxFormula"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelDescription">
|
||||
<property name="text">
|
||||
<string>Description:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="comboBoxDescription"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelStatus">
|
||||
<property name="text">
|
||||
<string>Ready</string>
|
||||
</property>
|
||||
</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/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DialogKnownMeasurementsCSVColumns</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DialogKnownMeasurementsCSVColumns</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -37,10 +37,16 @@
|
|||
#include <QPushButton>
|
||||
#include <QShowEvent>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
|
||||
#include "../vmisc/compatibility.h"
|
||||
#endif
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogMeasurementsCSVColumns::DialogMeasurementsCSVColumns(const QString &filename, MeasurementsType type,
|
||||
QWidget *parent) :
|
||||
QDialog(parent),
|
||||
QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::DialogMeasurementsCSVColumns),
|
||||
m_fileName{filename},
|
||||
m_type(type)
|
||||
|
@ -53,8 +59,8 @@ DialogMeasurementsCSVColumns::DialogMeasurementsCSVColumns(const QString &filena
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
DialogMeasurementsCSVColumns::DialogMeasurementsCSVColumns(const QString &filename, MeasurementsType type,
|
||||
const QList<MeasurementDimension_p> &dimensions,
|
||||
QWidget *parent) :
|
||||
QDialog(parent),
|
||||
QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui(new Ui::DialogMeasurementsCSVColumns),
|
||||
m_fileName{filename},
|
||||
m_type(type),
|
||||
|
@ -94,8 +100,8 @@ void DialogMeasurementsCSVColumns::changeEvent(QEvent *event)
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogMeasurementsCSVColumns::showEvent(QShowEvent *event)
|
||||
{
|
||||
QDialog::showEvent( event );
|
||||
if ( event->spontaneous() )
|
||||
QDialog::showEvent(event);
|
||||
if (event->spontaneous())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -116,48 +122,47 @@ void DialogMeasurementsCSVColumns::showEvent(QShowEvent *event)
|
|||
InitImportHeaders();
|
||||
ShowImportPreview();
|
||||
|
||||
connect(ui->comboBoxName, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxValue, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxName, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxValue, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
|
||||
if (m_type == MeasurementsType::Multisize)
|
||||
{
|
||||
if (not m_dimensions.empty())
|
||||
{
|
||||
connect(ui->comboBoxShiftA, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxShiftA, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
}
|
||||
|
||||
if (m_dimensions.size() > 1)
|
||||
{
|
||||
connect(ui->comboBoxShiftB, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxShiftB, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
}
|
||||
|
||||
if (m_dimensions.size() > 2)
|
||||
{
|
||||
connect(ui->comboBoxShiftC, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxShiftC, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
connect(ui->comboBoxFullName, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxDescription, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxFullName, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
connect(ui->comboBoxDescription, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DialogMeasurementsCSVColumns::ColumnChanged);
|
||||
|
||||
CheckStatus();
|
||||
}
|
||||
|
||||
m_isInitialized = true;//first show windows are held
|
||||
m_isInitialized = true; // first show windows are held
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogMeasurementsCSVColumns::ColumnChanged()
|
||||
{
|
||||
auto *control = qobject_cast<QComboBox*>(sender());
|
||||
auto *control = qobject_cast<QComboBox *>(sender());
|
||||
|
||||
if (control == ui->comboBoxName)
|
||||
{
|
||||
|
@ -229,7 +234,7 @@ auto DialogMeasurementsCSVColumns::ColumnHeader(int column) const -> QString
|
|||
if (m_type == MeasurementsType::Individual)
|
||||
{
|
||||
const auto individualColumn = static_cast<IndividualMeasurementsColumns>(column);
|
||||
switch(individualColumn)
|
||||
switch (individualColumn)
|
||||
{
|
||||
case IndividualMeasurementsColumns::Name:
|
||||
return tr("Name", "measurement column");
|
||||
|
@ -245,8 +250,9 @@ auto DialogMeasurementsCSVColumns::ColumnHeader(int column) const -> QString
|
|||
}
|
||||
else
|
||||
{
|
||||
const QString suffix = QStringLiteral(" (%1):");
|
||||
const auto multisizeColumn = static_cast<MultisizeMeasurementsColumns>(column);
|
||||
switch(multisizeColumn)
|
||||
switch (multisizeColumn)
|
||||
{
|
||||
case MultisizeMeasurementsColumns::Name:
|
||||
return tr("Name", "measurement column");
|
||||
|
@ -256,7 +262,7 @@ auto DialogMeasurementsCSVColumns::ColumnHeader(int column) const -> QString
|
|||
if (not m_dimensions.empty())
|
||||
{
|
||||
MeasurementDimension_p dimension = m_dimensions.at(0);
|
||||
return tr("Shift (%1):", "measurement column").arg(dimension->Name());
|
||||
return tr("Shift", "measurement column") + suffix.arg(dimension->Name());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -266,7 +272,7 @@ auto DialogMeasurementsCSVColumns::ColumnHeader(int column) const -> QString
|
|||
if (m_dimensions.size() > 1)
|
||||
{
|
||||
MeasurementDimension_p dimension = m_dimensions.at(1);
|
||||
return tr("Shift (%1):", "measurement column").arg(dimension->Name());
|
||||
return tr("Shift", "measurement column") + suffix.arg(dimension->Name());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -276,7 +282,7 @@ auto DialogMeasurementsCSVColumns::ColumnHeader(int column) const -> QString
|
|||
if (m_dimensions.size() > 2)
|
||||
{
|
||||
MeasurementDimension_p dimension = m_dimensions.at(2);
|
||||
return tr("Shift (%1):", "measurement column").arg(dimension->Name());
|
||||
return tr("Shift", "measurement column") + suffix.arg(dimension->Name());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -287,7 +293,7 @@ auto DialogMeasurementsCSVColumns::ColumnHeader(int column) const -> QString
|
|||
case MultisizeMeasurementsColumns::Description:
|
||||
return tr("Description", "measurement column");
|
||||
default:
|
||||
return {};
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,9 +342,9 @@ auto DialogMeasurementsCSVColumns::ColumnsValid() -> bool
|
|||
|
||||
const QColor errorColor = Qt::red;
|
||||
|
||||
auto ChangeColumnColor = [this, errorColor]
|
||||
(QLabel *label, bool &columnFlag, MultisizeMeasurementsColumns multisizeColumn,
|
||||
IndividualMeasurementsColumns individualColumn)
|
||||
auto ChangeColumnColor = [this, errorColor](QLabel *label, bool &columnFlag,
|
||||
MultisizeMeasurementsColumns multisizeColumn,
|
||||
IndividualMeasurementsColumns individualColumn)
|
||||
{
|
||||
if (m_type == MeasurementsType::Multisize ? not ColumnValid(multisizeColumn)
|
||||
: not ColumnValid(individualColumn))
|
||||
|
@ -424,7 +430,7 @@ void DialogMeasurementsCSVColumns::InitColumnsMap()
|
|||
QSharedPointer<QxtCsvModel> csv = DialogMeasurementsCSVColumns::CSVModel();
|
||||
m_columnsMap.clear();
|
||||
|
||||
auto InitColumn = [this, csv](int column, int &index, bool forceSkip=false)
|
||||
auto InitColumn = [this, csv](int column, int &index, bool forceSkip = false)
|
||||
{
|
||||
if (forceSkip)
|
||||
{
|
||||
|
@ -449,7 +455,7 @@ void DialogMeasurementsCSVColumns::InitColumnsMap()
|
|||
m_columnsMap.resize(static_cast<int>(IndividualMeasurementsColumns::LAST_DO_NOT_USE));
|
||||
int index = -1;
|
||||
|
||||
for(int column = 0; column < static_cast<int>(IndividualMeasurementsColumns::LAST_DO_NOT_USE); ++column)
|
||||
for (int column = 0; column < static_cast<int>(IndividualMeasurementsColumns::LAST_DO_NOT_USE); ++column)
|
||||
{
|
||||
InitColumn(column, index);
|
||||
}
|
||||
|
@ -488,9 +494,9 @@ void DialogMeasurementsCSVColumns::InitColumnsControls()
|
|||
control->blockSignals(true);
|
||||
control->clear();
|
||||
|
||||
for(int i=0; i < inputColumnCount; ++i)
|
||||
for (int i = 0; i < inputColumnCount; ++i)
|
||||
{
|
||||
control->addItem(QString::number(i+1), i);
|
||||
control->addItem(QString::number(i + 1), i);
|
||||
}
|
||||
|
||||
if (not ColumnMandatory(column))
|
||||
|
@ -566,7 +572,7 @@ void DialogMeasurementsCSVColumns::InitImportHeaders()
|
|||
ui->tableWidgetImport->clear();
|
||||
ui->tableWidgetImport->setColumnCount(columns);
|
||||
|
||||
auto AddHeader = [this](int column, bool visible=true)
|
||||
auto AddHeader = [this](int column, bool visible = true)
|
||||
{
|
||||
auto *header = new QTableWidgetItem(ColumnHeader(column));
|
||||
ui->tableWidgetImport->setHorizontalHeaderItem(column, header);
|
||||
|
@ -618,17 +624,17 @@ void DialogMeasurementsCSVColumns::ShowInputPreview()
|
|||
ui->tableWidgetInput->horizontalHeader()->setVisible(m_withHeader);
|
||||
if (m_withHeader)
|
||||
{
|
||||
for(int column=0; column<columns; ++column)
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
auto *header = new QTableWidgetItem(csv->headerText(column));
|
||||
header->setToolTip(QString::number(column+1));
|
||||
header->setToolTip(QString::number(column + 1));
|
||||
ui->tableWidgetInput->setHorizontalHeaderItem(column, header);
|
||||
}
|
||||
}
|
||||
|
||||
for (int row=0; row < rows; ++row)
|
||||
for (int row = 0; row < rows; ++row)
|
||||
{
|
||||
for(int column=0; column<columns; ++column)
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
const QString text = csv->text(row, column);
|
||||
auto *item = new QTableWidgetItem(text);
|
||||
|
@ -664,9 +670,9 @@ void DialogMeasurementsCSVColumns::ShowImportPreview()
|
|||
ui->tableWidgetImport->clearContents();
|
||||
ui->tableWidgetImport->setRowCount(rows);
|
||||
|
||||
for (int row=0; row < rows; ++row)
|
||||
for (int row = 0; row < rows; ++row)
|
||||
{
|
||||
for(int column=0; column < importColumns; ++column)
|
||||
for (int column = 0; column < importColumns; ++column)
|
||||
{
|
||||
const int tableColumn = m_columnsMap.at(column);
|
||||
if (tableColumn >= 0 && tableColumn < columns)
|
||||
|
@ -721,32 +727,34 @@ void DialogMeasurementsCSVColumns::HackColumnControls()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void DialogMeasurementsCSVColumns::RetranslateLabels()
|
||||
{
|
||||
ui->labelName->setText(tr("Name") + "*:");
|
||||
ui->labelName->setText(tr("Name", "measurement column") + "*:"_L1);
|
||||
|
||||
if (m_type == MeasurementsType::Individual)
|
||||
{
|
||||
ui->labelValue->setText(tr("Value") + "*:");
|
||||
ui->labelValue->setText(tr("Value", "measurement column") + "*:"_L1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->labelValue->setText(tr("Base value") + "*:");
|
||||
ui->labelValue->setText(tr("Base value", "measurement column") + "*:"_L1);
|
||||
|
||||
const QString suffix = QStringLiteral(" (%1)");
|
||||
|
||||
if (not m_dimensions.empty())
|
||||
{
|
||||
MeasurementDimension_p dimension = m_dimensions.at(0);
|
||||
ui->labelShiftA->setText(tr("Shift (%1)*:").arg(dimension->Name()));
|
||||
ui->labelShiftA->setText(tr("Shift", "measurement column") + suffix.arg(dimension->Name()));
|
||||
}
|
||||
|
||||
if (m_dimensions.size() > 1)
|
||||
{
|
||||
MeasurementDimension_p dimension = m_dimensions.at(1);
|
||||
ui->labelShiftB->setText(tr("Shift (%1)*:").arg(dimension->Name()));
|
||||
ui->labelShiftB->setText(tr("Shift", "measurement column") + suffix.arg(dimension->Name()));
|
||||
}
|
||||
|
||||
if (m_dimensions.size() > 2)
|
||||
{
|
||||
MeasurementDimension_p dimension = m_dimensions.at(2);
|
||||
ui->labelShiftC->setText(tr("Shift (%1)*:").arg(dimension->Name()));
|
||||
ui->labelShiftC->setText(tr("Shift", "measurement column") + suffix.arg(dimension->Name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -845,8 +853,7 @@ void DialogMeasurementsCSVColumns::CheckStatus()
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void DialogMeasurementsCSVColumns::HackWidget(T **widget)
|
||||
template <class T> void DialogMeasurementsCSVColumns::HackWidget(T **widget)
|
||||
{
|
||||
delete *widget;
|
||||
*widget = new T();
|
||||
|
@ -854,8 +861,7 @@ void DialogMeasurementsCSVColumns::HackWidget(T **widget)
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class T>
|
||||
auto DialogMeasurementsCSVColumns::ColumnValid(T column) const -> bool
|
||||
template <class T> auto DialogMeasurementsCSVColumns::ColumnValid(T column) const -> bool
|
||||
{
|
||||
const int columnNumber = static_cast<int>(column);
|
||||
int value = m_columnsMap.at(columnNumber);
|
||||
|
@ -865,7 +871,7 @@ auto DialogMeasurementsCSVColumns::ColumnValid(T column) const -> bool
|
|||
return true;
|
||||
}
|
||||
|
||||
for (int c=0; c < m_columnsMap.size(); ++c)
|
||||
for (int c = 0; c < m_columnsMap.size(); ++c)
|
||||
{
|
||||
if (c == columnNumber)
|
||||
{
|
||||
|
@ -882,8 +888,7 @@ auto DialogMeasurementsCSVColumns::ColumnValid(T column) const -> bool
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void DialogMeasurementsCSVColumns::SaveColum(QComboBox *control, T column)
|
||||
template <class T> void DialogMeasurementsCSVColumns::SaveColum(QComboBox *control, T column)
|
||||
{
|
||||
SCASSERT(control != nullptr)
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ SOURCES += \
|
|||
$$PWD/vtapesettings.cpp \
|
||||
$$PWD/dialogs/dialogsetupmultisize.cpp \
|
||||
$$PWD/vtapeshortcutmanager.cpp \
|
||||
$$PWD/tkmmainwindow.cpp
|
||||
$$PWD/tkmmainwindow.cpp \
|
||||
$$PWD/dialogs/dialogknownmeasurementscsvcolumns.cpp
|
||||
|
||||
*msvc*:SOURCES += $$PWD/stable.cpp
|
||||
|
||||
|
@ -42,7 +43,8 @@ HEADERS += \
|
|||
$$PWD/vtapesettings.h \
|
||||
$$PWD/dialogs/dialogsetupmultisize.h \
|
||||
$$PWD/vtapeshortcutmanager.h \
|
||||
$$PWD/tkmmainwindow.h
|
||||
$$PWD/tkmmainwindow.h \
|
||||
$$PWD/dialogs/dialogknownmeasurementscsvcolumns.h
|
||||
|
||||
FORMS += \
|
||||
$$PWD/dialogs/dialogdimensioncustomnames.ui \
|
||||
|
@ -57,5 +59,6 @@ FORMS += \
|
|||
$$PWD/dialogs/configpages/tapepreferencesconfigurationpage.ui \
|
||||
$$PWD/dialogs/configpages/tapepreferencespathpage.ui \
|
||||
$$PWD/dialogs/dialogsetupmultisize.ui \
|
||||
$$PWD/tkmmainwindow.ui
|
||||
$$PWD/tkmmainwindow.ui \
|
||||
$$PWD/dialogs/dialogknownmeasurementscsvcolumns.ui
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ VToolApp {
|
|||
"configpages/tapepreferencespathpage.ui",
|
||||
"dialogdimensioncustomnames.cpp",
|
||||
"dialogdimensionlabels.cpp",
|
||||
"dialogknownmeasurementscsvcolumns.cpp",
|
||||
"dialogknownmeasurementscsvcolumns.h",
|
||||
"dialogknownmeasurementscsvcolumns.ui",
|
||||
"dialogmeasurementscsvcolumns.cpp",
|
||||
"dialogrestrictdimension.cpp",
|
||||
"dialogabouttape.cpp",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "../vmisc/theme/vtheme.h"
|
||||
#include "../vmisc/vsysexits.h"
|
||||
#include "dialogs/dialogabouttape.h"
|
||||
#include "dialogs/dialogknownmeasurementscsvcolumns.h"
|
||||
#include "knownmeasurements/vknownmeasurements.h"
|
||||
#include "mapplication.h" // Should be last because of definning qApp
|
||||
#include "quuid.h"
|
||||
|
@ -468,54 +469,35 @@ auto TKMMainWindow::eventFilter(QObject *object, QEvent *event) -> bool
|
|||
void TKMMainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)
|
||||
{
|
||||
QxtCsvModel csv;
|
||||
const int columns = ui->tableWidget->columnCount();
|
||||
|
||||
int columns = 5;
|
||||
int colCount = 0;
|
||||
for (int column = 0; column <= columns; ++column)
|
||||
{
|
||||
int colCount = 0;
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
if (not ui->tableWidget->isColumnHidden(column))
|
||||
{
|
||||
csv.insertColumn(colCount++);
|
||||
}
|
||||
}
|
||||
csv.insertColumn(colCount++);
|
||||
}
|
||||
|
||||
if (withHeader)
|
||||
{
|
||||
int colCount = 0;
|
||||
for (int column = 0; column < columns; ++column)
|
||||
for (int column = 0; column <= columns; ++column)
|
||||
{
|
||||
if (not ui->tableWidget->isColumnHidden(column))
|
||||
{
|
||||
QString text;
|
||||
if (QTableWidgetItem *header = ui->tableWidget->horizontalHeaderItem(column))
|
||||
{
|
||||
text = header->text();
|
||||
}
|
||||
csv.setHeaderText(colCount, text);
|
||||
++colCount;
|
||||
}
|
||||
csv.setHeaderText(column, CSVColumnHeader(column));
|
||||
}
|
||||
}
|
||||
|
||||
const int rows = ui->tableWidget->rowCount();
|
||||
for (int row = 0; row < rows; ++row)
|
||||
const QMap<int, VKnownMeasurement> orderedTable = m_known.OrderedMeasurments();
|
||||
int row = 0;
|
||||
for (auto iMap = orderedTable.constBegin(); iMap != orderedTable.constEnd(); ++iMap)
|
||||
{
|
||||
const VKnownMeasurement &m = iMap.value();
|
||||
|
||||
csv.insertRow(row);
|
||||
int colCount = 0;
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
if (not ui->tableWidget->isColumnHidden(column))
|
||||
{
|
||||
QString text;
|
||||
if (QTableWidgetItem *item = ui->tableWidget->item(row, column))
|
||||
{
|
||||
text = item->text();
|
||||
}
|
||||
csv.setText(row, colCount, text);
|
||||
++colCount;
|
||||
}
|
||||
}
|
||||
csv.setText(row, 0, m.name);
|
||||
csv.setText(row, 1, m.fullName);
|
||||
csv.setText(row, 2, m.group);
|
||||
csv.setText(row, 3, m.formula);
|
||||
csv.setText(row, 4, m.description);
|
||||
++row;
|
||||
}
|
||||
|
||||
QString error;
|
||||
|
@ -729,6 +711,53 @@ void TKMMainWindow::ShowWindow() const
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TKMMainWindow::ImportDataFromCSV()
|
||||
{
|
||||
if (m_m == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const QString filters = tr("Comma-Separated Values") + QStringLiteral(" (*.csv)");
|
||||
const QString suffix = QStringLiteral("csv");
|
||||
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Import from CSV"), QDir::homePath(), filters, nullptr,
|
||||
VAbstractApplication::VApp()->NativeFileDialog());
|
||||
|
||||
if (fileName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo f(fileName);
|
||||
if (f.suffix().isEmpty() && f.suffix() != suffix)
|
||||
{
|
||||
fileName += '.'_L1 + suffix;
|
||||
}
|
||||
|
||||
DialogExportToCSV dialog(this);
|
||||
dialog.SetWithHeader(VAbstractApplication::VApp()->Settings()->GetCSVWithHeader());
|
||||
dialog.SetSelectedMib(VAbstractApplication::VApp()->Settings()->GetCSVCodec());
|
||||
dialog.SetSeparator(VAbstractApplication::VApp()->Settings()->GetCSVSeparator());
|
||||
dialog.ShowFilePreview(fileName);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
VAbstractApplication::VApp()->Settings()->SetCSVSeparator(dialog.GetSeparator());
|
||||
VAbstractApplication::VApp()->Settings()->SetCSVCodec(dialog.GetSelectedMib());
|
||||
VAbstractApplication::VApp()->Settings()->SetCSVWithHeader(dialog.IsWithHeader());
|
||||
|
||||
auto columns = QSharedPointer<DialogKnownMeasurementsCSVColumns>::create(fileName, this);
|
||||
columns->SetWithHeader(dialog.IsWithHeader());
|
||||
columns->SetSeparator(dialog.GetSeparator());
|
||||
columns->SetCodec(VTextCodec::codecForMib(dialog.GetSelectedMib()));
|
||||
|
||||
if (columns->exec() == QDialog::Accepted)
|
||||
{
|
||||
QxtCsvModel csv(fileName, nullptr, dialog.IsWithHeader(), dialog.GetSeparator(),
|
||||
VTextCodec::codecForMib(dialog.GetSelectedMib()));
|
||||
const QVector<int> map = columns->ColumnsMap();
|
||||
ImportKnownMeasurements(csv, map, dialog.IsWithHeader());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -2429,3 +2458,184 @@ void TKMMainWindow::InitMeasurementDiagramList()
|
|||
ui->comboBoxDiagram->addItem(title, i.key());
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TKMMainWindow::ShowError(const QString &text)
|
||||
{
|
||||
QMessageBox messageBox(this);
|
||||
messageBox.setIcon(QMessageBox::Critical);
|
||||
messageBox.setText(text);
|
||||
messageBox.setStandardButtons(QMessageBox::Ok);
|
||||
messageBox.setDefaultButton(QMessageBox::Ok);
|
||||
messageBox.exec();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TKMMainWindow::RefreshDataAfterImport()
|
||||
{
|
||||
const int currentRow = ui->tableWidget->currentRow();
|
||||
m_search->AddRow(currentRow);
|
||||
m_known = VKnownMeasurements();
|
||||
RefreshTable();
|
||||
m_search->RefreshList(ui->lineEditFind->text());
|
||||
ui->tableWidget->selectRow(currentRow);
|
||||
ui->actionExportToCSV->setEnabled(ui->tableWidget->rowCount() > 0);
|
||||
MeasurementsWereSaved(false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto TKMMainWindow::CheckMName(const QString &name, const QSet<QString> &importedNames) const -> QString
|
||||
{
|
||||
if (name.isEmpty())
|
||||
{
|
||||
throw VException(tr("Measurement name is empty."));
|
||||
}
|
||||
|
||||
if (importedNames.contains(name))
|
||||
{
|
||||
throw VException(tr("Imported file must not contain the same name twice."));
|
||||
}
|
||||
|
||||
QRegularExpression rx(NameRegExp(VariableRegex::KnownMeasurement));
|
||||
if (not rx.match(name).hasMatch())
|
||||
{
|
||||
throw VException(tr("Measurement '%1' doesn't match regex pattern.").arg(name));
|
||||
}
|
||||
|
||||
if (m_known.Measurments().contains(name))
|
||||
{
|
||||
throw VException(tr("Measurement '%1' already used in the file.").arg(name));
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto TKMMainWindow::CSVColumnHeader(int column) const -> QString
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0: // name
|
||||
return tr("Name", "measurement column");
|
||||
case 1: // full name
|
||||
return tr("Full name", "measurement column");
|
||||
case 2: // group
|
||||
return tr("Group", "measurement column");
|
||||
case 3: // formula
|
||||
return tr("Formula", "measurement column");
|
||||
case 4: // description
|
||||
return tr("Description", "measurement column");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto TKMMainWindow::ReadCSV(const QxtCsvModel &csv, const QVector<int> &map, bool withHeader)
|
||||
-> QVector<VKnownMeasurement>
|
||||
{
|
||||
QVector<VKnownMeasurement> measurements;
|
||||
QSet<QString> importedNames;
|
||||
|
||||
const int rows = csv.rowCount();
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
const int nameColumn = map.at(static_cast<int>(KnownMeasurementsColumns::Name));
|
||||
const QString name = csv.text(i, nameColumn).simplified();
|
||||
if (name.isEmpty())
|
||||
{
|
||||
ShowError(tr("Error in row %1. The measurement name is empty.").arg(i));
|
||||
continue;
|
||||
}
|
||||
|
||||
VKnownMeasurement measurement;
|
||||
const QString mName = CheckMName(name, importedNames);
|
||||
importedNames.insert(mName);
|
||||
measurement.name = mName;
|
||||
|
||||
const int nameGroup = map.at(static_cast<int>(KnownMeasurementsColumns::Group));
|
||||
if (nameGroup >= 0)
|
||||
{
|
||||
measurement.group = csv.text(i, nameGroup).simplified();
|
||||
}
|
||||
|
||||
const int nameFullName = map.at(static_cast<int>(KnownMeasurementsColumns::FullName));
|
||||
if (nameFullName >= 0)
|
||||
{
|
||||
measurement.fullName = csv.text(i, nameFullName);
|
||||
}
|
||||
|
||||
const int nameFormula = map.at(static_cast<int>(KnownMeasurementsColumns::Formula));
|
||||
if (nameFormula >= 0)
|
||||
{
|
||||
measurement.formula = csv.text(i, nameFormula);
|
||||
}
|
||||
|
||||
const int nameDescription = map.at(static_cast<int>(KnownMeasurementsColumns::Description));
|
||||
if (nameDescription >= 0)
|
||||
{
|
||||
measurement.description = csv.text(i, nameDescription);
|
||||
}
|
||||
|
||||
measurements.append(measurement);
|
||||
}
|
||||
catch (VException &e)
|
||||
{
|
||||
int rowIndex = i + 1;
|
||||
if (withHeader)
|
||||
{
|
||||
++rowIndex;
|
||||
}
|
||||
ShowError(tr("Error in row %1. %2").arg(rowIndex).arg(e.ErrorMessage()));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return measurements;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TKMMainWindow::ImportKnownMeasurements(const QxtCsvModel &csv, const QVector<int> &map, bool withHeader)
|
||||
{
|
||||
if (csv.columnCount() < 2)
|
||||
{
|
||||
ShowError(tr("Individual measurements require at least 2 columns."));
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<VKnownMeasurement> measurements = ReadCSV(csv, map, withHeader);
|
||||
if (measurements.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto &im : qAsConst(measurements))
|
||||
{
|
||||
m_m->AddEmptyMeasurement(im.name);
|
||||
|
||||
if (not im.group.isEmpty())
|
||||
{
|
||||
m_m->SetMGroup(im.name, im.group);
|
||||
}
|
||||
|
||||
if (not im.fullName.isEmpty())
|
||||
{
|
||||
m_m->SetMFullName(im.name, im.fullName);
|
||||
}
|
||||
|
||||
if (not im.formula.isEmpty())
|
||||
{
|
||||
m_m->SetMFormula(im.name, im.formula);
|
||||
}
|
||||
|
||||
if (not im.description.isEmpty())
|
||||
{
|
||||
m_m->SetMDescription(im.name, im.description);
|
||||
}
|
||||
}
|
||||
|
||||
RefreshDataAfterImport();
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class TKMMainWindow;
|
|||
class VKnownMeasurementsDocument;
|
||||
class VPatternImage;
|
||||
class QCompleter;
|
||||
class QxtCsvModel;
|
||||
|
||||
class TKMMainWindow : public VAbstractMainWindow
|
||||
{
|
||||
|
@ -181,6 +182,14 @@ private:
|
|||
|
||||
void InitMeasurementUnits();
|
||||
void InitMeasurementDiagramList();
|
||||
|
||||
void ShowError(const QString &text);
|
||||
void RefreshDataAfterImport();
|
||||
auto CheckMName(const QString &name, const QSet<QString> &importedNames) const -> QString;
|
||||
|
||||
auto CSVColumnHeader(int column) const -> QString;
|
||||
auto ReadCSV(const QxtCsvModel &csv, const QVector<int> &map, bool withHeader) -> QVector<VKnownMeasurement>;
|
||||
void ImportKnownMeasurements(const QxtCsvModel &csv, const QVector<int> &map, bool withHeader);
|
||||
};
|
||||
|
||||
#endif // TKMMAINWINDOW_H
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabMeasurements">
|
||||
<attribute name="icon">
|
||||
|
@ -947,6 +947,8 @@
|
|||
<addaction name="separator"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="actionSaveAs"/>
|
||||
<addaction name="actionExportToCSV"/>
|
||||
<addaction name="actionImportFromCSV"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionReadOnly"/>
|
||||
<addaction name="separator"/>
|
||||
|
|
|
@ -38,9 +38,12 @@
|
|||
#include "../vformat/knownmeasurements/vknownmeasurementsdatabase.h"
|
||||
#include "../vganalytics/vganalytics.h"
|
||||
#include "../vmisc/compatibility.h"
|
||||
#include "../vmisc/def.h"
|
||||
#include "../vmisc/defglobal.h"
|
||||
#include "../vmisc/dialogs/dialogaskcollectstatistic.h"
|
||||
#include "../vmisc/dialogs/dialogexporttocsv.h"
|
||||
#include "../vmisc/dialogs/dialogselectlanguage.h"
|
||||
#include "../vmisc/literals.h"
|
||||
#include "../vmisc/qxtcsvmodel.h"
|
||||
#include "../vmisc/theme/vtheme.h"
|
||||
#include "../vmisc/vsysexits.h"
|
||||
|
@ -49,7 +52,6 @@
|
|||
#include "../vpatterndb/vcontainer.h"
|
||||
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
|
||||
#include "../vwidgets/vaspectratiopixmaplabel.h"
|
||||
#include "def.h"
|
||||
#include "dialogs/dialogabouttape.h"
|
||||
#include "dialogs/dialogdimensioncustomnames.h"
|
||||
#include "dialogs/dialogdimensionlabels.h"
|
||||
|
@ -134,10 +136,11 @@ struct IndividualMeasurement
|
|||
{
|
||||
IndividualMeasurement() = default;
|
||||
|
||||
QString name{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString value{'0'}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString fullName{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString description{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString name{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString value{'0'}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString fullName{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString description{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
bool specialUnits{false}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -878,54 +881,46 @@ auto TMainWindow::eventFilter(QObject *object, QEvent *event) -> bool
|
|||
void TMainWindow::ExportToCSVData(const QString &fileName, bool withHeader, int mib, const QChar &separator)
|
||||
{
|
||||
QxtCsvModel csv;
|
||||
const int columns = ui->tableWidget->columnCount();
|
||||
|
||||
int columns = 2;
|
||||
if (m_mType == MeasurementsType::Individual)
|
||||
{
|
||||
int colCount = 0;
|
||||
for (int column = 0; column < columns; ++column)
|
||||
columns = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
columns = 5;
|
||||
|
||||
const QList<MeasurementDimension_p> dimensions = m_m->Dimensions().values();
|
||||
if (dimensions.size() > 1)
|
||||
{
|
||||
if (not ui->tableWidget->isColumnHidden(column))
|
||||
{
|
||||
csv.insertColumn(colCount++);
|
||||
}
|
||||
columns += qMin(static_cast<int>(dimensions.size()), 2);
|
||||
}
|
||||
}
|
||||
|
||||
int colCount = 0;
|
||||
for (int column = 0; column <= columns; ++column)
|
||||
{
|
||||
csv.insertColumn(colCount++);
|
||||
}
|
||||
|
||||
if (withHeader)
|
||||
{
|
||||
int colCount = 0;
|
||||
for (int column = 0; column < columns; ++column)
|
||||
for (int column = 0; column <= columns; ++column)
|
||||
{
|
||||
if (not ui->tableWidget->isColumnHidden(column))
|
||||
{
|
||||
QString text;
|
||||
if (QTableWidgetItem *header = ui->tableWidget->horizontalHeaderItem(column))
|
||||
{
|
||||
text = header->text();
|
||||
}
|
||||
csv.setHeaderText(colCount, text);
|
||||
++colCount;
|
||||
}
|
||||
csv.setHeaderText(column, CSVColumnHeader(column));
|
||||
}
|
||||
}
|
||||
|
||||
const int rows = ui->tableWidget->rowCount();
|
||||
for (int row = 0; row < rows; ++row)
|
||||
VKnownMeasurementsDatabase *db = MApplication::VApp()->KnownMeasurementsDatabase();
|
||||
VKnownMeasurements knownDB = db->KnownMeasurements(m_m->KnownMeasurements());
|
||||
|
||||
const QMap<int, QSharedPointer<VMeasurement>> orderedTable = OrderedMeasurments();
|
||||
int row = 0;
|
||||
for (auto iMap = orderedTable.constBegin(); iMap != orderedTable.constEnd(); ++iMap)
|
||||
{
|
||||
csv.insertRow(row);
|
||||
int colCount = 0;
|
||||
for (int column = 0; column < columns; ++column)
|
||||
{
|
||||
if (not ui->tableWidget->isColumnHidden(column))
|
||||
{
|
||||
QString text;
|
||||
if (QTableWidgetItem *item = ui->tableWidget->item(row, column))
|
||||
{
|
||||
text = item->text();
|
||||
}
|
||||
csv.setText(row, colCount, text);
|
||||
++colCount;
|
||||
}
|
||||
}
|
||||
ExportRowToCSV(csv, row, iMap.value(), knownDB);
|
||||
++row;
|
||||
}
|
||||
|
||||
QString error;
|
||||
|
@ -4314,25 +4309,15 @@ auto TMainWindow::CheckMName(const QString &name, const QSet<QString> &importedN
|
|||
throw VException(tr("Imported file must not contain the same name twice."));
|
||||
}
|
||||
|
||||
if (name.indexOf(CustomMSign) == 0)
|
||||
QRegularExpression rx(NameRegExp());
|
||||
if (not rx.match(name).hasMatch())
|
||||
{
|
||||
QRegularExpression rx(NameRegExp());
|
||||
if (not rx.match(name).hasMatch())
|
||||
{
|
||||
throw VException(tr("Measurement '%1' doesn't match regex pattern.").arg(name));
|
||||
}
|
||||
|
||||
if (not m_data->IsUnique(name))
|
||||
{
|
||||
throw VException(tr("Measurement '%1' already used in the file.").arg(name));
|
||||
}
|
||||
throw VException(tr("Measurement '%1' doesn't match regex pattern.").arg(name));
|
||||
}
|
||||
else
|
||||
|
||||
if (not m_data->IsUnique(name))
|
||||
{
|
||||
if (not m_data->IsUnique(name))
|
||||
{
|
||||
throw VException(tr("Measurement '%1' already used in file.").arg(name));
|
||||
}
|
||||
throw VException(tr("Measurement '%1' already used in the file.").arg(name));
|
||||
}
|
||||
|
||||
return name;
|
||||
|
@ -4395,8 +4380,16 @@ void TMainWindow::ImportIndividualMeasurements(const QxtCsvModel &csv, const QVe
|
|||
measurement.name = mName;
|
||||
|
||||
const int valueColumn = map.at(static_cast<int>(IndividualMeasurementsColumns::Value));
|
||||
QString rawValue = csv.text(i, valueColumn);
|
||||
|
||||
if (rawValue.endsWith(degreeSymbol))
|
||||
{
|
||||
measurement.specialUnits = true;
|
||||
RemoveLast(rawValue);
|
||||
}
|
||||
|
||||
measurement.value = VTranslateVars::TryFormulaFromUser(
|
||||
csv.text(i, valueColumn), VAbstractApplication::VApp()->Settings()->GetOsSeparator());
|
||||
rawValue, VAbstractApplication::VApp()->Settings()->GetOsSeparator());
|
||||
|
||||
SetIndividualMeasurementFullName(i, name, csv, map, measurement);
|
||||
SetIndividualMeasurementDescription(i, name, csv, map, measurement);
|
||||
|
@ -4424,6 +4417,11 @@ void TMainWindow::ImportIndividualMeasurements(const QxtCsvModel &csv, const QVe
|
|||
m_m->SetMFullName(im.name, im.fullName);
|
||||
}
|
||||
|
||||
if (im.specialUnits)
|
||||
{
|
||||
m_m->SetMSpecialUnits(im.name, im.specialUnits);
|
||||
}
|
||||
|
||||
if (not im.description.isEmpty())
|
||||
{
|
||||
m_m->SetMDescription(im.name, im.description);
|
||||
|
@ -4489,6 +4487,11 @@ void TMainWindow::ImportMultisizeMeasurements(const QxtCsvModel &csv, const QVec
|
|||
m_m->SetMFullName(mm.name, mm.fullName);
|
||||
}
|
||||
|
||||
if (mm.specialUnits)
|
||||
{
|
||||
m_m->SetMSpecialUnits(mm.name, mm.specialUnits);
|
||||
}
|
||||
|
||||
if (not mm.description.isEmpty())
|
||||
{
|
||||
m_m->SetMDescription(mm.name, mm.description);
|
||||
|
@ -4517,8 +4520,15 @@ auto TMainWindow::ImportMultisizeMeasurement(const QxtCsvModel &csv, int i, cons
|
|||
measurement.name = mName;
|
||||
|
||||
const auto baseValueColumn = map.at(static_cast<int>(MultisizeMeasurementsColumns::BaseValue));
|
||||
measurement.base =
|
||||
ConverToDouble(csv.text(i, baseValueColumn), tr("Cannot convert base value to double in column 2."));
|
||||
QString rawBaseValue = csv.text(i, baseValueColumn);
|
||||
|
||||
if (rawBaseValue.endsWith(degreeSymbol))
|
||||
{
|
||||
measurement.specialUnits = true;
|
||||
RemoveLast(rawBaseValue);
|
||||
}
|
||||
|
||||
measurement.base = ConverToDouble(rawBaseValue, tr("Cannot convert base value to double in column 2."));
|
||||
|
||||
const auto shiftAColumn = map.at(static_cast<int>(MultisizeMeasurementsColumns::ShiftA));
|
||||
measurement.shiftA = ConverToDouble(csv.text(i, shiftAColumn),
|
||||
|
@ -4831,6 +4841,159 @@ auto TMainWindow::KnownMeasurementsRegistred(const QUuid &id) -> bool
|
|||
return known.contains(id);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
auto TMainWindow::CSVColumnHeader(int column) const -> QString
|
||||
{
|
||||
if (m_mType == MeasurementsType::Individual)
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0: // name
|
||||
return tr("Name", "measurement column");
|
||||
case 1: // full name
|
||||
return tr("Full name", "measurement column");
|
||||
case 2: // calculated value
|
||||
return tr("Calculated value", "measurement column") + " ("_L1 + UnitsToStr(m_pUnit) + ')'_L1;
|
||||
case 3: // formula
|
||||
return tr("Formula", "measurement column");
|
||||
case 4: // description
|
||||
return tr("Description", "measurement column");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
if (column == 0)
|
||||
{
|
||||
return tr("Name", "measurement column");
|
||||
}
|
||||
|
||||
if (column == 1)
|
||||
{
|
||||
return tr("Full name", "measurement column");
|
||||
}
|
||||
|
||||
if (column == 2)
|
||||
{
|
||||
return tr("Calculated value", "measurement column") + " ("_L1 + UnitsToStr(m_pUnit) + ')'_L1;
|
||||
}
|
||||
|
||||
if (column == 3)
|
||||
{
|
||||
return tr("Base value", "measurement column");
|
||||
}
|
||||
|
||||
const QList<MeasurementDimension_p> dimensions = m_m->Dimensions().values();
|
||||
const QString suffix = QStringLiteral(" (%1):");
|
||||
|
||||
if (column == 4)
|
||||
{
|
||||
if (not dimensions.empty())
|
||||
{
|
||||
const MeasurementDimension_p &dimension = dimensions.at(0);
|
||||
return tr("Shift", "measurement column") + suffix.arg(dimension->Name());
|
||||
}
|
||||
|
||||
return QStringLiteral("Shift A");
|
||||
}
|
||||
|
||||
if (column == 5 && dimensions.size() > 1)
|
||||
{
|
||||
const MeasurementDimension_p &dimension = dimensions.at(1);
|
||||
return tr("Shift", "measurement column") + suffix.arg(dimension->Name());
|
||||
}
|
||||
|
||||
if (column == 6 && dimensions.size() > 2)
|
||||
{
|
||||
const MeasurementDimension_p &dimension = dimensions.at(2);
|
||||
return tr("Shift", "measurement column") + suffix.arg(dimension->Name());
|
||||
}
|
||||
|
||||
if ((column == 5 && dimensions.size() <= 1) || (column == 6 && dimensions.size() <= 2) || column == 7)
|
||||
{
|
||||
return tr("Description", "measurement column");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TMainWindow::ExportRowToCSV(QxtCsvModel &csv, int row, const QSharedPointer<VMeasurement> &meash,
|
||||
const VKnownMeasurements &knownDB) const
|
||||
{
|
||||
csv.insertRow(row);
|
||||
|
||||
VKnownMeasurement known = knownDB.Measurement(meash->GetName());
|
||||
|
||||
csv.setText(row, 0, meash->GetName());
|
||||
|
||||
if (meash->IsCustom())
|
||||
{
|
||||
csv.setText(row, 1, meash->GetGuiText());
|
||||
}
|
||||
else
|
||||
{
|
||||
csv.setText(row, 1, known.fullName);
|
||||
}
|
||||
|
||||
QString calculatedValue;
|
||||
if (meash->IsSpecialUnits())
|
||||
{
|
||||
calculatedValue = locale().toString(*meash->GetValue()) + degreeSymbol;
|
||||
}
|
||||
else
|
||||
{
|
||||
calculatedValue = locale().toString(UnitConvertor(*meash->GetValue(), m_mUnit, m_pUnit));
|
||||
}
|
||||
csv.setText(row, 2, calculatedValue);
|
||||
|
||||
if (m_mType == MeasurementsType::Individual)
|
||||
{
|
||||
QString formula = VTranslateVars::TryFormulaToUser(meash->GetFormula(),
|
||||
VAbstractApplication::VApp()->Settings()->GetOsSeparator());
|
||||
csv.setText(row, 3, formula);
|
||||
|
||||
if (meash->IsCustom())
|
||||
{
|
||||
csv.setText(row, 4, meash->GetDescription());
|
||||
}
|
||||
else
|
||||
{
|
||||
csv.setText(row, 4, known.description);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
csv.setText(row, 3, locale().toString(meash->GetBase()));
|
||||
|
||||
const QList<MeasurementDimension_p> dimensions = m_m->Dimensions().values();
|
||||
|
||||
csv.setText(row, 4, locale().toString(meash->GetShiftA()));
|
||||
|
||||
int column = 5;
|
||||
if (dimensions.size() > 1)
|
||||
{
|
||||
csv.setText(row, column, locale().toString(meash->GetShiftB()));
|
||||
++column;
|
||||
}
|
||||
|
||||
if (dimensions.size() > 2)
|
||||
{
|
||||
csv.setText(row, column, locale().toString(meash->GetShiftC()));
|
||||
++column;
|
||||
}
|
||||
|
||||
if (meash->IsCustom())
|
||||
{
|
||||
csv.setText(row, column, meash->GetDescription());
|
||||
}
|
||||
else
|
||||
{
|
||||
csv.setText(row, column, known.description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void TMainWindow::SetDecimals()
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ class QxtCsvModel;
|
|||
class VMeasurement;
|
||||
class QAbstractButton;
|
||||
class QUuid;
|
||||
class VKnownMeasurements;
|
||||
|
||||
class TMainWindow : public VAbstractMainWindow
|
||||
{
|
||||
|
@ -198,13 +199,14 @@ private:
|
|||
{
|
||||
MultisizeMeasurement() = default;
|
||||
|
||||
QString name{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal base{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal shiftA{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal shiftB{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal shiftC{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString fullName{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString description{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString name{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal base{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal shiftA{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal shiftB{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
qreal shiftC{0}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString fullName{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
QString description{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
bool specialUnits{false}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||
};
|
||||
|
||||
QMultiHash<VShortcutAction, QAction *> m_actionShortcuts{};
|
||||
|
@ -306,6 +308,10 @@ private:
|
|||
void InitKnownMeasurementsDescription();
|
||||
|
||||
static auto KnownMeasurementsRegistred(const QUuid &id) -> bool;
|
||||
|
||||
auto CSVColumnHeader(int column) const -> QString;
|
||||
void ExportRowToCSV(QxtCsvModel &csv, int row, const QSharedPointer<VMeasurement> &meash,
|
||||
const VKnownMeasurements &knownDB) const;
|
||||
};
|
||||
|
||||
#endif // TMAINWINDOW_H
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabMeasurements">
|
||||
<attribute name="icon">
|
||||
|
|
|
@ -475,4 +475,17 @@ template <typename T> inline void SetTextAlignment(T *item, Qt::Alignment alignm
|
|||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
inline void RemoveLast(QString &str)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||
str.removeLast();
|
||||
#else
|
||||
if (!str.isEmpty())
|
||||
{
|
||||
str.remove(str.size() - 1, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // COMPATIBILITY_H
|
||||
|
|
Loading…
Reference in New Issue
Block a user