Symbol texts: width and height, each fixed or not

In a symbol text's properties, "Width (fixed)" and the new "Height
(fixed)" each carry a tick box. Not ticked, the field follows the text
and shows the size it has now, ready to be fixed; ticked, it keeps the
size beside the box.

A fixed height is new: the field keeps it whatever is written, and the
lines that do not fit are cut off, neither drawn nor picked, to shorten
a text where room is short. It is saved as text_height on the text,
only when set, and changed through an undoable property command like
the width. Translations for all languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DaTweety
2026-10-19 13:54:19 +02:00
parent 2f4af977b7
commit 255def181c
42 changed files with 1222 additions and 15 deletions
@@ -175,6 +175,8 @@ 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));
if (m_text_height > 0)
root_element.setAttribute(QStringLiteral("text_height"), QString::number(m_text_height));
root_element.setAttribute("font", QETUtils::fontToString(font()));
root_element.setAttribute("keep_visual_rotation", m_keep_visual_rotation ? "true" : "false");
root_element.setAttribute("rotation_point_center", m_rotation_point_center ? "true" : "false");
@@ -262,6 +264,7 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
m_uuid = QUuid(dom_elmt.attribute("uuid", QUuid::createUuid().toString()));
setFrame(dom_elmt.attribute("frame", "false") == "true"? true : false);
setTextWidth(dom_elmt.attribute("text_width", QString::number(-1)).toDouble());
setTextHeight(dom_elmt.attribute(QStringLiteral("text_height"), QStringLiteral("-1")).toDouble());
//Text from
QMetaEnum me = textFromMetaEnum();
@@ -867,7 +870,15 @@ void DynamicElementTextItem::paint(QPainter *painter, const QStyleOptionGraphics
if (m_jump_highlight)
painter->fillRect(boundingRect(), QColor(69, 137, 255, 90));
DiagramTextItem::paint(painter, option, widget);
//A fixed height cuts off the lines that do not fit
if (m_text_height > 0) {
painter->save();
painter->setClipRect(boundingRect(), Qt::IntersectClip);
DiagramTextItem::paint(painter, option, widget);
painter->restore();
} else {
DiagramTextItem::paint(painter, option, widget);
}
if (m_frame)
{
@@ -2069,6 +2080,60 @@ void DynamicElementTextItem::setTextWidth(qreal width)
emit textWidthChanged(width);
}
/**
@brief DynamicElementTextItem::setTextHeight
@param height : the height of the text field, -1 to follow the text.
With a height set, the field keeps it whatever is written: the lines
that do not fit are not drawn, to shorten a text where room is short.
*/
void DynamicElementTextItem::setTextHeight(qreal height)
{
if (height <= 0)
height = -1;
if (qFuzzyCompare(height + 2, m_text_height + 2))
return;
prepareGeometryChange();
m_text_height = height;
update();
emit textHeightChanged(height);
}
/**
@brief DynamicElementTextItem::boundingRect
@return the text's own box, cut to the height set by the user
*/
QRectF DynamicElementTextItem::boundingRect() const
{
QRectF rect = DiagramTextItem::boundingRect();
if (m_text_height > 0)
rect.setHeight(m_text_height);
return rect;
}
/**
@brief DynamicElementTextItem::shape
QGraphicsTextItem answers shape() and contains() from its own box, not
from boundingRect(): cut both to the height set by the user, so that
the lines cut off take no clicks either.
*/
QPainterPath DynamicElementTextItem::shape() const
{
QPainterPath path = DiagramTextItem::shape();
if (m_text_height > 0) {
QPainterPath cut;
cut.addRect(boundingRect());
path = path.intersected(cut);
}
return path;
}
bool DynamicElementTextItem::contains(const QPointF &point) const
{
if (m_text_height > 0 && !boundingRect().contains(point))
return false;
return DiagramTextItem::contains(point);
}
/**
@brief DynamicElementTextItem::fitAutoTextWidth
With no width set by the user, a QTextDocument has no width to centre