61 QList<TitleBlockCell *> new_list;
62 for (
int i = 0 ; i < count ; ++ i) new_list <<
createCell();
81 QFile template_file(filepath);
82 if (!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
85 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 86 qDebug() << Q_FUNC_INFO << filepath <<
"opened";
91 bool xml_parsing = xml_doc.setContent(&template_file);
95 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 96 qDebug() << Q_FUNC_INFO << filepath <<
"opened and parsed";
107 if (xml_element.tagName() !=
"titleblocktemplate") {
110 if (!xml_element.hasAttribute(
"name")) {
113 name_ = xml_element.attribute(
"name");
128 if (filepath.isEmpty())
return(
false);
132 QDomElement e = doc.createElement(
"root");
134 if (!saving)
return(
false);
147 if (
name_.isEmpty())
return(
false);
149 xml_element.setTagName(
"titleblocktemplate");
150 xml_element.setAttribute(
"name",
name_);
177 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 178 qDebug() << Q_FUNC_INFO <<
"copying " <<
bitmap_logos_[logo_key] -> cacheKey() <<
"to" << copy ->
bitmap_logos_[logo_key] -> cacheKey();
205 if (
TitleBlockCell *original_cell = current_cell -> spanner_cell) {
206 int original_cell_row = original_cell -> num_row;
207 int original_cell_col = original_cell -> num_col;
209 current_cell -> spanner_cell = copy_cell;
221 for (QDomNode n = xml_element.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
222 if (n.isElement() && n.toElement().tagName() ==
"information") {
248 for (QDomNode n = xml_element.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
249 if (n.isElement() && n.toElement().tagName() ==
"logos") {
250 for (QDomNode p = n.firstChild() ; !p.isNull() ; p = p.nextSibling()) {
251 if (p.isElement() && p.toElement().tagName() ==
"logo") {
269 if (!xml_element.hasAttribute(
"name")) {
272 QString logo_name = xml_element.attribute(
"name");
273 QString logo_type = xml_element.attribute(
"type",
"png");
274 QString logo_storage = xml_element.attribute(
"storage",
"base64");
278 QByteArray logo_data;
279 if (logo_storage ==
"xml") {
280 QDomNodeList svg_nodes = xml_element.elementsByTagName(
"svg");
281 if (svg_nodes.isEmpty()) {
284 QDomElement svg_element = svg_nodes.at(0).toElement();
285 QTextStream xml_to_byte_array(&logo_data);
286 svg_element.save(xml_to_byte_array, 0);
287 }
else if (logo_storage ==
"base64") {
288 logo_data = QByteArray::fromBase64(xml_element.text().toLatin1());
292 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 293 qDebug() << Q_FUNC_INFO << logo_name << logo_type << logo_storage;
295 addLogo(logo_name, &logo_data, logo_type, logo_storage);
307 QDomElement grid_element;
308 for (QDomNode n = xml_element.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
309 if (n.isElement() && n.toElement().tagName() ==
"grid") {
310 grid_element = n.toElement();
315 if (!grid_element.hasAttribute(
"rows") || !grid_element.hasAttribute(
"cols")) {
319 parseRows(grid_element.attribute(
"rows"));
335 QRegExp row_size_format(
"^([0-9]+)(?:px)?$", Qt::CaseInsensitive);
338 QStringList rows_descriptions = rows_string.split(QChar(
';'), QString::SkipEmptyParts);
339 foreach (QString rows_description, rows_descriptions) {
340 if (row_size_format.exactMatch(rows_description)) {
341 int row_size = row_size_format.capturedTexts().at(1).toInt(&conv_ok);
345 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 357 QRegExp abs_col_size_format(
"^([0-9]+)(?:px)?$", Qt::CaseInsensitive);
358 QRegExp rel_col_size_format(
"^([rt])([0-9]+)%$", Qt::CaseInsensitive);
361 QStringList cols_descriptions = cols_string.split(QChar(
';'), QString::SkipEmptyParts);
362 foreach (QString cols_description, cols_descriptions) {
363 if (abs_col_size_format.exactMatch(cols_description)) {
364 int col_size = abs_col_size_format.capturedTexts().at(1).toInt(&conv_ok);
366 }
else if (rel_col_size_format.exactMatch(cols_description)) {
367 int col_size = rel_col_size_format.capturedTexts().at(2).toInt(&conv_ok);
372 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 374 qDebug() << Q_FUNC_INFO << QString(
"%1 [%2]").arg(icd.value).arg(QET::titleBlockColumnLengthToString(icd.type));
387 QDomElement grid_element;
388 for (QDomNode n = xml_element.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
389 if (!n.isElement())
continue;
390 QDomElement cell_element = n.toElement();
391 if (cell_element.tagName() ==
"field" || cell_element.tagName() ==
"logo") {
404 if (!
checkCell(cell_element, &loaded_cell))
return;
405 loaded_cell -> loadContentFromXml(cell_element);
413 QDomNode information_text_node = xml_element.ownerDocument().createTextNode(
information());
415 QDomElement information_element = xml_element.ownerDocument().createElement(
"information");
416 information_element.appendChild(information_text_node);
417 xml_element.appendChild(information_element);
425 QDomElement logos_element = xml_element.ownerDocument().createElement(
"logos");
427 QDomElement logo_element = xml_element.ownerDocument().createElement(
"logo");
429 logos_element.appendChild(logo_element);
431 xml_element.appendChild(logos_element);
442 xml_element.setAttribute(
"name", logo_name);
443 xml_element.setAttribute(
"type",
type_logos_[logo_name]);
447 QDomDocument svg_logo;
449 QDomNode svg_logo_element = xml_element.ownerDocument().importNode(svg_logo.documentElement(),
true);
450 xml_element.appendChild(svg_logo_element.toElement());
452 QDomText base64_logo = xml_element.ownerDocument().createTextNode(
data_logos_[logo_name].toBase64());
453 xml_element.appendChild(base64_logo);
462 QDomElement grid_element = xml_element.ownerDocument().createElement(
"grid");
464 QString rows_attr, cols_attr;
465 foreach(
int row_height,
rows_heights_) rows_attr += QString(
"%1;").arg(row_height);
467 grid_element.setAttribute(
"rows", rows_attr);
468 grid_element.setAttribute(
"cols", cols_attr);
472 xml_element.appendChild(grid_element);
497 if (
cell -> spanner_cell)
return;
501 QDomElement cell_elmt = xml_element.ownerDocument().createElement(
"cell");
502 xml_element.appendChild(cell_elmt);
505 cell_elmt.setAttribute(
"row",
cell -> num_row);
506 cell_elmt.setAttribute(
"col",
cell -> num_col);
507 if (
cell -> row_span) cell_elmt.setAttribute(
"rowspan",
cell -> row_span);
508 if (
cell -> col_span) cell_elmt.setAttribute(
"colspan",
cell -> col_span);
511 cell -> saveContentToXml(cell_elmt);
525 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 526 qDebug() << Q_FUNC_INFO <<
"begin" << row_count << col_count;
529 int row_num, col_num, row_span, col_span;
530 row_num = col_num = -1;
531 row_span = col_span = 0;
542 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 543 qDebug() << Q_FUNC_INFO <<
"cell access" << col_num << row_num;
550 cell_ptr -> num_row = row_num;
551 cell_ptr -> num_col = col_num;
555 cell_ptr -> row_span = row_span;
559 cell_ptr -> col_span = col_span;
563 if (titleblock_cell_ptr) *titleblock_cell_ptr = cell_ptr;
581 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 582 qDebug() << Q_FUNC_INFO << toString();
674 if (total_width < 0)
return(QList<int>());
678 int abs_widths_sum = 0, rel_widths_sum = 0;
679 QList<int> relative_columns;
684 abs_widths_sum += icd.
value;
685 final_widths[i] = icd.
value;
687 int abs_value = qRound(total_width * icd.
value / 100.0);
688 relative_columns << i;
689 abs_widths_sum += abs_value;
690 final_widths[i] = abs_value;
695 int remaining_width = total_width - abs_widths_sum;
701 final_widths[i] = qRound(remaining_width * icd.
value / 100.0);
702 relative_columns << i;
703 rel_widths_sum += final_widths[i];
708 if (relative_columns.count()) {
711 int difference = total_width - abs_widths_sum - rel_widths_sum;
717 qreal max_acceptable_difference = relative_columns.count() * 0.5;
719 int share = difference > 0 ? 1 : -1;
720 if (qAbs(difference) <= max_acceptable_difference) {
722 foreach (
int index, relative_columns) {
723 final_widths[index] += share;
725 if (!difference)
break;
731 return(final_widths.toList());
861 cells_[j].insert(index, row[j]);
874 QList<TitleBlockCell *> row;
876 if (index < 0 || index >=
rows_heights_.count())
return(row);
878 row <<
cells_[j].takeAt(index);
923 cells_.insert(index, column);
937 return(QList<TitleBlockCell *>());
939 QList<TitleBlockCell *> column =
cells_.takeAt(i);
973 QSet<TitleBlockCell *>
set;
974 if (!given_cell)
return(
set);
977 int final_row_span = ignore_span_state ? given_cell -> row_span : given_cell -> applied_row_span;
978 int final_col_span = ignore_span_state ? given_cell -> col_span : given_cell -> applied_col_span;
979 if (!final_row_span && !final_col_span)
return(
set);
981 for (
int i = given_cell -> num_col ; i <= given_cell -> num_col + final_col_span ; ++ i) {
982 for (
int j = given_cell -> num_row ; j <= given_cell -> num_row + final_row_span ; ++ j) {
983 if (i == given_cell -> num_col && j == given_cell -> num_row)
continue;
985 if (current_cell)
set << current_cell;
995 QHash<TitleBlockCell *, QPair<int, int> > spans;
1001 cells_[i][j] -> row_span,
1015 cell -> row_span = spans[
cell].first;
1016 cell -> col_span = spans[
cell].second;
1031 if (logo_type ==
"svg") {
1033 QSvgRenderer *svg =
new QSvgRenderer();
1034 if (!svg -> load(*logo_data)) {
1040 QString final_logo_storage = logo_storage;
1041 if (logo_storage !=
"xml" && logo_storage !=
"base64") {
1042 final_logo_storage =
"xml";
1048 QPixmap logo_pixmap;
1049 logo_pixmap.loadFromData(*logo_data);
1050 if (!logo_pixmap.width() || !logo_pixmap.height()) {
1073 QFileInfo filepath_info(filepath);
1074 QString filename =
name.isEmpty() ? filepath_info.fileName() :
name;
1075 QString filetype = filepath_info.suffix();
1078 QFile logo_file(filepath);
1079 if (!logo_file.open(QIODevice::ReadOnly))
return(
false);
1080 QByteArray file_content = logo_file.readAll();
1083 if (
addLogo(filename, &file_content,
"svg",
"xml"))
return(
true);
1086 return addLogo(filename, &file_content, filepath_info.suffix(),
"base64");
1099 QFile target_file(filepath);
1100 if (!target_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
1105 target_file.close();
1214 int titleblock_height =
height();
1218 QPen pen(Qt::black);
1219 pen.setCosmetic(
true);
1220 painter.setPen(pen);
1223 painter.drawRect(QRect(0, 0, titleblock_width, titleblock_height));
1234 int row_span = 0, col_span = 0;
1236 row_span =
cells_[i][j] -> applied_row_span;
1237 col_span =
cells_[i][j] -> applied_col_span;
1241 QRect cell_rect(x, y, w, h);
1255 int titleblock_width, QString &file_path,
int color)
const {
1259 double xCoord = title_block_rect.topLeft().x();
1274 int row_span = 0, col_span = 0;
1276 row_span =
cells_[i][j] -> applied_row_span;
1277 col_span =
cells_[i][j] -> applied_col_span;
1306 QPen pen(QBrush(), 0.0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin);
1307 pen.setColor(Qt::black);
1308 painter.setPen(pen);
1309 painter.drawRect(cell_rect);
1331 painter.setBrush(Qt::NoBrush);
1332 painter.drawRect(cell_rect);
1351 cell_text = QString(
tr(
" %1 : %2",
"titleblock content - please let the blank space at the beginning")).arg(cell_label).arg(cell_text);
1353 cell_text = QString(
tr(
" %1")).arg(cell_text);
1364 QString interpreted_string = string;
1366 interpreted_string.replace(
"%{" + key +
"}", diagram_context[key].toString());
1367 interpreted_string.replace(
"%" + key, diagram_context[key].toString());
1369 return(interpreted_string);
1383 list <<
cells_[i][j] -> value.name().replace(
"%",
"");
1401 if (text.isEmpty())
return;
1403 painter.setFont(text_font);
1406 QFontMetricsF font_metrics(text_font);
1407 QRectF font_rect = font_metrics.boundingRect(QRect(-10000, -10000, 10000, 10000),
cell.
alignment, text);
1409 if (font_rect.width() > cell_rect.width()) {
1410 qreal ratio = qreal(cell_rect.width()) / qreal(font_rect.width());
1413 painter.translate(cell_rect.topLeft());
1414 qreal vertical_adjustment = cell_rect.height() * (1 - ratio) / 2.0;
1415 painter.translate(0.0, vertical_adjustment);
1416 painter.scale(ratio, ratio);
1418 QRectF new_world_cell_rect(cell_rect);
1419 new_world_cell_rect.moveTo(0, 0.0);
1420 new_world_cell_rect.setWidth(new_world_cell_rect.width() / ratio);
1421 painter.drawText(new_world_cell_rect,
cell.
alignment, text);
1435 qreal x, qreal y, qreal w, qreal h,
int color)
const {
1436 if (text.isEmpty())
return;
1438 double textHeight = text_font.pointSizeF();
1440 textHeight = text_font.pixelSize();
1446 bool hALigned =
false;
1476 QFontMetricsF font_metrics(text_font);
1477 QRectF font_rect = font_metrics.boundingRect(QRect(-10000, -10000, 10000, 10000),
cell.
alignment, text);
1481 textHeight *= ratio;
1497 cells_[i][j] -> spanner_cell =
nullptr;
1507 if (!spanning_cell)
return;
1509 spanned_cell -> spanner_cell =
nullptr;
1512 spanning_cell -> row_span = 0;
1513 spanning_cell -> col_span = 0;
1514 spanning_cell -> applied_row_span = 0;
1515 spanning_cell -> applied_col_span = 0;
1545 if (!
cell)
return(
false);
1548 cell -> applied_row_span =
cell -> row_span;
1549 cell -> applied_col_span =
cell -> col_span;
1562 for (
int i =
cell -> num_col ; i <=
cell -> num_col +
cell -> applied_col_span ; ++ i) {
1563 for (
int j =
cell -> num_row ; j <=
cell -> num_row +
cell -> applied_row_span ; ++ j) {
1564 if (i ==
cell -> num_col && j ==
cell -> num_row)
continue;
1565 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 1566 qDebug() << Q_FUNC_INFO <<
"span check" << i << j;
1585 if (!
cell || (!
cell -> row_span && !
cell -> col_span))
return;
1589 for (
int i =
cell -> num_col ; i <=
cell -> num_col +
cell -> applied_col_span ; ++ i) {
1590 for (
int j =
cell -> num_row ; j <=
cell -> num_row +
cell -> applied_row_span ; ++ j) {
1592 if (i ==
cell -> num_col && j ==
cell -> num_row)
continue;
1593 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 1594 qDebug() << Q_FUNC_INFO <<
"marking cell at" << j << i <<
"as spanned by cell at" <<
cell -> num_row <<
cell -> num_col;
1608 cells_[i][j] -> num_col = i;
1609 cells_[i][j] -> num_row = j;
1629 if (start > end || start >= lengths_list.count() || end > lengths_list.count()) {
1630 #ifdef TITLEBLOCK_TEMPLATE_DEBUG 1631 qDebug() << Q_FUNC_INFO <<
"wont use" << start <<
"and" << end;
1637 for (
int i = start ; i < end ; ++i) {
1638 length += lengths_list[i];
bool attributeIsAnInteger(const QDomElement &, const QString &, int *=nullptr)
bool loadFromXmlFile(const QString &)
NamesList value
Text displayed by the cell.
QHash< QString, QByteArray > data_logos_
Logos raw data.
the length is just a fraction of the length that is still available when other types of lengths have ...
bool loadGrid(const QDomElement &)
QList< TitleBlockCell * > createColumn()
bool addLogoFromFile(const QString &, const QString &=QString())
void parseColumns(const QString &)
QHash< QString, QPixmap > bitmap_logos_
Pixmaps for bitmap logos.
bool saveLogoToFile(const QString &, const QString &)
QList< int > rows_heights_
rows heights – simple integers
QList< TitleBlockCell * > registered_cells_
Cells objects created rattached to this template, but not mandatorily used.
int lengthRange(int, int, const QList< int > &) const
QString name_
name identifying the Title Block Template within its parent collection
int columnTypeCount(QET::TitleBlockColumnLength)
void saveGrid(QDomElement &) const
void saveCells(QDomElement &) const
QList< TitleBlockCell * > createRow()
void applyCellSpan(TitleBlockCell *)
TitleBlockTemplate * clone() const
void setColumnDimension(int, const TitleBlockDimension &)
the length is absolute and should be applied as is
void renderCell(QPainter &, const TitleBlockCell &, const DiagramContext &, const QRect &) const
static void drawRectangle(const QString &filepath, double, double, double, double, const int &colorcode)
QHash< QString, QSvgRenderer * > vector_logos_
Rendered objects for vector logos.
bool loadFromXmlElement(const QDomElement &)
int alignment
Where the label+text should be displayed within the visual cell.
QList< int > columnsWidth(int) const
void setAllSpans(const QHash< TitleBlockCell *, QPair< int, int > > &)
QStringList listOfVariables()
Get list of variables.
QString name(const QString &=QString()) const
QList< TitleBlockDimension > columns_width_
columns widths –
TitleBlockColumnLength
enum used to specify the type of a length
void saveLogos(QDomElement &) const
QString interpreteVariables(const QString &, const DiagramContext &) const
static const double sheetHeight
QPixmap bitmapLogo(const QString &) const
bool addLogo(const QString &, QByteArray *, const QString &="svg", const QString &="xml")
void setLogoStorage(const QString &, const QString &)
bool moveColumn(int, int)
void exportCellToXml(TitleBlockCell *, QDomElement &) const
void parseRows(const QString &)
void saveLogo(const QString &, QDomElement &) const
TitleBlockDimension columnDimension(int)
void render(QPainter &, const DiagramContext &, int) const
bool loadLogos(const QDomElement &, bool=false)
QList< QString > keys(KeyOrder=None) const
QList< TitleBlockCell * > createCellsList(int)
bool display_label
Whether to display the label or not.
the cell span parameters should be applied without restriction
QList< int > rowsHeights() const
int font_size
Font size the text should be rendered with.
the cell span parameters should be applied with some restrictions
bool checkCell(const QDomElement &, TitleBlockCell **=nullptr)
QString toShortString() const
bool checkCellSpan(TitleBlockCell *)
bool removeLogo(const QString &)
void saveCell(TitleBlockCell *, QDomElement &, bool=false) const
void renderTextCell(QPainter &, const QString &, const TitleBlockCell &, const QRectF &) const
the length is just a fraction of the total available length
QHash< TitleBlockCell *, QPair< int, int > > getAllSpans() const
void setRowDimension(int, const TitleBlockDimension &)
TitleBlockTemplate(QObject *=nullptr)
QList< TitleBlockCell * > takeRow(int)
bool writeXmlFile(QDomDocument &xml_doc, const QString &filepath, QString *error_message=nullptr)
QString logoType(const QString &) const
void renderTextCellDxf(QString &, const QString &, const TitleBlockCell &, qreal, qreal, qreal, qreal, int) const
bool loadLogo(const QDomElement &)
static QFont fontForCell(const TitleBlockCell &)
NamesList label
Label displayed by the cell.
int columnTypeTotal(QET::TitleBlockColumnLength)
bool hadjust
Whether to reduce the font size if the text does not fit in the cell.
void loadInformation(const QDomElement &)
TitleBlockCell * cell(int, int) const
QList< QString > logos() const
QHash< QString, QString > storage_logos_
Logos applied storage type (e.g. "xml" or "base64")
bool saveToXmlFile(const QString &)
bool renameLogo(const QString &, const QString &)
the cell span parameters should not applied at all
void loadCell(const QDomElement &)
void renderDxf(QRectF &, const DiagramContext &, int, QString &, int) const
~TitleBlockTemplate() override
TitleBlockCell * createCell(const TitleBlockCell *=nullptr)
void setInformation(const QString &)
static QFont diagramTextsFont(qreal=-1.0)
QETApp::diagramTextsFont The font to use By default the font is "sans Serif" and size 9...
bool insertRow(int, const QList< TitleBlockCell *> &, int=-1)
QString logo_reference
Logo displayed by this cell, it it is a logo cell.
bool saveToXmlElement(QDomElement &) const
void saveInformation(QDomElement &) const
QSet< TitleBlockCell * > spannedCells(const TitleBlockCell *, bool=false) const
QString finalTextForCell(const TitleBlockCell &, const DiagramContext &) const
static void drawTextAligned(const QString &fileName, const QString &text, double x, double y, double height, double rotation, double oblique, int hAlign, int vAlign, double xAlign, int colour, bool leftAlign=false, float scale=0)
TemplateCellType type() const
bool loadCells(const QDomElement &)
QSvgRenderer * vectorLogo(const QString &) const
QHash< QString, QString > type_logos_
Logos types (e.g. "png", "jpeg", "svg")
QList< QList< TitleBlockCell * > > cells_
Cells grid.
bool insertColumn(const TitleBlockDimension &, const QList< TitleBlockCell *> &, int=-1)
QList< TitleBlockCell * > takeColumn(int)
QString information() const
QET::TitleBlockColumnLength type
Kind of length.