Improve multisize measurements format. Allow excluding combinations inside min/max range.

This commit is contained in:
Roman Telezhynskyi 2021-01-19 21:13:17 +02:00
parent 61867fa2d7
commit a569a20756
12 changed files with 523 additions and 152 deletions

View File

@ -8,6 +8,7 @@
- Improve the layout option "Auto crop unused width".
- Improve multisize measurements format. Allow decimal step 0.5.
- Improve restrict dimension dialog. Disable not available combinations.
- Improve multisize measurements format. Allow excluding combinations inside min/max range.
# Version 0.7.41 Dec 4, 2020
- Bug fixes.

View File

@ -28,6 +28,7 @@
#include "dialogrestrictdimension.h"
#include "ui_dialogrestrictdimension.h"
#include <QMenu>
#include <QTableWidgetItem>
#include "../vpatterndb/variables/vmeasurement.h"
@ -79,12 +80,12 @@ auto FilterByMaximum(const QVector<qreal> &base, qreal restriction) -> QVector<q
//---------------------------------------------------------------------------------------------------------------------
DialogRestrictDimension::DialogRestrictDimension(const QList<MeasurementDimension_p> &dimensions,
const QMap<QString, QPair<qreal, qreal>> &restrictions,
bool oneDimesionRestriction, bool fullCircumference,
const QMap<QString, VDimensionRestriction> &restrictions,
RestrictDimension restrictionType, bool fullCircumference,
QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogRestrictDimension),
m_oneDimesionRestriction(oneDimesionRestriction),
m_restrictionType(restrictionType),
m_fullCircumference(fullCircumference),
m_dimensions(dimensions),
m_restrictions(restrictions)
@ -93,8 +94,11 @@ DialogRestrictDimension::DialogRestrictDimension(const QList<MeasurementDimensio
ui->tableWidget->setItemDelegate(
new VDecorationAligningDelegate(Qt::AlignHCenter | Qt::AlignCenter, ui->tableWidget));
ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this, &DialogRestrictDimension::RowSelected);
connect(ui->tableWidget, &QTableWidget::customContextMenuRequested, this,
&DialogRestrictDimension::CellContextMenu);
connect(ui->comboBoxDimensionA, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&DialogRestrictDimension::DimensionAChanged);
@ -140,7 +144,7 @@ void DialogRestrictDimension::changeEvent(QEvent *event)
}
};
if (not m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::Third)
{
RetranslateControls(0, ui->labelDimensionA, ui->comboBoxDimensionA);
}
@ -163,7 +167,7 @@ void DialogRestrictDimension::RowSelected()
qreal base2 = 0;
MeasurementDimension_p dimension;
if (m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::Second)
{
base1 = item->data(Qt::UserRole).toDouble();
@ -183,8 +187,7 @@ void DialogRestrictDimension::RowSelected()
}
}
QPair<qreal, qreal> restriction = m_restrictions.value(VMeasurement::CorrectionHash(base1, base2),
QPair<qreal, qreal>(0, 0));
VDimensionRestriction restriction = m_restrictions.value(VMeasurement::CorrectionHash(base1, base2));
if (dimension.isNull())
{
@ -195,17 +198,17 @@ void DialogRestrictDimension::RowSelected()
ui->comboBoxMin->blockSignals(true);
ui->comboBoxMin->clear();
QVector<qreal> filtered = FilterByMaximum(bases, restriction.second);
QVector<qreal> filtered = FilterByMaximum(bases, restriction.GetMax());
FillBases(filtered, dimension, ui->comboBoxMin);
int index = ui->comboBoxMin->findData(restriction.first);
int index = ui->comboBoxMin->findData(restriction.GetMin());
ui->comboBoxMin->setCurrentIndex(index != -1 ? index : 0);
ui->comboBoxMin->blockSignals(false);
ui->comboBoxMax->blockSignals(true);
ui->comboBoxMax->clear();
filtered = FilterByMinimum(bases, restriction.first);
FillBases(FilterByMinimum(bases, restriction.first), dimension, ui->comboBoxMax);
index = ui->comboBoxMax->findData(restriction.second);
filtered = FilterByMinimum(bases, restriction.GetMin());
FillBases(FilterByMinimum(bases, restriction.GetMin()), dimension, ui->comboBoxMax);
index = ui->comboBoxMax->findData(restriction.GetMax());
ui->comboBoxMax->setCurrentIndex(index != -1 ? index : ui->comboBoxMax->count() - 1);
ui->comboBoxMax->blockSignals(false);
@ -229,7 +232,7 @@ void DialogRestrictDimension::MinRestrictionChanged()
qreal base1 = 0;
qreal base2 = 0;
if (m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::Second)
{
base1 = item->data(Qt::UserRole).toDouble();
}
@ -240,9 +243,9 @@ void DialogRestrictDimension::MinRestrictionChanged()
}
const QString coordinates = VMeasurement::CorrectionHash(base1, base2);
QPair<qreal, qreal> restriction = m_restrictions.value(coordinates, QPair<qreal, qreal>(0, 0));
VDimensionRestriction restriction = m_restrictions.value(coordinates);
restriction.first = ui->comboBoxMin->currentData().toDouble();
restriction.SetMin(ui->comboBoxMin->currentData().toDouble());
m_restrictions.insert(coordinates, restriction);
const int currentRow = ui->tableWidget->currentRow();
@ -266,7 +269,7 @@ void DialogRestrictDimension::MaxRestrictionChanged()
qreal base1 = 0;
qreal base2 = 0;
if (m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::Second)
{
base1 = item->data(Qt::UserRole).toDouble();
}
@ -277,9 +280,9 @@ void DialogRestrictDimension::MaxRestrictionChanged()
}
const QString coordinates = VMeasurement::CorrectionHash(base1, base2);
QPair<qreal, qreal> restriction = m_restrictions.value(coordinates, QPair<qreal, qreal>(0, 0));
VDimensionRestriction restriction = m_restrictions.value(coordinates);
restriction.second = ui->comboBoxMax->currentData().toDouble();
restriction.SetMax(ui->comboBoxMax->currentData().toDouble());
m_restrictions.insert(coordinates, restriction);
const int currentRow = ui->tableWidget->currentRow();
@ -293,6 +296,111 @@ void DialogRestrictDimension::MaxRestrictionChanged()
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogRestrictDimension::CellContextMenu(QPoint pos)
{
QTableWidgetItem *item = ui->tableWidget->itemAt(pos);
if (item != nullptr && (item->flags() & Qt::ItemIsEnabled) != 0U)
{
qreal columnValue = 0;
QString coordinates;
MeasurementDimension_p dimension;
if (m_restrictionType == RestrictDimension::First)
{
if (not m_dimensions.empty())
{
columnValue = m_dimensions.at(0)->ValidBases().at(item->column());
coordinates = QChar('0');
}
else
{
return;
}
}
else if (m_restrictionType == RestrictDimension::Second)
{
if (m_dimensions.size() >= 2)
{
dimension = m_dimensions.at(1);
columnValue = dimension->ValidBases().at(item->column());
qreal base1 = m_dimensions.at(0)->ValidBases().at(item->row());
coordinates = VMeasurement::CorrectionHash(base1);
}
else
{
return;
}
}
else if (m_restrictionType == RestrictDimension::Third)
{
if (m_dimensions.size() >= 3)
{
dimension = m_dimensions.at(2);
columnValue = dimension->ValidBases().at(item->column());
qreal base1 = ui->comboBoxDimensionA->currentData().toDouble();
qreal base2 = m_dimensions.at(1)->ValidBases().at(item->row());
coordinates = VMeasurement::CorrectionHash(base1, base2);
}
else
{
return;
}
}
else
{
return;
}
VDimensionRestriction restriction = m_restrictions.value(coordinates);
bool exclude = not restriction.GetExcludeValues().contains(columnValue);
QScopedPointer<QMenu> menu(new QMenu());
QAction *actionExclude = menu->addAction(exclude ? tr("Exclude") : tr("Include"));
if (m_restrictionType == RestrictDimension::Second || m_restrictionType == RestrictDimension::Third)
{
if (dimension != nullptr)
{
qreal min = restriction.GetMin();
if (qFuzzyIsNull(min))
{
min = dimension->MinValue();
}
qreal max = restriction.GetMax();
if (qFuzzyIsNull(max))
{
max = dimension->MaxValue();
}
actionExclude->setEnabled(columnValue >= min && columnValue <= max);
}
else
{
return;
}
}
QAction *selectedAction = menu->exec(ui->tableWidget->viewport()->mapToGlobal(pos));
if (selectedAction == actionExclude)
{
QSet<qreal> list = restriction.GetExcludeValues();
if (exclude)
{
list.insert(columnValue);
item->setIcon(QIcon(QStringLiteral("://icon/24x24/close.png")));
}
else
{
list.remove(columnValue);
item->setIcon(QIcon(QStringLiteral("://icon/24x24/star.png")));
}
restriction.SetExcludeValues(list);
m_restrictions[coordinates] = restriction;
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogRestrictDimension::InitDimensionsBaseValues()
{
@ -313,7 +421,18 @@ void DialogRestrictDimension::InitDimensionsBaseValues()
}
};
if (not m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::First)
{
ui->labelDimensionA->setVisible(false);
ui->comboBoxDimensionA->setVisible(false);
ui->groupBoxRestriction->setVisible(false);
}
else if (m_restrictionType == RestrictDimension::Second)
{
ui->labelDimensionA->setVisible(false);
ui->comboBoxDimensionA->setVisible(false);
}
else if (m_restrictionType == RestrictDimension::Third)
{
if (not m_dimensions.empty())
{
@ -325,11 +444,6 @@ void DialogRestrictDimension::InitDimensionsBaseValues()
ui->comboBoxDimensionA->setVisible(false);
}
}
else
{
ui->labelDimensionA->setVisible(false);
ui->comboBoxDimensionA->setVisible(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -346,7 +460,7 @@ void DialogRestrictDimension::InitDimensionGradation(const MeasurementDimension_
control->blockSignals(true);
control->clear();
FillBases(dimension->ValidBases(), dimension, control);
FillBases(DimensionRestrictedValues(dimension), dimension, control);
int i = control->findData(current);
if (i != -1)
@ -367,23 +481,44 @@ void DialogRestrictDimension::InitTable()
ui->tableWidget->blockSignals(true);
ui->tableWidget->clear();
auto InitHeaders = [this](int index)
auto InitVerticalHeaderForDimension = [this](int index)
{
if (m_dimensions.size() > index)
{
MeasurementDimension_p dimensionA = m_dimensions.at(index-1);
const QVector<qreal> basesA = dimensionA->ValidBases();
ui->tableWidget->setRowCount(basesA.size());
ui->tableWidget->setVerticalHeaderLabels(DimensionLabels(basesA, dimensionA));
MeasurementDimension_p dimensionB = m_dimensions.at(index);
const QVector<qreal> basesB = dimensionB->ValidBases();
ui->tableWidget->setColumnCount(basesB.size());
ui->tableWidget->setHorizontalHeaderLabels(DimensionLabels(basesB, dimensionB));
MeasurementDimension_p dimension = m_dimensions.at(index);
const QVector<qreal> bases = dimension->ValidBases();
ui->tableWidget->setRowCount(bases.size());
ui->tableWidget->setVerticalHeaderLabels(DimensionLabels(bases, dimension));
}
};
InitHeaders(m_oneDimesionRestriction ? 1 : 2);
auto InitHorizontalHeaderForDimension = [this](int index)
{
if (m_dimensions.size() > index)
{
MeasurementDimension_p dimension = m_dimensions.at(index);
const QVector<qreal> bases = dimension->ValidBases();
ui->tableWidget->setColumnCount(bases.size());
ui->tableWidget->setHorizontalHeaderLabels(DimensionLabels(bases, dimension));
}
};
if (m_restrictionType == RestrictDimension::First)
{
InitHorizontalHeaderForDimension(0);
ui->tableWidget->setRowCount(1);
}
else if (m_restrictionType == RestrictDimension::Second)
{
InitVerticalHeaderForDimension(0);
InitHorizontalHeaderForDimension(1);
}
else if (m_restrictionType == RestrictDimension::Third)
{
InitVerticalHeaderForDimension(1);
InitHorizontalHeaderForDimension(2);
}
ui->tableWidget->blockSignals(false);
RefreshTable();
@ -396,7 +531,19 @@ void DialogRestrictDimension::RefreshTable()
QVector<qreal> basesRow;
QVector<qreal> basesColumn;
if (m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::First)
{
if (not m_dimensions.empty())
{
MeasurementDimension_p dimensionA = m_dimensions.at(0);
basesColumn = dimensionA->ValidBases();
}
else
{
return;
}
}
else if (m_restrictionType == RestrictDimension::Second)
{
if (m_dimensions.size() >= 2)
{
@ -411,7 +558,7 @@ void DialogRestrictDimension::RefreshTable()
return;
}
}
else
else if (m_restrictionType == RestrictDimension::Third)
{
if (m_dimensions.size() >= 3)
{
@ -430,16 +577,30 @@ void DialogRestrictDimension::RefreshTable()
ui->tableWidget->blockSignals(true);
ui->tableWidget->clearContents();
for(int row=0; row < basesRow.size(); ++row)
if (m_restrictionType == RestrictDimension::First)
{
for(int column=0; column < basesColumn.size(); ++column)
{
AddCell(row, column, basesRow.at(row), basesColumn.at(column));
AddCell(0, column, 0, basesColumn.at(column));
}
}
else
{
for(int row=0; row < basesRow.size(); ++row)
{
for(int column=0; column < basesColumn.size(); ++column)
{
AddCell(row, column, basesRow.at(row), basesColumn.at(column));
}
}
}
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
if (m_restrictionType != RestrictDimension::First)
{
ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
}
ui->tableWidget->blockSignals(false);
}
@ -450,74 +611,95 @@ void DialogRestrictDimension::AddCell(int row, int column, qreal rowValue, qreal
auto *item = new QTableWidgetItem();
item->setData(Qt::UserRole, rowValue);
qreal base1 = 0;
qreal base2 = 0;
MeasurementDimension_p dimension;
QVector<qreal> bases;
QVector<qreal> validRows;
if (m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::First)
{
base1 = rowValue;
if (m_dimensions.size() >= 2)
VDimensionRestriction restriction = m_restrictions.value(QChar('0'));
if (restriction.GetExcludeValues().contains(columnValue))
{
validRows = m_dimensions.at(0)->ValidBases();
dimension = m_dimensions.at(1);
bases = dimension->ValidBases();
item->setIcon(QIcon(QStringLiteral("://icon/24x24/close.png")));
}
else
{
item->setIcon(QIcon(QStringLiteral("://icon/24x24/star.png")));
}
}
else
{
base1 = ui->comboBoxDimensionA->currentData().toDouble();
base2 = rowValue;
qreal base1 = 0;
qreal base2 = 0;
MeasurementDimension_p dimension;
QVector<qreal> bases;
QVector<qreal> validRows;
if (m_dimensions.size() >= 3)
if (m_restrictionType == RestrictDimension::Second)
{
validRows = DimensionRestrictedValues(m_dimensions.at(1));
dimension = m_dimensions.at(2);
bases = dimension->ValidBases();
base1 = rowValue;
if (m_dimensions.size() >= 2)
{
validRows = m_dimensions.at(0)->ValidBases();
dimension = m_dimensions.at(1);
bases = dimension->ValidBases();
}
}
}
QPair<qreal, qreal> restriction = m_restrictions.value(VMeasurement::CorrectionHash(base1, base2),
QPair<qreal, qreal>(0, 0));
qreal min = INT32_MIN;
qreal max = INT32_MAX;
if (not dimension.isNull())
{
min = bases.indexOf(restriction.first) != -1 ? restriction.first : dimension->MinValue();
max = bases.indexOf(restriction.second) != -1 ? restriction.second : dimension->MaxValue();
if (max < min)
else if (m_restrictionType == RestrictDimension::Third)
{
min = dimension->MinValue();
max = dimension->MaxValue();
base1 = ui->comboBoxDimensionA->currentData().toDouble();
base2 = rowValue;
if (m_dimensions.size() >= 3)
{
validRows = DimensionRestrictedValues(m_dimensions.at(1));
dimension = m_dimensions.at(2);
bases = dimension->ValidBases();
}
}
}
if (validRows.contains(rowValue))
{
const bool leftRestriction = columnValue >= min;
const bool rightRestriction = columnValue <= max;
VDimensionRestriction restriction = m_restrictions.value(VMeasurement::CorrectionHash(base1, base2));
qreal min = INT32_MIN;
qreal max = INT32_MAX;
if (leftRestriction && rightRestriction)
if (not dimension.isNull())
{
item->setIcon(QIcon(QStringLiteral("://icon/24x24/star.png")));
min = bases.indexOf(restriction.GetMin()) != -1 ? restriction.GetMin() : dimension->MinValue();
max = bases.indexOf(restriction.GetMax()) != -1 ? restriction.GetMax() : dimension->MaxValue();
if (max < min)
{
min = dimension->MinValue();
max = dimension->MaxValue();
}
}
if (validRows.contains(rowValue))
{
const bool leftRestriction = columnValue >= min;
const bool rightRestriction = columnValue <= max;
if (leftRestriction && rightRestriction)
{
if (restriction.GetExcludeValues().contains(columnValue))
{
item->setIcon(QIcon(QStringLiteral("://icon/24x24/close.png")));
}
else
{
item->setIcon(QIcon(QStringLiteral("://icon/24x24/star.png")));
}
}
else
{
item->setIcon(QIcon(QStringLiteral("://icon/24x24/close.png")));
}
}
else
{
item->setIcon(QIcon(QStringLiteral("://icon/24x24/close.png")));
}
}
else
{
item->setIcon(QIcon(QStringLiteral("://icon/24x24/close.png")));
Qt::ItemFlags flags = item->flags();
flags &= ~(Qt::ItemIsEnabled);
item->setFlags(flags);
Qt::ItemFlags flags = item->flags();
flags &= ~(Qt::ItemIsEnabled);
item->setFlags(flags);
}
}
// set the item non-editable (view only), and non-selectable
@ -671,18 +853,22 @@ auto DialogRestrictDimension::DimensionLabels(const QVector<qreal> &bases,
//---------------------------------------------------------------------------------------------------------------------
auto DialogRestrictDimension::DimensionRestrictedValues(const MeasurementDimension_p &dimension) const -> QVector<qreal>
{
QPair<qreal, qreal> restriction;
VDimensionRestriction restriction;
if (not m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::First)
{
restriction = m_restrictions.value(QChar('0'));
}
else if (m_restrictionType == RestrictDimension::Third)
{
qreal base1 = ui->comboBoxDimensionA->currentData().toDouble();
restriction = m_restrictions.value(VMeasurement::CorrectionHash(base1), QPair<qreal, qreal>(0, 0));
restriction = m_restrictions.value(VMeasurement::CorrectionHash(base1));
}
const QVector<qreal> bases = dimension->ValidBases();
qreal min = bases.indexOf(restriction.first) != -1 ? restriction.first : dimension->MinValue();
qreal max = bases.indexOf(restriction.second) != -1 ? restriction.second : dimension->MaxValue();
qreal min = bases.indexOf(restriction.GetMin()) != -1 ? restriction.GetMin() : dimension->MinValue();
qreal max = bases.indexOf(restriction.GetMax()) != -1 ? restriction.GetMax() : dimension->MaxValue();
if (min > max)
{
@ -690,13 +876,13 @@ auto DialogRestrictDimension::DimensionRestrictedValues(const MeasurementDimensi
max = dimension->MaxValue();
}
return VAbstartMeasurementDimension::ValidBases(min, max, dimension->Step());
return VAbstartMeasurementDimension::ValidBases(min, max, dimension->Step(), restriction.GetExcludeValues());
}
//---------------------------------------------------------------------------------------------------------------------
auto DialogRestrictDimension::StartRow() const -> int
{
if (m_oneDimesionRestriction)
if (m_restrictionType == RestrictDimension::Second)
{
return 0;
}

View File

@ -40,6 +40,13 @@ class DialogRestrictDimension;
class QTableWidgetItem;
enum class RestrictDimension: qint8
{
First = 0,
Second = 1,
Third = 2
};
class DialogRestrictDimension : public QDialog
{
@ -47,11 +54,11 @@ class DialogRestrictDimension : public QDialog
public:
DialogRestrictDimension(const QList<MeasurementDimension_p> &dimensions,
const QMap<QString, QPair<qreal, qreal>> &restrictions, bool oneDimesionRestriction,
const QMap<QString, VDimensionRestriction> &restrictions, RestrictDimension restrictionType,
bool fullCircumference, QWidget *parent = nullptr);
virtual ~DialogRestrictDimension();
auto Restrictions() const -> QMap<QString, QPair<qreal, qreal> >;
auto Restrictions() const -> QMap<QString, VDimensionRestriction>;
protected:
virtual void changeEvent(QEvent* event) override;
@ -62,14 +69,17 @@ protected slots:
void MinRestrictionChanged();
void MaxRestrictionChanged();
private slots:
void CellContextMenu(QPoint pos);
private:
Q_DISABLE_COPY(DialogRestrictDimension)
Ui::DialogRestrictDimension *ui;
bool m_oneDimesionRestriction;
RestrictDimension m_restrictionType;
bool m_fullCircumference;
QList<MeasurementDimension_p> m_dimensions;
QMap<QString, QPair<qreal, qreal>> m_restrictions;
QMap<QString, VDimensionRestriction> m_restrictions;
void InitDimensionsBaseValues();
void InitDimensionGradation(const MeasurementDimension_p &dimension, QComboBox *control);
@ -89,7 +99,7 @@ private:
};
//---------------------------------------------------------------------------------------------------------------------
inline auto DialogRestrictDimension::Restrictions() const -> QMap<QString, QPair<qreal, qreal> >
inline auto DialogRestrictDimension::Restrictions() const -> QMap<QString, VDimensionRestriction >
{
return m_restrictions;
}

View File

@ -2245,16 +2245,36 @@ void TMainWindow::ExportToIndividual()
}
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::RestrictFirstDimesion()
{
const QList<MeasurementDimension_p> dimensions = m->Dimensions().values();
const QMap<QString, VDimensionRestriction> restrictions = m->GetRestrictions();
bool fullCircumference = m->IsFullCircumference();
DialogRestrictDimension dialog(dimensions, restrictions, RestrictDimension::First, fullCircumference, this);
if (dialog.exec() == QDialog::Rejected)
{
return;
}
m->SetRestrictions(dialog.Restrictions());
MeasurementsWereSaved(false);
if (not dimensions.isEmpty())
{
InitDimensionGradation(0, dimensions.at(0), gradationDimensionA);
}
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::RestrictSecondDimesion()
{
const QList<MeasurementDimension_p> dimensions = m->Dimensions().values();
const QMap<QString, QPair<qreal, qreal>> restrictions = m->GetRestrictions();
bool oneDimesionRestriction = true;
const QMap<QString, VDimensionRestriction> restrictions = m->GetRestrictions();
bool fullCircumference = m->IsFullCircumference();
DialogRestrictDimension dialog(dimensions, restrictions, oneDimesionRestriction, fullCircumference, this);
DialogRestrictDimension dialog(dimensions, restrictions, RestrictDimension::Second, fullCircumference, this);
if (dialog.exec() == QDialog::Rejected)
{
return;
@ -2269,12 +2289,10 @@ void TMainWindow::RestrictSecondDimesion()
void TMainWindow::RestrictThirdDimesion()
{
const QList<MeasurementDimension_p> dimensions = m->Dimensions().values();
const QMap<QString, QPair<qreal, qreal>> restrictions = m->GetRestrictions();
bool oneDimesionRestriction = false;
const QMap<QString, VDimensionRestriction> restrictions = m->GetRestrictions();
bool fullCircumference = m->IsFullCircumference();
DialogRestrictDimension dialog(dimensions, restrictions, oneDimesionRestriction, fullCircumference, this);
DialogRestrictDimension dialog(dimensions, restrictions, RestrictDimension::Third, fullCircumference, this);
if (dialog.exec() == QDialog::Rejected)
{
return;
@ -2591,18 +2609,26 @@ void TMainWindow::InitMenu()
ui->menuMeasurements->insertAction(ui->actionUseFullCircumference, separator);
const QList<MeasurementDimension_p> dimensions = m->Dimensions().values();
if (dimensions.size() > 1)
if (dimensions.size() > 0)
{
ui->actionRestrictSecondDimension->setVisible(true);
ui->actionRestrictSecondDimension->setEnabled(true);
connect(ui->actionRestrictSecondDimension, &QAction::triggered, this, &TMainWindow::RestrictSecondDimesion);
ui->actionRestrictFirstDimension->setVisible(true);
ui->actionRestrictFirstDimension->setEnabled(true);
connect(ui->actionRestrictFirstDimension, &QAction::triggered, this, &TMainWindow::RestrictFirstDimesion);
if (dimensions.size() > 2)
if (dimensions.size() > 1)
{
ui->actionRestrictThirdDimension->setVisible(true);
ui->actionRestrictThirdDimension->setEnabled(true);
connect(ui->actionRestrictThirdDimension, &QAction::triggered, this,
&TMainWindow::RestrictThirdDimesion);
ui->actionRestrictSecondDimension->setVisible(true);
ui->actionRestrictSecondDimension->setEnabled(true);
connect(ui->actionRestrictSecondDimension, &QAction::triggered, this,
&TMainWindow::RestrictSecondDimesion);
if (dimensions.size() > 2)
{
ui->actionRestrictThirdDimension->setVisible(true);
ui->actionRestrictThirdDimension->setEnabled(true);
connect(ui->actionRestrictThirdDimension, &QAction::triggered, this,
&TMainWindow::RestrictThirdDimesion);
}
}
}
@ -4176,18 +4202,24 @@ void TMainWindow::SetCurrentDimensionValues()
//---------------------------------------------------------------------------------------------------------------------
QVector<qreal> TMainWindow::DimensionRestrictedValues(int index, const MeasurementDimension_p &dimension)
{
VDimensionRestriction restriction;
if (index == 0)
{
return dimension->ValidBases();
restriction = m->Restriction(0);
}
else if (index == 1)
{
restriction = m->Restriction(currentDimensionA);
}
else
{
restriction = m->Restriction(currentDimensionA, currentDimensionB);
}
QPair<qreal, qreal> restriction = index == 1 ? m->Restriction(currentDimensionA)
: m->Restriction(currentDimensionA, currentDimensionB);
const QVector<qreal> bases = dimension->ValidBases();
qreal min = bases.indexOf(restriction.first) != -1 ? restriction.first : dimension->MinValue();
qreal max = bases.indexOf(restriction.second) != -1 ? restriction.second : dimension->MaxValue();
qreal min = bases.indexOf(restriction.GetMin()) != -1 ? restriction.GetMin() : dimension->MinValue();
qreal max = bases.indexOf(restriction.GetMax()) != -1 ? restriction.GetMax() : dimension->MaxValue();
if (min > max)
{
@ -4195,7 +4227,7 @@ QVector<qreal> TMainWindow::DimensionRestrictedValues(int index, const Measureme
max = dimension->MaxValue();
}
return VAbstartMeasurementDimension::ValidBases(min, max, dimension->Step());
return VAbstartMeasurementDimension::ValidBases(min, max, dimension->Step(), restriction.GetExcludeValues());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -140,6 +140,7 @@ private slots:
void ExportToIndividual();
void RestrictFirstDimesion();
void RestrictSecondDimesion();
void RestrictThirdDimesion();

View File

@ -1016,6 +1016,7 @@
<addaction name="actionImportFromPattern"/>
<addaction name="actionMeasurementDiagram"/>
<addaction name="actionUseFullCircumference"/>
<addaction name="actionRestrictFirstDimension"/>
<addaction name="actionRestrictSecondDimension"/>
<addaction name="actionRestrictThirdDimension"/>
<addaction name="actionDimensionLabels"/>
@ -1401,6 +1402,9 @@
<property name="visible">
<bool>false</bool>
</property>
<property name="menuRole">
<enum>QAction::ApplicationSpecificRole</enum>
</property>
</action>
<action name="actionRestrictThirdDimension">
<property name="enabled">
@ -1412,6 +1416,9 @@
<property name="visible">
<bool>false</bool>
</property>
<property name="menuRole">
<enum>QAction::ApplicationSpecificRole</enum>
</property>
</action>
<action name="actionDimensionLabels">
<property name="enabled">
@ -1424,6 +1431,20 @@
<bool>false</bool>
</property>
</action>
<action name="actionRestrictFirstDimension">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Restrict first dimension</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
<property name="menuRole">
<enum>QAction::ApplicationSpecificRole</enum>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@ -1448,8 +1469,8 @@
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>764</x>
<y>377</y>
<x>1187</x>
<y>457</y>
</hint>
</hints>
</connection>
@ -1460,8 +1481,8 @@
<slot>setChecked(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>734</x>
<y>384</y>
<x>1187</x>
<y>464</y>
</hint>
<hint type="destinationlabel">
<x>-1</x>

View File

@ -2148,11 +2148,10 @@ void MainWindow::StoreIndividualMDimensions()
//---------------------------------------------------------------------------------------------------------------------
QVector<qreal> MainWindow::DimensionRestrictedValues(int index, const MeasurementDimension_p &dimension)
{
QPair<qreal, qreal> restriction;
VDimensionRestriction restriction;
if (index == 0)
{
return dimension->ValidBases();
restriction = m->Restriction(0);
}
else if (index == 1)
{
@ -2165,8 +2164,8 @@ QVector<qreal> MainWindow::DimensionRestrictedValues(int index, const Measuremen
const QVector<qreal> bases = dimension->ValidBases();
qreal min = bases.indexOf(restriction.first) != -1 ? restriction.first : dimension->MinValue();
qreal max = bases.indexOf(restriction.second) != -1 ? restriction.second : dimension->MaxValue();
qreal min = bases.indexOf(restriction.GetMin()) != -1 ? restriction.GetMin() : dimension->MinValue();
qreal max = bases.indexOf(restriction.GetMax()) != -1 ? restriction.GetMax() : dimension->MaxValue();
if (min > max)
{
@ -2174,7 +2173,7 @@ QVector<qreal> MainWindow::DimensionRestrictedValues(int index, const Measuremen
max = dimension->MaxValue();
}
return VAbstartMeasurementDimension::ValidBases(min, max, dimension->Step());
return VAbstartMeasurementDimension::ValidBases(min, max, dimension->Step(), restriction.GetExcludeValues());
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -47,6 +47,7 @@
<xs:attribute name="coordinates" type="xs:string" use="required"/>
<xs:attribute name="min" type="dimesionValue"/>
<xs:attribute name="max" type="dimesionValue"/>
<xs:attribute name="exclude" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>

View File

@ -87,7 +87,7 @@ auto VAbstartMeasurementDimension::ValidSteps() const -> QVector<qreal>
//---------------------------------------------------------------------------------------------------------------------
auto VAbstartMeasurementDimension::ValidBases() const -> QVector<qreal>
{
return VAbstartMeasurementDimension::ValidBases(m_minValue, m_maxValue, m_step);
return VAbstartMeasurementDimension::ValidBases(m_minValue, m_maxValue, m_step, QSet<qreal>());
}
//---------------------------------------------------------------------------------------------------------------------
@ -105,7 +105,8 @@ auto VAbstartMeasurementDimension::ValidBasesList() const -> QStringList
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstartMeasurementDimension::ValidBases(qreal min, qreal max, qreal step) -> QVector<qreal>
auto VAbstartMeasurementDimension::ValidBases(qreal min, qreal max, qreal step,
const QSet<qreal> &exclude) -> QVector<qreal>
{
QVector<qreal> validBases;
@ -124,11 +125,25 @@ auto VAbstartMeasurementDimension::ValidBases(qreal min, qreal max, qreal step)
qreal value = min;
do
{
validBases.append(value);
if (not exclude.contains(value))
{
validBases.append(value);
}
value += step;
}
while(value < max + step);
if (validBases.isEmpty())
{
value = min;
do
{
validBases.append(value);
value += step;
}
while(value < max + step);
}
return validBases;
}
@ -463,3 +478,36 @@ auto VZMeasurementDimension::RangeMax() const -> int
return 0;
}
}
// VDimensionRestriction
//---------------------------------------------------------------------------------------------------------------------
void VDimensionRestriction::SetExcludeString(const QString &exclude)
{
m_exclude.clear();
QStringList values = exclude.split(';');
for(auto &value : values)
{
bool ok = false;
qreal val = value.toDouble(&ok);
if (ok)
{
m_exclude.insert(val);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VDimensionRestriction::GetExcludeString() const -> QString
{
QList<qreal> list = m_exclude.values();
QStringList excludeList;
for(auto &value : list)
{
excludeList.append(QString::number(value));
}
return excludeList.join(';');
}

View File

@ -30,6 +30,7 @@
#include <QCoreApplication>
#include <QMap>
#include <QSet>
#include "../vmisc/def.h"
@ -85,7 +86,7 @@ public:
auto ValidBases() const -> QVector<qreal>;
auto ValidBasesList() const -> QStringList;
static auto ValidBases(qreal min, qreal max, qreal step) -> QVector<qreal>;
static auto ValidBases(qreal min, qreal max, qreal step, const QSet<qreal> &exclude) -> QVector<qreal>;
static auto DimensionName(MeasurementDimension type) -> QString;
static auto DimensionToolTip(MeasurementDimension type, bool circumference, bool fc) -> QString;
@ -271,4 +272,70 @@ public:
virtual auto RangeMax() const -> int override;
};
class VDimensionRestriction
{
public:
VDimensionRestriction()
{}
VDimensionRestriction(qreal min, qreal max, const QString &exclude = QString()) :
m_min(min),
m_max(max)
{
SetExcludeString(exclude);
}
void SetMin(qreal min);
auto GetMin() const -> qreal;
void SetMax(qreal max);
auto GetMax() const -> qreal;
void SetExcludeString(const QString &exclude);
auto GetExcludeString() const -> QString;
void SetExcludeValues(const QSet<qreal> &exclude);
auto GetExcludeValues() const -> QSet<qreal>;
private:
qreal m_min{0};
qreal m_max{0};
QSet<qreal> m_exclude{};
};
//---------------------------------------------------------------------------------------------------------------------
inline void VDimensionRestriction::SetMin(qreal min)
{
m_min = min;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VDimensionRestriction::GetMin() const -> qreal
{
return m_min;
}
//---------------------------------------------------------------------------------------------------------------------
inline void VDimensionRestriction::SetMax(qreal max)
{
m_max = max;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VDimensionRestriction::GetMax() const -> qreal
{
return m_max;
}
//---------------------------------------------------------------------------------------------------------------------
inline void VDimensionRestriction::SetExcludeValues(const QSet<qreal> &exclude)
{
m_exclude = exclude;
}
//---------------------------------------------------------------------------------------------------------------------
inline auto VDimensionRestriction::GetExcludeValues() const -> QSet<qreal>
{
return m_exclude;
}
#endif // VDIMENSIONS_H

View File

@ -84,6 +84,7 @@ const QString VMeasurements::AttrShiftB = QStringLiteral("shiftB");
const QString VMeasurements::AttrShiftC = QStringLiteral("shiftC");
const QString VMeasurements::AttrCorrection = QStringLiteral("correction");
const QString VMeasurements::AttrCoordinates = QStringLiteral("coordinates");
const QString VMeasurements::AttrExclude = QStringLiteral("exclude");
const QString VMeasurements::AttrSpecialUnits = QStringLiteral("specialUnits");
const QString VMeasurements::AttrDescription = QStringLiteral("description");
const QString VMeasurements::AttrName = QStringLiteral("name");
@ -903,9 +904,9 @@ auto VMeasurements::Dimensions() const -> QMap<MeasurementDimension, Measurement
}
//---------------------------------------------------------------------------------------------------------------------
auto VMeasurements::GetRestrictions() const -> QMap<QString, QPair<qreal, qreal> >
auto VMeasurements::GetRestrictions() const -> QMap<QString, VDimensionRestriction >
{
QMap<QString, QPair<qreal, qreal> > restrictions;
QMap<QString, VDimensionRestriction > restrictions;
const QDomNodeList list = elementsByTagName(TagRestriction);
for (int i=0; i < list.size(); ++i)
@ -915,15 +916,16 @@ auto VMeasurements::GetRestrictions() const -> QMap<QString, QPair<qreal, qreal>
QString coordinates = GetParametrString(res, AttrCoordinates);
const qreal min = GetParametrDouble(res, AttrMin, QChar('0'));
const qreal max = GetParametrDouble(res, AttrMax, QChar('0'));
const QString exclude = GetParametrEmptyString(res, AttrExclude);
restrictions.insert(coordinates, qMakePair(min, max));
restrictions.insert(coordinates, VDimensionRestriction(min, max, exclude));
}
return restrictions;
}
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetRestrictions(const QMap<QString, QPair<qreal, qreal> > &restrictions)
void VMeasurements::SetRestrictions(const QMap<QString, VDimensionRestriction> &restrictions)
{
QDomElement root = documentElement();
QDomElement restrictionsTag = root.firstChildElement(TagRestrictions);
@ -941,8 +943,10 @@ void VMeasurements::SetRestrictions(const QMap<QString, QPair<qreal, qreal> > &r
QDomElement restrictionTag = createElement(TagRestriction);
SetAttribute(restrictionTag, AttrCoordinates, i.key());
SetAttributeOrRemoveIf(restrictionTag, AttrMin, i.value().first, qFuzzyIsNull(i.value().first));
SetAttributeOrRemoveIf(restrictionTag, AttrMax, i.value().second, qFuzzyIsNull(i.value().second));
SetAttributeOrRemoveIf(restrictionTag, AttrMin, i.value().GetMin(), qFuzzyIsNull(i.value().GetMin()));
SetAttributeOrRemoveIf(restrictionTag, AttrMax, i.value().GetMax(), qFuzzyIsNull(i.value().GetMax()));
SetAttributeOrRemoveIf(restrictionTag, AttrExclude, i.value().GetExcludeString(),
i.value().GetExcludeString().isEmpty());
restrictionsTag.appendChild(restrictionTag);
++i;
@ -950,11 +954,11 @@ void VMeasurements::SetRestrictions(const QMap<QString, QPair<qreal, qreal> > &r
}
//---------------------------------------------------------------------------------------------------------------------
auto VMeasurements::Restriction(qreal base, qreal base2) const -> QPair<qreal, qreal>
auto VMeasurements::Restriction(qreal base, qreal base2) const -> VDimensionRestriction
{
const QMap<QString, QPair<qreal, qreal> > restrictions = GetRestrictions();
const QMap<QString, VDimensionRestriction > restrictions = GetRestrictions();
const QString hash = VMeasurement::CorrectionHash(base, base2, 0);
return restrictions.value(hash, QPair<qreal, qreal>(0, 0));
return restrictions.value(hash);
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -119,9 +119,9 @@ public:
auto Dimensions() const -> QMap<MeasurementDimension, MeasurementDimension_p >;
auto GetRestrictions() const -> QMap<QString, QPair<qreal, qreal> >;
void SetRestrictions(const QMap<QString, QPair<qreal, qreal> > &restrictions);
auto Restriction(qreal base, qreal base2=0) const -> QPair<double, double>;
auto GetRestrictions() const -> QMap<QString, VDimensionRestriction >;
void SetRestrictions(const QMap<QString, VDimensionRestriction > &restrictions);
auto Restriction(qreal base, qreal base2=0) const -> VDimensionRestriction;
void SetDimensionLabels(const QMap<MeasurementDimension, DimesionLabels> &labels);
@ -153,6 +153,7 @@ public:
static const QString AttrShiftC;
static const QString AttrCorrection;
static const QString AttrCoordinates;
static const QString AttrExclude;
static const QString AttrSpecialUnits;
static const QString AttrDescription;
static const QString AttrName;