diff --git a/ChangeLog.txt b/ChangeLog.txt index e660ee814..219eb4238 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,4 +1,5 @@ # Version 0.5.0 +- [#24] User can now add labels with different information on the detail - [#505] New installer script based on Inno Setup 5. - Size of preferences dialog in both Valentina and Tape app is now preserved between sessions - [#479] Preferences dialog is now extendable and when it is opened again, it will be resized to its previous size. diff --git a/src/app/valentina/dialogs/dialogpatternproperties.cpp b/src/app/valentina/dialogs/dialogpatternproperties.cpp index 373158a44..6792ab260 100644 --- a/src/app/valentina/dialogs/dialogpatternproperties.cpp +++ b/src/app/valentina/dialogs/dialogpatternproperties.cpp @@ -55,6 +55,7 @@ DialogPatternProperties::DialogPatternProperties(const QString &filePath, VPatte gradationChanged(false), defaultChanged(false), securityChanged(false), + generalInfoChanged(false), deleteAction(nullptr), changeImageAction(nullptr), saveImageAction(nullptr), @@ -164,6 +165,32 @@ DialogPatternProperties::DialogPatternProperties(const QString &filePath, VPatte gradationChanged = false; defaultChanged = false; securityChanged = false; + + ui->lineEditPatternName->setText(doc->GetPatternName()); + ui->lineEditPatternNumber->setText(doc->GetPatternNumber()); + ui->lineEditCompanyName->setText(doc->GetCompanyName()); + ui->lineEditCustomerName->setText(doc->GetCustomerName()); + ui->labelCreationDate->setText(QDate::currentDate().toString(Qt::SystemLocaleLongDate)); + ui->lineEditSize->setText(doc->GetPatternSize()); + ui->checkBoxShowDate->setChecked(doc->IsDateVisible()); + if (doc->MPath().isEmpty() == true) + { + ui->checkBoxShowMeasurements->setChecked(false); + ui->checkBoxShowMeasurements->setEnabled(false); + } + else + { + ui->checkBoxShowMeasurements->setChecked(doc->IsMeasurementsVisible()); + } + + + connect(ui->lineEditPatternName, &QLineEdit::editingFinished, this, &DialogPatternProperties::GeneralInfoChanged); + connect(ui->lineEditPatternNumber, &QLineEdit::editingFinished, this, &DialogPatternProperties::GeneralInfoChanged); + connect(ui->lineEditCompanyName, &QLineEdit::editingFinished, this, &DialogPatternProperties::GeneralInfoChanged); + connect(ui->lineEditCustomerName, &QLineEdit::editingFinished, this, &DialogPatternProperties::GeneralInfoChanged); + connect(ui->lineEditSize, &QLineEdit::editingFinished, this, &DialogPatternProperties::GeneralInfoChanged); + connect(ui->checkBoxShowDate, &QCheckBox::stateChanged, this, &DialogPatternProperties::GeneralInfoChanged); + connect(ui->checkBoxShowMeasurements, &QCheckBox::stateChanged, this, &DialogPatternProperties::GeneralInfoChanged); } //--------------------------------------------------------------------------------------------------------------------- @@ -194,6 +221,12 @@ void DialogPatternProperties::Apply() securityChanged = false; emit doc->patternChanged(false); break; + case 3: + SaveGeneralInfo(); + generalInfoChanged = false; + emit doc->patternChanged(false); + break; + default: break; } @@ -230,6 +263,13 @@ void DialogPatternProperties::Ok() emit doc->patternChanged(false); } + if (generalInfoChanged == true) + { + SaveGeneralInfo(); + generalInfoChanged = false; + emit doc->patternChanged(false); + } + close(); } @@ -364,6 +404,31 @@ void DialogPatternProperties::DescEdited() descriptionChanged = true; } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPatternProperties::ToggleComboBox() +{ + ui->comboBoxHeight->setEnabled(ui->radioButtonDefFromP->isChecked()); + ui->comboBoxSize->setEnabled(ui->radioButtonDefFromP->isChecked()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPatternProperties::DefValueChanged() +{ + defaultChanged = true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPatternProperties::SecurityValueChanged() +{ + securityChanged = true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogPatternProperties::GeneralInfoChanged() +{ + generalInfoChanged = true; +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPatternProperties::SetHeightsChecked(bool enabled) { @@ -500,6 +565,18 @@ void DialogPatternProperties::SaveDefValues() defaultChanged = false; } +//--------------------------------------------------------------------------------------------------------------------- +void DialogPatternProperties::SaveGeneralInfo() +{ + doc->SetPatternName(ui->lineEditPatternName->text()); + doc->SetPatternNumber(ui->lineEditPatternNumber->text()); + doc->SetCompanyName(ui->lineEditCompanyName->text()); + doc->SetCustomerName(ui->lineEditCustomerName->text()); + doc->SetPatternSize(ui->lineEditSize->text()); + doc->SetDateVisible(ui->checkBoxShowDate->isChecked()); + doc->SetMesurementsVisible(ui->checkBoxShowMeasurements->isChecked()); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogPatternProperties::SetDefaultHeight(const QString &def) { diff --git a/src/app/valentina/dialogs/dialogpatternproperties.h b/src/app/valentina/dialogs/dialogpatternproperties.h index b3e2cc731..0c26a8661 100644 --- a/src/app/valentina/dialogs/dialogpatternproperties.h +++ b/src/app/valentina/dialogs/dialogpatternproperties.h @@ -52,6 +52,10 @@ public: signals: void UpdateGradation(); private slots: + void ToggleComboBox(); + void DefValueChanged(); + void SecurityValueChanged(); + void GeneralInfoChanged(); void Apply(); void Ok(); void SelectAll(int state); @@ -74,6 +78,7 @@ private: bool gradationChanged; bool defaultChanged; bool securityChanged; + bool generalInfoChanged; QAction *deleteAction; QAction *changeImageAction; QAction *saveImageAction; @@ -94,6 +99,7 @@ private: void SaveDescription(); void SaveGradation(); void SaveDefValues(); + void SaveGeneralInfo(); void SetDefaultHeight(const QString &def); void SetDefaultSize(const QString &def); diff --git a/src/app/valentina/dialogs/dialogpatternproperties.ui b/src/app/valentina/dialogs/dialogpatternproperties.ui index a236c93fa..69e597dfc 100644 --- a/src/app/valentina/dialogs/dialogpatternproperties.ui +++ b/src/app/valentina/dialogs/dialogpatternproperties.ui @@ -21,7 +21,7 @@ - 0 + 3 @@ -1043,6 +1043,124 @@ + + + General info + + + + + 10 + 10 + 401 + 241 + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Pattern name: + + + + + + + 30 + + + + + + + Pattern number: + + + + + + + 30 + + + + + + + Company/Designer name: + + + + + + + 30 + + + + + + + Customer name: + + + + + + + 30 + + + + + + + + + + + + + + Created: + + + + + + + Pattern size: + + + + + + + 30 + + + + + + + Show measurements + + + + + + + Show date of creation + + + + + + diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index 121990bfb..d481ac942 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -37,6 +37,8 @@ #include "dialogs/dialoglayoutprogress.h" #include "dialogs/dialogsavelayout.h" #include "../vlayout/vposter.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vpatterninfogeometry.h" #include #include @@ -472,7 +474,24 @@ void MainWindowsNoGUI::PrepareDetailsForLayout(const QHash *de det.SetCountourPoints(d.ContourPoints(pattern)); det.SetSeamAllowencePoints(d.SeamAllowancePoints(pattern), d.getSeamAllowance(), d.getClosed()); det.setName(d.getName()); + const VPatternPieceData& data = d.GetPatternPieceData(); + if (data.IsVisible() == true) + { + det.SetDetail(d.getName(), data, qApp->font()); + } + const VPatternInfoGeometry& geom = d.GetPatternInfo(); + if (geom.IsVisible() == true) + { + VAbstractPattern* pDoc = qApp->getCurrentDocument(); + QDate date; + if (pDoc->IsDateVisible() == true) + { + date = QDate::currentDate(); + } + det.SetPatternInfo(pDoc, geom, qApp->font()); + } det.setWidth(qApp->toPixel(d.getWidth())); + det.CreateTextItems(); listDetails.append(det); ++i; diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp index 6bfd1b954..9a3169d1a 100644 --- a/src/app/valentina/xml/vpattern.cpp +++ b/src/app/valentina/xml/vpattern.cpp @@ -48,6 +48,8 @@ #include "../vgeometry/vcubicbezierpath.h" #include "../core/vapplication.h" #include "../vpatterndb/calculator.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vpatterninfogeometry.h" #include #include @@ -131,7 +133,9 @@ void VPattern::Parse(const Document &parse) SCASSERT(sceneDraw != nullptr); SCASSERT(sceneDetail != nullptr); QStringList tags = QStringList() << TagDraw << TagIncrements << TagAuthor << TagDescription << TagNotes - << TagMeasurements << TagVersion << TagGradation << TagImage << TagUnit; + << TagMeasurements << TagVersion << TagGradation << TagImage << TagUnit + << TagPatternName << TagPatternNum << TagCompanyName << TagCustomerName + << TagSize << TagShowDate << TagShowMeasurements; PrepareForParse(parse); QDomNode domNode = documentElement().firstChild(); while (domNode.isNull() == false) @@ -191,6 +195,27 @@ void VPattern::Parse(const Document &parse) case 9: // TagUnit qCDebug(vXML, "Tag unit."); break; + case 10: // TagPatternName + qCDebug(vXML, "Pattern name."); + break; + case 11: // TagPatternNumber + qCDebug(vXML, "Pattern number."); + break; + case 12: // TagCompanyName + qCDebug(vXML, "Company name."); + break; + case 13: // TagCustomerName + qCDebug(vXML, "Customer name."); + break; + case 14: // TagSize + qCDebug(vXML, "Size"); + break; + case 15: + qCDebug(vXML, "Show creation date"); + break; + case 16: + qCDebug(vXML, "Show measurements"); + break; default: qCDebug(vXML, "Wrong tag name %s", qUtf8Printable(domElement.tagName())); break; @@ -633,6 +658,59 @@ void VPattern::ParseDetailElement(const QDomElement &domElement, const Document } detail.append(VNodeDetail(id, tool, nodeType, mx, my, reverse)); } + else if (element.tagName() == TagData) + { + bool bVisible = GetParametrBool(element, AttrVisible, trueStr); + detail.GetPatternPieceData().SetVisible(bVisible); + try + { + QString qsLetter = GetParametrString(element, AttrLetter, ""); + detail.GetPatternPieceData().SetLetter(qsLetter); + } catch(...) + { + detail.GetPatternPieceData().SetLetter(""); + } + QPointF ptPos; + ptPos.setX(GetParametrDouble(element, AttrMx, "0")); + ptPos.setY(GetParametrDouble(element, AttrMy, "0")); + detail.GetPatternPieceData().SetPos(ptPos); + qreal dLW = GetParametrDouble(element, VToolDetail::AttrWidth, "0"); + detail.GetPatternPieceData().SetLabelWidth(dLW); + qreal dLH = GetParametrDouble(element, VToolDetail::AttrHeight, "0"); + detail.GetPatternPieceData().SetLabelHeight(dLH); + int iFS = GetParametrUInt(element, VToolDetail::AttrFont, "0"); + detail.GetPatternPieceData().SetFontSize(iFS); + qreal dRot = GetParametrDouble(element, VToolDetail::AttrRotation, "0"); + detail.GetPatternPieceData().SetRotation(dRot); + + QDomNodeList nodeListMCP = element.childNodes(); + for (int iMCP = 0; iMCP < nodeListMCP.count(); ++iMCP) + { + MaterialCutPlacement mcp; + QDomElement domMCP = nodeListMCP.at(iMCP).toElement(); + mcp.m_eMaterial = MaterialType(GetParametrUInt(domMCP, AttrMaterial, 0)); + mcp.m_qsMaterialUserDef = GetParametrString(domMCP, AttrUserDefined, ""); + mcp.m_iCutNumber = GetParametrUInt(domMCP, AttrCutNumber, 0); + mcp.m_ePlacement = PlacementType(GetParametrUInt(domMCP, AttrPlacement, 0)); + detail.GetPatternPieceData().Append(mcp); + } + } + else if (element.tagName() == TagPatternInfo) + { + detail.GetPatternInfo().SetVisible(GetParametrBool(element, AttrVisible, trueStr)); + QPointF ptPos; + ptPos.setX(GetParametrDouble(element, AttrMx, "0")); + ptPos.setY(GetParametrDouble(element, AttrMy, "0")); + detail.GetPatternInfo().SetPos(ptPos); + qreal dLW = GetParametrDouble(element, VToolDetail::AttrWidth, "0"); + detail.GetPatternInfo().SetLabelWidth(dLW); + qreal dLH = GetParametrDouble(element, VToolDetail::AttrHeight, "0"); + detail.GetPatternInfo().SetLabelHeight(dLH); + int iFS = GetParametrUInt(element, VToolDetail::AttrFont, "0"); + detail.GetPatternInfo().SetFontSize(iFS); + qreal dRot = GetParametrDouble(element, VToolDetail::AttrRotation, "0"); + detail.GetPatternInfo().SetRotation(dRot); + } } } VToolDetail::Create(id, detail, sceneDetail, this, data, parse, Source::FromFile); diff --git a/src/libs/ifc/schema.qrc b/src/libs/ifc/schema.qrc index fe077d4dc..9b8a3e493 100644 --- a/src/libs/ifc/schema.qrc +++ b/src/libs/ifc/schema.qrc @@ -16,6 +16,7 @@ schema/pattern/v0.3.0.xsd schema/pattern/v0.3.1.xsd schema/pattern/v0.3.2.xsd + schema/pattern/v0.3.3.xsd schema/standard_measurements/v0.3.0.xsd schema/standard_measurements/v0.4.0.xsd schema/standard_measurements/v0.4.1.xsd diff --git a/src/libs/ifc/schema/pattern/v0.3.3.xsd b/src/libs/ifc/schema/pattern/v0.3.3.xsd new file mode 100644 index 000000000..5084f71c1 --- /dev/null +++ b/src/libs/ifc/schema/pattern/v0.3.3.xsd @@ -0,0 +1,571 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index 015f57b62..5818b4aaa 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -34,83 +34,98 @@ #include "../exception/vexceptionobjecterror.h" #include "../vtools/tools/vdatatool.h" -const QString VAbstractPattern::TagPattern = QStringLiteral("pattern"); -const QString VAbstractPattern::TagCalculation = QStringLiteral("calculation"); -const QString VAbstractPattern::TagModeling = QStringLiteral("modeling"); -const QString VAbstractPattern::TagDetails = QStringLiteral("details"); -const QString VAbstractPattern::TagDetail = QStringLiteral("detail"); -const QString VAbstractPattern::TagAuthor = QStringLiteral("author"); -const QString VAbstractPattern::TagDescription = QStringLiteral("description"); -const QString VAbstractPattern::TagNotes = QStringLiteral("notes"); -const QString VAbstractPattern::TagImage = QStringLiteral("image"); -const QString VAbstractPattern::TagMeasurements = QStringLiteral("measurements"); -const QString VAbstractPattern::TagIncrements = QStringLiteral("increments"); -const QString VAbstractPattern::TagIncrement = QStringLiteral("increment"); -const QString VAbstractPattern::TagDraw = QStringLiteral("draw"); -const QString VAbstractPattern::TagGroups = QStringLiteral("groups"); -const QString VAbstractPattern::TagGroup = QStringLiteral("group"); -const QString VAbstractPattern::TagGroupItem = QStringLiteral("item"); -const QString VAbstractPattern::TagPoint = QStringLiteral("point"); -const QString VAbstractPattern::TagLine = QStringLiteral("line"); -const QString VAbstractPattern::TagSpline = QStringLiteral("spline"); -const QString VAbstractPattern::TagArc = QStringLiteral("arc"); -const QString VAbstractPattern::TagTools = QStringLiteral("tools"); -const QString VAbstractPattern::TagOperation = QStringLiteral("operation"); -const QString VAbstractPattern::TagGradation = QStringLiteral("gradation"); -const QString VAbstractPattern::TagHeights = QStringLiteral("heights"); -const QString VAbstractPattern::TagSizes = QStringLiteral("sizes"); -const QString VAbstractPattern::TagUnit = QStringLiteral("unit"); +const QString VAbstractPattern::TagPattern = QStringLiteral("pattern"); +const QString VAbstractPattern::TagCalculation = QStringLiteral("calculation"); +const QString VAbstractPattern::TagModeling = QStringLiteral("modeling"); +const QString VAbstractPattern::TagDetails = QStringLiteral("details"); +const QString VAbstractPattern::TagDetail = QStringLiteral("detail"); +const QString VAbstractPattern::TagAuthor = QStringLiteral("author"); +const QString VAbstractPattern::TagDescription = QStringLiteral("description"); +const QString VAbstractPattern::TagNotes = QStringLiteral("notes"); +const QString VAbstractPattern::TagImage = QStringLiteral("image"); +const QString VAbstractPattern::TagMeasurements = QStringLiteral("measurements"); +const QString VAbstractPattern::TagIncrements = QStringLiteral("increments"); +const QString VAbstractPattern::TagIncrement = QStringLiteral("increment"); +const QString VAbstractPattern::TagDraw = QStringLiteral("draw"); +const QString VAbstractPattern::TagGroups = QStringLiteral("groups"); +const QString VAbstractPattern::TagGroup = QStringLiteral("group"); +const QString VAbstractPattern::TagGroupItem = QStringLiteral("item"); +const QString VAbstractPattern::TagPoint = QStringLiteral("point"); +const QString VAbstractPattern::TagLine = QStringLiteral("line"); +const QString VAbstractPattern::TagSpline = QStringLiteral("spline"); +const QString VAbstractPattern::TagArc = QStringLiteral("arc"); +const QString VAbstractPattern::TagTools = QStringLiteral("tools"); +const QString VAbstractPattern::TagOperation = QStringLiteral("operation"); +const QString VAbstractPattern::TagGradation = QStringLiteral("gradation"); +const QString VAbstractPattern::TagHeights = QStringLiteral("heights"); +const QString VAbstractPattern::TagSizes = QStringLiteral("sizes"); +const QString VAbstractPattern::TagUnit = QStringLiteral("unit"); +const QString VAbstractPattern::TagData = QStringLiteral("data"); +const QString VAbstractPattern::TagPatternInfo = QStringLiteral("patternInfo"); +const QString VAbstractPattern::TagMCP = QStringLiteral("mcp"); +const QString VAbstractPattern::TagPatternName = QStringLiteral("patternName"); +const QString VAbstractPattern::TagPatternNum = QStringLiteral("patternNumber"); +const QString VAbstractPattern::TagCustomerName = QStringLiteral("customer"); +const QString VAbstractPattern::TagCompanyName = QStringLiteral("company"); +const QString VAbstractPattern::TagSize = QStringLiteral("size"); +const QString VAbstractPattern::TagShowDate = QStringLiteral("showDate"); +const QString VAbstractPattern::TagShowMeasurements = QStringLiteral("showMeasurements"); -const QString VAbstractPattern::AttrName = QStringLiteral("name"); -const QString VAbstractPattern::AttrVisible = QStringLiteral("visible"); -const QString VAbstractPattern::AttrObject = QStringLiteral("object"); -const QString VAbstractPattern::AttrTool = QStringLiteral("tool"); -const QString VAbstractPattern::AttrType = QStringLiteral("type"); +const QString VAbstractPattern::AttrName = QStringLiteral("name"); +const QString VAbstractPattern::AttrVisible = QStringLiteral("visible"); +const QString VAbstractPattern::AttrObject = QStringLiteral("object"); +const QString VAbstractPattern::AttrTool = QStringLiteral("tool"); +const QString VAbstractPattern::AttrType = QStringLiteral("type"); +const QString VAbstractPattern::AttrLetter = QStringLiteral("letter"); +const QString VAbstractPattern::AttrMaterial = QStringLiteral("material"); +const QString VAbstractPattern::AttrUserDefined = QStringLiteral("userDef"); +const QString VAbstractPattern::AttrCutNumber = QStringLiteral("cutNumber"); +const QString VAbstractPattern::AttrPlacement = QStringLiteral("placement"); -const QString VAbstractPattern::AttrAll = QStringLiteral("all"); +const QString VAbstractPattern::AttrAll = QStringLiteral("all"); -const QString VAbstractPattern::AttrH92 = QStringLiteral("h92"); -const QString VAbstractPattern::AttrH98 = QStringLiteral("h98"); -const QString VAbstractPattern::AttrH104 = QStringLiteral("h104"); -const QString VAbstractPattern::AttrH110 = QStringLiteral("h110"); -const QString VAbstractPattern::AttrH116 = QStringLiteral("h116"); -const QString VAbstractPattern::AttrH122 = QStringLiteral("h122"); -const QString VAbstractPattern::AttrH128 = QStringLiteral("h128"); -const QString VAbstractPattern::AttrH134 = QStringLiteral("h134"); -const QString VAbstractPattern::AttrH140 = QStringLiteral("h140"); -const QString VAbstractPattern::AttrH146 = QStringLiteral("h146"); -const QString VAbstractPattern::AttrH152 = QStringLiteral("h152"); -const QString VAbstractPattern::AttrH158 = QStringLiteral("h158"); -const QString VAbstractPattern::AttrH164 = QStringLiteral("h164"); -const QString VAbstractPattern::AttrH170 = QStringLiteral("h170"); -const QString VAbstractPattern::AttrH176 = QStringLiteral("h176"); -const QString VAbstractPattern::AttrH182 = QStringLiteral("h182"); -const QString VAbstractPattern::AttrH188 = QStringLiteral("h188"); -const QString VAbstractPattern::AttrH194 = QStringLiteral("h194"); +const QString VAbstractPattern::AttrH92 = QStringLiteral("h92"); +const QString VAbstractPattern::AttrH98 = QStringLiteral("h98"); +const QString VAbstractPattern::AttrH104 = QStringLiteral("h104"); +const QString VAbstractPattern::AttrH110 = QStringLiteral("h110"); +const QString VAbstractPattern::AttrH116 = QStringLiteral("h116"); +const QString VAbstractPattern::AttrH122 = QStringLiteral("h122"); +const QString VAbstractPattern::AttrH128 = QStringLiteral("h128"); +const QString VAbstractPattern::AttrH134 = QStringLiteral("h134"); +const QString VAbstractPattern::AttrH140 = QStringLiteral("h140"); +const QString VAbstractPattern::AttrH146 = QStringLiteral("h146"); +const QString VAbstractPattern::AttrH152 = QStringLiteral("h152"); +const QString VAbstractPattern::AttrH158 = QStringLiteral("h158"); +const QString VAbstractPattern::AttrH164 = QStringLiteral("h164"); +const QString VAbstractPattern::AttrH170 = QStringLiteral("h170"); +const QString VAbstractPattern::AttrH176 = QStringLiteral("h176"); +const QString VAbstractPattern::AttrH182 = QStringLiteral("h182"); +const QString VAbstractPattern::AttrH188 = QStringLiteral("h188"); +const QString VAbstractPattern::AttrH194 = QStringLiteral("h194"); -const QString VAbstractPattern::AttrS22 = QStringLiteral("s22"); -const QString VAbstractPattern::AttrS24 = QStringLiteral("s24"); -const QString VAbstractPattern::AttrS26 = QStringLiteral("s26"); -const QString VAbstractPattern::AttrS28 = QStringLiteral("s28"); -const QString VAbstractPattern::AttrS30 = QStringLiteral("s30"); -const QString VAbstractPattern::AttrS32 = QStringLiteral("s32"); -const QString VAbstractPattern::AttrS34 = QStringLiteral("s34"); -const QString VAbstractPattern::AttrS36 = QStringLiteral("s36"); -const QString VAbstractPattern::AttrS38 = QStringLiteral("s38"); -const QString VAbstractPattern::AttrS40 = QStringLiteral("s40"); -const QString VAbstractPattern::AttrS42 = QStringLiteral("s42"); -const QString VAbstractPattern::AttrS44 = QStringLiteral("s44"); -const QString VAbstractPattern::AttrS46 = QStringLiteral("s46"); -const QString VAbstractPattern::AttrS48 = QStringLiteral("s48"); -const QString VAbstractPattern::AttrS50 = QStringLiteral("s50"); -const QString VAbstractPattern::AttrS52 = QStringLiteral("s52"); -const QString VAbstractPattern::AttrS54 = QStringLiteral("s54"); -const QString VAbstractPattern::AttrS56 = QStringLiteral("s56"); +const QString VAbstractPattern::AttrS22 = QStringLiteral("s22"); +const QString VAbstractPattern::AttrS24 = QStringLiteral("s24"); +const QString VAbstractPattern::AttrS26 = QStringLiteral("s26"); +const QString VAbstractPattern::AttrS28 = QStringLiteral("s28"); +const QString VAbstractPattern::AttrS30 = QStringLiteral("s30"); +const QString VAbstractPattern::AttrS32 = QStringLiteral("s32"); +const QString VAbstractPattern::AttrS34 = QStringLiteral("s34"); +const QString VAbstractPattern::AttrS36 = QStringLiteral("s36"); +const QString VAbstractPattern::AttrS38 = QStringLiteral("s38"); +const QString VAbstractPattern::AttrS40 = QStringLiteral("s40"); +const QString VAbstractPattern::AttrS42 = QStringLiteral("s42"); +const QString VAbstractPattern::AttrS44 = QStringLiteral("s44"); +const QString VAbstractPattern::AttrS46 = QStringLiteral("s46"); +const QString VAbstractPattern::AttrS48 = QStringLiteral("s48"); +const QString VAbstractPattern::AttrS50 = QStringLiteral("s50"); +const QString VAbstractPattern::AttrS52 = QStringLiteral("s52"); +const QString VAbstractPattern::AttrS54 = QStringLiteral("s54"); +const QString VAbstractPattern::AttrS56 = QStringLiteral("s56"); -const QString VAbstractPattern::AttrCustom = QStringLiteral("custom"); -const QString VAbstractPattern::AttrDefHeight = QStringLiteral("defHeight"); -const QString VAbstractPattern::AttrDefSize = QStringLiteral("defSize"); -const QString VAbstractPattern::AttrExtension = QStringLiteral("extension"); +const QString VAbstractPattern::AttrCustom = QStringLiteral("custom"); +const QString VAbstractPattern::AttrDefHeight = QStringLiteral("defHeight"); +const QString VAbstractPattern::AttrDefSize = QStringLiteral("defSize"); +const QString VAbstractPattern::AttrExtension = QStringLiteral("extension"); const QString VAbstractPattern::IncrementName = QStringLiteral("name"); const QString VAbstractPattern::IncrementFormula = QStringLiteral("formula"); @@ -980,6 +995,111 @@ void VAbstractPattern::SetNotes(const QString &text) emit patternChanged(false); } +//--------------------------------------------------------------------------------------------------------------------- +QString VAbstractPattern::GetPatternName() const +{ + return UniqueTagText(TagPatternName); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetPatternName(const QString &qsName) +{ + CheckTagExists(TagPatternName); + setTagText(TagPatternName, qsName); + modified = true; + emit patternChanged(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VAbstractPattern::GetCompanyName() const +{ + return UniqueTagText(TagCompanyName); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetCompanyName(const QString& qsName) +{ + CheckTagExists(TagCompanyName); + setTagText(TagCompanyName, qsName); + modified = true; + emit patternChanged(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VAbstractPattern::GetPatternNumber() const +{ + return UniqueTagText(TagPatternNum); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetPatternNumber(const QString& qsNum) +{ + CheckTagExists(TagPatternNum); + setTagText(TagPatternNum, qsNum); + modified = true; + emit patternChanged(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VAbstractPattern::GetCustomerName() const +{ + return UniqueTagText(TagCustomerName); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetCustomerName(const QString& qsName) +{ + CheckTagExists(TagCustomerName); + setTagText(TagCustomerName, qsName); + modified = true; + emit patternChanged(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +QString VAbstractPattern::GetPatternSize() const +{ + return UniqueTagText(TagSize); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetPatternSize(const QString& qsSize) +{ + CheckTagExists(TagSize); + setTagText(TagSize, qsSize); + modified = true; + emit patternChanged(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPattern::IsDateVisible() const +{ + return UniqueTagText(TagShowDate) != falseStr; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetDateVisible(bool bVisible) +{ + CheckTagExists(TagShowDate); + setTagText(TagShowDate, bVisible == true? trueStr : falseStr); + modified = true; + emit patternChanged(false); +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VAbstractPattern::IsMeasurementsVisible() const +{ + return UniqueTagText(TagShowMeasurements) == trueStr; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VAbstractPattern::SetMesurementsVisible(bool bVisible) +{ + CheckTagExists(TagShowMeasurements); + setTagText(TagShowMeasurements, bVisible == true? trueStr : falseStr); + modified = true; + emit patternChanged(false); +} + //--------------------------------------------------------------------------------------------------------------------- QString VAbstractPattern::GetImage() const { @@ -1093,7 +1213,8 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag) if (list.isEmpty()) { const QStringList tags = QStringList() << TagUnit << TagImage << TagAuthor << TagDescription << TagNotes - << TagGradation; + << TagGradation << TagPatternName << TagPatternNum << TagCompanyName + << TagCustomerName << TagSize << TagShowDate << TagShowMeasurements; switch (tags.indexOf(tag)) { case 0: //TagUnit @@ -1134,6 +1255,42 @@ QDomElement VAbstractPattern::CheckTagExists(const QString &tag) element.appendChild(sizes); break; } + case 6: // TagPatternName + { + element = createElement(TagPatternName); + break; + } + case 7: // TagPatternNum + { + element = createElement(TagPatternNum); + break; + } + case 8: // TagCompanyName + { + element = createElement(TagCompanyName); + break; + } + case 9: // TagCustomerName + { + element = createElement(TagCustomerName); + break; + } + case 10: // TagSize + { + element = createElement(TagSize); + break; + } + case 11: // TagShowDate + { + element = createElement(TagShowDate); + break; + } + case 12: // TagShowMeasurements + { + element = createElement(TagShowMeasurements); + break; + } + default: { return QDomElement(); diff --git a/src/libs/ifc/xml/vabstractpattern.h b/src/libs/ifc/xml/vabstractpattern.h index 1788c8ca9..873b6d1b9 100644 --- a/src/libs/ifc/xml/vabstractpattern.h +++ b/src/libs/ifc/xml/vabstractpattern.h @@ -33,6 +33,7 @@ #include "vtoolrecord.h" #include +#include enum class Document : char { LiteParse, LitePPParse, FullParse }; enum class LabelType : char {NewPatternPiece, NewLabel}; @@ -107,6 +108,21 @@ public: QString GetNotes() const; void SetNotes(const QString &text); + QString GetPatternName() const; + void SetPatternName(const QString& qsName); + QString GetCompanyName() const; + void SetCompanyName(const QString& qsName); + QString GetPatternNumber() const; + void SetPatternNumber(const QString &qsNum); + QString GetCustomerName() const; + void SetCustomerName(const QString& qsName); + QString GetPatternSize() const; + void SetPatternSize(const QString &qsSize); + bool IsDateVisible() const; + void SetDateVisible(bool bVisible); + bool IsMeasurementsVisible() const; + void SetMesurementsVisible(bool bVisible); + QString GetImage() const; QString GetImageExtension() const; void SetImage(const QString &text, const QString &extension); @@ -155,12 +171,27 @@ public: static const QString TagHeights; static const QString TagSizes; static const QString TagUnit; + static const QString TagData; + static const QString TagPatternInfo; + static const QString TagMCP; + static const QString TagPatternName; + static const QString TagPatternNum; + static const QString TagCompanyName; + static const QString TagCustomerName; + static const QString TagSize; + static const QString TagShowDate; + static const QString TagShowMeasurements; static const QString AttrName; static const QString AttrVisible; static const QString AttrObject; static const QString AttrTool; static const QString AttrType; + static const QString AttrLetter; + static const QString AttrMaterial; + static const QString AttrUserDefined; + static const QString AttrCutNumber; + static const QString AttrPlacement; static const QString AttrAll; @@ -284,6 +315,8 @@ protected: QDomElement CheckTagExists(const QString &tag); void InsertTag(const QStringList &tags, const QDomElement &element); + void SetChildTag(const QString& qsParent, const QString& qsChild, const QString& qsValue); + int GetIndexActivPP() const; private: Q_DISABLE_COPY(VAbstractPattern) diff --git a/src/libs/ifc/xml/vpatternconverter.cpp b/src/libs/ifc/xml/vpatternconverter.cpp index f9170188c..5723fadca 100644 --- a/src/libs/ifc/xml/vpatternconverter.cpp +++ b/src/libs/ifc/xml/vpatternconverter.cpp @@ -43,8 +43,8 @@ */ const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0"); -const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.3.2"); -const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.3.2.xsd"); +const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.3.3"); +const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.3.3.xsd"); constexpr int VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! constexpr int VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! @@ -96,6 +96,8 @@ QString VPatternConverter::XSDSchema(int ver) const case (0x000301): return QStringLiteral("://schema/pattern/v0.3.1.xsd"); case (0x000302): + return QStringLiteral("://schema/pattern/v0.3.2.xsd"); + case (0x000303): return CurrentSchema; default: InvalidVersion(ver); @@ -171,6 +173,10 @@ void VPatternConverter::ApplyPatches() ValidateXML(XSDSchema(0x000302), fileName); V_FALLTHROUGH case (0x000302): + ToV0_3_3(); + ValidateXML(XSDSchema(0x000303), fileName); + V_FALLTHROUGH + case (0x000303): break; default: break; @@ -314,6 +320,13 @@ void VPatternConverter::ToV0_3_2() Save(); } +//--------------------------------------------------------------------------------------------------------------------- +void VPatternConverter::ToV0_3_3() +{ + SetVersion(QStringLiteral("0.3.3")); + Save(); +} + //--------------------------------------------------------------------------------------------------------------------- void VPatternConverter::TagUnitToV0_2_0() { diff --git a/src/libs/ifc/xml/vpatternconverter.h b/src/libs/ifc/xml/vpatternconverter.h index cbecfa5f0..76c0caa71 100644 --- a/src/libs/ifc/xml/vpatternconverter.h +++ b/src/libs/ifc/xml/vpatternconverter.h @@ -41,7 +41,7 @@ public: static const QString PatternMaxVerStr; static const QString CurrentSchema; static constexpr int PatternMinVer = CONVERTER_VERSION_CHECK(0, 1, 0); - static constexpr int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 3, 2); + static constexpr int PatternMaxVer = CONVERTER_VERSION_CHECK(0, 3, 3); protected: virtual int MinVer() const Q_DECL_OVERRIDE; @@ -73,6 +73,7 @@ private: void ToV0_3_0(); void ToV0_3_1(); void ToV0_3_2(); + void ToV0_3_3(); void TagUnitToV0_2_0(); void TagIncrementToV0_2_0(); diff --git a/src/libs/vlayout/vlayout.pri b/src/libs/vlayout/vlayout.pri index 171d943cd..d1cc7645f 100644 --- a/src/libs/vlayout/vlayout.pri +++ b/src/libs/vlayout/vlayout.pri @@ -16,6 +16,7 @@ HEADERS += \ $$PWD/vcontour_p.h \ $$PWD/vbestsquare.h \ $$PWD/vposition.h \ + $$PWD/vtextmanager.h \ vposter.h SOURCES += \ @@ -27,6 +28,7 @@ SOURCES += \ $$PWD/vcontour.cpp \ $$PWD/vbestsquare.cpp \ $$PWD/vposition.cpp \ + $$PWD/vtextmanager.cpp \ vposter.cpp win32-msvc*:SOURCES += $$PWD/stable.cpp diff --git a/src/libs/vlayout/vlayout.pro b/src/libs/vlayout/vlayout.pro index 0a77c8638..de7ae8b22 100644 --- a/src/libs/vlayout/vlayout.pro +++ b/src/libs/vlayout/vlayout.pro @@ -7,7 +7,7 @@ # File with common stuff for whole project include(../../../common.pri) -QT += core gui widgets printsupport +QT += core gui widgets printsupport xml # Name of library TARGET = vlayout diff --git a/src/libs/vlayout/vlayoutdetail.cpp b/src/libs/vlayout/vlayoutdetail.cpp index 7cf91035a..aae990633 100644 --- a/src/libs/vlayout/vlayoutdetail.cpp +++ b/src/libs/vlayout/vlayoutdetail.cpp @@ -31,6 +31,9 @@ #include #include +#include +#include +#include #if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) # include "../vmisc/vmath.h" @@ -47,7 +50,7 @@ VLayoutDetail::VLayoutDetail() //--------------------------------------------------------------------------------------------------------------------- VLayoutDetail::VLayoutDetail(const VLayoutDetail &detail) - :VAbstractDetail(detail), d (detail.d) + :VAbstractDetail(detail), d(detail.d) {} //--------------------------------------------------------------------------------------------------------------------- @@ -112,6 +115,59 @@ QVector VLayoutDetail::GetLayoutAllowencePoints() const return Map(d->layoutAllowence); } +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutDetail::SetDetail(const QString& qsName, const VPatternPieceData& data, const QFont &font) +{ + d->detailData = data; + qreal dAng = qDegreesToRadians(data.GetRotation()); + QPointF ptCenter(data.GetPos().x() + data.GetLabelWidth()/2, data.GetPos().y() + data.GetLabelHeight()/2); + QPointF ptPos = data.GetPos(); + QVector v; + v << ptPos << QPointF(ptPos.x() + data.GetLabelWidth(), ptPos.y()) + << QPointF(ptPos.x() + data.GetLabelWidth(), ptPos.y() + data.GetLabelHeight()) + << QPointF(ptPos.x(), ptPos.y() + data.GetLabelHeight()); + for (int i = 0; i < v.count(); ++i) + { + v[i] = RotatePoint(ptCenter, v.at(i), dAng); + } + d->detailLabel = RoundPoints(v); + + // generate text + d->m_tmDetail.SetFont(font); + d->m_tmDetail.SetFontSize(data.GetFontSize()); + d->m_tmDetail.Update(qsName, data); + // this will generate the lines of text + d->m_tmDetail.SetFontSize(data.GetFontSize()); + d->m_tmDetail.FitFontSize(data.GetLabelWidth(), data.GetLabelHeight()); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutDetail::SetPatternInfo(const VAbstractPattern* pDoc, const VPatternInfoGeometry& geom, const QFont &font) +{ + d->patternGeom = geom; + qreal dAng = qDegreesToRadians(geom.GetRotation()); + QPointF ptCenter(geom.GetPos().x() + geom.GetLabelWidth()/2, geom.GetPos().y() + geom.GetLabelHeight()/2); + QPointF ptPos = geom.GetPos(); + QVector v; + v << ptPos << QPointF(ptPos.x() + geom.GetLabelWidth(), ptPos.y()) + << QPointF(ptPos.x() + geom.GetLabelWidth(), ptPos.y() + geom.GetLabelHeight()) + << QPointF(ptPos.x(), ptPos.y() + geom.GetLabelHeight()); + for (int i = 0; i < v.count(); ++i) + { + v[i] = RotatePoint(ptCenter, v.at(i), dAng); + } + d->patternInfo = RoundPoints(v); + + // Generate text + d->m_tmPattern.SetFont(font); + d->m_tmPattern.SetFontSize(geom.GetFontSize()); + + d->m_tmPattern.Update(pDoc); + // generate lines of text + d->m_tmPattern.SetFontSize(geom.GetFontSize()); + d->m_tmPattern.FitFontSize(geom.GetLabelWidth(), geom.GetLabelHeight()); +} + //--------------------------------------------------------------------------------------------------------------------- QTransform VLayoutDetail::GetMatrix() const { @@ -423,6 +479,163 @@ QPainterPath VLayoutDetail::ContourPath() const return path; } +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutDetail::ClearTextItems() +{ + d->m_liPP.clear(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VLayoutDetail::CreateTextItems() +{ + ClearTextItems(); + // first add detail texts + if (d->detailLabel.count() > 0) + { + // get the mapped label vertices + QVector points = Map(Mirror(d->detailLabel)); + // append the first point to obtain the closed rectangle + points.push_back(points.at(0)); + // calculate the angle of rotation + qreal dAng = qAtan2(points.at(1).y() - points.at(0).y(), points.at(1).x() - points.at(0).x()); + // calculate the label width + qreal dW = GetDistance(points.at(0), points.at(1)); + qreal dY = 0; + qreal dX; + // set up the rotation around top-left corner matrix + QMatrix mat; + mat.translate(points.at(0).x(), points.at(0).y()); + mat.rotate(qRadiansToDegrees(dAng)); + + for (int i = 0; i < d->m_tmDetail.GetCount(); ++i) + { + const TextLine& tl = d->m_tmDetail.GetLine(i); + QFont fnt = d->m_tmDetail.GetFont(); + fnt.setPixelSize(d->m_tmDetail.GetFont().pixelSize() + tl.m_iFontSize); + fnt.setWeight(tl.m_eFontWeight); + fnt.setStyle(tl.m_eStyle); + dY += tl.m_iHeight; + + QFontMetrics fm(fnt); + // find the correct horizontal offset, depending on the alignment flag + if ((tl.m_eAlign & Qt::AlignLeft) > 0) + { + dX = 0; + } + else if ((tl.m_eAlign & Qt::AlignHCenter) > 0) + { + dX = (dW - fm.width(tl.m_qsText))/2; + } + else + { + dX = dW - fm.width(tl.m_qsText); + } + // create text path and add it to the list + QPainterPath path; + path.addText(dX, dY - (fm.height() - fm.ascent())/2, fnt, tl.m_qsText); + d->m_liPP << mat.map(path); + dY += d->m_tmDetail.GetSpacing(); + } + } + // and then add pattern texts + if (d->patternInfo.count() > 0) + { + // similar approach like for the detail label + QVector points = Map(Mirror(d->patternInfo)); + points.push_back(points.at(0)); + qreal dAng = qAtan2(points.at(1).y() - points.at(0).y(), points.at(1).x() - points.at(0).x()); + qreal dW = GetDistance(points.at(0), points.at(1)); + qreal dY = 0; + qreal dX; + QMatrix mat; + mat.translate(points.at(0).x(), points.at(0).y()); + mat.rotate(qRadiansToDegrees(dAng)); + + for (int i = 0; i < d->m_tmPattern.GetCount(); ++i) + { + const TextLine& tl = d->m_tmPattern.GetLine(i); + QFont fnt = d->m_tmPattern.GetFont(); + fnt.setPixelSize(d->m_tmPattern.GetFont().pixelSize() + tl.m_iFontSize); + fnt.setWeight(tl.m_eFontWeight); + fnt.setStyle(tl.m_eStyle); + dY += tl.m_iHeight; + + QFontMetrics fm(fnt); + if ((tl.m_eAlign & Qt::AlignLeft) > 0) + { + dX = 0; + } + else if ((tl.m_eAlign & Qt::AlignHCenter) > 0) + { + dX = (dW - fm.width(tl.m_qsText))/2; + } + else + { + dX = dW - fm.width(tl.m_qsText); + } + QPainterPath path; + path.addText(dX, dY - (fm.height() - fm.ascent())/2, fnt, tl.m_qsText); + d->m_liPP << mat.map(path); + dY += d->m_tmPattern.GetSpacing(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +int VLayoutDetail::GetTextItemsCount() const +{ + return d->m_liPP.count(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::GetTextItem Creates and returns the i-th text item + * @param i index of the requested item + * @return pointer to the newly created item. The caller is responsible to delete it. + */ +QGraphicsItem* VLayoutDetail::GetTextItem(int i) const +{ + QGraphicsPathItem* item = new QGraphicsPathItem(); + QTransform transform = d->matrix; + + QPainterPath path = transform.map(d->m_liPP[i]); + + if (d->mirror == true) + { + QVector points; + if (i < d->m_tmDetail.GetCount()) + { + points = Map(Mirror(d->detailLabel)); + } + else + { + points = Map(Mirror(d->patternInfo)); + } + QPointF ptCenter = (points.at(1) + points.at(3))/2; + qreal dRot = qRadiansToDegrees(qAtan2(points.at(1).y() - points.at(0).y(), points.at(1).x() - points.at(0).x())); + + // we need to move the center back to the origin, rotate it to align it with x axis, + // then mirror it to obtain the proper text direction, rotate it and translate it back to original position. + // The operations must be added in reverse order + QTransform t; + // move the label back to its original position + t.translate(ptCenter.x(), ptCenter.y()); + // rotate the label back to original angle + t.rotate(dRot); + // mirror the label horizontally + t.scale(-1, 1); + // rotate the label to normal position + t.rotate(-dRot); + // move the label center into origin + t.translate(-ptCenter.x(), -ptCenter.y()); + path = t.map(path); + } + + item->setPath(path); + item->setBrush(QBrush(Qt::black)); + return item; +} + //--------------------------------------------------------------------------------------------------------------------- QPainterPath VLayoutDetail::LayoutAllowencePath() const { @@ -459,3 +672,61 @@ void VLayoutDetail::SetMirror(bool value) { d->mirror = value; } + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::RotatePoint rotates a point around the center for given angle + * @param ptCenter center around which the point is rotated + * @param pt point, which is rotated around the center + * @param dAng angle of rotation + * @return position of point pt after rotating it around the center for dAng radians + */ +QPointF VLayoutDetail::RotatePoint(const QPointF &ptCenter, const QPointF& pt, qreal dAng) const +{ + QPointF ptDest; + QPointF ptRel = pt - ptCenter; + ptDest.setX(cos(dAng)*ptRel.x() - sin(dAng)*ptRel.y()); + ptDest.setY(sin(dAng)*ptRel.x() + cos(dAng)*ptRel.y()); + + return ptDest + ptCenter; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::Mirror if the detail layout is rotated, this method will flip the + * label points over vertical axis, which goes through the center of the label + * @param list of 4 label vertices + * @return list of flipped points + */ +QVector VLayoutDetail::Mirror(const QVector &points) const +{ + // should only call this method with rectangular shapes + Q_ASSERT(points.count() == 4); + if (d->mirror == false) + { + return points; + } + + QVector v; + v.resize(4); + v[0] = points.at(2); + v[1] = points.at(3); + v[2] = points.at(0); + v[3] = points.at(1); + return v; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VLayoutDetail::GetDistance calculates the Euclidian distance between the points + * @param pt1 first point + * @param pt2 second point + * @return Euclidian distance between the two points + */ +qreal VLayoutDetail::GetDistance(const QPointF &pt1, const QPointF &pt2) const +{ + qreal dX = pt1.x() - pt2.x(); + qreal dY = pt1.y() - pt2.y(); + + return qSqrt(dX*dX + dY*dY); +} diff --git a/src/libs/vlayout/vlayoutdetail.h b/src/libs/vlayout/vlayoutdetail.h index 2e75159ad..56cb5aff0 100644 --- a/src/libs/vlayout/vlayoutdetail.h +++ b/src/libs/vlayout/vlayoutdetail.h @@ -30,9 +30,14 @@ #define VLAYOUTDETAIL_H #include "vabstractdetail.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vpatterninfogeometry.h" +#include "../ifc/xml/vabstractpattern.h" + #include #include +#include class VLayoutDetailData; class QGraphicsItem; @@ -54,6 +59,10 @@ public: QVector GetLayoutAllowencePoints() const; void SetLayoutAllowencePoints(); + void SetDetail(const QString &qsName, const VPatternPieceData& data, const QFont& font); + + void SetPatternInfo(const VAbstractPattern* pDoc, const VPatternInfoGeometry& geom, const QFont& font); + QTransform GetMatrix() const; void SetMatrix(const QTransform &matrix); @@ -78,14 +87,22 @@ public: bool isNull() const; qint64 Square() const; QPainterPath ContourPath() const; + void ClearTextItems(); + void CreateTextItems(); + int GetTextItemsCount() const Q_REQUIRED_RESULT; + QGraphicsItem* GetTextItem(int i) const Q_REQUIRED_RESULT; QPainterPath LayoutAllowencePath() const; QGraphicsItem *GetItem() const Q_REQUIRED_RESULT; private: - QSharedDataPointer d; + QSharedDataPointer d; QVector Map(const QVector &points) const; static QVector RoundPoints(const QVector &points); + + QPointF RotatePoint(const QPointF& ptCenter, const QPointF& pt, qreal dAng) const; + QVector Mirror(const QVector& points) const; + qreal GetDistance(const QPointF& pt1, const QPointF& pt2) const; }; Q_DECLARE_TYPEINFO(VLayoutDetail, Q_MOVABLE_TYPE); diff --git a/src/libs/vlayout/vlayoutdetail_p.h b/src/libs/vlayout/vlayoutdetail_p.h index 8a008ac80..01995de98 100644 --- a/src/libs/vlayout/vlayoutdetail_p.h +++ b/src/libs/vlayout/vlayoutdetail_p.h @@ -34,6 +34,11 @@ #include #include +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vpatterninfogeometry.h" +#include "vtextmanager.h" + + #ifdef Q_CC_GNU #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" @@ -44,13 +49,17 @@ class VLayoutDetailData : public QSharedData public: VLayoutDetailData() :contour(QVector()), seamAllowence(QVector()), layoutAllowence(QVector()), - matrix(QMatrix()), layoutWidth(0), mirror(false) + matrix(QMatrix()), layoutWidth(0), mirror(false), detailLabel(QVector()), + patternInfo(QVector()), detailData(), patternGeom(), m_tmDetail(), + m_tmPattern(), m_liPP(QList()) {} VLayoutDetailData(const VLayoutDetailData &detail) :QSharedData(detail), contour(detail.contour), seamAllowence(detail.seamAllowence), - layoutAllowence(detail.layoutAllowence), matrix(detail.matrix), layoutWidth(detail.layoutWidth), - mirror(detail.mirror) + layoutAllowence(detail.layoutAllowence), matrix(detail.matrix), + layoutWidth(detail.layoutWidth), mirror(detail.mirror), detailLabel(detail.detailLabel), + patternInfo(detail.patternInfo), detailData(detail.detailData), patternGeom(detail.patternGeom), + m_tmDetail(detail.m_tmDetail), m_tmPattern(detail.m_tmPattern), m_liPP(detail.m_liPP) {} ~VLayoutDetailData() {} @@ -72,6 +81,21 @@ public: bool mirror; + /** @brief detailLabel detail label rectangle */ + QVector detailLabel; + /** @brief patternInfo pattern info rectangle */ + QVector patternInfo; + /** @brief detailData detail data */ + VPatternPieceData detailData; + /** @brief patternGeom pattern geometry */ + VPatternInfoGeometry patternGeom; + /** @brief m_tmDetail text manager for laying out detail info */ + VTextManager m_tmDetail; + /** @brief m_tmPattern text manager for laying out pattern info */ + VTextManager m_tmPattern; + /** @bried m_liPP list of generated text painter paths */ + QList m_liPP; + private: VLayoutDetailData &operator=(const VLayoutDetailData &) Q_DECL_EQ_DELETE; }; diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp index 91a7213ba..21710bcc5 100644 --- a/src/libs/vlayout/vlayoutpaper.cpp +++ b/src/libs/vlayout/vlayoutpaper.cpp @@ -313,6 +313,10 @@ QList VLayoutPaper::GetItemDetails() const for (int i=0; i < d->details.count(); ++i) { list.append(d->details.at(i).GetItem()); + for (int iT = 0; iT < d->details.at(i).GetTextItemsCount(); ++iT) + { + list.append(d->details.at(i).GetTextItem(iT)); + } } return list; } diff --git a/src/libs/vlayout/vposter.cpp b/src/libs/vlayout/vposter.cpp index 6347e58e4..fab73e12a 100644 --- a/src/libs/vlayout/vposter.cpp +++ b/src/libs/vlayout/vposter.cpp @@ -241,6 +241,8 @@ int VPoster::CountColumns(int width) const //--------------------------------------------------------------------------------------------------------------------- PosterData VPoster::Cut(int i, int j, const QRect &imageRect) const { + Q_UNUSED(imageRect); + const int x = j*PageRect().width() - j*static_cast(allowence); const int y = i*PageRect().height() - i*static_cast(allowence); diff --git a/src/libs/vlayout/vtextmanager.cpp b/src/libs/vlayout/vtextmanager.cpp new file mode 100644 index 000000000..62de75761 --- /dev/null +++ b/src/libs/vlayout/vtextmanager.cpp @@ -0,0 +1,353 @@ +#include +#include +#include + +#include "vtextmanager.h" + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief TextLine::TextLine default constructor + */ +TextLine::TextLine() + :m_qsText(), m_iFontSize(MIN_FONT_SIZE), m_eFontWeight(QFont::Normal), m_eStyle(QFont::StyleNormal), + m_eAlign(Qt::AlignCenter), m_iHeight(0) +{} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::VTextManager constructor + */ +VTextManager::VTextManager() + :m_font(), m_liLines(), m_liOutput() +{} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::~VTextManager destructor + */ +VTextManager::~VTextManager() +{} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetSpacing returns the vertical spacing between the lines + * @return + */ +int VTextManager::GetSpacing() const +{ + return 2; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::SetFont set the text base font + * @param font text base font + */ +void VTextManager::SetFont(const QFont& font) +{ + m_font = font; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetFont returns the text base font + * @return text base font + */ +const QFont& VTextManager::GetFont() const +{ + return m_font; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::SetFontSize sets the font size + * @param iFS font size in pixels + */ +void VTextManager::SetFontSize(int iFS) +{ + m_font.setPixelSize(iFS); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::AddLine add new text line to the list + * @param tl text line object to be added + */ +void VTextManager::AddLine(const TextLine& tl) +{ + m_liLines << tl; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::Clear deletes the list of texts + */ +void VTextManager::Clear() +{ + m_liLines.clear(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetCount returns the number of output text lines + * @return number of output text lines + */ +int VTextManager::GetCount() const +{ + return m_liOutput.count(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetSourceLineCount returns the number of input text lines + * @return number of text lines that were added to the list by calling AddLine + */ +int VTextManager::GetSourceLineCount() const +{ + return m_liLines.count(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::GetLine returns the i-th output text line + * @param i index of the output text line + * @return i-th output text line + */ +const TextLine& VTextManager::GetLine(int i) const +{ + return m_liOutput[i]; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::IsBigEnough Checks if rectangle of size (fW, fH) is big enough to hold the text with base font + * size iFontSize + * @param fW rectangle width + * @param fH rectangle height + * @param iFontSize base font size + * @return true, if rectangle of size (fW, fH) + */ +bool VTextManager::IsBigEnough(qreal fW, qreal fH, int iFontSize) +{ + m_liOutput.clear(); + QFont fnt = m_font; + int iY = 0; + for (int i = 0; i < m_liLines.count(); ++i) + { + const TextLine& tl = m_liLines.at(i); + TextLine tlOut = tl; + fnt.setPixelSize(iFontSize + tl.m_iFontSize); + QFontMetrics fm(fnt); + int iHorSp = fm.width(" "); + tlOut.m_iHeight = fm.height(); + QStringList qslLines = SplitString(tlOut.m_qsText, fW, fm); + for (int iL = 0; iL < qslLines.count(); ++iL) + { + // check if every line fits within the label width + if (fm.width(qslLines[iL]) + iHorSp > fW) + { + return false; + } + tlOut.m_qsText = qslLines[iL]; + m_liOutput << tlOut; + iY += tlOut.m_iHeight + GetSpacing(); + } + } + return iY < fH; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::FitFontSize sets the font size just big enough, so that the text fits into rectangle of + * size (fW, fH) + * @param fW rectangle width + * @param fH rectangle height + */ +void VTextManager::FitFontSize(qreal fW, qreal fH) +{ + int iFontSize = GetFont().pixelSize(); + while (IsBigEnough(fW, fH, iFontSize) == true && iFontSize <= MAX_FONT_SIZE) + { + ++iFontSize; + } + while (IsBigEnough(fW, fH, iFontSize) == false && iFontSize >= MIN_FONT_SIZE) + { + --iFontSize; + } + SetFontSize(iFontSize); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::Update updates the text lines with detail data + * @param qsName detail name + * @param data reference to the detail data + */ +void VTextManager::Update(const QString& qsName, const VPatternPieceData& data) +{ + Clear(); + TextLine tl; + // all text must be centered and normal style! + tl.m_eAlign = Qt::AlignCenter; + tl.m_eStyle = QFont::StyleNormal; + + // letter + tl.m_qsText = data.GetLetter(); + if (tl.m_qsText.isEmpty() == false) + { + tl.m_eFontWeight = QFont::Bold; + tl.m_iFontSize = 6; + AddLine(tl); + } + // name + tl.m_qsText = qsName; + if (tl.m_qsText.isEmpty() == false) + { + tl.m_eFontWeight = QFont::DemiBold; + tl.m_iFontSize = 2; + AddLine(tl); + } + // MCP + QString qsText = "Cut %1 on %2%3"; + QStringList qslPlace; + qslPlace << "" << " on Fold"; + tl.m_eFontWeight = QFont::Normal; + tl.m_iFontSize = 0; + for (int i = 0; i < data.GetMCPCount(); ++i) + { + MaterialCutPlacement mcp = data.GetMCP(i); + if (mcp.m_iCutNumber > 0) + { + tl.m_qsText = qsText.arg(mcp.m_iCutNumber).arg(mcp.m_qsMaterialUserDef). + arg(qslPlace[int(mcp.m_ePlacement)]); + AddLine(tl); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::Update updates the text lines with pattern info + * @param pDoc pointer to the abstract pattern object + */ +void VTextManager::Update(const VAbstractPattern *pDoc) +{ + Clear(); + TextLine tl; + // all information must be centered + tl.m_eAlign = Qt::AlignCenter; + + // Company name + tl.m_qsText = pDoc->GetCompanyName(); + if (tl.m_qsText.isEmpty() == false) + { + tl.m_eFontWeight = QFont::DemiBold; + tl.m_eStyle = QFont::StyleNormal; + tl.m_iFontSize = 4; + AddLine(tl); + } + // Pattern name + tl.m_qsText = pDoc->GetPatternName(); + if (tl.m_qsText.isEmpty() == false) + { + tl.m_eFontWeight = QFont::Normal; + tl.m_eStyle = QFont::StyleNormal; + tl.m_iFontSize = 2; + AddLine(tl); + } + // Pattern number + tl.m_qsText = pDoc->GetPatternNumber(); + if (tl.m_qsText.isEmpty() == false) + { + tl.m_eFontWeight = QFont::Normal; + tl.m_eStyle = QFont::StyleNormal; + tl.m_iFontSize = 0; + AddLine(tl); + } + // Customer name + tl.m_qsText = pDoc->GetCustomerName(); + if (tl.m_qsText.isEmpty() == false) + { + tl.m_eFontWeight = QFont::Normal; + tl.m_eStyle = QFont::StyleItalic; + tl.m_iFontSize = 0; + AddLine(tl); + } + // Size + tl.m_qsText = pDoc->GetPatternSize(); + if (tl.m_qsText.isEmpty() == false) + { + tl.m_eFontWeight = QFont::Normal; + tl.m_eStyle = QFont::StyleNormal; + tl.m_iFontSize = 0; + AddLine(tl); + } + // Measurements + tl.m_qsText = QFileInfo(pDoc->MPath()).fileName(); + if (tl.m_qsText.isEmpty() == false && pDoc->IsMeasurementsVisible() == true) + { + tl.m_eFontWeight = QFont::Normal; + tl.m_eStyle = QFont::StyleNormal; + tl.m_iFontSize = 0; + AddLine(tl); + } + // Date + QDate date; + if (pDoc->IsDateVisible() == true) + { + date = QDate::currentDate(); + } + if (date.isValid() == true) + { + tl.m_qsText = date.toString("dd MMMM yyyy"); + tl.m_eFontWeight = QFont::Normal; + tl.m_eStyle = QFont::StyleNormal; + tl.m_iFontSize = 0; + AddLine(tl); + } + +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextManager::SplitString splits the string into several lines, which all fit into width fW + * @param qs string to split + * @param fW required width of every output string + * @param fm font metrics of the font used + * @return list of strings, each of which is not wider than fW using the font metrics fm + */ +QStringList VTextManager::SplitString(const QString &qs, qreal fW, const QFontMetrics &fm) +{ + QRegularExpression reg("\\s+"); + // split the string into words + QStringList qslWords = qs.split(reg); + QStringList qslLines; + QString qsCurrent; + for (int i = 0; i < qslWords.count(); ++i) + { + if (qsCurrent.length() > 0) + { + qsCurrent += QLatin1Literal(" "); + } + // check if another word can be added into current line + if (fm.width(qsCurrent + qslWords[i]) > fW) + { + // if not, add the current line into the list of text lines + if (qsCurrent.isEmpty() == false) + { + qslLines << qsCurrent; + } + // and set the current line to contain the current word + qsCurrent = qslWords[i]; + } + else + { + qsCurrent += qslWords[i]; + } + } + qslLines << qsCurrent; + return qslLines; +} + + + diff --git a/src/libs/vlayout/vtextmanager.h b/src/libs/vlayout/vtextmanager.h new file mode 100644 index 000000000..aea6741ab --- /dev/null +++ b/src/libs/vlayout/vtextmanager.h @@ -0,0 +1,62 @@ +#ifndef VTEXTMANAGER_H +#define VTEXTMANAGER_H + +#include +#include +#include + +#include "../vpatterndb/vpatternpiecedata.h" +#include "../ifc/xml/vabstractpattern.h" + +#define MIN_FONT_SIZE 12 +#define MAX_FONT_SIZE 128 + +/** + * @brief The TextLine struct holds the information about one text line + */ +struct TextLine +{ + QString m_qsText; + int m_iFontSize; // 0 means default + QFont::Weight m_eFontWeight; + QFont::Style m_eStyle; + Qt::Alignment m_eAlign; + int m_iHeight; + + TextLine(); +}; + +/** + * @brief The VTextManager class this class is used to determine whether a collection of + * text lines can fit into specified bounding box and with what font size + */ +class VTextManager +{ +public: + VTextManager(); + virtual ~VTextManager(); + + virtual int GetSpacing() const; + void SetFont(const QFont& font); + const QFont& GetFont() const; + void SetFontSize(int iFS); + void AddLine(const TextLine& tl); + void Clear(); + int GetCount() const; + int GetSourceLineCount() const; + const TextLine& GetLine(int i) const; + bool IsBigEnough(qreal fW, qreal fH, int iFontSize); + void FitFontSize(qreal fW, qreal fH); + void Update(const QString& qsName, const VPatternPieceData& data); + void Update(const VAbstractPattern* pDoc); + +protected: + QStringList SplitString(const QString& qs, qreal fW, const QFontMetrics& fm); + +private: + QFont m_font; + QList m_liLines; + QList m_liOutput; +}; + +#endif // VTEXTMANAGER_H diff --git a/src/libs/vmisc/def.cpp b/src/libs/vmisc/def.cpp index 9e4276438..02785f3d2 100644 --- a/src/libs/vmisc/def.cpp +++ b/src/libs/vmisc/def.cpp @@ -439,6 +439,28 @@ void SetOverrideCursor(const QString &pixmapPath, int hotX, int hotY) #endif } +//--------------------------------------------------------------------------------------------------------------------- +void SetOverrideCursor(Qt::CursorShape shape) +{ +#ifndef QT_NO_CURSOR + QPixmap oldPixmap; + QCursor* pOldCursor = QGuiApplication::overrideCursor(); + if (pOldCursor != 0) + { + oldPixmap = pOldCursor->pixmap(); + } + QCursor cursor(shape); + QPixmap newPixmap = cursor.pixmap(); + if (oldPixmap.toImage() != newPixmap.toImage()) + { + QApplication::setOverrideCursor(cursor); + } + +#else + Q_UNUSED(shape); +#endif +} + //--------------------------------------------------------------------------------------------------------------------- void RestoreOverrideCursor(const QString &pixmapPath) { @@ -462,6 +484,28 @@ void RestoreOverrideCursor(const QString &pixmapPath) #endif } +//--------------------------------------------------------------------------------------------------------------------- +void RestoreOverrideCursor(Qt::CursorShape shape) +{ +#ifndef QT_NO_CURSOR + QPixmap oldPixmap; + QCursor* pOldCursor = QGuiApplication::overrideCursor(); + if (pOldCursor != 0) + { + oldPixmap = pOldCursor->pixmap(); + } + QCursor cursor(shape); + QPixmap newPixmap = cursor.pixmap(); + if (oldPixmap.toImage() == newPixmap.toImage()) + { + QApplication::restoreOverrideCursor(); + } + +#else + Q_UNUSED(shape); +#endif +} + const qreal PrintDPI = 96.0; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index 60399132f..9e5be5209 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -595,7 +595,9 @@ extern const QString trueStr; extern const QString falseStr; void SetOverrideCursor(const QString & pixmapPath, int hotX = -1, int hotY = -1); +void SetOverrideCursor(Qt::CursorShape shape); void RestoreOverrideCursor(const QString & pixmapPath); +void RestoreOverrideCursor(Qt::CursorShape shape); extern const qreal PrintDPI; diff --git a/src/libs/vpatterndb/vdetail.cpp b/src/libs/vpatterndb/vdetail.cpp index 2d9d87e2f..8f0d25092 100644 --- a/src/libs/vpatterndb/vdetail.cpp +++ b/src/libs/vpatterndb/vdetail.cpp @@ -92,6 +92,7 @@ void VDetail::Clear() d->nodes.clear(); d->mx = 0; d->my = 0; + GetPatternPieceData().Clear(); } //--------------------------------------------------------------------------------------------------------------------- @@ -524,6 +525,46 @@ QVector VDetail::listNodePoint() const return list; } +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns full access to the pattern piece data object + * @return pattern piece data object + */ +VPatternPieceData& VDetail::GetPatternPieceData() +{ + return d->m_ppData; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the read only reference to the pattern piece data object + * @return pattern piece data object + */ +const VPatternPieceData& VDetail::GetPatternPieceData() const +{ + return d->m_ppData; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns full access to the pattern info geometry object + * @return pattern info geometry object + */ +VPatternInfoGeometry& VDetail::GetPatternInfo() +{ + return d->m_piPatternInfo; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief Returns the read only reference to the pattern info geometry object + * @return pattern info geometry object + */ +const VPatternInfoGeometry& VDetail::GetPatternInfo() const +{ + return d->m_piPatternInfo; +} + //--------------------------------------------------------------------------------------------------------------------- /** * @brief indexOfNode return index in list node using id object. diff --git a/src/libs/vpatterndb/vdetail.h b/src/libs/vpatterndb/vdetail.h index 5ef7f34c1..976b885d7 100644 --- a/src/libs/vpatterndb/vdetail.h +++ b/src/libs/vpatterndb/vdetail.h @@ -37,6 +37,8 @@ class VDetailData; class VContainer; class QPainterPath; +class VPatternPieceData; +class VPatternInfoGeometry; /** * @brief The VDetail class for path of object (points, arcs, splines). @@ -87,6 +89,11 @@ public: QPainterPath ContourPath(const VContainer *data) const; QPainterPath SeamAllowancePath(const VContainer *data) const; QVector listNodePoint()const; + VPatternPieceData& GetPatternPieceData(); + const VPatternPieceData& GetPatternPieceData() const; + VPatternInfoGeometry& GetPatternInfo(); + const VPatternInfoGeometry& GetPatternInfo() const; + private: QSharedDataPointer d; diff --git a/src/libs/vpatterndb/vdetail_p.h b/src/libs/vpatterndb/vdetail_p.h index b22d094da..4092cec9a 100644 --- a/src/libs/vpatterndb/vdetail_p.h +++ b/src/libs/vpatterndb/vdetail_p.h @@ -31,6 +31,8 @@ #include #include "vnodedetail.h" +#include "vpatternpiecedata.h" +#include "vpatterninfogeometry.h" #include "../ifc/ifcdef.h" #ifdef Q_CC_GNU @@ -50,7 +52,8 @@ public: {} VDetailData(const VDetailData &detail) - :QSharedData(detail), _id(NULL_ID), nodes(detail.nodes), mx(detail.mx), my(detail.my), inLayout(detail.inLayout) + :QSharedData(detail), _id(NULL_ID), nodes(detail.nodes), mx(detail.mx), my(detail.my), + m_ppData(detail.m_ppData), m_piPatternInfo(detail.m_piPatternInfo), inLayout(detail.inLayout) {} ~VDetailData() {} @@ -67,6 +70,11 @@ public: /** @brief my bias y axis. */ qreal my; + /** @brief Pattern piece data */ + VPatternPieceData m_ppData; + /** @brief Pattern info coordinates */ + VPatternInfoGeometry m_piPatternInfo; + bool inLayout; private: diff --git a/src/libs/vpatterndb/vpatterndb.pri b/src/libs/vpatterndb/vpatterndb.pri index a9b035682..b2e055a6e 100644 --- a/src/libs/vpatterndb/vpatterndb.pri +++ b/src/libs/vpatterndb/vpatterndb.pri @@ -17,7 +17,9 @@ SOURCES += \ $$PWD/variables/vlinelength.cpp \ $$PWD/variables/vmeasurement.cpp \ $$PWD/variables/vvariable.cpp \ - $$PWD/vformula.cpp + $$PWD/vformula.cpp \ + $$PWD/vpatternpiecedata.cpp \ + $$PWD/vpatterninfogeometry.cpp win32-msvc*:SOURCES += $$PWD/stable.cpp @@ -49,4 +51,6 @@ HEADERS += \ $$PWD/variables/vmeasurement_p.h \ $$PWD/variables/vvariable.h \ $$PWD/variables/vvariable_p.h \ - $$PWD/vformula.h + $$PWD/vformula.h \ + $$PWD/vpatternpiecedata.h \ + $$PWD/vpatterninfogeometry.h diff --git a/src/libs/vpatterndb/vpatterninfogeometry.cpp b/src/libs/vpatterndb/vpatterninfogeometry.cpp new file mode 100644 index 000000000..6de2bcc5d --- /dev/null +++ b/src/libs/vpatterndb/vpatterninfogeometry.cpp @@ -0,0 +1,126 @@ +/************************************************************************ + ** + ** @file vpatterninfogeometry.cpp + ** @author Bojan Kverh + ** @date June 16, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vpatterninfogeometry.h" + +//--------------------------------------------------------------------------------------------------------------------- +VPatternInfoGeometry::VPatternInfoGeometry() + :m_ptPos(0, 0), m_dLabelWidth(0), m_dLabelHeight(0), m_iFontSize(MIN_FONT_SIZE), + m_dRotation(0), m_bVisible(true) +{ + m_iFontSize = MIN_FONT_SIZE; + // 0 means unknown width + m_dLabelWidth = 0; + m_dLabelHeight = 0; + m_dRotation = 0; +} + +//--------------------------------------------------------------------------------------------------------------------- +VPatternInfoGeometry::~VPatternInfoGeometry() +{} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VPatternInfoGeometry::GetPos() const +{ + return m_ptPos; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternInfoGeometry::SetPos(const QPointF& ptPos) +{ + m_ptPos = ptPos; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPatternInfoGeometry::GetLabelWidth() const +{ + return m_dLabelWidth; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternInfoGeometry::SetLabelWidth(qreal dLabelW) +{ + m_dLabelWidth = dLabelW; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPatternInfoGeometry::GetLabelHeight() const +{ + return m_dLabelHeight; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternInfoGeometry::SetLabelHeight(qreal dLabelH) +{ + m_dLabelHeight = dLabelH; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPatternInfoGeometry::GetFontSize() const +{ + return m_iFontSize; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternInfoGeometry::SetFontSize(int iSize) +{ + if (iSize >= MIN_FONT_SIZE) + { + m_iFontSize = iSize; + } + else + { + m_iFontSize = MIN_FONT_SIZE; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPatternInfoGeometry::GetRotation() const +{ + return m_dRotation; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternInfoGeometry::SetRotation(qreal dRot) +{ + m_dRotation = dRot; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPatternInfoGeometry::IsVisible() const +{ + return m_bVisible; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternInfoGeometry::SetVisible(bool bVal) +{ + m_bVisible = bVal; +} + +//--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vpatterndb/vpatterninfogeometry.h b/src/libs/vpatterndb/vpatterninfogeometry.h new file mode 100644 index 000000000..6bb562fa1 --- /dev/null +++ b/src/libs/vpatterndb/vpatterninfogeometry.h @@ -0,0 +1,87 @@ +/************************************************************************ + ** + ** @file vpatterninfogeometry.h + ** @author Bojan Kverh + ** @date June 16, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VPATTERNINFOGEOMETRY_H +#define VPATTERNINFOGEOMETRY_H + +#define MIN_FONT_SIZE 12 + +#include + +/** + * @brief The VPatternInfoGeometry class holds the information about pattern info label geometry + */ +class VPatternInfoGeometry +{ +public: + VPatternInfoGeometry(); + ~VPatternInfoGeometry(); + + // methods, which set up label parameters + QPointF GetPos() const; + void SetPos(const QPointF& ptPos); + qreal GetLabelWidth() const; + void SetLabelWidth(qreal dLabelW); + qreal GetLabelHeight() const; + void SetLabelHeight(qreal dLabelH); + int GetFontSize() const; + void SetFontSize(int iSize); + qreal GetRotation() const; + void SetRotation(qreal dRot); + bool IsVisible() const; + void SetVisible(bool bVal); + +private: + /** + * @brief m_ptPos position of label's top left corner + */ + QPointF m_ptPos; + /** + * @brief m_dLabelWidth label width + */ + qreal m_dLabelWidth; + /** + * @brief m_dLabelHeight label height + */ + qreal m_dLabelHeight; + /** + * @brief m_iFontSize label text base font size + */ + int m_iFontSize; + /** + * @brief m_dRotation Label rotation + */ + qreal m_dRotation; + /** + * @brief m_bVisible visibility flag + */ + bool m_bVisible; + +}; + +#endif // VPATTERNINFOGEOMETRY_H diff --git a/src/libs/vpatterndb/vpatternpiecedata.cpp b/src/libs/vpatterndb/vpatternpiecedata.cpp new file mode 100644 index 000000000..08beb8e54 --- /dev/null +++ b/src/libs/vpatterndb/vpatternpiecedata.cpp @@ -0,0 +1,189 @@ +/************************************************************************ + ** + ** @file vpatternpiecedata.cpp + ** @author Bojan Kverh + ** @date June 16, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include "vpatternpiecedata.h" + +//--------------------------------------------------------------------------------------------------------------------- +MaterialCutPlacement::MaterialCutPlacement() + :m_eMaterial(MaterialType::mtFabric), m_qsMaterialUserDef(), m_iCutNumber(0), m_ePlacement(PlacementType::ptNone) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPatternPieceData::VPatternPieceData() + :m_qsLetter(), m_conMCP(), m_ptPos(0, 0), m_dLabelWidth(0), m_dLabelHeight(0), + m_iFontSize(MIN_FONT_SIZE), m_dRotation(0), m_bVisible(true) +{} + +//--------------------------------------------------------------------------------------------------------------------- +VPatternPieceData::~VPatternPieceData() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::Append(const MaterialCutPlacement& rMCP) +{ + m_conMCP.append(rMCP); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::Insert(int i, const MaterialCutPlacement& rMCP) +{ + Q_ASSERT(i >= 0); + Q_ASSERT(i <= GetMCPCount()); + m_conMCP.insert(i, rMCP); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::Set(int i, const MaterialCutPlacement& rMCP) +{ + Q_ASSERT(i >= 0); + Q_ASSERT(i < GetMCPCount()); + m_conMCP[i] = rMCP; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPatternPieceData::GetMCPCount() const +{ + return m_conMCP.count(); +} + +//--------------------------------------------------------------------------------------------------------------------- +const MaterialCutPlacement& VPatternPieceData::GetMCP(int i) const +{ + Q_ASSERT(i >= 0); + Q_ASSERT(i < GetMCPCount()); + return m_conMCP.at(i); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::RemoveMCP(int i) +{ + Q_ASSERT(i >= 0); + Q_ASSERT(i < GetMCPCount()); + m_conMCP.removeAt(i); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::Clear() +{ + m_qsLetter.clear(); + m_conMCP.clear(); +} + +//--------------------------------------------------------------------------------------------------------------------- +const QString& VPatternPieceData::GetLetter() const +{ + return m_qsLetter; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::SetLetter(QString qsLetter) +{ + m_qsLetter = qsLetter.left(3); +} + +//--------------------------------------------------------------------------------------------------------------------- +QPointF VPatternPieceData::GetPos() const +{ + return m_ptPos; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::SetPos(const QPointF& ptPos) +{ + m_ptPos = ptPos; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPatternPieceData::GetLabelWidth() const +{ + return m_dLabelWidth; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::SetLabelWidth(qreal dLabelW) +{ + m_dLabelWidth = dLabelW; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPatternPieceData::GetLabelHeight() const +{ + return m_dLabelHeight; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::SetLabelHeight(qreal dLabelH) +{ + m_dLabelHeight = dLabelH; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPatternPieceData::GetFontSize() const +{ + return m_iFontSize; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::SetFontSize(int iSize) +{ + if (iSize >= MIN_FONT_SIZE) + { + m_iFontSize = iSize; + } + else + { + m_iFontSize = MIN_FONT_SIZE; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPatternPieceData::GetRotation() const +{ + return m_dRotation; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::SetRotation(qreal dRot) +{ + m_dRotation = dRot; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool VPatternPieceData::IsVisible() const +{ + return m_bVisible; +} + +//--------------------------------------------------------------------------------------------------------------------- +void VPatternPieceData::SetVisible(bool bVal) +{ + m_bVisible = bVal; +} + +//--------------------------------------------------------------------------------------------------------------------- + diff --git a/src/libs/vpatterndb/vpatternpiecedata.h b/src/libs/vpatterndb/vpatternpiecedata.h new file mode 100644 index 000000000..0852b5724 --- /dev/null +++ b/src/libs/vpatterndb/vpatternpiecedata.h @@ -0,0 +1,141 @@ +/************************************************************************ + ** + ** @file vpatternpiecedata.h + ** @author Bojan Kverh + ** @date June 16, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VPATTERNPIECEDATA_H +#define VPATTERNPIECEDATA_H + +#define MIN_FONT_SIZE 12 + +#include +#include +#include + +enum class MaterialType : char +{ + mtFabric = 0, + mtLining = 1, + mtInterfacing = 2, + mtInterlining = 3, + mtUserDefined = 4 +}; + +enum class PlacementType : char +{ + ptNone = 0, + ptCutOnFold = 1 +}; + +/** + * @brief The MaterialCutPlacement struct used to hold a material, cut number and placement 3-tuple + */ +struct MaterialCutPlacement +{ + MaterialType m_eMaterial; + QString m_qsMaterialUserDef; + int m_iCutNumber; + PlacementType m_ePlacement; + + MaterialCutPlacement(); +}; + +typedef QList MCPContainer; + +/** + * @brief The VPatternPieceData class holds some information about a single + * piece like letter, name, material type, cut number and placement. + */ +class VPatternPieceData +{ +public: + VPatternPieceData(); + ~VPatternPieceData(); + + // methods, which operate on MaterialCutPlacement container + void Append(const MaterialCutPlacement& rMCP); + void Insert(int i, const MaterialCutPlacement& rMCP); + void Set(int i, const MaterialCutPlacement& rMCP); + int GetMCPCount() const; + const MaterialCutPlacement& GetMCP(int i) const; + void RemoveMCP(int i); + void Clear(); + + // methods, which operate on other members + const QString& GetLetter() const; + void SetLetter(QString qsLetter); + + // methods, which set up label parameters + QPointF GetPos() const; + void SetPos(const QPointF& ptPos); + qreal GetLabelWidth() const; + void SetLabelWidth(qreal dLabelW); + qreal GetLabelHeight() const; + void SetLabelHeight(qreal dLabelH); + int GetFontSize() const; + void SetFontSize(int iSize); + qreal GetRotation() const; + void SetRotation(qreal dRot); + bool IsVisible() const; + void SetVisible(bool bVal); + +private: + /** + * @brief m_qsLetter Detail letter (should be no more than 3 characters) + */ + QString m_qsLetter; + /** + * @brief m_conMCP List of material, cut, placement tuples + */ + MCPContainer m_conMCP; + /** + * @brief m_ptPos position of label's top left corner + */ + QPointF m_ptPos; + /** + * @brief m_dLabelWidth label width + */ + qreal m_dLabelWidth; + /** + * @brief m_dLabelHeight label height + */ + qreal m_dLabelHeight; + /** + * @brief m_iFontSize label font size + */ + int m_iFontSize; + /** + * @brief m_dRotation label rotation + */ + qreal m_dRotation; + /** + * @brief m_bVisible visibility flag + */ + bool m_bVisible; + +}; + +#endif // VPATTERNPIECEDATA_H diff --git a/src/libs/vtools/dialogs/dialogs.pri b/src/libs/vtools/dialogs/dialogs.pri index 1a358d539..5c1cc848e 100644 --- a/src/libs/vtools/dialogs/dialogs.pri +++ b/src/libs/vtools/dialogs/dialogs.pri @@ -40,6 +40,7 @@ HEADERS += \ $$PWD/tools/dialoggroup.h \ $$PWD/tools/dialogrotation.h + SOURCES += \ $$PWD/tools/dialogalongline.cpp \ $$PWD/tools/dialogarc.cpp \ diff --git a/src/libs/vtools/dialogs/tools/dialogdetail.cpp b/src/libs/vtools/dialogs/tools/dialogdetail.cpp index 7119afdaa..29d1df0ed 100644 --- a/src/libs/vtools/dialogs/tools/dialogdetail.cpp +++ b/src/libs/vtools/dialogs/tools/dialogdetail.cpp @@ -44,15 +44,16 @@ * @param parent parent widget */ DialogDetail::DialogDetail(const VContainer *data, const quint32 &toolId, QWidget *parent) - :DialogTool(data, toolId, parent), ui(), detail(VDetail()), supplement(true), closed(true), flagWidth(true) + :DialogTool(data, toolId, parent), ui(), detail(VDetail()), supplement(true), closed(true), flagWidth(true), + m_bAddMode(true), m_qslMaterials(), m_qslPlacements(), m_conMCP(), m_oldData(), m_oldGeom() { ui.setupUi(this); #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) - ui.lineEditNameDetail->setClearButtonEnabled(true); + ui.lineEditName->setClearButtonEnabled(true); #endif - labelEditNamePoint = ui.labelEditNameDetail; + labelEditNamePoint = ui.labelEditName; ui.labelUnit->setText( VDomDocument::UnitsToStr(qApp->patternUnit(), true)); ui.labelUnitX->setText(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); ui.labelUnitY->setText(VDomDocument::UnitsToStr(qApp->patternUnit(), true)); @@ -85,11 +86,24 @@ DialogDetail::DialogDetail(const VContainer *data, const quint32 &toolId, QWidge connect(ui.checkBoxSeams, &QCheckBox::clicked, this, &DialogDetail::ClickedSeams); connect(ui.checkBoxClosed, &QCheckBox::clicked, this, &DialogDetail::ClickedClosed); connect(ui.checkBoxReverse, &QCheckBox::clicked, this, &DialogDetail::ClickedReverse); - connect(ui.lineEditNameDetail, &QLineEdit::textChanged, this, &DialogDetail::NameDetailChanged); + connect(ui.lineEditName, &QLineEdit::textChanged, this, &DialogDetail::NameDetailChanged); connect(ui.toolButtonDelete, &QToolButton::clicked, this, &DialogDetail::DeleteItem); connect(ui.toolButtonUp, &QToolButton::clicked, this, &DialogDetail::ScrollUp); connect(ui.toolButtonDown, &QToolButton::clicked, this, &DialogDetail::ScrollDown); + + m_qslMaterials << tr("Fabric") << tr("Lining") << tr("Interfacing") << tr("Interlining"); + ui.comboBoxMaterial->addItems(m_qslMaterials); + m_qslPlacements << tr("None") << tr("Cut on fold"); + ui.comboBoxPlacement->addItems(m_qslPlacements); + + connect(ui.pushButtonAdd, &QPushButton::clicked, this, &DialogDetail::AddUpdate); + connect(ui.pushButtonCancel, &QPushButton::clicked, this, &DialogDetail::Cancel); + connect(ui.pushButtonRemove, &QPushButton::clicked, this, &DialogDetail::Remove); + connect(ui.listWidgetMCP, &QListWidget::itemClicked, this, &DialogDetail::SetEditMode); + SetAddMode(); + + ui.tabWidget->setCurrentIndex(0); } //--------------------------------------------------------------------------------------------------------------------- @@ -155,6 +169,85 @@ void DialogDetail::CheckState() } } +//--------------------------------------------------------------------------------------------------------------------- +void DialogDetail::UpdateList() +{ + ui.listWidgetMCP->clear(); + for (int i = 0; i < m_conMCP.count(); ++i) + { + MaterialCutPlacement mcp = m_conMCP.at(i); + QString qsText = tr("Cut %1 of %2%3").arg(mcp.m_iCutNumber); + if (mcp.m_eMaterial < MaterialType::mtUserDefined) + { + qsText = qsText.arg(m_qslMaterials[int(mcp.m_eMaterial)]); + } + else + { + qsText = qsText.arg(mcp.m_qsMaterialUserDef); + } + if (mcp.m_ePlacement == PlacementType::ptCutOnFold) + { + qsText = qsText.arg(tr(" on Fold")); + } + else + { + qsText = qsText.arg(""); + } + + ui.listWidgetMCP->addItem(qsText); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogDetail::AddUpdate() +{ + MaterialCutPlacement mcp; + mcp.m_qsMaterialUserDef = ui.comboBoxMaterial->currentText(); + mcp.m_eMaterial = MaterialType::mtUserDefined; + for (int i = 0; i < m_qslMaterials.count(); ++i) + { + if (mcp.m_qsMaterialUserDef == m_qslMaterials[i]) + { + mcp.m_eMaterial = MaterialType(i); + } + } + + mcp.m_iCutNumber = ui.spinBoxCutNumber->value(); + mcp.m_ePlacement = PlacementType(ui.comboBoxPlacement->currentIndex()); + + if (m_bAddMode == true) + { + m_conMCP << mcp; + } + else + { + int iR = ui.listWidgetMCP->currentRow(); + SCASSERT(iR >= 0); + m_conMCP[iR] = mcp; + SetAddMode(); + } + UpdateList(); + ClearFields(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogDetail::Cancel() +{ + ClearFields(); + SetAddMode(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogDetail::Remove() +{ + int iR = ui.listWidgetMCP->currentRow(); + SCASSERT(iR >= 0); + m_conMCP.removeAt(iR); + UpdateList(); + ClearFields(); + SetAddMode(); +} + //--------------------------------------------------------------------------------------------------------------------- void DialogDetail::NameDetailChanged() { @@ -166,11 +259,15 @@ void DialogDetail::NameDetailChanged() { flagName = false; ChangeColor(labelEditNamePoint, Qt::red); + QIcon icon(":/icons/win.icon.theme/16x16/status/dialog-warning.png"); + ui.tabWidget->setTabIcon(1, icon); } else { flagName = true; ChangeColor(labelEditNamePoint, okColor); + QIcon icon; + ui.tabWidget->setTabIcon(1, icon); } } CheckState(); @@ -265,9 +362,29 @@ VDetail DialogDetail::CreateDetail() const detail.append( qvariant_cast(item->data(Qt::UserRole))); } detail.setWidth(ui.doubleSpinBoxSeams->value()); - detail.setName(ui.lineEditNameDetail->text()); + detail.setName(ui.lineEditName->text()); detail.setSeamAllowance(supplement); detail.setClosed(closed); + + detail.GetPatternPieceData().SetLetter(ui.lineEditLetter->text()); + + for (int i = 0; i < m_conMCP.count(); ++i) + { + detail.GetPatternPieceData().Append(m_conMCP[i]); + } + + detail.GetPatternPieceData().SetPos(m_oldData.GetPos()); + detail.GetPatternPieceData().SetLabelWidth(m_oldData.GetLabelWidth()); + detail.GetPatternPieceData().SetLabelHeight(m_oldData.GetLabelHeight()); + detail.GetPatternPieceData().SetFontSize(m_oldData.GetFontSize()); + detail.GetPatternPieceData().SetRotation(m_oldData.GetRotation()); + detail.GetPatternPieceData().SetVisible(ui.checkBoxDetail->isChecked()); + + qDebug() << "DD VISIBLE" << detail.GetPatternPieceData().IsVisible(); + + detail.GetPatternInfo() = m_oldGeom; + detail.GetPatternInfo().SetVisible(ui.checkBoxPattern->isChecked()); + return detail; } @@ -315,7 +432,7 @@ void DialogDetail::setDetail(const VDetail &value) NewItem(node.getId(), node.getTypeTool(), node.getTypeNode(), node.getMx(), node.getMy(), node.getReverse()); } - ui.lineEditNameDetail->setText(detail.getName()); + ui.lineEditName->setText(detail.getName()); ui.checkBoxSeams->setChecked(detail.getSeamAllowance()); ui.checkBoxClosed->setChecked(detail.getClosed()); ClickedClosed(detail.getClosed()); @@ -324,6 +441,21 @@ void DialogDetail::setDetail(const VDetail &value) ui.listWidget->setCurrentRow(0); ui.listWidget->setFocus(Qt::OtherFocusReason); ui.toolButtonDelete->setEnabled(true); + + ui.lineEditLetter->setText(detail.GetPatternPieceData().GetLetter()); + ui.checkBoxDetail->setChecked(detail.GetPatternPieceData().IsVisible()); + ui.checkBoxPattern->setChecked(detail.GetPatternInfo().IsVisible()); + + m_conMCP.clear(); + for (int i = 0; i < detail.GetPatternPieceData().GetMCPCount(); ++i) + { + m_conMCP << detail.GetPatternPieceData().GetMCP(i); + } + + UpdateList(); + m_oldData = detail.GetPatternPieceData(); + m_oldGeom = detail.GetPatternInfo(); + ValidObjects(DetailIsValid()); } @@ -581,3 +713,43 @@ bool DialogDetail::DetailIsClockwise() const } return false; } + +//--------------------------------------------------------------------------------------------------------------------- +void DialogDetail::ClearFields() +{ + ui.comboBoxMaterial->setCurrentIndex(0); + ui.spinBoxCutNumber->setValue(0); + ui.comboBoxPlacement->setCurrentIndex(0); +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogDetail::SetAddMode() +{ + ui.pushButtonAdd->setText(tr("Add")); + ui.pushButtonCancel->hide(); + ui.pushButtonRemove->hide(); + ui.listWidgetMCP->setCurrentRow(-1); + m_bAddMode = true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void DialogDetail::SetEditMode() +{ + int iR = ui.listWidgetMCP->currentRow(); + // this method can be called by clicking on item or by update. In the latter case there is nothing else to do! + if (iR < 0 || iR >= m_conMCP.count()) + { + return; + } + + ui.pushButtonAdd->setText(tr("Update")); + ui.pushButtonCancel->show(); + ui.pushButtonRemove->show(); + + MaterialCutPlacement mcp = m_conMCP.at(iR); + ui.comboBoxMaterial->setCurrentText(mcp.m_qsMaterialUserDef); + ui.spinBoxCutNumber->setValue(mcp.m_iCutNumber); + ui.comboBoxPlacement->setCurrentIndex(int(mcp.m_ePlacement)); + + m_bAddMode = false; +} diff --git a/src/libs/vtools/dialogs/tools/dialogdetail.h b/src/libs/vtools/dialogs/tools/dialogdetail.h index d6d31c803..482a5ee5d 100644 --- a/src/libs/vtools/dialogs/tools/dialogdetail.h +++ b/src/libs/vtools/dialogs/tools/dialogdetail.h @@ -32,6 +32,8 @@ #include "ui_dialogdetail.h" #include "dialogtool.h" #include "../vpatterndb/vdetail.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vpatterninfogeometry.h" /** * @brief The DialogDetail class dialog for ToolDetai. Help create detail and edit option. @@ -62,6 +64,13 @@ protected: */ virtual void SaveData() Q_DECL_OVERRIDE; virtual void CheckState() Q_DECL_OVERRIDE; + +protected slots: + void UpdateList(); + void AddUpdate(); + void Cancel(); + void Remove(); + private slots: void NameDetailChanged(); private: @@ -78,6 +87,16 @@ private: /** @brief closed keep option about equdistant (closed or not) */ bool closed; bool flagWidth; + bool m_bAddMode; + + QStringList m_qslMaterials; + QStringList m_qslPlacements; + // temporary container for Material/Cut/Placement 3-tuples + MCPContainer m_conMCP; + VPatternPieceData m_oldData; + VPatternInfoGeometry m_oldGeom; + + bool DetailIsValid() const; bool FirstPointEqualLast() const; bool DetailIsClockwise() const; @@ -87,7 +106,14 @@ private: VDetail CreateDetail() const; void ValidObjects(bool value); void EnableObjectGUI(bool value); + + void ClearFields(); + quint32 RowId(int i) const; + +private slots: + void SetAddMode(); + void SetEditMode(); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vtools/dialogs/tools/dialogdetail.ui b/src/libs/vtools/dialogs/tools/dialogdetail.ui index 29a7ae68b..418b88edf 100644 --- a/src/libs/vtools/dialogs/tools/dialogdetail.ui +++ b/src/libs/vtools/dialogs/tools/dialogdetail.ui @@ -7,7 +7,7 @@ 0 0 522 - 425 + 481 @@ -20,11 +20,355 @@ - - - - + + + + + 1 + + + + General + + + + + 59 + 468 + 504 + 15 + + + + Ready! + + + Qt::RichText + + + false + + + + + + 50 + 40 + 367 + 34 + + + + + + + + 0 + 30 + 561 + 361 + + + + + + + + + 6 + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + + + + 1 + 0 + + + + Bias X: + + + + + + + + 1 + 0 + + + + -900.990000000000009 + + + 900.990000000000009 + + + 0.100000000000000 + + + 0.000000000000000 + + + + + + + cm + + + + + + + + + + + + 1 + 0 + + + + Bias Y: + + + + + + + + 1 + 0 + + + + -900.990000000000009 + + + 900.990000000000009 + + + 0.100000000000000 + + + + + + + cm + + + + + + + + + + + Reverse + + + + + + + + + Options + + + + + + + + + Seam allowance + + + true + + + + + + + + + + 1 + 0 + + + + + + + Width: + + + + + + + + 1 + 0 + + + + 900.990000000000009 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + + 0 + 0 + + + + cm + + + + + + + + + Closed + + + true + + + + + + + QLayout::SetFixedSize + + + 10 + + + 10 + + + 10 + + + 10 + + + + + false + + + Delete + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Scroll down the list + + + ... + + + + + + + + + + + + Scroll up the list + + + ... + + + + + + + + + + + + + + + + + + + + + + + + 50 + 0 + 327 + 32 + + + + All objects in path should follow in clockwise direction. + + + + + 10 + 0 + 32 + 32 + + 0 @@ -38,376 +382,174 @@ :/icon/32x32/clockwise.png - - - - - All objects in path should follow in clockwise direction. - - - - - - - - - - - - - 6 - - - QLayout::SetDefaultConstraint - - - 0 - - - 0 - - - - - - 1 - 0 - - - - Bias X: - - - - - - - - 1 - 0 - - - - -900.990000000000009 - - - 900.990000000000009 - - - 0.100000000000000 - - - 0.000000000000000 - - - - - - - cm - - - - - - - - - - - - 1 - 0 - - - - Bias Y: - - - - - - - - 1 - 0 - - - - -900.990000000000009 - - - 900.990000000000009 - - - 0.100000000000000 - - - - - - - cm - - - - - - - - - - - Reverse - - - - - - - - - Options - - - - - - - - - 0 - 0 - - - - - - - - - 255 - 0 - 0 - - - - - - - - - 255 - 0 - 0 - - - - - - - - - 159 - 158 - 158 - - - - - - - - - - - Name of detail: - - - - - - - - 0 - 0 - - - - Detail - - - - - - - - - Seam allowance - - - true - - - - - - - - - - 1 - 0 - - - - - - - Width: - - - - - - - - 1 - 0 - - - - 900.990000000000009 - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - - 0 - 0 - - - - cm - - - - - - - - - Closed - - - true - - - - - - - QLayout::SetFixedSize - - - 10 - - - 10 - - - 10 - - - 10 - - - - - false - - - Delete - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Scroll down the list - - - ... - - - - - - - - - - - - Scroll up the list - - - ... - - - - - - - - - - - + + + + Pattern piece data + + + + + + + + 280 + 0 + 201 + 381 + + + + Qt::ClickFocus + + + + + + 0 + 70 + 271 + 153 + + + + Material/Cut number/Placement + + + + + + Material type: + + + + + + + true + + + + + + + Cut number: + + + + + + + 1000 + + + + + + + Placement: + + + + + + + + + + Add + + + + + + + Cancel + + + + + + + Remove + + + + + + + + + 0 + 0 + 271 + 61 + + + + + + + Letter: + + + + + + + 3 + + + + + + + Name of detail: + + + + + + + 15 + + + + + + + + + 0 + 230 + 261 + 80 + + + + + + + Detail label visible + + + + + + + Pattern label visible + + + + + - - - - - - - - - - Ready! - - - Qt::RichText - - - false - + - + Qt::Horizontal @@ -420,14 +562,27 @@ + lineEditLetter + lineEditName + comboBoxMaterial + spinBoxCutNumber + comboBoxPlacement + pushButtonAdd + pushButtonCancel + pushButtonRemove + tabWidget + listWidgetMCP + buttonBox + toolButtonUp listWidget + checkBoxClosed + toolButtonDelete doubleSpinBoxBiasX doubleSpinBoxBiasY - lineEditNameDetail + checkBoxReverse checkBoxSeams doubleSpinBoxSeams - checkBoxClosed - buttonBox + toolButtonDown diff --git a/src/libs/vtools/tools/tools.pri b/src/libs/vtools/tools/tools.pri index 36b6f986c..0391ca475 100644 --- a/src/libs/vtools/tools/tools.pri +++ b/src/libs/vtools/tools/tools.pri @@ -50,7 +50,8 @@ HEADERS += \ $$PWD/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.h \ $$PWD/drawTools/toolcurve/vtoolcubicbezier.h \ $$PWD/drawTools/toolcurve/vtoolcubicbezierpath.h \ - $$PWD/drawTools/operation/vtoolrotation.h + $$PWD/drawTools/operation/vtoolrotation.h \ + $$PWD/vtextgraphicsitem.h SOURCES += \ $$PWD/vtooldetail.cpp \ @@ -98,4 +99,5 @@ SOURCES += \ $$PWD/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.cpp \ $$PWD/drawTools/toolcurve/vtoolcubicbezier.cpp \ $$PWD/drawTools/toolcurve/vtoolcubicbezierpath.cpp \ - $$PWD/drawTools/operation/vtoolrotation.cpp + $$PWD/drawTools/operation/vtoolrotation.cpp \ + $$PWD/vtextgraphicsitem.cpp diff --git a/src/libs/vtools/tools/vtextgraphicsitem.cpp b/src/libs/vtools/tools/vtextgraphicsitem.cpp new file mode 100644 index 000000000..aa312ca32 --- /dev/null +++ b/src/libs/vtools/tools/vtextgraphicsitem.cpp @@ -0,0 +1,602 @@ +/************************************************************************ + ** + ** @file vtextgraphicsitem.h + ** @author Bojan Kverh + ** @date June 16, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../vmisc/def.h" +#include "vtextgraphicsitem.h" + +#define RESIZE_SQUARE 30 +#define ROTATE_CIRCLE 20 +#define ROTATE_RECT 60 +#define ROTATE_ARC 50 +#define MIN_W 120 +#define MIN_H 60 +#define TOP_Z 2 + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::VTextGraphicsItem constructor + * @param pParent pointer to the parent item + */ +VTextGraphicsItem::VTextGraphicsItem(QGraphicsItem* pParent) + :QGraphicsObject(pParent), m_eMode(VTextGraphicsItem::mNormal), m_bReleased(false), + m_ptStartPos(), m_ptStart(), m_ptRotCenter(), m_szStart(), m_dRotation(0), m_dAngle(0), + m_rectResize(), m_iMinH(MIN_H), m_rectBoundingBox(), m_tm() +{ + m_rectBoundingBox.setTopLeft(QPointF(0, 0)); + SetSize(MIN_W, m_iMinH); + setZValue(TOP_Z); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::~VTextGraphicsItem destructor + */ +VTextGraphicsItem::~VTextGraphicsItem() +{} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::SetFont sets the item font + * @param fnt font to be used in item + */ +void VTextGraphicsItem::SetFont(const QFont& fnt) +{ + m_tm.SetFont(fnt); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::paint redraws the item content + * @param painter pointer to the QPainter in use + * @param option pointer to the object containing the actual label rectangle + * @param widget not used + */ +void VTextGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget); + painter->fillRect(option->rect, QColor(251, 251, 175)); + painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + + // draw text lines + int iY = 0; + int iH = 0; + painter->setPen(Qt::black); + QFont fnt = m_tm.GetFont(); + for (int i = 0; i < m_tm.GetCount(); ++i) + { + const TextLine& tl = m_tm.GetLine(i); + iH = tl.m_iHeight; + fnt.setPixelSize(m_tm.GetFont().pixelSize() + tl.m_iFontSize); + fnt.setWeight(tl.m_eFontWeight); + fnt.setStyle(tl.m_eStyle); + painter->setFont(fnt); + painter->drawText(0, iY, qRound(boundingRect().width()), iH, tl.m_eAlign, tl.m_qsText); + iY += iH + m_tm.GetSpacing(); + } + + // now draw the features specific to non-normal modes + if (m_eMode != mNormal) + { + // outline the rectangle + painter->setPen(QPen(Qt::black, 2, Qt::DashLine)); + painter->drawRect(boundingRect().adjusted(1, 1, -1, -1)); + + if (m_eMode != mRotate) + { + // draw the resize square + painter->setPen(Qt::black); + painter->setBrush(Qt::black); + painter->drawRect(m_rectResize); + + if (m_eMode == mResize) + { + // draw the resize diagonal lines + painter->drawLine(0, 0, qRound(m_rectBoundingBox.width()), qRound(m_rectBoundingBox.height())); + painter->drawLine(0, qRound(m_rectBoundingBox.height()), qRound(m_rectBoundingBox.width()), 0); + } + } + else + { + // in rotate mode, draw the circle in the middle + painter->setPen(Qt::black); + painter->setBrush(Qt::black); + painter->drawEllipse( + QPointF(m_rectBoundingBox.width()/2, m_rectBoundingBox.height()/2), + ROTATE_CIRCLE, + ROTATE_CIRCLE + ); + painter->setPen(QPen(Qt::black, 3)); + painter->setBrush(Qt::NoBrush); + // and then draw the arc in each of the corners + int iTop = ROTATE_RECT - ROTATE_ARC; + int iLeft = ROTATE_RECT - ROTATE_ARC; + int iRight = qRound(m_rectBoundingBox.width()) - ROTATE_RECT; + int iBottom = qRound(m_rectBoundingBox.height()) - ROTATE_RECT; + painter->drawArc(iLeft, iTop, ROTATE_ARC, ROTATE_ARC, 180*16, -90*16); + painter->drawArc(iRight, iTop, ROTATE_ARC, ROTATE_ARC, 90*16, -90*16); + painter->drawArc(iLeft, iBottom, ROTATE_ARC, ROTATE_ARC, 270*16, -90*16); + painter->drawArc(iRight, iBottom, ROTATE_ARC, ROTATE_ARC, 0*16, -90*16); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::Reset resets the item, putting the mode and z coordinate to normal and redraws it + */ +void VTextGraphicsItem::Reset() +{ + m_eMode = mNormal; + m_bReleased = false; + Update(); + setZValue(TOP_Z); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::AddLine adds a line of text to the label list. If necessary, it also resizes the + * label bounding box until it is big enough to contain all the text + * @param tl line of text to add + */ +void VTextGraphicsItem::AddLine(const TextLine& tl) +{ + m_tm.AddLine(tl); + while (m_tm.IsBigEnough(MIN_W, m_iMinH, MIN_FONT_SIZE) == false) + { + m_iMinH += 5; + } + if (m_rectBoundingBox.height() < m_iMinH) + { + SetSize(m_rectBoundingBox.width(), m_iMinH); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::Clear deletes all the label texts + */ +void VTextGraphicsItem::Clear() +{ + m_tm.Clear(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::SetSize Tries to set the label size to (fW, fH). If any of those is too small, the label + * size does not change. + * @param fW label width + * @param fH label height + */ +void VTextGraphicsItem::SetSize(qreal fW, qreal fH) +{ + // don't allow resize under specific size + if (fW < MIN_W || fH < m_iMinH) + { + return; + } + + m_rectBoundingBox.setTopLeft(QPointF(0, 0)); + m_rectBoundingBox.setWidth(fW); + m_rectBoundingBox.setHeight(fH); + m_rectResize.setTopLeft(QPointF(fW - RESIZE_SQUARE, fH - RESIZE_SQUARE)); + m_rectResize.setWidth(RESIZE_SQUARE); + m_rectResize.setHeight(RESIZE_SQUARE); + setTransformOriginPoint(m_rectBoundingBox.center()); + prepareGeometryChange(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::Update sets the correct font size and redraws the label + */ +void VTextGraphicsItem::Update() +{ + UpdateFont(); + UpdateBox(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::IsContained checks if the bounding box around rotated rectBB is contained in + * the parent. If that is not the case, it calculates the amount of movement needed to put it inside the parent + * and write it into dX, dY + * @param rectBB bounding box in question + * @param dRot bounding box rotation in degrees + * @param dX horizontal translation needed to put the box inside parent item + * @param dY vertical translation needed to put the box inside parent item + * @return true, if rectBB is contained in parent item and false otherwise + */ +bool VTextGraphicsItem::IsContained(QRectF rectBB, qreal dRot, qreal &dX, qreal &dY) const +{ + QRectF rectParent = parentItem()->boundingRect(); + rectBB = GetBoundingRect(rectBB, dRot); + dX = 0; + dY = 0; + + if (rectParent.contains(rectBB) == false) + { + if (rectParent.left() - rectBB.left() > fabs(dX)) + { + dX = rectParent.left() - rectBB.left(); + } + else if (rectBB.right() - rectParent.right() > fabs(dX)) + { + dX = rectParent.right() - rectBB.right(); + } + + if (rectParent.top() - rectBB.top() > fabs(dY)) + { + dY = rectParent.top() - rectBB.top(); + } + else if (rectBB.bottom() - rectParent.bottom() > fabs(dY)) + { + dY = rectParent.bottom() - rectBB.bottom(); + } + + return false; + } + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateData Updates the detail label + * @param qsName name of detail + * @param data reference to VPatternPieceData + */ +void VTextGraphicsItem::UpdateData(const QString &qsName, const VPatternPieceData &data) +{ + m_tm.Update(qsName, data); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateData Updates the pattern label + * @param pDoc pointer to the pattern object + */ +void VTextGraphicsItem::UpdateData(const VAbstractPattern* pDoc) +{ + m_tm.Update(pDoc); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::GetTextLines returns the number of lines of text to show + * @return number of lines of text + */ +int VTextGraphicsItem::GetTextLines() const +{ + return m_tm.GetCount(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::GetFontSize returns the currently used text base font size + * @return current text base font size + */ +int VTextGraphicsItem::GetFontSize() const +{ + return m_tm.GetFont().pixelSize(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::boundingRect returns the label bounding box + * @return label bounding box + */ +QRectF VTextGraphicsItem::boundingRect() const +{ + return m_rectBoundingBox; +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::mousePressEvent handles left button mouse press events + * @param pME pointer to QGraphicsSceneMouseEvent object + */ +void VTextGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *pME) +{ + if (pME->button() == Qt::LeftButton) + { + // record the parameters of the mouse press. Specially record the position + // of the press as the origin for the following operations + m_ptStartPos = pos(); + m_ptStart = pME->scenePos(); + m_szStart = m_rectBoundingBox.size(); + m_ptRotCenter = mapToScene(m_rectBoundingBox.center()); + m_dAngle = GetAngle(pME->scenePos()); + m_dRotation = rotation(); + // in rotation mode, do not do any changes here, because user might want to + // rotate the label more. + if (m_eMode != mRotate) + { + // if user pressed the button inside the resize square, switch to resize mode + if (m_rectResize.contains(pME->pos()) == true) + { + m_eMode = mResize; + SetOverrideCursor(Qt::SizeFDiagCursor); + } + else + { + // if user pressed the button outside the resize square, switch to move mode + m_eMode = mMove; + SetOverrideCursor(cursorArrowCloseHand, 1, 1); + } + } + // raise the label and redraw it + setZValue(TOP_Z + 1); + UpdateBox(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::mouseMoveEvent handles mouse move events + * @param pME pointer to QGraphicsSceneMouseEvent object + */ +void VTextGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pME) +{ + qreal dX; + qreal dY; + QRectF rectBB; + QPointF ptDiff = pME->scenePos() - m_ptStart; + if (m_eMode == mMove) + { + // in move mode move the label along the mouse move from the origin + QPointF pt = m_ptStartPos + ptDiff; + rectBB.setTopLeft(pt); + rectBB.setWidth(m_rectBoundingBox.width()); + rectBB.setHeight(m_rectBoundingBox.height()); + // before moving label to a new position, check if it will still be inside the parent item + if (IsContained(rectBB, rotation(), dX, dY) == false) + { + pt.setX(pt.x() + dX); + pt.setY(pt.y() + dY); + } + setPos(pt); + UpdateBox(); + } + else if (m_eMode == mResize) + { + // in resize mode, resize the label along the mouse move from the origin + QPointF pt = m_ptStartPos; + rectBB.setTopLeft(pt); + QSizeF sz(m_szStart.width() + ptDiff.x(), m_szStart.height() + ptDiff.y()); + rectBB.setSize(sz); + // before resizing the label to a new size, check if it will still be inside the parent item + if (IsContained(rectBB, rotation(), dX, dY) == true) + { + SetSize(sz.width(), sz.height()); + Update(); + emit SignalShrink(); + } + } + else if (m_eMode == mRotate) + { + // if the angle from the original position is small (0.5 degrees), just remeber the new angle + // new angle will be the starting angle for rotation + if (fabs(m_dAngle) < 0.01) + { + m_dAngle = GetAngle(pME->scenePos()); + return; + } + // calculate the angle difference from the starting angle + double dAng = qRadiansToDegrees(GetAngle(pME->scenePos()) - m_dAngle); + rectBB.setTopLeft(m_ptStartPos); + rectBB.setWidth(m_rectBoundingBox.width()); + rectBB.setHeight(m_rectBoundingBox.height()); + // check if the rotated label will be inside the parent item and then rotate it + if (IsContained(rectBB, m_dRotation + dAng, dX, dY) == true) + { + setRotation(m_dRotation + dAng); + Update(); + } + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::mouseReleaseEvent handles left button mouse release events + * @param pME pointer to QGraphicsSceneMouseEvent object + */ +void VTextGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pME) +{ + if (pME->button() == Qt::LeftButton) + { + // restore the cursor + if (m_eMode == mMove) + { + RestoreOverrideCursor(cursorArrowCloseHand); + } + else if (m_eMode == mResize) + { + RestoreOverrideCursor(Qt::SizeFDiagCursor); + } + double dDist = fabs(pME->scenePos().x() - m_ptStart.x()) + fabs(pME->scenePos().y() - m_ptStart.y()); + // determine if this was just press/release (bShort == true) or user did some operation between press and release + bool bShort = (dDist < 2); + + if (m_eMode == mMove || m_eMode == mResize) + { // if user just pressed and released the button, we must switch the mode to rotate + // but if user did some operation (move/resize), emit the proper signal and update the label + if (bShort == true) + { + if (m_bReleased == true) + { + m_eMode = mRotate; + UpdateBox(); + } + } + else if (m_eMode == mMove) + { + emit SignalMoved(pos()); + UpdateBox(); + } + else + { + emit SignalResized(m_rectBoundingBox.width(), m_tm.GetFont().pixelSize()); + Update(); + } + } + else + { // in rotate mode, if user did just press/release, switch to move mode + if (bShort == true) + { + m_eMode = mMove; + UpdateBox(); + } + else + { + // if user rotated the item, emit proper signal and update the label + emit SignalRotated(rotation()); + UpdateBox(); + } + } + m_bReleased = true; + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateBox redraws the label content + */ +void VTextGraphicsItem::UpdateBox() +{ + update(m_rectBoundingBox); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::UpdateFont sets the text font size, so that the entire text will + * just fit into the label bounding box + */ +void VTextGraphicsItem::UpdateFont() +{ + int iFS = m_tm.GetFont().pixelSize(); + + // increase the font size until the bounding rect is not big enough + while (iFS < MAX_FONT_SIZE && m_tm.IsBigEnough(m_rectBoundingBox.width(), m_rectBoundingBox.height(), iFS) == true) + { + ++iFS; + } + // decrease the font size until the bounding rect is big enough + while (iFS >= MIN_FONT_SIZE && m_tm.IsBigEnough(m_rectBoundingBox.width(), m_rectBoundingBox.height(), iFS) == false) + { + --iFS; + } + m_tm.SetFontSize(iFS); + UpdateBox(); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::GetAngle calculates the angle between the line, which goes from + * rotation center to pt and x axis + * @param pt point of interest + * @return the angle between line from rotation center and point of interest and x axis + */ +double VTextGraphicsItem::GetAngle(QPointF pt) const +{ + double dX = pt.x() - m_ptRotCenter.x(); + double dY = pt.y() - m_ptRotCenter.y(); + + if (fabs(dX) < 1 && fabs(dY) < 1) + { + return 0; + } + else + { + return qAtan2(dY, dX); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief VTextGraphicsItem::GetBoundingRect calculates the bounding box + * around rectBB rectangle, rotated around its center by dRot degrees + * @param rectBB rectangle of interest + * @param dRot rectangle rotation + * @return bounding box around rectBB rotated by dRot + */ +QRectF VTextGraphicsItem::GetBoundingRect(QRectF rectBB, qreal dRot) const +{ + QPointF apt[4] = { rectBB.topLeft(), rectBB.topRight(), rectBB.bottomLeft(), rectBB.bottomRight() }; + QPointF ptCenter = rectBB.center(); + + qreal dX1 = 0; + qreal dX2 = 0; + qreal dY1 = 0; + qreal dY2 = 0; + + double dAng = qDegreesToRadians(dRot); + for (int i = 0; i < 4; ++i) + { + QPointF pt = apt[i] - ptCenter; + qreal dX = pt.x()*cos(dAng) + pt.y()*sin(dAng); + qreal dY = -pt.x()*sin(dAng) + pt.y()*cos(dAng); + + if (i == 0) + { + dX1 = dX2 = dX; + dY1 = dY2 = dY; + } + else + { + if (dX < dX1) + { + dX1 = dX; + } + else if (dX > dX2) + { + dX2 = dX; + } + if (dY < dY1) + { + dY1 = dY; + } + else if (dY > dY2) + { + dY2 = dY; + } + } + } + QRectF rect; + rect.setTopLeft(ptCenter + QPointF(dX1, dY1)); + rect.setWidth(dX2 - dX1); + rect.setHeight(dY2 - dY1); + return rect; +} diff --git a/src/libs/vtools/tools/vtextgraphicsitem.h b/src/libs/vtools/tools/vtextgraphicsitem.h new file mode 100644 index 000000000..c86b1a639 --- /dev/null +++ b/src/libs/vtools/tools/vtextgraphicsitem.h @@ -0,0 +1,106 @@ +/************************************************************************ + ** + ** @file vtextgraphicsitem.h + ** @author Bojan Kverh + ** @date June 16, 2016 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2013-2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef VTEXTGRAPHICSITEM_H +#define VTEXTGRAPHICSITEM_H + +#include +#include +#include + +#include "../vlayout/vtextmanager.h" + +/** + * @brief The VTextGraphicsItem class. This class implements text graphics item, + * which can be dragged around, resized and rotated within the parent item. The text font + * size will be automatically updated, so that the entire text will fit into the item. + */ +class VTextGraphicsItem : public QGraphicsObject +{ + Q_OBJECT + + enum Mode { + mNormal, + mMove, + mResize, + mRotate + }; + +public: + VTextGraphicsItem(QGraphicsItem* pParent = 0); + ~VTextGraphicsItem(); + + void SetFont(const QFont& fnt); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void Reset(); + + int GetFontSize() const; + QRectF boundingRect() const; + void AddLine(const TextLine& tl); + void Clear(); + void SetSize(qreal fW, qreal fH); + void Update(); + bool IsContained(QRectF rectBB, qreal dRot, qreal& dX, qreal& dY) const; + void UpdateData(const QString& qsName, const VPatternPieceData& data); + void UpdateData(const VAbstractPattern* pDoc); + int GetTextLines() const; + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent* pME); + void mouseMoveEvent(QGraphicsSceneMouseEvent* pME); + void mouseReleaseEvent(QGraphicsSceneMouseEvent* pME); + void UpdateBox(); + void UpdateFont(); + + double GetAngle(QPointF pt) const; + +signals: + void SignalMoved(const QPointF& ptPos); + void SignalResized(qreal iTW, int iFontSize); + void SignalRotated(qreal dAng); + void SignalShrink(); + +private: + Mode m_eMode; + bool m_bReleased; + QPointF m_ptStartPos; + QPointF m_ptStart; + QPointF m_ptRotCenter; + QSizeF m_szStart; + double m_dRotation; + double m_dAngle; + QRectF m_rectResize; + int m_iMinH; + QRectF m_rectBoundingBox; + VTextManager m_tm; + + QRectF GetBoundingRect(QRectF rectBB, qreal dRot) const; +}; + +#endif // VTEXTGRAPHICSITEM_H diff --git a/src/libs/vtools/tools/vtooldetail.cpp b/src/libs/vtools/tools/vtooldetail.cpp index 9eed8d8c3..1d827e268 100644 --- a/src/libs/vtools/tools/vtooldetail.cpp +++ b/src/libs/vtools/tools/vtooldetail.cpp @@ -40,6 +40,8 @@ #include "../undocommands/movedetail.h" #include "../undocommands/adddet.h" #include "../undocommands/deletedetail.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vpatterninfogeometry.h" #include #include @@ -52,8 +54,11 @@ const QString VToolDetail::TagNode = QStringLiteral("node"); const QString VToolDetail::AttrSupplement = QStringLiteral("supplement"); const QString VToolDetail::AttrClosed = QStringLiteral("closed"); const QString VToolDetail::AttrWidth = QStringLiteral("width"); +const QString VToolDetail::AttrHeight = QStringLiteral("height"); const QString VToolDetail::AttrNodeType = QStringLiteral("nodeType"); const QString VToolDetail::AttrReverse = QStringLiteral("reverse"); +const QString VToolDetail::AttrFont = QStringLiteral("fontSize"); +const QString VToolDetail::AttrRotation = QStringLiteral("rotation"); const QString VToolDetail::NodeTypeContour = QStringLiteral("Contour"); const QString VToolDetail::NodeTypeModeling = QStringLiteral("Modeling"); @@ -76,7 +81,8 @@ const QString VToolDetail::NodeSplinePath = QStringLiteral("NodeSplinePath"); VToolDetail::VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 &id, const Source &typeCreation, VMainGraphicsScene *scene, const QString &drawName, QGraphicsItem *parent) :VAbstractTool(doc, data, id), VNoBrushScalePathItem(parent), dialog(nullptr), sceneDetails(scene), - drawName(drawName), seamAllowance(new VNoBrushScalePathItem(this)) + drawName(drawName), seamAllowance(new VNoBrushScalePathItem(this)), dataLabel(new VTextGraphicsItem(this)), + patternInfo(new VTextGraphicsItem(this)) { VDetail detail = data->GetDetail(id); for (int i = 0; i< detail.CountNode(); ++i) @@ -114,6 +120,7 @@ VToolDetail::VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 this->setFlag(QGraphicsItem::ItemIsFocusable, true);// For keyboard input focus connect(scene, &VMainGraphicsScene::EnableToolMove, this, &VToolDetail::EnableToolMove); + connect(scene, &VMainGraphicsScene::ItemClicked, this, &VToolDetail::ResetChildren); if (typeCreation == Source::FromGui || typeCreation == Source::FromTool) { AddToFile(); @@ -123,6 +130,20 @@ VToolDetail::VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 } } setAcceptHoverEvents(true); + + connect(dataLabel, &VTextGraphicsItem::SignalMoved, this, &VToolDetail::SaveMoveDetail); + connect(dataLabel, &VTextGraphicsItem::SignalResized, this, &VToolDetail::SaveResizeDetail); + connect(dataLabel, &VTextGraphicsItem::SignalRotated, this, &VToolDetail::SaveRotationDetail); + + connect(patternInfo, &VTextGraphicsItem::SignalMoved, this, &VToolDetail::SaveMovePattern); + connect(patternInfo, &VTextGraphicsItem::SignalResized, this, &VToolDetail::SaveResizePattern); + connect(patternInfo, &VTextGraphicsItem::SignalRotated, this, &VToolDetail::SaveRotationPattern); + + connect(doc, &VAbstractPattern::patternChanged, this, &VToolDetail::UpdatePatternInfo); + connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdateLabel); + connect(doc, &VAbstractPattern::CheckLayout, this, &VToolDetail::UpdatePatternInfo); + UpdateLabel(); + UpdatePatternInfo(); } //--------------------------------------------------------------------------------------------------------------------- @@ -300,9 +321,11 @@ void VToolDetail::FullUpdateFromGuiOk(int result) const VDetail newDet = dialogTool->getDetail(); const VDetail oldDet = VAbstractTool::data.GetDetail(id); + qDebug() << "VToolDetail Position" << newDet.GetPatternPieceData().GetPos(); SaveDetailOptions *saveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); connect(saveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); qApp->getUndoStack()->push(saveCommand); + UpdateLabel(); } delete dialog; dialog = nullptr; @@ -325,6 +348,39 @@ void VToolDetail::AddToFile() doc->SetAttribute(domElement, AttrClosed, static_cast(detail.getClosed())); doc->SetAttribute(domElement, AttrWidth, detail.getWidth()); + QDomElement domData = doc->createElement(VAbstractPattern::TagData); + const VPatternPieceData& data = detail.GetPatternPieceData(); + doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, data.GetPos().x()); + doc->SetAttribute(domData, AttrMy, data.GetPos().y()); + doc->SetAttribute(domData, AttrWidth, data.GetLabelWidth()); + doc->SetAttribute(domData, AttrHeight, data.GetLabelHeight()); + doc->SetAttribute(domData, AttrFont, data.GetFontSize()); + doc->SetAttribute(domData, AttrRotation, data.GetRotation()); + + for (int i = 0; i < data.GetMCPCount(); ++i) + { + MaterialCutPlacement mcp = data.GetMCP(i); + QDomElement domMCP = doc->createElement(VAbstractPattern::TagMCP); + doc->SetAttribute(domMCP, VAbstractPattern::AttrMaterial, int(mcp.m_eMaterial)); + doc->SetAttribute(domMCP, VAbstractPattern::AttrUserDefined, mcp.m_qsMaterialUserDef); + doc->SetAttribute(domMCP, VAbstractPattern::AttrCutNumber, mcp.m_iCutNumber); + doc->SetAttribute(domMCP, VAbstractPattern::AttrPlacement, int(mcp.m_ePlacement)); + domData.appendChild(domMCP); + } + domElement.appendChild(domData); + + domData = doc->createElement(VAbstractPattern::TagPatternInfo); + const VPatternInfoGeometry& geom = detail.GetPatternInfo(); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, geom.GetPos().x()); + doc->SetAttribute(domData, AttrMy, geom.GetPos().y()); + doc->SetAttribute(domData, AttrWidth, geom.GetLabelWidth()); + doc->SetAttribute(domData, AttrHeight, geom.GetLabelHeight()); + doc->SetAttribute(domData, AttrFont, geom.GetFontSize()); + doc->SetAttribute(domData, AttrRotation, geom.GetRotation()); + for (int i = 0; i < detail.CountNode(); ++i) { AddNode(doc, domElement, detail.at(i)); @@ -350,6 +406,40 @@ void VToolDetail::RefreshDataInFile() doc->SetAttribute(domElement, AttrClosed, QString().setNum(static_cast(det.getClosed()))); doc->SetAttribute(domElement, AttrWidth, QString().setNum(det.getWidth())); doc->RemoveAllChildren(domElement); + + QDomElement domData = doc->createElement(VAbstractPattern::TagData); + const VPatternPieceData& data = det.GetPatternPieceData(); + doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, data.GetPos().x()); + doc->SetAttribute(domData, AttrMy, data.GetPos().y()); + doc->SetAttribute(domData, AttrWidth, data.GetLabelWidth()); + doc->SetAttribute(domData, AttrHeight, data.GetLabelHeight()); + doc->SetAttribute(domData, AttrFont, data.GetFontSize()); + doc->SetAttribute(domData, AttrRotation, data.GetRotation()); + + for (int i = 0; i < data.GetMCPCount(); ++i) + { + MaterialCutPlacement mcp = data.GetMCP(i); + QDomElement domMCP = doc->createElement(VAbstractPattern::TagMCP); + doc->SetAttribute(domMCP, VAbstractPattern::AttrMaterial, int(mcp.m_eMaterial)); + doc->SetAttribute(domMCP, VAbstractPattern::AttrUserDefined, mcp.m_qsMaterialUserDef); + doc->SetAttribute(domMCP, VAbstractPattern::AttrCutNumber, mcp.m_iCutNumber); + doc->SetAttribute(domMCP, VAbstractPattern::AttrPlacement, int(mcp.m_ePlacement)); + domData.appendChild(domMCP); + } + domElement.appendChild(domData); + + domData = doc->createElement(VAbstractPattern::TagPatternInfo); + const VPatternInfoGeometry& geom = det.GetPatternInfo(); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, geom.IsVisible() == true? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, geom.GetPos().x()); + doc->SetAttribute(domData, AttrMy, geom.GetPos().y()); + doc->SetAttribute(domData, AttrWidth, geom.GetLabelWidth()); + doc->SetAttribute(domData, AttrHeight, geom.GetLabelHeight()); + doc->SetAttribute(domData, AttrFont, geom.GetFontSize()); + doc->SetAttribute(domData, AttrRotation, geom.GetRotation()); + for (int i = 0; i < det.CountNode(); ++i) { AddNode(doc, domElement, det.at(i)); @@ -520,7 +610,7 @@ void VToolDetail::hoverEnterEvent(QGraphicsSceneHoverEvent *event) } } -////--------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- void VToolDetail::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); @@ -560,7 +650,7 @@ void VToolDetail::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) setDialog(); dialog->show(); } - if (selectedAction == actionRemove) + else if (selectedAction == actionRemove) { try { @@ -575,6 +665,221 @@ void VToolDetail::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) } } +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief UpdateLabel updates the text label, making it just big enough for the text to fit it + */ +void VToolDetail::UpdateLabel() +{ + const VDetail detail = VAbstractTool::data.GetDetail(id); + const VPatternPieceData& data = detail.GetPatternPieceData(); + + if (data.IsVisible() == true) + { + //dataLabel->Reset(); + + QString qsText = "Cut %1 of %2%3"; + QStringList qslPlace; + qslPlace << "" << " on Fold"; + QFont fnt = qApp->font(); + fnt.setPixelSize(data.GetFontSize()); + dataLabel->SetFont(fnt); + dataLabel->SetSize(data.GetLabelWidth(), data.GetLabelHeight()); + dataLabel->UpdateData(detail.getName(), data); + QPointF pt = data.GetPos(); + QRectF rectBB; + rectBB.setTopLeft(pt); + rectBB.setWidth(data.GetLabelWidth()); + rectBB.setHeight(data.GetLabelHeight()); + qreal dX; + qreal dY; + if (dataLabel->IsContained(rectBB, data.GetRotation(), dX, dY) == false) + { + pt.setX(pt.x() + dX); + pt.setY(pt.y() + dY); + } + + dataLabel->setPos(pt); + dataLabel->setRotation(data.GetRotation()); + dataLabel->Update(); + dataLabel->show(); + } + else + { + dataLabel->hide(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief UpdatePatternInfo updates the pattern info label + */ +void VToolDetail::UpdatePatternInfo() +{ + const VDetail detail = VAbstractTool::data.GetDetail(id); + const VPatternInfoGeometry& geom = detail.GetPatternInfo(); + + if (geom.IsVisible() == true) + { + QFont fnt = qApp->font(); + int iFS = geom.GetFontSize(); + if (iFS < MIN_FONT_SIZE) + { + iFS = MIN_FONT_SIZE; + } + fnt.setPixelSize(iFS); + patternInfo->SetFont(fnt); + patternInfo->SetSize(geom.GetLabelWidth(), geom.GetLabelHeight()); + patternInfo->UpdateData(doc); + + QPointF pt = geom.GetPos(); + QRectF rectBB; + rectBB.setTopLeft(pt); + rectBB.setWidth(geom.GetLabelWidth()); + rectBB.setHeight(geom.GetLabelHeight()); + qreal dX; + qreal dY; + if (patternInfo->IsContained(rectBB, geom.GetRotation(), dX, dY) == false) + { + pt.setX(pt.x() + dX); + pt.setY(pt.y() + dY); + } + + patternInfo->setPos(pt); + patternInfo->setRotation(geom.GetRotation()); + patternInfo->Update(); + if (patternInfo->GetTextLines() > 0) + { + patternInfo->show(); + } + else + { + patternInfo->hide(); + } + } + else + { + patternInfo->hide(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- + +/** + * @brief SaveMoveDetail saves the move detail operation to the undo stack + */ +void VToolDetail::SaveMoveDetail(const QPointF& ptPos) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + newDet.GetPatternPieceData().SetPos(ptPos); + newDet.GetPatternPieceData().SetLabelWidth(dataLabel->boundingRect().width()); + newDet.GetPatternPieceData().SetLabelHeight(dataLabel->boundingRect().height()); + newDet.GetPatternPieceData().SetFontSize(dataLabel->GetFontSize()); + newDet.GetPatternPieceData().SetRotation(dataLabel->rotation()); + + SaveDetailOptions* moveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + moveCommand->setText(tr("move pattern piece label")); + connect(moveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief SaveResizeDetail saves the resize detail label operation to the undo stack + */ +void VToolDetail::SaveResizeDetail(qreal dLabelW, int iFontSize) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + newDet.GetPatternPieceData().SetLabelWidth(dLabelW); + newDet.GetPatternPieceData().SetLabelHeight(dataLabel->boundingRect().height()); + newDet.GetPatternPieceData().SetFontSize(iFontSize); + newDet.GetPatternPieceData().SetRotation(dataLabel->rotation()); + SaveDetailOptions* resizeCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + resizeCommand->setText(tr("resize pattern piece label")); + connect(resizeCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(resizeCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief SaveRotationDetail saves the rotation detail label operation to the undo stack + */ +void VToolDetail::SaveRotationDetail(qreal dRot) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + newDet.GetPatternPieceData().SetPos(dataLabel->pos()); + newDet.GetPatternPieceData().SetLabelWidth(dataLabel->boundingRect().width()); + newDet.GetPatternPieceData().SetLabelHeight(dataLabel->boundingRect().height()); + newDet.GetPatternPieceData().SetFontSize(dataLabel->GetFontSize()); + newDet.GetPatternPieceData().SetRotation(dRot); + + SaveDetailOptions* rotateCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + rotateCommand->setText(tr("rotate pattern piece label")); + connect(rotateCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(rotateCommand); +} + + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief SaveMovePattern saves the pattern label position + */ +void VToolDetail::SaveMovePattern(const QPointF &ptPos) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + newDet.GetPatternInfo().SetPos(ptPos); + newDet.GetPatternInfo().SetLabelWidth(patternInfo->boundingRect().width()); + newDet.GetPatternInfo().SetLabelHeight(patternInfo->boundingRect().height()); + newDet.GetPatternInfo().SetFontSize(patternInfo->GetFontSize()); + newDet.GetPatternInfo().SetRotation(patternInfo->rotation()); + + SaveDetailOptions* moveCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + moveCommand->setText(tr("move pattern info label")); + connect(moveCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(moveCommand); + +} + +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief: SaveResizePattern saves the pattern label width and font size + */ +void VToolDetail::SaveResizePattern(qreal dLabelW, int iFontSize) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + newDet.GetPatternInfo().SetLabelWidth(dLabelW); + newDet.GetPatternInfo().SetLabelHeight(patternInfo->boundingRect().height()); + newDet.GetPatternInfo().SetFontSize(iFontSize); + newDet.GetPatternInfo().SetRotation(patternInfo->rotation()); + SaveDetailOptions* resizeCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + resizeCommand->setText(tr("resize pattern info label")); + connect(resizeCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(resizeCommand); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolDetail::SaveRotationPattern(qreal dRot) +{ + VDetail oldDet = VAbstractTool::data.GetDetail(id); + VDetail newDet = oldDet; + newDet.GetPatternInfo().SetPos(patternInfo->pos()); + newDet.GetPatternInfo().SetLabelWidth(patternInfo->boundingRect().width()); + newDet.GetPatternInfo().SetLabelHeight(patternInfo->boundingRect().height()); + newDet.GetPatternInfo().SetFontSize(patternInfo->GetFontSize()); + newDet.GetPatternInfo().SetRotation(dRot); + + SaveDetailOptions* rotateCommand = new SaveDetailOptions(oldDet, newDet, doc, id, this->scene()); + rotateCommand->setText(tr("rotate pattern info label")); + connect(rotateCommand, &SaveDetailOptions::NeedLiteParsing, doc, &VAbstractPattern::LiteParseTree); + qApp->getUndoStack()->push(rotateCommand); +} + + //--------------------------------------------------------------------------------------------------------------------- /** * @brief AddNode add node to the file. @@ -722,3 +1027,24 @@ void VToolDetail::AllowSelecting(bool enabled) { setFlag(QGraphicsItem::ItemIsSelectable, enabled); } + +//--------------------------------------------------------------------------------------------------------------------- +void VToolDetail::ResetChildren(QGraphicsItem *pItem) +{ + VTextGraphicsItem* pVGI = dynamic_cast(pItem); + if (pVGI != dataLabel) + { + dataLabel->Reset(); + } + if (pVGI != patternInfo) + { + patternInfo->Reset(); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void VToolDetail::UpdateAll() +{ + sceneDetails->update(); + update(); +} diff --git a/src/libs/vtools/tools/vtooldetail.h b/src/libs/vtools/tools/vtooldetail.h index 18dba00c2..a91526e05 100644 --- a/src/libs/vtools/tools/vtooldetail.h +++ b/src/libs/vtools/tools/vtooldetail.h @@ -31,6 +31,7 @@ #include "vabstracttool.h" #include "../vwidgets/vnobrushscalepathitem.h" +#include "vtextgraphicsitem.h" class VMainGraphicsScene; class DialogTool; @@ -68,8 +69,11 @@ public: static const QString AttrSupplement; static const QString AttrClosed; static const QString AttrWidth; + static const QString AttrHeight; static const QString AttrNodeType; static const QString AttrReverse; + static const QString AttrFont; + static const QString AttrRotation; static const QString NodeTypeContour; static const QString NodeTypeModeling; static const QString NodeArc; @@ -89,6 +93,8 @@ public slots: void EnableToolMove(bool move); virtual void AllowHover(bool enabled) Q_DECL_OVERRIDE; virtual void AllowSelecting(bool enabled) Q_DECL_OVERRIDE; + virtual void ResetChildren(QGraphicsItem* pItem); + virtual void UpdateAll(); protected: virtual void AddToFile () Q_DECL_OVERRIDE; virtual void RefreshDataInFile() Q_DECL_OVERRIDE; @@ -101,16 +107,29 @@ protected: virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ) Q_DECL_OVERRIDE; virtual void keyReleaseEvent(QKeyEvent * event) Q_DECL_OVERRIDE; virtual void SetVisualization() Q_DECL_OVERRIDE {} + +protected slots: + virtual void UpdateLabel(); + virtual void UpdatePatternInfo(); + virtual void SaveMoveDetail(const QPointF &ptPos); + virtual void SaveResizeDetail(qreal dLabelW, int iFontSize); + virtual void SaveRotationDetail(qreal dRot); + virtual void SaveMovePattern(const QPointF& ptPos); + virtual void SaveResizePattern(qreal dLabelW, int iFontSize); + virtual void SaveRotationPattern(qreal dRot); + private: Q_DISABLE_COPY(VToolDetail) /** @brief dialog dialog options. */ - DialogTool *dialog; + DialogTool *dialog; /** @brief sceneDetails pointer to the scene. */ - VMainGraphicsScene *sceneDetails; - QString drawName; + VMainGraphicsScene *sceneDetails; + QString drawName; - VNoBrushScalePathItem *seamAllowance; + VNoBrushScalePathItem *seamAllowance; + VTextGraphicsItem *dataLabel; + VTextGraphicsItem *patternInfo; VToolDetail(VAbstractPattern *doc, VContainer *data, const quint32 &id, const Source &typeCreation, VMainGraphicsScene *scene, const QString &drawName, QGraphicsItem * parent = nullptr); diff --git a/src/libs/vtools/undocommands/savedetailoptions.cpp b/src/libs/vtools/undocommands/savedetailoptions.cpp index 5563bf530..1aadf15f6 100644 --- a/src/libs/vtools/undocommands/savedetailoptions.cpp +++ b/src/libs/vtools/undocommands/savedetailoptions.cpp @@ -29,6 +29,9 @@ #include "savedetailoptions.h" #include "../tools/nodeDetails/vabstractnode.h" #include "../../vwidgets/vmaingraphicsview.h" +#include "../ifc/xml/vabstractpattern.h" +#include "../vpatterndb/vpatternpiecedata.h" +#include "../vpatterndb/vpatterninfogeometry.h" #include @@ -55,6 +58,8 @@ void SaveDetailOptions::undo() { SaveDet(domElement, oldDet); doc->RemoveAllChildren(domElement); + SavePatternPieceData(domElement, oldDet); + SavePatternInfo(domElement, oldDet); for (int i = 0; i < oldDet.CountNode(); ++i) { VToolDetail::AddNode(doc, domElement, oldDet.at(i)); @@ -79,6 +84,9 @@ void SaveDetailOptions::redo() { SaveDet(domElement, newDet); doc->RemoveAllChildren(domElement); + SavePatternPieceData(domElement, newDet); + SavePatternInfo(domElement, newDet); + for (int i = 0; i < newDet.CountNode(); ++i) { VToolDetail::AddNode(doc, domElement, newDet.at(i)); @@ -101,7 +109,7 @@ bool SaveDetailOptions::mergeWith(const QUndoCommand *command) SCASSERT(saveCommand != nullptr); const quint32 id = saveCommand->getDetId(); - if (id != nodeId) + if (id != nodeId || text() != command->text()) { return false; } @@ -124,3 +132,46 @@ void SaveDetailOptions::SaveDet(QDomElement &domElement, const VDetail &det) doc->SetAttribute(domElement, VToolDetail::AttrClosed, QString().setNum(det.getClosed())); doc->SetAttribute(domElement, VToolDetail::AttrWidth, QString().setNum(det.getWidth())); } + +//--------------------------------------------------------------------------------------------------------------------- +void SaveDetailOptions::SavePatternPieceData(QDomElement &domElement, const VDetail &det) +{ + QDomElement domData = doc->createElement(VAbstractPattern::TagData); + const VPatternPieceData& data = det.GetPatternPieceData(); + doc->SetAttribute(domData, VAbstractPattern::AttrLetter, data.GetLetter()); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, data.GetPos().x()); + doc->SetAttribute(domData, AttrMy, data.GetPos().y()); + doc->SetAttribute(domData, VToolDetail::AttrWidth, data.GetLabelWidth()); + doc->SetAttribute(domData, VToolDetail::AttrHeight, data.GetLabelHeight()); + doc->SetAttribute(domData, VToolDetail::AttrFont, data.GetFontSize()); + doc->SetAttribute(domData, VToolDetail::AttrRotation, data.GetRotation()); + + for (int i = 0; i < data.GetMCPCount(); ++i) + { + MaterialCutPlacement mcp = data.GetMCP(i); + QDomElement domMCP = doc->createElement(VAbstractPattern::TagMCP); + doc->SetAttribute(domMCP, VAbstractPattern::AttrMaterial, int(mcp.m_eMaterial)); + doc->SetAttribute(domMCP, VAbstractPattern::AttrUserDefined, mcp.m_qsMaterialUserDef); + doc->SetAttribute(domMCP, VAbstractPattern::AttrCutNumber, mcp.m_iCutNumber); + doc->SetAttribute(domMCP, VAbstractPattern::AttrPlacement, int(mcp.m_ePlacement)); + domData.appendChild(domMCP); + } + domElement.appendChild(domData); +} + +//--------------------------------------------------------------------------------------------------------------------- +void SaveDetailOptions::SavePatternInfo(QDomElement &domElement, const VDetail &det) +{ + QDomElement domData = doc->createElement(VAbstractPattern::TagPatternInfo); + const VPatternInfoGeometry& data = det.GetPatternInfo(); + doc->SetAttribute(domData, VAbstractPattern::AttrVisible, data.IsVisible() == true? trueStr : falseStr); + doc->SetAttribute(domData, AttrMx, data.GetPos().x()); + doc->SetAttribute(domData, AttrMy, data.GetPos().y()); + doc->SetAttribute(domData, VToolDetail::AttrWidth, data.GetLabelWidth()); + doc->SetAttribute(domData, VToolDetail::AttrHeight, data.GetLabelHeight()); + doc->SetAttribute(domData, VToolDetail::AttrFont, data.GetFontSize()); + doc->SetAttribute(domData, VToolDetail::AttrRotation, data.GetRotation()); + + domElement.appendChild(domData); +} diff --git a/src/libs/vtools/undocommands/savedetailoptions.h b/src/libs/vtools/undocommands/savedetailoptions.h index 922a7a976..58e1ba789 100644 --- a/src/libs/vtools/undocommands/savedetailoptions.h +++ b/src/libs/vtools/undocommands/savedetailoptions.h @@ -53,6 +53,8 @@ private: VDetail newDet; QGraphicsScene *scene; void SaveDet(QDomElement &domElement, const VDetail &det); + void SavePatternPieceData(QDomElement &domElement, const VDetail &det); + void SavePatternInfo(QDomElement &domElement, const VDetail &det); }; //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vwidgets/vmaingraphicsscene.cpp b/src/libs/vwidgets/vmaingraphicsscene.cpp index 35fe577c8..791903482 100644 --- a/src/libs/vwidgets/vmaingraphicsscene.cpp +++ b/src/libs/vwidgets/vmaingraphicsscene.cpp @@ -80,6 +80,10 @@ void VMainGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) } QGraphicsScene::mousePressEvent(event); + + QTransform t; + QGraphicsItem* pItem = itemAt(event->scenePos(), t); + emit ItemClicked(pItem); } //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/libs/vwidgets/vmaingraphicsscene.h b/src/libs/vwidgets/vmaingraphicsscene.h index e65896965..6f86c46a3 100644 --- a/src/libs/vwidgets/vmaingraphicsscene.h +++ b/src/libs/vwidgets/vmaingraphicsscene.h @@ -93,6 +93,7 @@ signals: void MouseLeftPressed(); void MouseLeftReleased(); + void ItemClicked(QGraphicsItem* pItem); /** * @brief ChoosedObject send option choosed object.