From 0a6efa466ee6df17c7e70782ae414f13b85110a8 Mon Sep 17 00:00:00 2001 From: achim Date: Sat, 2 Aug 2025 23:27:09 +0200 Subject: [PATCH] Correcting dynamicElementTextItem alignment on copying When copying and pasting selected areas, right-aligned dynamic text in report and slave elements was not displayed correctly. The text insertion point was always shifted to the left by the text width. To correct this, the insertion point of dynamicElementTextItems is reset to its origin insertion point before writing to clipboard. --- sources/diagram.cpp | 91 ++++++++++++++++++++++++++++++++++++++++- sources/diagram.h | 4 +- sources/diagramview.cpp | 2 +- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/sources/diagram.cpp b/sources/diagram.cpp index 79a945a8e..6ee509aa5 100644 --- a/sources/diagram.cpp +++ b/sources/diagram.cpp @@ -762,10 +762,12 @@ QList < QSet > Diagram::potentials() represent the entire schema or only the selected content \~French Booleen (a vrai par defaut) indiquant si le XML genere doit representer l'integralite du schema ou seulement le contenu selectionne + \~ @param is_copy_command: + Boolean (false by default) indicating if function is called by an copy command \~ @return An XML Document (QDomDocument) \~French Un Document XML (QDomDocument) */ -QDomDocument Diagram::toXml(bool whole_content) { +QDomDocument Diagram::toXml(bool whole_content, bool is_copy_command) { // document QDomDocument document; @@ -912,8 +914,13 @@ QDomDocument Diagram::toXml(bool whole_content) { { case Element::Type: { auto elmt = static_cast(qgi); - if (whole_content || elmt->isSelected()) + if (whole_content || elmt->isSelected()){ + // For a copy/paste command, the text positions must be recalculated for + // correct text alignment, before it is saved to the clipboard + if(is_copy_command && (elmt->linkType() == Element::Slave || elmt->linkType()&Element::AllReport)) + correctTextPos(elmt); list_elements << elmt; + } break; } case Conductor::Type: { @@ -973,6 +980,9 @@ QDomDocument Diagram::toXml(bool whole_content) { for (auto elmt : list_elements) { dom_elements.appendChild(elmt->toXml(document, table_adr_id)); + // If copy is active we have to undo the changes we have made during creating(filling) 'list_elements' + if(is_copy_command && (elmt->linkType() == Element::Slave || elmt->linkType()&Element::AllReport)) + restoreText(elmt); } dom_root.appendChild(dom_elements); } @@ -2472,3 +2482,80 @@ bool Diagram::canRotateSelection() const return false; } +/* + * To copy elements with right-aligned or centered elementtext, the text position + of dynamicElementTextItems in report- and slave elements must be reset + to the original insert position bevor writing to clipboard. + It is only necessary for right-aligned and centered texts, + but we do it for all, because it has no influence on other texts. +*/ +/** + @brief Diagram::correctTextPos + set insertion position to the original insertion position of the element texts before copying + @param Element +*/ +void Diagram::correctTextPos(Element* elmt) +{ + for (auto deti : elmt->dynamicTextItems()){ + if( deti->textFrom() == DynamicElementTextItem::ElementInfo || + deti->textFrom() == DynamicElementTextItem::CompositeText) { + + if (deti->text().isEmpty()){ + deti->setText(deti->toPlainText()); + } + // block alignment calculation + deti->m_block_alignment = true; + deti->setPlainText(deti->text()); + // release the alignment calculation + deti->m_block_alignment = false; + // writing an empty string sets the insertion point + // to the original insertion point + deti->setPlainText(""); + } + } + // same for textgroups + for (auto group : elmt->textGroups()){ + for(DynamicElementTextItem *deti : group->texts()){ + if( deti->textFrom() == DynamicElementTextItem::ElementInfo || + deti->textFrom() == DynamicElementTextItem::CompositeText) { + if (deti->text().isEmpty()){ + deti->setText(deti->toPlainText()); + } + deti->m_block_alignment = true; + deti->setPlainText(deti->text()); + deti->m_block_alignment = false; + deti->setPlainText(""); + } + } + } +} + +/* + * After changing the element texts for copying, the element texts has to be restored. + */ +/** + @brief Diagram::restoreText + After correcting the elementtext position during copying + the Text has to be restored + @param Element +*/ +void Diagram::restoreText(Element* elmt) +{ + for (auto deti : elmt->dynamicTextItems()){ + if( deti->textFrom() == DynamicElementTextItem::ElementInfo || + deti->textFrom() == DynamicElementTextItem::CompositeText) + { + deti->setPlainText(deti->text()); + } + } + + for (auto group : elmt->textGroups()){ + for(DynamicElementTextItem *deti : group->texts()){ + if( deti->textFrom() == DynamicElementTextItem::ElementInfo || + deti->textFrom() == DynamicElementTextItem::CompositeText) + { + deti->setPlainText(deti->text()); + } + } + } +} diff --git a/sources/diagram.h b/sources/diagram.h index 452c52a24..3c421e36f 100644 --- a/sources/diagram.h +++ b/sources/diagram.h @@ -142,6 +142,8 @@ class Diagram : public QGraphicsScene void wheelEvent (QGraphicsSceneWheelEvent *event) override; void keyPressEvent (QKeyEvent *event) override; void keyReleaseEvent (QKeyEvent *) override; + void correctTextPos(Element* elmt); + void restoreText(Element* elmt); public: QUuid uuid(); @@ -167,7 +169,7 @@ class Diagram : public QGraphicsScene QList < QSet > potentials(); // methods related to XML import/export - QDomDocument toXml(bool = true); + QDomDocument toXml(bool wholeContent = true, bool is_copy_command = false); bool initFromXml(QDomElement &, QPointF = QPointF(), bool = true, diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 73dcb018a..cacefcd1d 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -391,7 +391,7 @@ void DiagramView::cut() void DiagramView::copy() { QClipboard *presse_papier = QApplication::clipboard(); - QString contenu_presse_papier = m_diagram -> toXml(false).toString(4); + QString contenu_presse_papier = m_diagram -> toXml(false, true).toString(4); if (presse_papier -> supportsSelection()) presse_papier -> setText(contenu_presse_papier, QClipboard::Selection); presse_papier -> setText(contenu_presse_papier); }