Seamly2D
Code documentation
vtextmanager.cpp
Go to the documentation of this file.
1 /************************************************************************
2  **
3  ** @file vpatternpiecedata.cpp
4  ** @author Bojan Kverh
5  ** @date July 19, 2016
6  **
7  ** @brief
8  ** @copyright
9  ** This source code is part of the Valentine project, a pattern making
10  ** program, whose allow create and modeling patterns of clothing.
11  ** Copyright (C) 2013-2015 Seamly2D project
12  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
13  **
14  ** Seamly2D is free software: you can redistribute it and/or modify
15  ** it under the terms of the GNU General Public License as published by
16  ** the Free Software Foundation, either version 3 of the License, or
17  ** (at your option) any later version.
18  **
19  ** Seamly2D is distributed in the hope that it will be useful,
20  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  ** GNU General Public License for more details.
23  **
24  ** You should have received a copy of the GNU General Public License
25  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
26  **
27  *************************************************************************/
28 
29 #include <QDate>
30 #include <QFileInfo>
31 #include <QFontMetrics>
32 #include <QLatin1String>
33 #include <QRegularExpression>
34 #include <QApplication>
35 #include <QDebug>
36 
37 #include "../ifc/xml/vabstractpattern.h"
38 #include "../vpatterndb/floatItemData/vpiecelabeldata.h"
39 #include "../vmisc/vabstractapplication.h"
40 #include "../vmisc/vmath.h"
41 #include "../vpatterndb/vcontainer.h"
42 #include "vtextmanager.h"
43 
44 //---------------------------------------------------------------------------------------------------------------------
45 /**
46  * @brief TextLine::TextLine default constructor
47  */
49  : m_text(),
50  m_iFontSize(MIN_FONT_SIZE),
51  bold(false),
52  italic(false),
53  m_eAlign(Qt::AlignCenter)
54 {}
55 
57 
58 namespace
59 {
60 
61 //---------------------------------------------------------------------------------------------------------------------
63 {
64  SCASSERT(doc != nullptr)
65 
66  QMap<QString, QString> placeholders;
67 
68  // Pattern tags
69  QLocale locale(qApp->Settings()->GetLocale());
70 
71  const QString date = locale.toString(QDate::currentDate(), doc->GetLabelDateFormat());
72  placeholders.insert(pl_date, date);
73 
74  const QString time = locale.toString(QTime::currentTime(), doc->GetLabelTimeFormat());
75  placeholders.insert(pl_time, time);
76 
77  placeholders.insert(pl_patternName, doc->GetPatternName());
78  placeholders.insert(pl_patternNumber, doc->GetPatternNumber());
79  placeholders.insert(pl_author, doc->GetCompanyName());
80  placeholders.insert(pl_customer, doc->GetCustomerName());
81  placeholders.insert(pl_pExt, QString("val"));
82  placeholders.insert(pl_pFileName, QFileInfo(qApp->getFilePath()).baseName());
83  placeholders.insert(pl_mFileName, QFileInfo(doc->MPath()).baseName());
84 
85  QString curSize;
86  QString curHeight;
87  QString mExt;
88  if (qApp->patternType() == MeasurementsType::Multisize)
89  {
90  curSize = QString::number(VContainer::size());
91  curHeight = QString::number(VContainer::height());
92  mExt = "vst";
93  }
94  else if (qApp->patternType() == MeasurementsType::Individual)
95  {
96  curSize = QString::number(VContainer::size());
97  curHeight = QString::number(VContainer::height());
98  mExt = "vit";
99  }
100 
101  placeholders.insert(pl_size, curSize);
102  placeholders.insert(pl_height, curHeight);
103  placeholders.insert(pl_mExt, mExt);
104 
105  // Piece tags
106  placeholders.insert(pl_pLetter, "");
107  placeholders.insert(pl_pAnnotation, "");
108  placeholders.insert(pl_pOrientation, "");
109  placeholders.insert(pl_pRotation, "");
110  placeholders.insert(pl_pTilt, "");
111  placeholders.insert(pl_pFoldPosition, "");
112  placeholders.insert(pl_pName, "");
113  placeholders.insert(pl_pQuantity, "");
114  placeholders.insert(pl_wOnFold, "");
115  placeholders.insert(pl_mFabric, QObject::tr("Fabric"));
116  placeholders.insert(pl_mLining, QObject::tr("Lining"));
117  placeholders.insert(pl_mInterfacing, QObject::tr("Interfacing"));
118  placeholders.insert(pl_mInterlining, QObject::tr("Interlining"));
119  placeholders.insert(pl_wCut, QObject::tr("Cut"));
120 
121  return placeholders;
122 }
123 
124 //---------------------------------------------------------------------------------------------------------------------
125 void InitPiecePlaceholders(QMap<QString, QString> &placeholders, const QString &name, const VPieceLabelData& data)
126 {
127  placeholders[pl_pLetter] = data.GetLetter();
128  placeholders[pl_pAnnotation] = data.GetAnnotation();
129  placeholders[pl_pOrientation] = data.GetOrientation();
130  placeholders[pl_pRotation] = data.GetRotationWay();
131  placeholders[pl_pTilt] = data.GetTilt();
132  placeholders[pl_pFoldPosition] = data.GetFoldPosition();
133  placeholders[pl_pName] = name;
134  placeholders[pl_pQuantity] = QString::number(data.GetQuantity());
135 
136  if (data.IsOnFold())
137  {
138  placeholders[pl_wOnFold] = QObject::tr("on fold");
139  }
140 }
141 
142 //---------------------------------------------------------------------------------------------------------------------
143 QString ReplacePlaceholders(const QMap<QString, QString> &placeholders, QString line)
144 {
145  QChar per('%');
146  auto i = placeholders.constBegin();
147  while (i != placeholders.constEnd())
148  {
149  line.replace(per+i.key()+per, i.value());
150  ++i;
151  }
152  return line;
153 }
154 
155 //---------------------------------------------------------------------------------------------------------------------
157 {
158  QList<TextLine> textLines;
159 
160  for (int i=0; i < lines.size(); ++i)
161  {
162  if (not lines.at(i).line.isEmpty())
163  {
164  TextLine tl;
165  tl.m_text = lines.at(i).line;
166  tl.m_eAlign = static_cast<Qt::Alignment>(lines.at(i).alignment);
167  tl.m_iFontSize = lines.at(i).fontSizeIncrement;
168  tl.bold = lines.at(i).bold;
169  tl.italic = lines.at(i).italic;
170 
171  textLines << tl;
172  }
173  }
174 
175  return textLines;
176 }
177 }
178 
179 //---------------------------------------------------------------------------------------------------------------------
180 /**
181  * @brief VTextManager::VTextManager constructor
182  */
184  : m_font(), m_liLines()
185 {}
186 
187 //---------------------------------------------------------------------------------------------------------------------
189  : m_font(text.GetFont()), m_liLines(text.GetAllSourceLines())
190 {}
191 
192 //---------------------------------------------------------------------------------------------------------------------
194 {
195  if ( &text == this )
196  {
197  return *this;
198  }
199  m_font = text.GetFont();
200  m_liLines = text.GetAllSourceLines();
201  return *this;
202 }
203 
204 //---------------------------------------------------------------------------------------------------------------------
205 /**
206  * @brief GetSpacing returns the vertical spacing between the lines
207  * @return spacing
208  */
210 {
211  return 0;
212 }
213 
214 //---------------------------------------------------------------------------------------------------------------------
215 /**
216  * @brief SetFont set the text base font
217  * @param font text base font
218  */
219 void VTextManager::setFont(const QFont& font)
220 {
221  m_font = font;
222 }
223 
224 //---------------------------------------------------------------------------------------------------------------------
225 /**
226  * @brief GetFont returns the text base font
227  * @return text base font
228  */
229 const QFont& VTextManager::GetFont() const
230 {
231  return m_font;
232 }
233 
234 //---------------------------------------------------------------------------------------------------------------------
235 /**
236  * @brief SetFontSize sets the font size
237  * @param iFS font size in pixels
238  */
240 {
241  iFS < MIN_FONT_SIZE ? m_font.setPixelSize(MIN_FONT_SIZE) : m_font.setPixelSize(iFS);
242 }
243 
244 //---------------------------------------------------------------------------------------------------------------------
246 {
247  return m_liLines;
248 }
249 
250 //---------------------------------------------------------------------------------------------------------------------
251 /**
252  * @brief VTextManager::GetSourceLinesCount returns the number of input text lines
253  * @return number of text lines that were added to the list by calling AddLine
254  */
256 {
257  return m_liLines.count();
258 }
259 
260 //---------------------------------------------------------------------------------------------------------------------
261 /**
262  * @brief VTextManager::GetSourceLine returns the reference to i-th text line
263  * @param i index of the requested line
264  * @return reference to the requested TextLine object
265  */
267 {
268  Q_ASSERT(i >= 0);
269  Q_ASSERT(i < m_liLines.count());
270  return m_liLines.at(i);
271 }
272 
273 //---------------------------------------------------------------------------------------------------------------------
274 /**
275  * @brief VTextManager::FitFontSize sets the font size just big enough, so that the text fits into rectangle of
276  * size (fW, fH)
277  * @param fW rectangle width
278  * @param fH rectangle height
279  */
280 void VTextManager::FitFontSize(qreal fW, qreal fH)
281 {
282  int iFS = 0;
283  if (GetSourceLinesCount() > 0)
284  {//division by zero
285  iFS = 3*qFloor(fH/GetSourceLinesCount())/4;
286  }
287 
288  if (iFS < MIN_FONT_SIZE)
289  {
290  iFS = MIN_FONT_SIZE;
291  }
292 
293  // get ratio between char width and height
294 
295  int iMaxLen = 0;
296  TextLine maxLine;
297  QFont fnt;
298  for (int i = 0; i < GetSourceLinesCount(); ++i)
299  {
300  const TextLine& tl = GetSourceLine(i);
301  fnt = m_font;
302  fnt.setPixelSize(iFS + tl.m_iFontSize);
303  fnt.setBold(tl.bold);
304  fnt.setItalic(tl.italic);
305  QFontMetrics fm(fnt);
306  const int iTW = fm.horizontalAdvance(tl.m_text);
307  if (iTW > iMaxLen)
308  {
309  iMaxLen = iTW;
310  maxLine = tl;
311  }
312  }
313  if (iMaxLen > fW)
314  {
315  QFont fnt = m_font;
316  fnt.setBold(maxLine.bold);
317  fnt.setItalic(maxLine.italic);
318 
319  int lineLength = 0;
320  do
321  {
322  --iFS;
323  fnt.setPixelSize(iFS + maxLine.m_iFontSize);
324  QFontMetrics fm(fnt);
325  lineLength = fm.horizontalAdvance(maxLine.m_text);
326  }
327  while (lineLength > fW && iFS > MIN_FONT_SIZE);
328  }
329  SetFontSize(iFS);
330  qDebug() << "Font size" << GetSourceLinesCount() << iFS;
331 }
332 
333 //---------------------------------------------------------------------------------------------------------------------
334 /**
335  * @brief VTextManager::Update updates the text lines with detail data
336  * @param qsName detail name
337  * @param data reference to the detail data
338  */
339 void VTextManager::Update(const QString& qsName, const VPieceLabelData& data)
340 {
341  m_liLines.clear();
342 
343  QMap<QString, QString> placeholders = PreparePlaceholders(qApp->getCurrentDocument());
344  InitPiecePlaceholders(placeholders, qsName, data);
345 
347 
348  for (int i=0; i<lines.size(); ++i)
349  {
350  lines[i].line = ReplacePlaceholders(placeholders, lines.at(i).line);
351  }
352 
353  m_liLines = PrepareLines(lines);
354 }
355 
356 //---------------------------------------------------------------------------------------------------------------------
357 /**
358  * @brief VTextManager::Update updates the text lines with pattern info
359  * @param pDoc pointer to the abstract pattern object
360  */
362 {
363  m_liLines.clear();
364 
365  if (m_patternLabelLines.isEmpty() || pDoc->GetPatternWasChanged())
366  {
368  if (lines.isEmpty() && m_patternLabelLines.isEmpty())
369  {
370  return; // Nothing to parse
371  }
372 
373  const QMap<QString, QString> placeholders = PreparePlaceholders(pDoc);
374 
375  for (int i=0; i<lines.size(); ++i)
376  {
377  lines[i].line = ReplacePlaceholders(placeholders, lines.at(i).line);
378  }
379 
380  pDoc->SetPatternWasChanged(false);
382  }
383 
385 }
bool GetPatternWasChanged() const
QString GetCompanyName() const
QVector< VLabelTemplateLine > getPatternLabelTemplate() const
QString GetLabelDateFormat() const
QString MPath() const
QString GetPatternName() const
QString GetPatternNumber() const
void SetPatternWasChanged(bool changed)
QString GetCustomerName() const
QString GetLabelTimeFormat() const
static qreal height()
height return height
Definition: vcontainer.cpp:690
static qreal size()
size return size
Definition: vcontainer.cpp:674
The VPieceLabelData class holds some information about a single piece like letter,...
QString GetOrientation() const
QVector< VLabelTemplateLine > GetLabelTemplate() const
bool IsOnFold() const
int GetQuantity() const
QString GetRotationWay() const
QString GetAnnotation() const
QString GetTilt() const
QString GetLetter() const
QString GetFoldPosition() const
The VTextManager class this class is used to determine whether a collection of text lines can fit int...
Definition: vtextmanager.h:66
VTextManager & operator=(const VTextManager &text)
int GetSourceLinesCount() const
VTextManager::GetSourceLinesCount returns the number of input text lines.
virtual int GetSpacing() const
GetSpacing returns the vertical spacing between the lines.
VTextManager()
VTextManager::VTextManager constructor.
const QFont & GetFont() const
GetFont returns the text base font.
const TextLine & GetSourceLine(int i) const
VTextManager::GetSourceLine returns the reference to i-th text line.
QList< TextLine > GetAllSourceLines() const
void Update(const QString &qsName, const VPieceLabelData &data)
VTextManager::Update updates the text lines with detail data.
QList< TextLine > m_liLines
Definition: vtextmanager.h:91
static QList< TextLine > m_patternLabelLines
Definition: vtextmanager.h:93
void setFont(const QFont &font)
SetFont set the text base font.
void FitFontSize(qreal fW, qreal fH)
VTextManager::FitFontSize sets the font size just big enough, so that the text fits into rectangle of...
void SetFontSize(int iFS)
SetFontSize sets the font size.
const QString pl_size
Definition: def.cpp:137
const QString pl_customer
Definition: def.cpp:144
const QString pl_pExt
Definition: def.cpp:145
const QString pl_mExt
Definition: def.cpp:148
const QString pl_pFoldPosition
Definition: def.cpp:154
const QString pl_wCut
Definition: def.cpp:161
const QString pl_author
Definition: def.cpp:143
const QString pl_time
Definition: def.cpp:140
const QString pl_pQuantity
Definition: def.cpp:156
const QString pl_mFileName
Definition: def.cpp:147
const QString pl_patternName
Definition: def.cpp:141
const QString pl_pAnnotation
Definition: def.cpp:150
const QString pl_pName
Definition: def.cpp:155
const QString pl_wOnFold
Definition: def.cpp:162
const QString pl_patternNumber
Definition: def.cpp:142
const QString pl_mLining
Definition: def.cpp:158
const QString pl_pFileName
Definition: def.cpp:146
const QString pl_date
Definition: def.cpp:139
const QString pl_mInterfacing
Definition: def.cpp:159
const QString pl_mFabric
Definition: def.cpp:157
const QString pl_pOrientation
Definition: def.cpp:151
const QString pl_pRotation
Definition: def.cpp:152
const QString pl_mInterlining
Definition: def.cpp:160
const QString pl_pTilt
Definition: def.cpp:153
const QString pl_height
Definition: def.cpp:138
const QString pl_pLetter
Definition: def.cpp:149
#define SCASSERT(cond)
Definition: def.h:317
QList< TextLine > PrepareLines(const QVector< VLabelTemplateLine > &lines)
void InitPiecePlaceholders(QMap< QString, QString > &placeholders, const QString &name, const VPieceLabelData &data)
QString ReplacePlaceholders(const QMap< QString, QString > &placeholders, QString line)
QMap< QString, QString > PreparePlaceholders(const VAbstractPattern *doc)
The TextLine struct holds the information about one text line.
Definition: vtextmanager.h:51
QString m_text
Definition: vtextmanager.h:52
TextLine()
TextLine::TextLine default constructor.
bool bold
Definition: vtextmanager.h:54
int m_iFontSize
Definition: vtextmanager.h:53
Qt::Alignment m_eAlign
Definition: vtextmanager.h:56
bool italic
Definition: vtextmanager.h:55
#define qApp
Definition: vapplication.h:67
#define MIN_FONT_SIZE
Definition: vtextmanager.h:44