diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.cpp b/sources/qetgraphicsitem/dynamicelementtextitem.cpp index 0b8dbf982..6f178f8dd 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.cpp +++ b/sources/qetgraphicsitem/dynamicelementtextitem.cpp @@ -16,6 +16,8 @@ along with QElectroTech. If not, see . */ #include "dynamicelementtextitem.h" +#include +#include #include "../QetGraphicsItemModeler/textresizehandles.h" #include "../shownkinds.h" #include "../qetproject.h" @@ -1063,6 +1065,20 @@ void DynamicElementTextItem::handlerMousePressEvent(QetGraphicsHandlerItem *hand m_resize_fixed_parent = mapToParent(resizeAnchor()); } +/** + @brief DynamicElementTextItem::minimumTextWidth + @return the narrowest width the text can be dragged to: that of its + widest word. Narrower, a long word runs out of the text's box while + the short lines are still aligned inside it, and a centred or right + aligned text falls apart (a lone "1" in the middle under its words). +*/ +qreal DynamicElementTextItem::minimumTextWidth() const +{ + QScopedPointer narrowest(document()->clone()); + narrowest->setTextWidth(0); + return qMax(narrowest->idealWidth(), qreal(10)); +} + /** @brief DynamicElementTextItem::resizeAnchor @return the point of the text, in its own coordinates, that a drag on @@ -1102,7 +1118,7 @@ void DynamicElementTextItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *handl if (handle == m_left_resize_handle) delta = -delta; - qreal new_width = qMax(m_resize_baseline_width + delta, qreal(10)); + qreal new_width = qMax(m_resize_baseline_width + delta, minimumTextWidth()); setTextWidth(new_width); //Keep the point the text is aligned on in place, whatever the new diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.h b/sources/qetgraphicsitem/dynamicelementtextitem.h index 275420f36..3bc2a0afc 100644 --- a/sources/qetgraphicsitem/dynamicelementtextitem.h +++ b/sources/qetgraphicsitem/dynamicelementtextitem.h @@ -171,6 +171,7 @@ class DynamicElementTextItem : public DiagramTextItem void removeResizeHandles(); void updateResizeHandlesPos(); QPointF resizeAnchor() const; + qreal minimumTextWidth() const; void fitAutoTextWidth(); void handlerMousePressEvent(QetGraphicsHandlerItem *handle, QGraphicsSceneMouseEvent *event); void handlerMouseMoveEvent(QetGraphicsHandlerItem *handle, QGraphicsSceneMouseEvent *event); diff --git a/tests/qttest/element_text_resize_probe.cpp b/tests/qttest/element_text_resize_probe.cpp index ba144873a..965efd5ad 100644 --- a/tests/qttest/element_text_resize_probe.cpp +++ b/tests/qttest/element_text_resize_probe.cpp @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include #include #include @@ -82,6 +85,20 @@ static void drag(Diagram *scene, DynamicElementTextItem *text, bool left, qreal mouse(scene, h, QEvent::GraphicsSceneMouseRelease, end); } +/// Every line lies inside the text's width: none runs out of it. +static bool linesInside(DynamicElementTextItem *text) +{ + QTextDocument *doc = text->document(); + const qreal inner = doc->textWidth() - 2 * doc->documentMargin(); + for (QTextBlock b = doc->begin(); b.isValid(); b = b.next()) + for (int i = 0; i < b.layout()->lineCount(); ++i) { + const QTextLine line = b.layout()->lineAt(i); + if (line.x() < -0.01 || line.x() + line.naturalTextWidth() > inner + 0.01) + return false; + } + return true; +} + /// The width changed by exactly as much as the mouse moved. static void checkGrowth(DynamicElementTextItem *text, qreal before, qreal moved, const char *message) { @@ -124,6 +141,7 @@ static void checkText(Diagram *scene, Element *element, DynamicElementTextItem * const qreal height = text->boundingRect().height(); drag(scene, text, false, 25 - width); check(text->boundingRect().height() > height + 5, "narrowing the text wraps it onto more lines"); + check(linesInside(text), "a text is not narrower than its widest word: no line runs out of it"); check(near(anchor(text), fixed), "a text that wraps keeps its alignment point in place"); scene->undoStack().undo(); check(near(text->pos(), pos), "undo puts the wrapped text back"); @@ -136,6 +154,7 @@ static void checkAll(Diagram *scene, Element *element, DynamicElementTextItem *t checkText(scene, element, text, Qt::AlignRight | Qt::AlignTop); checkText(scene, element, text, Qt::AlignHCenter | Qt::AlignVCenter); checkText(scene, element, text, Qt::AlignRight | Qt::AlignBottom); + checkText(scene, element, text, Qt::AlignLeft | Qt::AlignBottom); } int main(int argc, char **argv)