2016-08-12 12:11:12 +02:00
|
|
|
/************************************************************************
|
|
|
|
**
|
|
|
|
** @file vpatternpiecedata.cpp
|
|
|
|
** @author Bojan Kverh
|
|
|
|
** @date July 19, 2016
|
|
|
|
**
|
|
|
|
** @brief
|
|
|
|
** @copyright
|
2017-10-05 11:20:01 +02:00
|
|
|
** This source code is part of the Valentina project, a pattern making
|
2016-08-12 12:11:12 +02:00
|
|
|
** program, whose allow create and modeling patterns of clothing.
|
|
|
|
** Copyright (C) 2013-2015 Valentina project
|
2020-01-31 07:00:05 +01:00
|
|
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
2016-08-12 12:11:12 +02:00
|
|
|
**
|
|
|
|
** Valentina is free software: you can redistribute it and/or modify
|
|
|
|
** it under the terms of the GNU General Public License as published by
|
|
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** Valentina is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
**
|
|
|
|
*************************************************************************/
|
|
|
|
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QDate>
|
|
|
|
#include <QFileInfo>
|
2016-07-18 22:30:14 +02:00
|
|
|
#include <QFontMetrics>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QLatin1String>
|
|
|
|
#include <QRegularExpression>
|
2016-08-11 22:44:53 +02:00
|
|
|
#include <QApplication>
|
2017-01-25 17:07:18 +01:00
|
|
|
#include <QDebug>
|
2019-07-01 13:02:52 +02:00
|
|
|
#include <QFlags> // QFlags<Qt::Alignment>
|
2016-07-18 22:30:14 +02:00
|
|
|
|
2016-08-08 13:44:49 +02:00
|
|
|
#include "../ifc/xml/vabstractpattern.h"
|
2017-02-23 10:37:19 +01:00
|
|
|
#include "../vpatterndb/floatItemData/vpiecelabeldata.h"
|
2020-10-15 17:05:21 +02:00
|
|
|
#include "../vmisc/vabstractvalapplication.h"
|
2016-12-14 10:59:21 +01:00
|
|
|
#include "../vmisc/vmath.h"
|
2020-01-07 13:21:47 +01:00
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
2020-01-07 08:45:26 +01:00
|
|
|
# include "../vmisc/vdatastreamenum.h"
|
|
|
|
#endif
|
2017-08-15 14:22:33 +02:00
|
|
|
#include "../vpatterndb/vcontainer.h"
|
2021-01-23 20:37:36 +01:00
|
|
|
#include "../vpatterndb/calculator.h"
|
2016-07-18 22:30:14 +02:00
|
|
|
#include "vtextmanager.h"
|
|
|
|
|
2019-07-01 10:02:09 +02:00
|
|
|
const quint32 TextLine::streamHeader = 0xA3881E49; // CRC-32Q string "TextLine"
|
|
|
|
const quint16 TextLine::classVersion = 1;
|
|
|
|
|
|
|
|
// Friend functions
|
2016-07-18 22:30:14 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto operator<<(QDataStream &dataStream, const TextLine &data) -> QDataStream&
|
2019-07-01 10:02:09 +02:00
|
|
|
{
|
|
|
|
dataStream << TextLine::streamHeader << TextLine::classVersion;
|
|
|
|
|
|
|
|
// Added in classVersion = 1
|
|
|
|
dataStream << data.m_qsText;
|
|
|
|
dataStream << data.m_iFontSize;
|
|
|
|
dataStream << data.m_bold;
|
|
|
|
dataStream << data.m_italic;
|
|
|
|
dataStream << data.m_eAlign;
|
|
|
|
|
|
|
|
// Added in classVersion = 2
|
|
|
|
|
|
|
|
return dataStream;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto operator>>(QDataStream &dataStream, TextLine &data) -> QDataStream&
|
2019-07-01 10:02:09 +02:00
|
|
|
{
|
|
|
|
quint32 actualStreamHeader = 0;
|
|
|
|
dataStream >> actualStreamHeader;
|
|
|
|
|
|
|
|
if (actualStreamHeader != TextLine::streamHeader)
|
|
|
|
{
|
|
|
|
QString message = QCoreApplication::tr("TextLine prefix mismatch error: actualStreamHeader = 0x%1 and "
|
|
|
|
"streamHeader = 0x%2")
|
|
|
|
.arg(actualStreamHeader, 8, 0x10, QChar('0'))
|
|
|
|
.arg(TextLine::streamHeader, 8, 0x10, QChar('0'));
|
|
|
|
throw VException(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
quint16 actualClassVersion = 0;
|
|
|
|
dataStream >> actualClassVersion;
|
|
|
|
|
|
|
|
if (actualClassVersion > TextLine::classVersion)
|
|
|
|
{
|
|
|
|
QString message = QCoreApplication::tr("TextLine compatibility error: actualClassVersion = %1 and "
|
|
|
|
"classVersion = %2")
|
|
|
|
.arg(actualClassVersion).arg(TextLine::classVersion);
|
|
|
|
throw VException(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
dataStream >> data.m_qsText;
|
|
|
|
dataStream >> data.m_iFontSize;
|
|
|
|
dataStream >> data.m_bold;
|
|
|
|
dataStream >> data.m_italic;
|
|
|
|
dataStream >> data.m_eAlign;
|
|
|
|
|
|
|
|
// if (actualClassVersion >= 2)
|
|
|
|
// {
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
return dataStream;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVector<TextLine> VTextManager::m_patternLabelLines = QVector<TextLine>();
|
|
|
|
const quint32 VTextManager::streamHeader = 0x47E6A9EE; // CRC-32Q string "VTextManager"
|
|
|
|
const quint16 VTextManager::classVersion = 1;
|
|
|
|
|
|
|
|
// Friend functions
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto operator<<(QDataStream &dataStream, const VTextManager &data) -> QDataStream&
|
2019-07-01 10:02:09 +02:00
|
|
|
{
|
|
|
|
dataStream << VTextManager::streamHeader << VTextManager::classVersion;
|
|
|
|
|
|
|
|
// Added in classVersion = 1
|
|
|
|
dataStream << data.m_font;
|
|
|
|
dataStream << data.m_liLines;
|
|
|
|
|
|
|
|
// Added in classVersion = 2
|
|
|
|
|
|
|
|
return dataStream;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto operator>>(QDataStream &dataStream, VTextManager &data) -> QDataStream&
|
2019-07-01 10:02:09 +02:00
|
|
|
{
|
|
|
|
quint32 actualStreamHeader = 0;
|
|
|
|
dataStream >> actualStreamHeader;
|
2016-07-18 22:30:14 +02:00
|
|
|
|
2019-07-01 10:02:09 +02:00
|
|
|
if (actualStreamHeader != VTextManager::streamHeader)
|
|
|
|
{
|
|
|
|
QString message = QCoreApplication::tr("VTextManager prefix mismatch error: actualStreamHeader = 0x%1 and "
|
|
|
|
"streamHeader = 0x%2")
|
|
|
|
.arg(actualStreamHeader, 8, 0x10, QChar('0'))
|
|
|
|
.arg(VTextManager::streamHeader, 8, 0x10, QChar('0'));
|
|
|
|
throw VException(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
quint16 actualClassVersion = 0;
|
|
|
|
dataStream >> actualClassVersion;
|
|
|
|
|
|
|
|
if (actualClassVersion > VTextManager::classVersion)
|
|
|
|
{
|
|
|
|
QString message = QCoreApplication::tr("VTextManager compatibility error: actualClassVersion = %1 and "
|
|
|
|
"classVersion = %2")
|
|
|
|
.arg(actualClassVersion).arg(VTextManager::classVersion);
|
|
|
|
throw VException(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
dataStream >> data.m_font;
|
|
|
|
dataStream >> data.m_liLines;
|
|
|
|
|
|
|
|
// if (actualClassVersion >= 2)
|
|
|
|
// {
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
return dataStream;
|
|
|
|
}
|
2017-08-15 14:22:33 +02:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto PreparePlaceholders(const VAbstractPattern *doc, const VContainer *data) -> QMap<QString, QString>
|
2017-08-15 14:22:33 +02:00
|
|
|
{
|
|
|
|
SCASSERT(doc != nullptr)
|
2020-10-16 12:43:54 +02:00
|
|
|
SCASSERT(data != nullptr)
|
2017-08-15 14:22:33 +02:00
|
|
|
|
|
|
|
QMap<QString, QString> placeholders;
|
|
|
|
|
2017-08-18 13:22:31 +02:00
|
|
|
// Pattern tags
|
2021-02-06 14:52:21 +01:00
|
|
|
QLocale locale(VAbstractApplication::VApp()->Settings()->GetLocale());
|
2017-08-19 18:37:14 +02:00
|
|
|
|
|
|
|
const QString date = locale.toString(QDate::currentDate(), doc->GetLabelDateFormat());
|
|
|
|
placeholders.insert(pl_date, date);
|
|
|
|
|
|
|
|
const QString time = locale.toString(QTime::currentTime(), doc->GetLabelTimeFormat());
|
|
|
|
placeholders.insert(pl_time, time);
|
|
|
|
|
2017-08-15 14:22:33 +02:00
|
|
|
placeholders.insert(pl_patternName, doc->GetPatternName());
|
|
|
|
placeholders.insert(pl_patternNumber, doc->GetPatternNumber());
|
|
|
|
placeholders.insert(pl_author, doc->GetCompanyName());
|
2017-09-19 15:07:48 +02:00
|
|
|
|
2021-02-06 14:52:21 +01:00
|
|
|
placeholders.insert(pl_mUnits, UnitsToStr(VAbstractValApplication::VApp()->MeasurementsUnits(), true));
|
|
|
|
placeholders.insert(pl_pUnits, UnitsToStr(VAbstractValApplication::VApp()->patternUnits(), true));
|
|
|
|
placeholders.insert(pl_mSizeUnits, UnitsToStr(VAbstractValApplication::VApp()->DimensionSizeUnits(), true));
|
2020-10-16 10:37:49 +02:00
|
|
|
|
2021-02-06 14:52:21 +01:00
|
|
|
if (VAbstractValApplication::VApp()->GetMeasurementsType() == MeasurementsType::Individual)
|
2017-09-19 15:07:48 +02:00
|
|
|
{
|
2021-02-06 14:52:21 +01:00
|
|
|
placeholders.insert(pl_customer, VAbstractValApplication::VApp()->GetCustomerName());
|
2020-10-16 10:37:49 +02:00
|
|
|
|
2021-02-06 14:52:21 +01:00
|
|
|
const QString birthDate = locale.toString(VAbstractValApplication::VApp()->GetCustomerBirthDate(),
|
|
|
|
doc->GetLabelDateFormat());
|
2020-10-16 10:37:49 +02:00
|
|
|
placeholders.insert(pl_birthDate, birthDate);
|
|
|
|
|
2021-02-06 14:52:21 +01:00
|
|
|
placeholders.insert(pl_email, VAbstractValApplication::VApp()->CustomerEmail());
|
2017-09-19 15:07:48 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
placeholders.insert(pl_customer, doc->GetCustomerName());
|
2020-10-16 10:37:49 +02:00
|
|
|
|
|
|
|
const QString birthDate = locale.toString(doc->GetCustomerBirthDate(), doc->GetLabelDateFormat());
|
|
|
|
placeholders.insert(pl_birthDate, birthDate);
|
|
|
|
|
|
|
|
placeholders.insert(pl_email, doc->GetCustomerEmail());
|
2017-09-19 15:07:48 +02:00
|
|
|
}
|
|
|
|
|
2019-07-01 10:02:09 +02:00
|
|
|
placeholders.insert(pl_pExt, QStringLiteral("val"));
|
2021-02-06 14:52:21 +01:00
|
|
|
placeholders.insert(pl_pFileName, QFileInfo(VAbstractValApplication::VApp()->GetPatternPath()).baseName());
|
2017-08-17 15:04:52 +02:00
|
|
|
placeholders.insert(pl_mFileName, QFileInfo(doc->MPath()).baseName());
|
2017-08-15 14:22:33 +02:00
|
|
|
|
2021-03-29 14:06:32 +02:00
|
|
|
QString heightValue = QString::number(VAbstractValApplication::VApp()->GetDimensionHeight());
|
|
|
|
placeholders.insert(pl_height, heightValue);
|
2022-02-14 13:11:27 +01:00
|
|
|
placeholders.insert(pl_dimensionX, heightValue);
|
2021-03-29 14:06:32 +02:00
|
|
|
|
|
|
|
QString sizeValue = QString::number(VAbstractValApplication::VApp()->GetDimensionSize());
|
|
|
|
placeholders.insert(pl_size, sizeValue);
|
2022-02-14 13:11:27 +01:00
|
|
|
placeholders.insert(pl_dimensionY, sizeValue);
|
2021-03-29 14:06:32 +02:00
|
|
|
|
|
|
|
QString hipValue = QString::number(VAbstractValApplication::VApp()->GetDimensionHip());
|
|
|
|
placeholders.insert(pl_hip, hipValue);
|
2022-02-14 13:11:27 +01:00
|
|
|
placeholders.insert(pl_dimensionZ, hipValue);
|
2021-03-29 14:06:32 +02:00
|
|
|
|
|
|
|
QString waistValue = QString::number(VAbstractValApplication::VApp()->GetDimensionWaist());
|
|
|
|
placeholders.insert(pl_waist, waistValue);
|
2022-02-14 13:11:27 +01:00
|
|
|
placeholders.insert(pl_dimensionW, waistValue);
|
2021-03-29 14:06:32 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
QString label = VAbstractValApplication::VApp()->GetDimensionHeightLabel();
|
|
|
|
placeholders.insert(pl_heightLabel, not label.isEmpty() ? label : heightValue);
|
|
|
|
|
|
|
|
label = VAbstractValApplication::VApp()->GetDimensionSizeLabel();
|
|
|
|
placeholders.insert(pl_sizeLabel, not label.isEmpty() ? label : sizeValue);
|
|
|
|
|
|
|
|
label = VAbstractValApplication::VApp()->GetDimensionHipLabel();
|
|
|
|
placeholders.insert(pl_hipLabel, not label.isEmpty() ? label : hipValue);
|
|
|
|
|
|
|
|
label = VAbstractValApplication::VApp()->GetDimensionWaistLabel();
|
|
|
|
placeholders.insert(pl_waistLabel, not label.isEmpty() ? label : waistValue);
|
|
|
|
}
|
|
|
|
|
2021-02-06 14:52:21 +01:00
|
|
|
placeholders.insert(pl_mExt, VAbstractValApplication::VApp()->GetMeasurementsType() == MeasurementsType::Multisize
|
2021-03-29 14:06:32 +02:00
|
|
|
? QStringLiteral("vst") : QStringLiteral("vit"));
|
2017-08-15 14:22:33 +02:00
|
|
|
|
2017-08-30 08:32:39 +02:00
|
|
|
const QMap<int, QString> materials = doc->GetPatternMaterials();
|
|
|
|
for (int i = 0; i < userMaterialPlaceholdersQuantity; ++i)
|
|
|
|
{
|
|
|
|
const QString number = QString::number(i + 1);
|
|
|
|
|
|
|
|
QString value;
|
|
|
|
if (materials.contains(i + 1))
|
|
|
|
{
|
|
|
|
value = materials.value(i + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
placeholders.insert(pl_userMaterial + number, value);
|
|
|
|
}
|
|
|
|
|
2020-10-16 12:43:54 +02:00
|
|
|
{
|
2021-01-23 20:37:36 +01:00
|
|
|
const QMap<QString, QSharedPointer<VMeasurement> > measurements = data->DataMeasurements();
|
|
|
|
auto i = measurements.constBegin();
|
|
|
|
while (i != measurements.constEnd())
|
|
|
|
{
|
|
|
|
placeholders.insert(pl_measurement + i.key(), QString::number(*i.value()->GetValue()));
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
const QVector<VFinalMeasurement> measurements = doc->GetFinalMeasurements();
|
|
|
|
const VContainer completeData = doc->GetCompleteData();
|
|
|
|
|
|
|
|
for (int i=0; i < measurements.size(); ++i)
|
|
|
|
{
|
|
|
|
const VFinalMeasurement &m = measurements.at(i);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
QScopedPointer<Calculator> cal(new Calculator());
|
|
|
|
const qreal result = cal->EvalFormula(completeData.DataVariables(), m.formula);
|
|
|
|
|
|
|
|
placeholders.insert(pl_finalMeasurement + m.name, QString::number(result));
|
|
|
|
}
|
|
|
|
catch (qmu::QmuParserError &e)
|
|
|
|
{
|
2021-01-30 20:15:49 +01:00
|
|
|
const QString errorMsg = QObject::tr("Failed to prepare final measurement placeholder. Parser error at "
|
|
|
|
"line %1: %2.").arg(i+1).arg(e.GetMsg());
|
2021-02-06 14:52:21 +01:00
|
|
|
VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
|
|
|
|
qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
|
2021-01-23 20:37:36 +01:00
|
|
|
}
|
|
|
|
}
|
2020-10-16 12:43:54 +02:00
|
|
|
}
|
|
|
|
|
2017-08-18 13:22:31 +02:00
|
|
|
// Piece tags
|
2018-03-14 15:01:24 +01:00
|
|
|
placeholders.insert(pl_pLetter, QString());
|
|
|
|
placeholders.insert(pl_pAnnotation, QString());
|
|
|
|
placeholders.insert(pl_pOrientation, QString());
|
|
|
|
placeholders.insert(pl_pRotation, QString());
|
|
|
|
placeholders.insert(pl_pTilt, QString());
|
|
|
|
placeholders.insert(pl_pFoldPosition, QString());
|
|
|
|
placeholders.insert(pl_pName, QString());
|
|
|
|
placeholders.insert(pl_pQuantity, QString());
|
|
|
|
placeholders.insert(pl_wOnFold, QString());
|
2017-08-18 13:22:31 +02:00
|
|
|
placeholders.insert(pl_mFabric, QObject::tr("Fabric"));
|
|
|
|
placeholders.insert(pl_mLining, QObject::tr("Lining"));
|
|
|
|
placeholders.insert(pl_mInterfacing, QObject::tr("Interfacing"));
|
|
|
|
placeholders.insert(pl_mInterlining, QObject::tr("Interlining"));
|
|
|
|
placeholders.insert(pl_wCut, QObject::tr("Cut"));
|
|
|
|
|
2017-08-15 14:22:33 +02:00
|
|
|
return placeholders;
|
|
|
|
}
|
|
|
|
|
2017-08-18 13:22:31 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void InitPiecePlaceholders(QMap<QString, QString> &placeholders, const QString &name, const VPieceLabelData& data)
|
|
|
|
{
|
|
|
|
placeholders[pl_pLetter] = data.GetLetter();
|
2017-08-21 12:16:43 +02:00
|
|
|
placeholders[pl_pAnnotation] = data.GetAnnotation();
|
|
|
|
placeholders[pl_pOrientation] = data.GetOrientation();
|
2017-08-21 16:10:55 +02:00
|
|
|
placeholders[pl_pRotation] = data.GetRotationWay();
|
2017-08-21 12:16:43 +02:00
|
|
|
placeholders[pl_pTilt] = data.GetTilt();
|
|
|
|
placeholders[pl_pFoldPosition] = data.GetFoldPosition();
|
2017-08-18 13:22:31 +02:00
|
|
|
placeholders[pl_pName] = name;
|
|
|
|
placeholders[pl_pQuantity] = QString::number(data.GetQuantity());
|
|
|
|
|
|
|
|
if (data.IsOnFold())
|
|
|
|
{
|
|
|
|
placeholders[pl_wOnFold] = QObject::tr("on fold");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-15 14:22:33 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto ReplacePlaceholders(const QMap<QString, QString> &placeholders, QString line) -> QString
|
2017-08-15 14:22:33 +02:00
|
|
|
{
|
|
|
|
QChar per('%');
|
2020-12-17 16:42:37 +01:00
|
|
|
|
|
|
|
auto TestDimension = [per, placeholders, line](const QString &placeholder, const QString &errorMsg)
|
|
|
|
{
|
|
|
|
if (line.contains(per+placeholder+per) && placeholders.value(placeholder) == QChar('0'))
|
|
|
|
{
|
2021-02-06 14:52:21 +01:00
|
|
|
VAbstractApplication::VApp()->IsPedantic() ? throw VException(errorMsg) :
|
|
|
|
qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
|
2020-12-17 16:42:37 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TestDimension(pl_height, QObject::tr("No data for the height dimension."));
|
|
|
|
TestDimension(pl_size, QObject::tr("No data for the size dimension."));
|
|
|
|
TestDimension(pl_hip, QObject::tr("No data for the hip dimension."));
|
|
|
|
TestDimension(pl_waist, QObject::tr("No data for the waist dimension."));
|
|
|
|
|
2022-02-14 13:11:27 +01:00
|
|
|
TestDimension(pl_dimensionX, QObject::tr("No data for the X dimension."));
|
|
|
|
TestDimension(pl_dimensionY, QObject::tr("No data for the Y dimension."));
|
|
|
|
TestDimension(pl_dimensionZ, QObject::tr("No data for the Z dimension."));
|
|
|
|
TestDimension(pl_dimensionW, QObject::tr("No data for the W dimension."));
|
|
|
|
|
2017-08-15 14:22:33 +02:00
|
|
|
auto i = placeholders.constBegin();
|
|
|
|
while (i != placeholders.constEnd())
|
|
|
|
{
|
|
|
|
line.replace(per+i.key()+per, i.value());
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto PrepareLines(const QVector<VLabelTemplateLine> &lines) -> QVector<TextLine>
|
2017-08-15 14:22:33 +02:00
|
|
|
{
|
2019-07-01 10:02:09 +02:00
|
|
|
QVector<TextLine> textLines;
|
2017-08-15 14:22:33 +02:00
|
|
|
|
2018-04-03 13:36:38 +02:00
|
|
|
for (auto &line : lines)
|
2017-08-15 14:22:33 +02:00
|
|
|
{
|
2018-04-03 13:36:38 +02:00
|
|
|
if (not line.line.isEmpty())
|
2017-08-15 14:22:33 +02:00
|
|
|
{
|
|
|
|
TextLine tl;
|
2018-04-03 13:36:38 +02:00
|
|
|
tl.m_qsText = line.line;
|
|
|
|
tl.m_eAlign = static_cast<Qt::Alignment>(line.alignment);
|
|
|
|
tl.m_iFontSize = line.fontSizeIncrement;
|
2019-07-01 10:02:09 +02:00
|
|
|
tl.m_bold = line.bold;
|
|
|
|
tl.m_italic = line.italic;
|
2017-08-15 14:22:33 +02:00
|
|
|
|
|
|
|
textLines << tl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return textLines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-18 22:30:14 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
|
|
|
* @brief VTextManager::VTextManager constructor
|
|
|
|
*/
|
2016-07-18 22:30:14 +02:00
|
|
|
VTextManager::VTextManager()
|
2016-12-15 07:46:45 +01:00
|
|
|
: m_font(), m_liLines()
|
2016-07-18 22:30:14 +02:00
|
|
|
{}
|
|
|
|
|
2016-11-01 09:42:32 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VTextManager::VTextManager(const VTextManager &text)
|
2016-12-14 00:56:30 +01:00
|
|
|
: m_font(text.GetFont()), m_liLines(text.GetAllSourceLines())
|
2016-11-01 09:42:32 +01:00
|
|
|
{}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VTextManager &VTextManager::operator=(const VTextManager &text)
|
|
|
|
{
|
|
|
|
if ( &text == this )
|
|
|
|
{
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
m_font = text.GetFont();
|
|
|
|
m_liLines = text.GetAllSourceLines();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-07-18 22:30:14 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
2016-11-01 09:42:32 +01:00
|
|
|
* @brief GetSpacing returns the vertical spacing between the lines
|
2016-11-01 10:46:51 +01:00
|
|
|
* @return spacing
|
2016-07-23 15:26:15 +02:00
|
|
|
*/
|
2021-08-14 14:19:28 +02:00
|
|
|
auto VTextManager::GetSpacing() const -> int
|
2016-07-19 02:26:50 +02:00
|
|
|
{
|
2016-12-14 00:56:30 +01:00
|
|
|
return 0;
|
2016-07-19 02:26:50 +02:00
|
|
|
}
|
2016-07-18 22:30:14 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
2016-11-01 09:42:32 +01:00
|
|
|
* @brief SetFont set the text base font
|
2016-07-23 15:26:15 +02:00
|
|
|
* @param font text base font
|
|
|
|
*/
|
2016-07-18 22:30:14 +02:00
|
|
|
void VTextManager::SetFont(const QFont& font)
|
2016-07-19 02:26:50 +02:00
|
|
|
{
|
|
|
|
m_font = font;
|
|
|
|
}
|
2016-07-18 22:30:14 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
2016-11-01 09:42:32 +01:00
|
|
|
* @brief GetFont returns the text base font
|
2016-07-23 15:26:15 +02:00
|
|
|
* @return text base font
|
|
|
|
*/
|
2021-08-14 14:19:28 +02:00
|
|
|
auto VTextManager::GetFont() const -> const QFont&
|
2016-07-19 02:26:50 +02:00
|
|
|
{
|
|
|
|
return m_font;
|
|
|
|
}
|
2016-07-18 22:30:14 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
2016-11-01 09:42:32 +01:00
|
|
|
* @brief SetFontSize sets the font size
|
2016-07-23 15:26:15 +02:00
|
|
|
* @param iFS font size in pixels
|
|
|
|
*/
|
2016-07-18 22:30:14 +02:00
|
|
|
void VTextManager::SetFontSize(int iFS)
|
2016-07-19 02:26:50 +02:00
|
|
|
{
|
2016-12-14 10:59:21 +01:00
|
|
|
iFS < MIN_FONT_SIZE ? m_font.setPixelSize(MIN_FONT_SIZE) : m_font.setPixelSize(iFS);
|
2016-07-19 02:26:50 +02:00
|
|
|
}
|
2016-07-18 22:30:14 +02:00
|
|
|
|
2016-11-01 09:42:32 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2021-08-14 14:19:28 +02:00
|
|
|
auto VTextManager::GetAllSourceLines() const -> QVector<TextLine>
|
2016-11-01 09:42:32 +01:00
|
|
|
{
|
|
|
|
return m_liLines;
|
|
|
|
}
|
|
|
|
|
2021-08-14 14:19:28 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VTextManager::SetAllSourceLines(const QVector<TextLine> &lines)
|
|
|
|
{
|
|
|
|
m_liLines = lines;
|
|
|
|
}
|
|
|
|
|
2016-07-19 02:26:50 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
2016-11-01 09:42:32 +01:00
|
|
|
* @brief VTextManager::GetSourceLinesCount returns the number of input text lines
|
2016-07-23 15:26:15 +02:00
|
|
|
* @return number of text lines that were added to the list by calling AddLine
|
|
|
|
*/
|
2021-08-14 14:19:28 +02:00
|
|
|
auto VTextManager::GetSourceLinesCount() const -> int
|
2016-07-19 02:26:50 +02:00
|
|
|
{
|
|
|
|
return m_liLines.count();
|
|
|
|
}
|
2016-07-18 22:30:14 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
2016-12-14 00:56:30 +01:00
|
|
|
* @brief VTextManager::GetSourceLine returns the reference to i-th text line
|
|
|
|
* @param i index of the requested line
|
|
|
|
* @return reference to the requested TextLine object
|
2016-07-23 15:26:15 +02:00
|
|
|
*/
|
2021-08-14 14:19:28 +02:00
|
|
|
auto VTextManager::GetSourceLine(int i) const -> const TextLine&
|
2016-07-19 02:26:50 +02:00
|
|
|
{
|
2016-12-14 00:56:30 +01:00
|
|
|
Q_ASSERT(i >= 0);
|
|
|
|
Q_ASSERT(i < m_liLines.count());
|
2016-12-14 10:59:21 +01:00
|
|
|
return m_liLines.at(i);
|
2016-07-19 02:26:50 +02:00
|
|
|
}
|
2016-07-18 22:30:14 +02:00
|
|
|
|
2022-02-19 20:17:51 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
auto VTextManager::MaxLineWidth(int width) const -> int
|
|
|
|
{
|
|
|
|
int maxWidth = 0;
|
|
|
|
for (int i = 0; i < m_liLines.count(); ++i)
|
|
|
|
{
|
|
|
|
const TextLine& tl = m_liLines.at(i);
|
|
|
|
|
|
|
|
QFont fnt = m_font;
|
|
|
|
fnt.setPixelSize(fnt.pixelSize() + tl.m_iFontSize);
|
|
|
|
fnt.setBold(tl.m_bold);
|
|
|
|
fnt.setItalic(tl.m_italic);
|
|
|
|
|
|
|
|
QFontMetrics fm(fnt);
|
|
|
|
|
|
|
|
QString qsText = tl.m_qsText;
|
|
|
|
|
|
|
|
if (TextWidth(fm, qsText) > width)
|
|
|
|
{
|
|
|
|
qsText = fm.elidedText(qsText, Qt::ElideMiddle, width);
|
|
|
|
}
|
|
|
|
|
|
|
|
maxWidth = qMax(TextWidth(fm, qsText), maxWidth);
|
|
|
|
}
|
|
|
|
|
|
|
|
return maxWidth;
|
|
|
|
}
|
|
|
|
|
2016-07-18 22:30:14 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
2016-12-14 00:56:30 +01:00
|
|
|
* @brief VTextManager::FitFontSize sets the font size just big enough, so that the text fits into rectangle of
|
|
|
|
* size (fW, fH)
|
2016-07-23 15:26:15 +02:00
|
|
|
* @param fW rectangle width
|
|
|
|
* @param fH rectangle height
|
|
|
|
*/
|
2016-12-14 00:56:30 +01:00
|
|
|
void VTextManager::FitFontSize(qreal fW, qreal fH)
|
2016-07-18 22:30:14 +02:00
|
|
|
{
|
2017-01-05 12:11:18 +01:00
|
|
|
int iFS = 0;
|
|
|
|
if (GetSourceLinesCount() > 0)
|
|
|
|
{//division by zero
|
|
|
|
iFS = 3*qFloor(fH/GetSourceLinesCount())/4;
|
|
|
|
}
|
|
|
|
|
2016-12-14 00:56:30 +01:00
|
|
|
if (iFS < MIN_FONT_SIZE)
|
|
|
|
{
|
|
|
|
iFS = MIN_FONT_SIZE;
|
|
|
|
}
|
2016-09-29 01:39:50 +02:00
|
|
|
|
2016-12-14 00:56:30 +01:00
|
|
|
// get ratio between char width and height
|
|
|
|
|
|
|
|
int iMaxLen = 0;
|
2016-12-15 07:50:25 +01:00
|
|
|
TextLine maxLine;
|
2016-12-14 00:56:30 +01:00
|
|
|
QFont fnt;
|
|
|
|
for (int i = 0; i < GetSourceLinesCount(); ++i)
|
2016-07-18 22:30:14 +02:00
|
|
|
{
|
2016-12-14 00:56:30 +01:00
|
|
|
const TextLine& tl = GetSourceLine(i);
|
|
|
|
fnt = m_font;
|
|
|
|
fnt.setPixelSize(iFS + tl.m_iFontSize);
|
2019-07-01 10:02:09 +02:00
|
|
|
fnt.setBold(tl.m_bold);
|
|
|
|
fnt.setItalic(tl.m_italic);
|
2016-07-18 22:30:14 +02:00
|
|
|
QFontMetrics fm(fnt);
|
2019-07-24 12:42:22 +02:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
|
|
|
const int iTW = fm.horizontalAdvance(tl.m_qsText);
|
|
|
|
#else
|
2016-12-15 07:50:25 +01:00
|
|
|
const int iTW = fm.width(tl.m_qsText);
|
2019-07-24 12:42:22 +02:00
|
|
|
#endif
|
2016-12-14 00:56:30 +01:00
|
|
|
if (iTW > iMaxLen)
|
2016-07-18 22:30:14 +02:00
|
|
|
{
|
2016-12-14 00:56:30 +01:00
|
|
|
iMaxLen = iTW;
|
2016-12-15 07:50:25 +01:00
|
|
|
maxLine = tl;
|
2016-07-18 22:30:14 +02:00
|
|
|
}
|
|
|
|
}
|
2016-12-14 00:56:30 +01:00
|
|
|
if (iMaxLen > fW)
|
2016-09-29 01:39:50 +02:00
|
|
|
{
|
2016-12-15 07:50:25 +01:00
|
|
|
QFont fnt = m_font;
|
2019-07-01 10:02:09 +02:00
|
|
|
fnt.setBold(maxLine.m_bold);
|
|
|
|
fnt.setItalic(maxLine.m_italic);
|
2016-12-15 07:50:25 +01:00
|
|
|
|
|
|
|
int lineLength = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
--iFS;
|
|
|
|
fnt.setPixelSize(iFS + maxLine.m_iFontSize);
|
|
|
|
QFontMetrics fm(fnt);
|
2019-07-24 12:42:22 +02:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
|
|
|
lineLength = fm.horizontalAdvance(maxLine.m_qsText);
|
|
|
|
#else
|
2016-12-15 07:50:25 +01:00
|
|
|
lineLength = fm.width(maxLine.m_qsText);
|
2019-07-24 12:42:22 +02:00
|
|
|
#endif
|
2016-12-15 07:50:25 +01:00
|
|
|
}
|
|
|
|
while (lineLength > fW && iFS > MIN_FONT_SIZE);
|
2016-09-29 01:39:50 +02:00
|
|
|
}
|
2016-12-14 00:56:30 +01:00
|
|
|
SetFontSize(iFS);
|
2016-07-19 13:47:21 +02:00
|
|
|
}
|
|
|
|
|
2016-07-21 21:46:49 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
|
|
|
* @brief VTextManager::Update updates the text lines with detail data
|
|
|
|
* @param qsName detail name
|
|
|
|
* @param data reference to the detail data
|
|
|
|
*/
|
2020-10-16 12:43:54 +02:00
|
|
|
void VTextManager::Update(const QString& qsName, const VPieceLabelData& data, const VContainer *pattern)
|
2016-07-21 21:46:49 +02:00
|
|
|
{
|
2017-08-15 14:22:33 +02:00
|
|
|
m_liLines.clear();
|
|
|
|
|
2021-02-06 14:52:21 +01:00
|
|
|
QMap<QString, QString> placeholders =
|
|
|
|
PreparePlaceholders(VAbstractValApplication::VApp()->getCurrentDocument(), pattern);
|
2017-08-18 13:22:31 +02:00
|
|
|
InitPiecePlaceholders(placeholders, qsName, data);
|
2016-07-21 21:46:49 +02:00
|
|
|
|
2017-08-18 13:22:31 +02:00
|
|
|
QVector<VLabelTemplateLine> lines = data.GetLabelTemplate();
|
|
|
|
|
|
|
|
for (int i=0; i<lines.size(); ++i)
|
2016-07-21 21:46:49 +02:00
|
|
|
{
|
2017-08-18 13:22:31 +02:00
|
|
|
lines[i].line = ReplacePlaceholders(placeholders, lines.at(i).line);
|
2016-07-21 21:46:49 +02:00
|
|
|
}
|
2017-08-18 13:22:31 +02:00
|
|
|
|
|
|
|
m_liLines = PrepareLines(lines);
|
2016-07-21 21:46:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-07-23 15:26:15 +02:00
|
|
|
/**
|
|
|
|
* @brief VTextManager::Update updates the text lines with pattern info
|
|
|
|
* @param pDoc pointer to the abstract pattern object
|
|
|
|
*/
|
2020-10-16 12:43:54 +02:00
|
|
|
void VTextManager::Update(VAbstractPattern *pDoc, const VContainer *pattern)
|
2016-07-21 21:46:49 +02:00
|
|
|
{
|
2017-08-15 14:22:33 +02:00
|
|
|
m_liLines.clear();
|
2016-07-21 21:46:49 +02:00
|
|
|
|
2017-08-15 14:22:33 +02:00
|
|
|
if (m_patternLabelLines.isEmpty() || pDoc->GetPatternWasChanged())
|
2016-07-21 21:46:49 +02:00
|
|
|
{
|
2017-08-15 14:22:33 +02:00
|
|
|
QVector<VLabelTemplateLine> lines = pDoc->GetPatternLabelTemplate();
|
|
|
|
if (lines.isEmpty() && m_patternLabelLines.isEmpty())
|
|
|
|
{
|
|
|
|
return; // Nothing to parse
|
|
|
|
}
|
|
|
|
|
2020-10-16 12:43:54 +02:00
|
|
|
const QMap<QString, QString> placeholders = PreparePlaceholders(pDoc, pattern);
|
2017-08-15 14:22:33 +02:00
|
|
|
|
|
|
|
for (int i=0; i<lines.size(); ++i)
|
|
|
|
{
|
|
|
|
lines[i].line = ReplacePlaceholders(placeholders, lines.at(i).line);
|
|
|
|
}
|
|
|
|
|
2017-08-19 18:52:33 +02:00
|
|
|
pDoc->SetPatternWasChanged(false);
|
2017-08-15 14:22:33 +02:00
|
|
|
m_patternLabelLines = PrepareLines(lines);
|
2016-07-21 21:46:49 +02:00
|
|
|
}
|
|
|
|
|
2017-08-15 14:22:33 +02:00
|
|
|
m_liLines = m_patternLabelLines;
|
|
|
|
}
|