diff --git a/sources/editor/graphicspart/partdynamictextfield.cpp b/sources/editor/graphicspart/partdynamictextfield.cpp index ee9b0c647..eea11ae89 100644 --- a/sources/editor/graphicspart/partdynamictextfield.cpp +++ b/sources/editor/graphicspart/partdynamictextfield.cpp @@ -20,6 +20,7 @@ #include "../../QPropertyUndoCommand/qpropertyundocommand.h" #include "../../qetapp.h" #include "../elementscene.h" +#include "../../utils/qetutils.h" #include #include @@ -142,7 +143,7 @@ const QDomElement PartDynamicTextField::toXml(QDomDocument &dom_doc) const root_element.setAttribute("y", QString::number(y)); root_element.setAttribute("z", QString::number(zValue())); root_element.setAttribute("rotation", QString::number(QET::correctAngle(rot))); - root_element.setAttribute("font", font().toString()); + root_element.setAttribute("font", QETUtils::fontToString(font())); root_element.setAttribute("uuid", m_uuid.toString()); root_element.setAttribute("frame", m_frame? "true" : "false"); root_element.setAttribute("text_width", QString::number(m_text_width)); diff --git a/sources/editor/graphicspart/parttext.cpp b/sources/editor/graphicspart/parttext.cpp index 25e02f1c4..3b6cc8e6e 100644 --- a/sources/editor/graphicspart/parttext.cpp +++ b/sources/editor/graphicspart/parttext.cpp @@ -23,6 +23,7 @@ #include "../elementprimitivedecorator.h" #include "../elementscene.h" #include "../ui/texteditor.h" +#include "../../utils/qetutils.h" /** Constructeur @@ -165,7 +166,7 @@ const QDomElement PartText::toXml(QDomDocument &xml_document) const xml_element.setAttribute("x", QString::number(x)); xml_element.setAttribute("y", QString::number(y)); xml_element.setAttribute("text", toPlainText()); - xml_element.setAttribute("font", font().toString()); + xml_element.setAttribute("font", QETUtils::fontToString(font())); xml_element.setAttribute("rotation", QString::number(rot)); xml_element.setAttribute("color", defaultTextColor().name()); diff --git a/sources/factory/ui/addtabledialog.cpp b/sources/factory/ui/addtabledialog.cpp index dce18168d..325b6c758 100644 --- a/sources/factory/ui/addtabledialog.cpp +++ b/sources/factory/ui/addtabledialog.cpp @@ -221,12 +221,12 @@ void AddTableDialog::saveConfig() header_object.insert("margins", QETUtils::marginsToString(this->headerMargins())); auto me = QMetaEnum::fromType(); header_object.insert("alignment", me.valueToKey(int(this->headerAlignment()))); - header_object.insert("font", this->headerFont().toString()); + header_object.insert("font", QETUtils::fontToString(this->headerFont())); QJsonObject table_object; table_object.insert("margins", QETUtils::marginsToString(this->tableMargins())); table_object.insert("alignment", me.valueToKey(int(this->tableAlignment()))); - table_object.insert("font", this->tableFont().toString()); + table_object.insert("font", QETUtils::fontToString(this->tableFont())); QJsonObject config_object; config_object.insert("header", header_object); diff --git a/sources/properties/terminaldata.cpp b/sources/properties/terminaldata.cpp index 57b135421..d06babc5c 100644 --- a/sources/properties/terminaldata.cpp +++ b/sources/properties/terminaldata.cpp @@ -17,6 +17,8 @@ */ #include "terminaldata.h" +#include "../utils/qetutils.h" + #include #include @@ -115,7 +117,7 @@ QDomElement TerminalData::toXml(QDomDocument &xml_document) const xml_element.setAttribute("show_name", "true"); xml_element.setAttribute("label_x", QString::number(m_label_pos.x())); xml_element.setAttribute("label_y", QString::number(m_label_pos.y())); - xml_element.setAttribute("label_font", m_label_font.toString()); + xml_element.setAttribute("label_font", QETUtils::fontToString(m_label_font)); xml_element.setAttribute("label_rotation", QString::number(m_label_rotation)); xml_element.setAttribute("label_halign", static_cast(m_label_halignment)); xml_element.setAttribute("label_valign", static_cast(m_label_valignment)); diff --git a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp index 91f137379..b01f73a17 100644 --- a/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp +++ b/sources/qetgraphicsitem/ViewItem/projectdbmodel.cpp @@ -22,6 +22,7 @@ #include "../../qetinformation.h" #include "../../qetproject.h" #include "../../qetxml.h" +#include "../../utils/qetutils.h" #include #include @@ -252,7 +253,7 @@ QDomElement ProjectDBModel::toXml(QDomDocument &document) const //Add index 0,0 data auto index_00 = document.createElement("index00"); - index_00.setAttribute("font", m_index_0_0_data.value(Qt::FontRole).toString()); + index_00.setAttribute("font", QETUtils::fontToString(m_index_0_0_data.value(Qt::FontRole).value())); auto me = QMetaEnum::fromType(); index_00.setAttribute("alignment", me.valueToKey(m_index_0_0_data.value(Qt::TextAlignmentRole).toInt())); dom_element.appendChild(index_00); diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.cpp b/sources/qetgraphicsitem/dynamicelementtextitem.cpp index de47ca808..f6854b8e4 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.cpp +++ b/sources/qetgraphicsitem/dynamicelementtextitem.cpp @@ -23,6 +23,7 @@ #include "../qetgraphicsitem/conductor.h" #include "../qetgraphicsitem/terminal.h" #include "../qetinformation.h" +#include "../utils/qetutils.h" #include "crossrefitem.h" #include "element.h" #include "elementtextitemgroup.h" @@ -96,7 +97,7 @@ QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const root_element.setAttribute("uuid", m_uuid.toString()); root_element.setAttribute("frame", m_frame? "true" : "false"); root_element.setAttribute("text_width", QString::number(m_text_width)); - root_element.setAttribute("font", font().toString()); + root_element.setAttribute("font", QETUtils::fontToString(font())); root_element.setAttribute("keep_visual_rotation", m_keep_visual_rotation ? "true" : "false"); QMetaEnum me = textFromMetaEnum(); diff --git a/sources/qetgraphicsitem/independenttextitem.cpp b/sources/qetgraphicsitem/independenttextitem.cpp index 1fc4b8559..972138126 100644 --- a/sources/qetgraphicsitem/independenttextitem.cpp +++ b/sources/qetgraphicsitem/independenttextitem.cpp @@ -21,6 +21,7 @@ #include "../diagramcommands.h" #include "../qet.h" #include "../qetapp.h" +#include "../utils/qetutils.h" #include #include @@ -80,7 +81,7 @@ QDomElement IndependentTextItem::toXml(QDomDocument &document) const result.setAttribute("y", QString("%1").arg(pos().y())); result.setAttribute("text", toHtml()); result.setAttribute("rotation", QString::number(QET::correctAngle(rotation()))); - result.setAttribute("font", font().toString()); + result.setAttribute("font", QETUtils::fontToString(font())); return(result); } diff --git a/sources/qetxml.cpp b/sources/qetxml.cpp index 92db3f787..440dece91 100644 --- a/sources/qetxml.cpp +++ b/sources/qetxml.cpp @@ -18,6 +18,7 @@ #include "qetxml.h" #include "NameList/nameslist.h" +#include "utils/qetutils.h" #include #include @@ -477,7 +478,7 @@ QDomElement QETXML::modelHeaderDataToXml( else if (role == Qt::FontRole) { auto font = variant.value(); - text_node.setData(font.toString()); + text_node.setData(QETUtils::fontToString(font)); } else if (role == Qt::TextAlignmentRole) { diff --git a/sources/ui/configpage/generalconfigurationpage.cpp b/sources/ui/configpage/generalconfigurationpage.cpp index d639e3a6a..9698fc889 100644 --- a/sources/ui/configpage/generalconfigurationpage.cpp +++ b/sources/ui/configpage/generalconfigurationpage.cpp @@ -21,6 +21,7 @@ #include "../../qeticons.h" #include "ui_generalconfigurationpage.h" #include "../../utils/qetsettings.h" +#include "../../utils/qetutils.h" #include "../../qetmessagebox.h" #include #include @@ -459,7 +460,7 @@ void GeneralConfigurationPage::on_m_dyn_text_font_pb_clicked() QFont font = QFontDialog::getFont(&ok, curFont, this); if (ok) { - settings.setValue("diagrameditor/dynamic_text_font", font.toString()); + settings.setValue("diagrameditor/dynamic_text_font", QETUtils::fontToString(font)); QString fontInfos = font.family() + " " + QString::number(font.pointSize()) + " (" + font.styleName() + ")"; @@ -563,7 +564,7 @@ void GeneralConfigurationPage::on_m_indi_text_font_pb_clicked() QFont font = QFontDialog::getFont(&ok, curFont, this); if (ok) { - settings.setValue("diagrameditor/independent_text_font", font.toString()); + settings.setValue("diagrameditor/independent_text_font", QETUtils::fontToString(font)); QString fontInfos = font.family() + " " + QString::number(font.pointSize()) + " (" + font.styleName() + ")"; diff --git a/sources/utils/qetutils.cpp b/sources/utils/qetutils.cpp index 4f6a393f7..8b9c126dc 100644 --- a/sources/utils/qetutils.cpp +++ b/sources/utils/qetutils.cpp @@ -150,3 +150,59 @@ void QETUtils::pixelSizedFont(QFont &font) auto px = font.pointSizeF()/72 * QFontMetrics{font}.fontDpi(); font.setPixelSize(qRound(px)); } + +/** + * @brief QETUtils::fontToString + * Serialize a font to the 10/11 field description format written by Qt 5, + * to be used instead of QFont::toString() everywhere a font description is + * stored in a project, element or settings file. + * The format of QFont::toString() is not stable across Qt versions : Qt 6.11 + * switched to a 19 field format carrying OpenType weights, which + * QFont::fromString() of Qt 5.x and Qt <= 6.10 rejects, leaving a broken font. + * The 10/11 field form is parsed correctly by every Qt version (they convert + * the legacy weight scale as needed), so composing it ourselves keeps files + * readable by every QET build in circulation. + * See @link https://github.com/qelectrotech/qelectrotech-source-mirror/issues/553 @endlink + * @param font + * @return the font description string + */ +QString QETUtils::fontToString(const QFont &font) +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + return font.toString(); +#else + //Legacy (Qt 5) weight <- OpenType weight, closest match, + //same table Qt uses when parsing a 10/11 field string. + static const int weight_map[9][2] = { + {0, 100}, {12, 200}, {25, 300}, {50, 400}, {57, 500}, + {63, 600}, {75, 700}, {81, 800}, {87, 900} + }; + const int weight = font.weight(); + int legacy_weight = weight_map[0][0]; + int closest_diff = qAbs(weight - weight_map[0][1]); + for (int i = 1 ; i < 9 ; ++i) + { + const int diff = qAbs(weight - weight_map[i][1]); + if (diff < closest_diff) { + closest_diff = diff; + legacy_weight = weight_map[i][0]; + } + } + + const QChar comma(QLatin1Char(',')); + QString description = font.family() + comma + + QString::number(font.pointSizeF()) + comma + + QString::number(font.pixelSize()) + comma + + QString::number(int(font.styleHint())) + comma + + QString::number(legacy_weight) + comma + + QString::number(int(font.style())) + comma + + QString::number(int(font.underline())) + comma + + QString::number(int(font.strikeOut())) + comma + + QString::number(int(font.fixedPitch())) + comma + + QString::number(0); + if (!font.styleName().isEmpty()) { + description += QChar(',') + font.styleName(); + } + return description; +#endif +} diff --git a/sources/utils/qetutils.h b/sources/utils/qetutils.h index ffc003db2..5f5bc63e0 100644 --- a/sources/utils/qetutils.h +++ b/sources/utils/qetutils.h @@ -32,6 +32,7 @@ namespace QETUtils QMargins marginsFromString(const QString &string); qreal graphicsHandlerSize(QGraphicsItem *item); void pixelSizedFont (QFont &font); + QString fontToString (const QFont &font); bool sortBeginIntString(const QString &str_a, const QString &str_b);