From 70fbce280ff0c86a56328adafa1a521ac5ea0fa0 Mon Sep 17 00:00:00 2001 From: blacksun Date: Thu, 1 Feb 2018 18:40:12 +0000 Subject: [PATCH] Element text item group : add new property -> hold to bottom of the page git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5224 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- sources/qetgraphicsitem/element.cpp | 152 ++++++++++++----- .../qetgraphicsitem/elementtextitemgroup.cpp | 155 ++++++++++++++++-- .../qetgraphicsitem/elementtextitemgroup.h | 14 +- .../qetgraphicsitem/qgraphicsitemutility.cpp | 34 ++-- .../qetgraphicsitem/qgraphicsitemutility.h | 4 +- sources/ui/dynamicelementtextmodel.cpp | 78 +++++++-- sources/ui/dynamicelementtextmodel.h | 10 +- sources/ui/elementpropertieswidget.cpp | 2 +- 8 files changed, 356 insertions(+), 93 deletions(-) diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index f1295617d..d49d56b33 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -519,7 +519,12 @@ bool Element::fromXml(QDomElement &e, QHash &table_id_adr, bool //that mean this is the good text if (qFuzzyCompare(qreal(dom_input.attribute("x").toDouble()), m_converted_text_from_xml_description.value(deti).x()) && qFuzzyCompare(qreal(dom_input.attribute("y").toDouble()), m_converted_text_from_xml_description.value(deti).y())) - { + { + //Once again this 'if', is only for retrocompatibility with old old old project + //when element text with tagg "label" is not null, but the element information "label" is. + if((deti->textFrom() == DynamicElementTextItem::ElementInfo) && (deti->infoName() == "label")) + m_element_informations.addValue("label", dom_input.attribute("text")); + deti->setText(dom_input.attribute("text")); qreal rotation = deti->rotation(); @@ -605,6 +610,11 @@ bool Element::fromXml(QDomElement &e, QHash &table_id_adr, bool { dc.addValue("formula", dc["label"]); } + //retrocompatibility with older version + if(dc.value("label").toString().isEmpty() && + !m_element_informations.value("label").toString().isEmpty()) + dc.addValue("label", m_element_informations.value("label")); + setElementInformations(dc); /** @@ -648,54 +658,112 @@ bool Element::fromXml(QDomElement &e, QHash &table_id_adr, bool bool la = m_element_informations.keyMustShow("label"); bool c = m_element_informations.keyMustShow("comment"); bool lo = m_element_informations.keyMustShow("location"); - if(!label.isEmpty() && la && - ((!comment.isEmpty() && c) || (!location.isEmpty() && lo))) + + if((m_link_type != Master) || + ((m_link_type == Master) && + (diagram()->project()->defaultXRefProperties(m_kind_informations["type"].toString()).snapTo() == XRefProperties::Label)) + ) { - //#2 in the converted list one text must have text from = element info and info name = label - for(DynamicElementTextItem *deti : successfully_converted) + if(!label.isEmpty() && la && + ((!comment.isEmpty() && c) || (!location.isEmpty() && lo))) { - if(deti->textFrom() == DynamicElementTextItem::ElementInfo && deti->infoName() == "label") + //#2 in the converted list one text must have text from = element info and info name = label + for(DynamicElementTextItem *deti : successfully_converted) { - //Create the comment item - DynamicElementTextItem *comment_text = nullptr; - if(!comment.isEmpty() && c) + if(deti->textFrom() == DynamicElementTextItem::ElementInfo && deti->infoName() == "label") { - comment_text = new DynamicElementTextItem(this); - comment_text->setTextFrom(DynamicElementTextItem::ElementInfo); - comment_text->setInfoName("comment"); - comment_text->setFontSize(6); - comment_text->setFrame(true); - comment_text->setTextWidth(70); - comment_text->setPos(deti->x(), deti->y()+10); //+10 is arbitrary, comment_text must be below deti - addDynamicTextItem(comment_text); + qreal rotation = deti->rotation(); + + //Create the comment item + DynamicElementTextItem *comment_text = nullptr; + if(!comment.isEmpty() && c) + { + comment_text = new DynamicElementTextItem(this); + comment_text->setTextFrom(DynamicElementTextItem::ElementInfo); + comment_text->setInfoName("comment"); + comment_text->setFontSize(6); + comment_text->setFrame(true); + if(comment_text->toPlainText().count() > 17) + comment_text->setTextWidth(80); + comment_text->setPos(deti->x(), deti->y()+10); //+10 is arbitrary, comment_text must be below deti + addDynamicTextItem(comment_text); + } + //create the location item + DynamicElementTextItem *location_text = nullptr; + if(!location.isEmpty() && lo) + { + location_text = new DynamicElementTextItem(this); + location_text->setTextFrom(DynamicElementTextItem::ElementInfo); + location_text->setInfoName("location"); + location_text->setFontSize(6); + if(comment_text->toPlainText().count() > 17) + location_text->setTextWidth(80); + location_text->setPos(deti->x(), deti->y()+20); //+20 is arbitrary, location_text must be below deti and comment + addDynamicTextItem(location_text); + } + + QPointF pos = deti->pos(); + //Create the group + ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire")); + addTextToGroup(deti, group); + if(comment_text) + addTextToGroup(comment_text, group); + if(location_text) + addTextToGroup(location_text, group); + group->setAlignment(Qt::AlignVCenter); + group->setVerticalAdjustment(-4); + group->setRotation(rotation); + //Change the position of the group, so that the text "label" stay in the same + //position in scene coordinate + group->setPos(pos - deti->pos()); + + break; } - //create the location item - DynamicElementTextItem *location_text = nullptr; - if(!location.isEmpty() && lo) - { - location_text = new DynamicElementTextItem(this); - location_text->setTextFrom(DynamicElementTextItem::ElementInfo); - location_text->setInfoName("location"); - location_text->setFontSize(6); - location_text->setTextWidth(70); - location_text->setPos(deti->x(), deti->y()+20); //+20 is arbitrary, location_text must be below deti and comment - addDynamicTextItem(location_text); - } - - //Create the group - ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire")); - addTextToGroup(deti, group); - if(comment_text) - addTextToGroup(comment_text, group); - if(location_text) - addTextToGroup(location_text, group); - group->setAlignment(Qt::AlignVCenter); - group->setVerticalAdjustment(-4); - - break; } } } + else + { + //This element is supposed to be a master and Xref property snap to bottom + if((!comment.isEmpty() && c) || (!location.isEmpty() && lo)) + { + //Create the comment item + DynamicElementTextItem *comment_text = nullptr; + if(!comment.isEmpty() && c) + { + comment_text = new DynamicElementTextItem(this); + comment_text->setTextFrom(DynamicElementTextItem::ElementInfo); + comment_text->setInfoName("comment"); + comment_text->setFontSize(6); + comment_text->setFrame(true); + comment_text->setTextWidth(80); + addDynamicTextItem(comment_text); + } + //create the location item + DynamicElementTextItem *location_text = nullptr; + if(!location.isEmpty() && lo) + { + location_text = new DynamicElementTextItem(this); + location_text->setTextFrom(DynamicElementTextItem::ElementInfo); + location_text->setInfoName("location"); + location_text->setFontSize(6); + location_text->setTextWidth(80); + if(comment_text) + location_text->setPos(comment_text->x(), comment_text->y()+10); //+10 is arbitrary, location_text must be below the comment + addDynamicTextItem(location_text); + } + + //Create the group + ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire")); + if(comment_text) + addTextToGroup(comment_text, group); + if(location_text) + addTextToGroup(location_text, group); + group->setAlignment(Qt::AlignVCenter); + group->setVerticalAdjustment(-4); + group->setHoldToBottomPage(true); + } + } } return(true); @@ -794,6 +862,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash &table //Dynamic texts owned by groups for(ElementTextItemGroup *group : m_texts_group) { + group->blockAlignmentUpdate(true); //temporarily remove the texts from group to get the pos relative to element and not group. //Set the alignment to top, because top is not used by groupand so, //each time a text is removed from the group, the alignement is not updated @@ -818,6 +887,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash &table //Save the group to xml texts_group.appendChild(group->toXml(document)); + group->blockAlignmentUpdate(false); } //Append the dynamic texts to element diff --git a/sources/qetgraphicsitem/elementtextitemgroup.cpp b/sources/qetgraphicsitem/elementtextitemgroup.cpp index db70d73b9..b8f944e36 100644 --- a/sources/qetgraphicsitem/elementtextitemgroup.cpp +++ b/sources/qetgraphicsitem/elementtextitemgroup.cpp @@ -23,6 +23,8 @@ #include "QPropertyUndoCommand/qpropertyundocommand.h" #include "crossrefitem.h" #include "qetapp.h" +#include "masterelement.h" +#include "qgraphicsitemutility.h" #include #include @@ -56,18 +58,13 @@ void ElementTextItemGroup::addToGroup(QGraphicsItem *item) { if(item->type() == DynamicElementTextItem::Type) { - //Befor add text to group we must to set the text and the group to the same rotation - item->setRotation(0); - item->setFlag(QGraphicsItem::ItemIsSelectable, false); - - qreal rot = this->rotation(); - this->setRotation(0); + //Befor add text to this group we must to set the text at the same rotation of this group + if((item->rotation() != rotation()) && !m_block_alignment_update) + item->setRotation(rotation()); QGraphicsItemGroup::addToGroup(item); updateAlignment(); - this->setRotation(rot); - DynamicElementTextItem *deti = qgraphicsitem_cast(item); connect(deti, &DynamicElementTextItem::fontSizeChanged, this, &ElementTextItemGroup::updateAlignment); connect(deti, &DynamicElementTextItem::textChanged, this, &ElementTextItemGroup::updateAlignment); @@ -115,6 +112,17 @@ void ElementTextItemGroup::removeFromGroup(QGraphicsItem *item) } } +/** + * @brief ElementTextItemGroup::blockAlignmentUpdate + * If true, the texts in this group are never aligned, moved, rotated etc... + * the texts stay as it was, until blockAlignmentUpdate is set to false. + * @param block + */ +void ElementTextItemGroup::blockAlignmentUpdate(bool block) +{ + m_block_alignment_update = block; +} + /** * @brief ElementTextItemGroup::setAlignement * Set the alignement of this group @@ -140,13 +148,42 @@ Qt::Alignment ElementTextItemGroup::alignment() const */ void ElementTextItemGroup::updateAlignment() { + if(m_block_alignment_update) + return; + prepareGeometryChange(); QList texts = this->texts(); - if (texts.size() > 1) + qreal rotation_ = rotation(); + + //Set the rotation of this group to 0° relative to the scene + qreal rot = rotation(); + QGraphicsItem *parent = parentItem(); + while (parent) { + rot += parent->rotation(); + parent = parent->parentItem(); + } + if(rot != 0) + setRotation(rotation() - rot); + + + if(texts.size() == 1) { prepareGeometryChange(); + + QGraphicsItem *first = texts.first(); + setPos(mapFromScene(first->mapToScene(pos()))); + first->setPos(0,0); + } + else if (texts.size() > 1) + { + qreal width = 0; + for(QGraphicsItem *item : texts) + if(item->boundingRect().width() > width) + width = item->boundingRect().width(); + + prepareGeometryChange(); std::sort(texts.begin(), texts.end(), sorting); qreal y_offset = 0; @@ -157,14 +194,13 @@ void ElementTextItemGroup::updateAlignment() for(QGraphicsItem *item : texts) { - item->setPos(ref.x(), ref.y()+y_offset); + item->setPos(0, ref.y()+y_offset); y_offset+=item->boundingRect().height() + m_vertical_adjustment; } } else if(m_alignment == Qt::AlignVCenter) { - QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width()/2, - texts.first()->pos().y()); + QPointF ref(width/2,0); for(QGraphicsItem *item : texts) { @@ -175,8 +211,7 @@ void ElementTextItemGroup::updateAlignment() } else if (m_alignment == Qt::AlignRight) { - QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width(), - texts.first()->pos().y()); + QPointF ref(width,0); for(QGraphicsItem *item : texts) { @@ -185,14 +220,17 @@ void ElementTextItemGroup::updateAlignment() y_offset+=item->boundingRect().height() + m_vertical_adjustment; } } - - setTransformOriginPoint(boundingRect().topLeft()); } + //Restor the rotation + setRotation(rotation_); + if(m_Xref_item) m_Xref_item->autoPos(); if(m_slave_Xref_item) adjustSlaveXrefPos(); + if(m_hold_to_bottom_of_page) + autoPos(); } /** @@ -219,6 +257,47 @@ void ElementTextItemGroup::setName(QString name) emit nameChanged(m_name); } +void ElementTextItemGroup::setHoldToBottomPage(bool hold) +{ + if(m_hold_to_bottom_of_page == hold) + return; + + m_hold_to_bottom_of_page = hold; + if(m_hold_to_bottom_of_page) + { + setFlag(QGraphicsItem::ItemIsSelectable, false); + setFlag(QGraphicsItem::ItemIsMovable, false); + connect(m_parent_element, &Element::yChanged, this, &ElementTextItemGroup::autoPos); + connect(m_parent_element, &Element::rotationChanged, this, &ElementTextItemGroup::autoPos); + if(m_parent_element->linkType() == Element::Master) + { + //We use timer to let the time of the parent element xref to be updated, befor update the position of this group + //because the position of this group is related to the size of the parent element Xref + m_linked_changed_timer = connect(m_parent_element, &Element::linkedElementChanged, + [this]() {QTimer::singleShot(200, this, &ElementTextItemGroup::autoPos);}); + if(m_parent_element->diagram()) + m_XrefChanged_timer = connect(m_parent_element->diagram()->project(), &QETProject::XRefPropertiesChanged, + [this]() {QTimer::singleShot(200, this, &ElementTextItemGroup::autoPos);}); + } + autoPos(); + } + else + { + setFlag(QGraphicsItem::ItemIsSelectable, true); + setFlag(QGraphicsItem::ItemIsMovable, true); + disconnect(m_parent_element, &Element::yChanged, this, &ElementTextItemGroup::autoPos); + disconnect(m_parent_element, &Element::rotationChanged, this, &ElementTextItemGroup::autoPos); + if(m_parent_element->linkType() == Element::Master) + { + disconnect(m_linked_changed_timer); + if(m_XrefChanged_timer) + disconnect(m_XrefChanged_timer); + } + } + + emit holdToBottomPageChanged(hold); +} + /** * @brief ElementTextItemGroup::texts * @return Every texts in this group @@ -268,6 +347,9 @@ QDomElement ElementTextItemGroup::toXml(QDomDocument &dom_document) const { QDomElement dom_element = dom_document.createElement(this->xmlTaggName()); dom_element.setAttribute("name", m_name); + + dom_element.setAttribute("x", QString::number(pos().x())); + dom_element.setAttribute("y", QString::number(pos().y())); QMetaEnum me = QMetaEnum::fromType(); dom_element.setAttribute("alignment", me.valueToKey(m_alignment)); @@ -275,6 +357,8 @@ QDomElement ElementTextItemGroup::toXml(QDomDocument &dom_document) const dom_element.setAttribute("rotation", this->rotation()); dom_element.setAttribute("vertical_adjustment", m_vertical_adjustment); + dom_element.setAttribute("hold_to_bottom_page", m_hold_to_bottom_of_page == true ? "true" : "false"); + QDomElement dom_texts = dom_document.createElement("texts"); for(DynamicElementTextItem *deti : texts()) { @@ -303,11 +387,18 @@ void ElementTextItemGroup::fromXml(QDomElement &dom_element) QMetaEnum me = QMetaEnum::fromType(); setAlignment(Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data()))); + setPos(dom_element.attribute("x", QString::number(0)).toDouble(), + dom_element.attribute("y", QString::number(0)).toDouble()); + setRotation(dom_element.attribute("rotation", QString::number(0)).toDouble()); setVerticalAdjustment(dom_element.attribute("vertical_adjustment").toInt()); + QString hold = dom_element.attribute("hold_to_bottom_page", "false"); + setHoldToBottomPage(hold == "true" ? true : false); + if(parentElement()) { + m_block_alignment_update = true; for(QDomElement text : QET::findInDomElement(dom_element, "texts", "text")) { DynamicElementTextItem *deti = nullptr; @@ -320,6 +411,7 @@ void ElementTextItemGroup::fromXml(QDomElement &dom_element) if (deti) parentElement()->addTextToGroup(deti, this); } + m_block_alignment_update = false; } } @@ -342,6 +434,7 @@ void ElementTextItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsIt t.setCosmetic(true); painter->setPen(t); painter->drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10); + painter->restore(); } } @@ -367,7 +460,7 @@ QRectF ElementTextItemGroup::boundingRect() const } void ElementTextItemGroup::setRotation(qreal angle) -{ +{ QGraphicsItemGroup::setRotation(angle); emit rotationChanged(angle); } @@ -614,3 +707,31 @@ void ElementTextItemGroup::adjustSlaveXrefPos() m_slave_Xref_item->setPos(pos); } +void ElementTextItemGroup::autoPos() +{ + int offset = 5; + + if(m_parent_element->linkType() == Element::Master) + { + if(!diagram()) + return; + + MasterElement *master = static_cast(m_parent_element); + XRefProperties xrp = diagram()->project()->defaultXRefProperties(master->kindInformations()["type"].toString()); + if(xrp.snapTo() == XRefProperties::Bottom) + { + QRectF rectXref = master->XrefBoundingRect(); + offset = xrp.offset() <= 40 ? 5 : xrp.offset(); + + offset += (int)rectXref.height(); + } + } + qreal r = rotation(); + centerToBottomDiagram(this, m_parent_element, offset); + //centerToBottomDiagram change the rotation of this group if needed, + //but setRotation is not a virtual function of QGraphicsItem, and the function centerToBottomDiagram + //work with a QGraphicsItem. So we emit the signal if rotation changed + if(rotation() != r) + emit rotationChanged(rotation()); +} + diff --git a/sources/qetgraphicsitem/elementtextitemgroup.h b/sources/qetgraphicsitem/elementtextitemgroup.h index 90903b58b..7da979005 100644 --- a/sources/qetgraphicsitem/elementtextitemgroup.h +++ b/sources/qetgraphicsitem/elementtextitemgroup.h @@ -1,4 +1,4 @@ -/* +/* Copyright 2006-2017 The QElectroTech Team This file is part of QElectroTech. @@ -41,6 +41,7 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup Q_PROPERTY(int verticalAdjustment READ verticalAdjustment WRITE setVerticalAdjustment NOTIFY verticalAdjustmentChanged) Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(bool holdToBottomPage READ holdToBottomPage WRITE setHoldToBottomPage NOTIFY holdToBottomPageChanged) public: signals: @@ -48,12 +49,14 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup void verticalAdjustmentChanged(int); void alignmentChanged(Qt::Alignment); void nameChanged(QString); + void holdToBottomPageChanged(bool); public: ElementTextItemGroup(const QString &name, Element *parent); ~ElementTextItemGroup() override; void addToGroup(QGraphicsItem *item); void removeFromGroup(QGraphicsItem *item); + void blockAlignmentUpdate(bool block); void setAlignment(Qt::Alignment alignement); Qt::Alignment alignment() const; @@ -62,6 +65,8 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup void setVerticalAdjustment(int v); void setName(QString name); QString name() const {return m_name;} + void setHoldToBottomPage(bool hold); + bool holdToBottomPage() const {return m_hold_to_bottom_of_page;} QList texts() const; Diagram *diagram() const; Element *parentElement() const; @@ -86,17 +91,22 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup private: void updateXref(); void adjustSlaveXrefPos(); + void autoPos(); private: Qt::Alignment m_alignment = Qt::AlignJustify; QString m_name; - bool m_first_move = true; + bool m_first_move = true, + m_hold_to_bottom_of_page = false, + m_block_alignment_update = false; QPointF m_initial_position; int m_vertical_adjustment = 0; CrossRefItem *m_Xref_item = nullptr; Element *m_parent_element = nullptr; QList m_update_slave_Xref_connection; QGraphicsTextItem *m_slave_Xref_item = nullptr; + QMetaObject::Connection m_XrefChanged_timer, + m_linked_changed_timer; }; #endif // ELEMENTTEXTITEMGROUP_H diff --git a/sources/qetgraphicsitem/qgraphicsitemutility.cpp b/sources/qetgraphicsitem/qgraphicsitemutility.cpp index 81443b98b..5f559993c 100644 --- a/sources/qetgraphicsitem/qgraphicsitemutility.cpp +++ b/sources/qetgraphicsitem/qgraphicsitemutility.cpp @@ -49,28 +49,38 @@ bool centerToParentBottom(QGraphicsItem *item) { * @param offset * @return true if element is centered else false (element_to_follow have not diagram) */ -bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, int offset) { +#include "elementtextitemgroup.h" +#include "crossrefitem.h" +bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset) { if (! element_to_follow -> diagram()) { qDebug() << "qgraphicsitemutility centerAtBottomDiagram : Element_to_follow have not diagram"; return false; } - + QRectF border = element_to_follow -> diagram() -> border_and_titleblock.insideBorderRect(); QPointF point = element_to_follow -> sceneBoundingRect().center(); - + point.setY(border.bottom() - item_to_center -> boundingRect().height() - offset ); - point.rx() -= (item_to_center -> boundingRect().width()/2 + - item_to_center -> boundingRect().left()); //< we add boundingrect.left because this value can be négative - + point.rx() -= (item_to_center -> boundingRect().width()/2); + + //Apply the difference between the pos() of item and his bounding rect + QPointF tl = item_to_center->boundingRect().topLeft(); + point.rx() -= tl.x(); + point.ry() -= tl.y(); + item_to_center -> setPos(0,0); //Due to a weird behavior or bug, before set the new position and rotation, item_to_center -> setRotation(0); //we must to set the position and rotation at 0. - - item_to_center -> setPos(item_to_center -> mapFromScene(point)); - - if (item_to_center -> rotation() != - element_to_follow -> rotation()) { - item_to_center -> setRotation(0); - item_to_center -> setRotation(- element_to_follow -> rotation()); + + item_to_center->setPos(item_to_center->mapFromScene(point)); + + qreal rot = item_to_center->rotation(); + QGraphicsItem *parent = item_to_center->parentItem(); + while (parent) { + rot += parent->rotation(); + parent = parent->parentItem(); } + if(rot != 0) + item_to_center->setRotation(item_to_center->rotation() - rot); return true; } diff --git a/sources/qetgraphicsitem/qgraphicsitemutility.h b/sources/qetgraphicsitem/qgraphicsitemutility.h index 4a1193c12..0e5a6714c 100644 --- a/sources/qetgraphicsitem/qgraphicsitemutility.h +++ b/sources/qetgraphicsitem/qgraphicsitemutility.h @@ -17,11 +17,11 @@ */ #ifndef QGRAPHICSITEMUTILITY_H #define QGRAPHICSITEMUTILITY_H - +#include class QGraphicsItem; class Element; bool centerToParentBottom (QGraphicsItem *item); -bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, int offset = 0 ); +bool centerToBottomDiagram (QGraphicsItem *item_to_center, Element *element_to_follow, qreal offset = 0 ); #endif // QGRAPHICSITEMUTILITY_H diff --git a/sources/ui/dynamicelementtextmodel.cpp b/sources/ui/dynamicelementtextmodel.cpp index a2f94c807..ace432c45 100644 --- a/sources/ui/dynamicelementtextmodel.cpp +++ b/sources/ui/dynamicelementtextmodel.cpp @@ -49,6 +49,7 @@ int rot_txt_row = 10; int align_grp_row = 0; int rot_grp_row = 1; int adjust_grp_row = 2; +int hold_to_bottom_grp_row = 3; DynamicElementTextModel::DynamicElementTextModel(Element *element, QObject *parent) : QStandardItemModel(parent), @@ -544,6 +545,10 @@ QUndoCommand *DynamicElementTextModel::undoForEditedGroup(ElementTextItemGroup * QString name = group_qsi->data(Qt::DisplayRole).toString(); if(group->name() != name) new QPropertyUndoCommand(group, "name", QVariant(group->name()), QVariant(name), undo); + + bool hold_to_bottom = group_qsi->child(hold_to_bottom_grp_row, 1)->checkState() == Qt::Checked? true : false; + if(group->holdToBottomPage() != hold_to_bottom) + new QPropertyUndoCommand(group, "holdToBottomPage", QVariant(group->holdToBottomPage()), QVariant(hold_to_bottom), undo); return undo; @@ -585,7 +590,7 @@ void DynamicElementTextModel::addGroup(ElementTextItemGroup *group) default: break;} QStandardItem *alignment_a = new QStandardItem(text); - alignment_a->setData(DynamicElementTextModel::grp_alignment, Qt::UserRole+1); + alignment_a->setData(DynamicElementTextModel::grpAlignment, Qt::UserRole+1); alignment_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); qsi_list.clear(); qsi_list << alignment << alignment_a; @@ -597,7 +602,7 @@ void DynamicElementTextModel::addGroup(ElementTextItemGroup *group) QStandardItem *rot_a = new QStandardItem; rot_a->setData(group->rotation(), Qt::EditRole); - rot_a->setData(DynamicElementTextModel::grp_rotation, Qt::UserRole+1); + rot_a->setData(DynamicElementTextModel::grpRotation, Qt::UserRole+1); rot_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); qsi_list.clear(); qsi_list << rot << rot_a; @@ -609,12 +614,25 @@ void DynamicElementTextModel::addGroup(ElementTextItemGroup *group) QStandardItem *v_adj_a = new QStandardItem; v_adj_a->setData(group->verticalAdjustment(), Qt::EditRole); - v_adj_a->setData(DynamicElementTextModel::grp_v_adjust, Qt::UserRole+1); + v_adj_a->setData(DynamicElementTextModel::grpVAdjust, Qt::UserRole+1); v_adj_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); qsi_list.clear(); qsi_list << v_adj << v_adj_a; grp->appendRow(qsi_list); + //Hold to the bottom of the page + QStandardItem *hold_bottom = new QStandardItem(tr("Maintenir en bas de page")); + hold_bottom->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + + QStandardItem *hold_bottom_a = new QStandardItem(); + hold_bottom_a->setCheckable(true); + hold_bottom_a->setCheckState(group->holdToBottomPage() ? Qt::Checked : Qt::Unchecked); + hold_bottom_a->setData(DynamicElementTextModel::grpHoldBottom, Qt::UserRole+1); + hold_bottom_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); + qsi_list.clear(); + qsi_list << hold_bottom << hold_bottom_a; + grp->appendRow(qsi_list); + //Add the texts of the group for(DynamicElementTextItem *deti : group->texts()) @@ -623,6 +641,7 @@ void DynamicElementTextModel::addGroup(ElementTextItemGroup *group) group_item->appendRow(itemsForText(deti)); } setConnection(group, true); + enableGroupRotation(group); } /** @@ -990,6 +1009,30 @@ void DynamicElementTextModel::enableSourceText(DynamicElementTextItem *deti, Dyn qsi->child(compo_txt_row,1)->setEnabled(compo); } +/** + * @brief DynamicElementTextModel::enableGroupRotation + * Enable/disable the item "group rotation" according the option hold to bottom + * @param group + */ +void DynamicElementTextModel::enableGroupRotation(ElementTextItemGroup *group) +{ + if(!m_groups_list.contains(group)) + return; + + QStandardItem *qsi = m_groups_list.value(group); + + if(group->holdToBottomPage()) + { + qsi->child(rot_grp_row, 0)->setFlags(Qt::ItemIsSelectable); + qsi->child(rot_grp_row, 1)->setFlags(Qt::ItemIsSelectable); + } + else + { + qsi->child(rot_grp_row, 0)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + qsi->child(rot_grp_row, 1)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + } +} + void DynamicElementTextModel::itemDataChanged(QStandardItem *qsi) { DynamicElementTextItem *deti = textFromItem(qsi); @@ -1107,10 +1150,11 @@ void DynamicElementTextModel::setConnection(ElementTextItemGroup *group, bool se return; QList connection_list; - connection_list << connect(group, &ElementTextItemGroup::alignmentChanged, [group, this]() {this->updateDataFromGroup(group, grp_alignment);}); - connection_list << connect(group, &ElementTextItemGroup::rotationChanged, [group, this]() {this->updateDataFromGroup(group, grp_rotation);}); - connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grp_v_adjust);}); - connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grp_name);}); + connection_list << connect(group, &ElementTextItemGroup::alignmentChanged, [group, this]() {this->updateDataFromGroup(group, grpAlignment);}); + connection_list << connect(group, &ElementTextItemGroup::rotationChanged, [group, this]() {this->updateDataFromGroup(group, grpRotation);}); + connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grpVAdjust);}); + connection_list << connect(group, &ElementTextItemGroup::verticalAdjustmentChanged, [group, this]() {this->updateDataFromGroup(group, grpName);}); + connection_list << connect(group, &ElementTextItemGroup::holdToBottomPageChanged, [group, this]() {this->updateDataFromGroup(group, grpHoldBottom);}); m_hash_group_connect.insert(group, connection_list); } @@ -1219,7 +1263,7 @@ void DynamicElementTextModel::updateDataFromGroup(ElementTextItemGroup *group, D switch (type) { - case grp_alignment: + case grpAlignment: { switch (group->alignment()) { @@ -1230,15 +1274,21 @@ void DynamicElementTextModel::updateDataFromGroup(ElementTextItemGroup *group, D } break; } - case grp_rotation: + case grpRotation: qsi->child(rot_grp_row,1)->setData(group->rotation(), Qt::EditRole); break; - case grp_v_adjust: + case grpVAdjust: qsi->child(adjust_grp_row,1)->setData(group->verticalAdjustment(), Qt::EditRole); break; - case grp_name: + case grpName: qsi->setData(group->name(), Qt::DisplayRole); break; + case grpHoldBottom: + { + qsi->child(hold_to_bottom_grp_row,1)->setCheckState(group->holdToBottomPage()? Qt::Checked : Qt::Unchecked); + enableGroupRotation(group); + break; + } } m_block_dataChanged = false; @@ -1350,7 +1400,7 @@ QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOpti sb->setSuffix(" px"); return sb; } - case DynamicElementTextModel::grp_alignment: + case DynamicElementTextModel::grpAlignment: { QComboBox *qcb = new QComboBox(parent); qcb->setFrame(false); @@ -1360,7 +1410,7 @@ QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOpti qcb->addItem(tr("Droite")); return qcb; } - case DynamicElementTextModel::grp_rotation: + case DynamicElementTextModel::grpRotation: { QSpinBox *sb = new QSpinBox(parent); sb->setObjectName("group_rotation"); @@ -1370,7 +1420,7 @@ QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOpti sb->setSuffix(" °"); return sb; } - case DynamicElementTextModel::grp_v_adjust: + case DynamicElementTextModel::grpVAdjust: { QSpinBox *sb = new QSpinBox(parent); sb->setObjectName("group_v_adjustment"); diff --git a/sources/ui/dynamicelementtextmodel.h b/sources/ui/dynamicelementtextmodel.h index e2805bfea..0e19d08dd 100644 --- a/sources/ui/dynamicelementtextmodel.h +++ b/sources/ui/dynamicelementtextmodel.h @@ -48,10 +48,11 @@ class DynamicElementTextModel : public QStandardItemModel frame, rotation, textWidth, - grp_alignment, - grp_rotation, - grp_v_adjust, - grp_name + grpAlignment, + grpRotation, + grpVAdjust, + grpName, + grpHoldBottom }; DynamicElementTextModel(Element *element, QObject *parent = nullptr); @@ -87,6 +88,7 @@ class DynamicElementTextModel : public QStandardItemModel void addTextToGroup(DynamicElementTextItem *deti, ElementTextItemGroup *group); void removeTextFromGroup(DynamicElementTextItem *deti, ElementTextItemGroup *group); void enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf ); + void enableGroupRotation(ElementTextItemGroup *group); void itemDataChanged(QStandardItem *qsi); void setConnection(DynamicElementTextItem *deti, bool set); void setConnection(ElementTextItemGroup *group, bool set); diff --git a/sources/ui/elementpropertieswidget.cpp b/sources/ui/elementpropertieswidget.cpp index 9ab360a59..a8fcd3c6e 100644 --- a/sources/ui/elementpropertieswidget.cpp +++ b/sources/ui/elementpropertieswidget.cpp @@ -361,9 +361,9 @@ QWidget *ElementPropertiesWidget::generalWidget() description_string += QString(tr("Folio : %1\n")).arg(folio_index + 1); } description_string += QString(tr("Position : %1\n")).arg(m_diagram -> convertPosition(m_element -> scenePos()).toString()); + description_string += QString(tr("Rotation : %1°\n")).arg(m_element.data()->rotation()); description_string += QString(tr("Dimensions : %1*%2\n")).arg(m_element -> size().width()).arg(m_element -> size().height()); description_string += QString(tr("Bornes : %1\n")).arg(m_element -> terminals().count()); - description_string += QString(tr("Champs de texte : %1\n")).arg(m_element -> texts().count()); if (custom_element) { description_string += QString(tr("Emplacement : %1\n")).arg(custom_element -> location().toString());