diff --git a/dev_doc/ID_of_QUndoCommand.txt b/dev_doc/ID_of_QUndoCommand.txt index a0966f646..e13f9d87b 100755 --- a/dev_doc/ID_of_QUndoCommand.txt +++ b/dev_doc/ID_of_QUndoCommand.txt @@ -3,4 +3,5 @@ LinkElementCommand = 2 ItemResizerCommand = 3 ChangeShapeStyleCommand = 4 QetShapeGeometryCommand = 5 +AlignmentTextsGroupCommand = 6 QPropertyUndoCommand = 10 000 diff --git a/sources/elementtextsmover.cpp b/sources/elementtextsmover.cpp index 7316dacd3..861ef989e 100644 --- a/sources/elementtextsmover.cpp +++ b/sources/elementtextsmover.cpp @@ -20,6 +20,8 @@ #include "diagram.h" #include "QPropertyUndoCommand/qpropertyundocommand.h" #include "dynamicelementtextitem.h" +#include "elementtextitemgroup.h" +#include /** * @brief ElementTextsMover::ElementTextsMover @@ -44,26 +46,54 @@ bool ElementTextsMover::isReady() const { */ int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item) { - if (m_movement_running || !diagram) return(-1); + if (m_movement_running || !diagram) + return(-1); m_diagram = diagram; m_movement_driver = driver_item; - m_texts_item_H.clear(); + m_last_pos = driver_item->pos(); + m_items_hash.clear(); + m_text_count = m_group_count =0; +// m_texts_hash.clear(); +// m_grps_hash.clear(); +// for(QGraphicsItem *item : diagram->selectedItems()) +// { +// if (item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type) +// { +// DiagramTextItem *dti = static_cast (item); +// m_texts_hash.insert(dti, dti->pos()); +// } +// } + for(QGraphicsItem *item : diagram->selectedItems()) { - if (item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type) - { - DiagramTextItem *dti = static_cast (item); - m_texts_item_H.insert(dti, dti->pos()); - } + if(item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type) + { + m_items_hash.insert(item, item->pos()); + m_text_count++; + } + else if(item->type() == QGraphicsItemGroup::Type) + { + if(dynamic_cast(item)) + { + m_items_hash.insert(item, item->pos()); + m_group_count++; + } + } } - if (!m_texts_item_H.size()) return(-1); +// if (!m_texts_hash.size()) +// return(-1); + + if(m_items_hash.isEmpty()) + return -1; m_movement_running = true; - return(m_texts_item_H.size()); + return m_items_hash.size(); + +// return(m_texts_hash.size()); } /** @@ -74,15 +104,28 @@ int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_ite */ void ElementTextsMover::continueMovement(const QPointF &movement) { - if (!m_movement_running || movement.isNull()) return; + if (!m_movement_running || movement.isNull()) + return; - for(DiagramTextItem *text_item : m_texts_item_H.keys()) + QPointF move = m_movement_driver->pos() - m_last_pos; + m_last_pos = m_movement_driver->pos(); + + for(QGraphicsItem *qgi : m_items_hash.keys()) { - if (text_item == m_movement_driver) + if(qgi == m_movement_driver) continue; - QPointF applied_movement = text_item->mapMovementToParent(text_item->mapMovementFromScene(movement)); - text_item->setPos(text_item->pos() + applied_movement); + + qgi->setPos(qgi->pos() + move); } + +// for(DiagramTextItem *text_item : m_texts_hash.keys()) +// { +// if (text_item == m_movement_driver) +// continue; + +// QPointF applied_movement = text_item->mapMovementToParent(text_item->mapMovementFromScene(movement)); +// text_item->setPos(text_item->pos() + applied_movement); +// } } /** @@ -91,26 +134,70 @@ void ElementTextsMover::continueMovement(const QPointF &movement) */ void ElementTextsMover::endMovement() { - //No movement running, or no text to move - if (!m_movement_running || m_texts_item_H.isEmpty()) - return; +// //No movement running, or no text to move +// if (!m_movement_running || m_texts_hash.isEmpty()) +// return; +// //Movement is null +// DiagramTextItem *dti = m_texts_hash.keys().first(); +// if (dti->pos() == m_texts_hash.value(dti)) +// return; + +// QUndoCommand *undo = new QUndoCommand(m_texts_hash.size() == 1 ? QString(QObject::tr("Déplacer un texte d'élément")) : +// QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_hash.size()))); + +// for (DiagramTextItem *dti : m_texts_hash.keys()) +// { +// QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_hash.value(dti), dti->pos(), undo); +// child_undo->enableAnimation(); +// } + + //No movement or no items to move + if(!m_movement_running || m_items_hash.isEmpty()) + return; + //Movement is null - DiagramTextItem *dti = m_texts_item_H.keys().first(); - if (dti->pos() == m_texts_item_H.value(dti)) + QGraphicsItem *qgi = m_items_hash.keys().first(); + if(qgi->pos() == m_items_hash.value(qgi)) return; + + QUndoCommand *undo = new QUndoCommand(undoText()); - QUndoCommand *undo = new QUndoCommand(m_texts_item_H.size() == 1 ? QString(QObject::tr("Déplacer un texte d'élément")) : - QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_item_H.size()))); - - for (DiagramTextItem *dti : m_texts_item_H.keys()) + for (QGraphicsItem *qgi : m_items_hash.keys()) { - QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_item_H.value(dti), dti->pos(), undo); - child_undo->enableAnimation(); - + if(QObject *object = dynamic_cast(qgi)) + { + QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(object, "pos", m_items_hash.value(qgi), qgi->pos(), undo); + child_undo->enableAnimation(); + } } m_diagram->undoStack().push(undo); m_movement_running = false; } + +QString ElementTextsMover::undoText() const +{ + QString undo_text; + + if(m_text_count == 1) + undo_text.append(QObject::tr("Déplacer un texte d'élément")); + else if(m_text_count > 1) + undo_text.append(QObject::tr("Déplacer %1 textes d'élément").arg(m_items_hash.size())); + + if(m_group_count >= 1) + { + if(undo_text.isEmpty()) + undo_text.append(QObject::tr("Déplacer")); + else + undo_text.append(QObject::tr(" et")); + + if(m_group_count == 1) + undo_text.append(QObject::tr(" un groupe de texte")); + else + undo_text.append(QObject::tr((" %1 groupes de textes")).arg(m_group_count)); + } + + return undo_text; +} diff --git a/sources/elementtextsmover.h b/sources/elementtextsmover.h index 01621fc21..3b7ac2b2c 100644 --- a/sources/elementtextsmover.h +++ b/sources/elementtextsmover.h @@ -24,6 +24,7 @@ class QGraphicsItem; class DiagramTextItem; class Diagram; +class QGraphicsItemGroup; /** This class manages the interactive movement of element text items on a @@ -41,11 +42,19 @@ class ElementTextsMover int beginMovement(Diagram *diagram, QGraphicsItem *driver_item = nullptr); void continueMovement(const QPointF &); void endMovement(); + + private: + QString undoText() const; private: bool m_movement_running = false; Diagram *m_diagram = nullptr; QGraphicsItem *m_movement_driver = nullptr; - QHash m_texts_item_H; + QHash m_texts_hash; + QHash m_grps_hash; + QHash m_items_hash; + QPointF m_last_pos; + int m_text_count = 0, + m_group_count = 0; }; #endif diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index 0559ca463..42aa02d3b 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -727,7 +727,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash &table //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 Qt::Alignment al = group->alignment(); - group->setAlignement(Qt::AlignTop); + group->setAlignment(Qt::AlignTop); //Remove the texts from group QList deti_list = group->texts(); @@ -743,7 +743,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash &table group->addToGroup(deti); //Restor the alignement - group->setAlignement(al); + group->setAlignment(al); //Save the group to xml texts_group.appendChild(group->toXml(document)); @@ -759,7 +759,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash &table /** * @brief Element::addDynamiqueTextItem - * Add @deti as a dynamic text item of this element + * Add @deti as a dynamic text item of this element, @deti is reparented to this * If @deti is null, a new DynamicElementTextItem is created and added to this element. * @param deti */ @@ -768,6 +768,7 @@ void Element::addDynamicTextItem(DynamicElementTextItem *deti) if (deti && !m_dynamic_text_list.contains(deti)) { m_dynamic_text_list.append(deti); + deti->setParentItem(this); emit textAdded(deti); } else @@ -780,9 +781,8 @@ void Element::addDynamicTextItem(DynamicElementTextItem *deti) /** * @brief Element::removeDynamicTextItem - * Remove @deti, no matter if is a child of this element or - * a child of a group of this element. - * The parent item of deti stay this item and deti is not deleted. + * Remove @deti, no matter if is a child of this element or a child of a group of this element. + * Set he parent item of @deti to 0, @deti is not deleted. * @param deti */ void Element::removeDynamicTextItem(DynamicElementTextItem *deti) @@ -790,6 +790,7 @@ void Element::removeDynamicTextItem(DynamicElementTextItem *deti) if (m_dynamic_text_list.contains(deti)) { m_dynamic_text_list.removeOne(deti); + deti->setParentItem(nullptr); emit textRemoved(deti); return; } @@ -800,6 +801,7 @@ void Element::removeDynamicTextItem(DynamicElementTextItem *deti) { removeTextFromGroup(deti, group); m_dynamic_text_list.removeOne(deti); + deti->setParentItem(nullptr); emit textRemoved(deti); return; } @@ -848,10 +850,26 @@ ElementTextItemGroup *Element::addTextGroup(const QString &name) return group; } +/** + * @brief Element::addTextGroup + * @param group add group @group to the group of this element. + * the group must not be owned by an element. + */ +void Element::addTextGroup(ElementTextItemGroup *group) +{ + if(group->parentElement()) + return; + + m_texts_group << group; + group->setParentItem(this); + emit textsGroupAdded(group); +} + /** * @brief Element::removeTextGroup - * Remove the text group with name @name - * All text owned by the group will be reparented to this element + * Remove the text group @group from this element, and set the parent of group to 0. + * group is not deleted. + * All texts owned by the group will be reparented to this element * @param name */ void Element::removeTextGroup(ElementTextItemGroup *group) @@ -870,9 +888,10 @@ void Element::removeTextGroup(ElementTextItemGroup *group) } } - m_texts_group.removeOne(group); + emit textsGroupAboutToBeRemoved(group); - delete group; + m_texts_group.removeOne(group); + group->setParentItem(nullptr); } /** @@ -912,10 +931,13 @@ bool Element::addTextToGroup(DynamicElementTextItem *text, ElementTextItemGroup return false; if(!m_texts_group.contains(group)) return false; + + m_dynamic_text_list.removeOne(text); + emit textRemoved(text); - removeDynamicTextItem(text); group->addToGroup(text); emit textAddedToGroup(text, group); + return true; } @@ -929,7 +951,7 @@ bool Element::removeTextFromGroup(DynamicElementTextItem *text, ElementTextItemG if(!m_texts_group.contains(group)) return false; - if(group->childItems().contains(text)) + if(group->texts().contains(text)) { group->removeFromGroup(text); emit textRemovedFromGroup(text, group); diff --git a/sources/qetgraphicsitem/element.h b/sources/qetgraphicsitem/element.h index 251a76821..ca0850c91 100644 --- a/sources/qetgraphicsitem/element.h +++ b/sources/qetgraphicsitem/element.h @@ -209,6 +209,7 @@ class Element : public QetGraphicsItem void removeDynamicTextItem(DynamicElementTextItem *deti); QList dynamicTextItems() const; ElementTextItemGroup *addTextGroup(const QString &name); + void addTextGroup(ElementTextItemGroup *group); void removeTextGroup(ElementTextItemGroup *group); ElementTextItemGroup *textGroup(const QString &name) const; QList textGroups() const; diff --git a/sources/qetgraphicsitem/elementtextitemgroup.cpp b/sources/qetgraphicsitem/elementtextitemgroup.cpp index 071ad809e..9b1912dba 100644 --- a/sources/qetgraphicsitem/elementtextitemgroup.cpp +++ b/sources/qetgraphicsitem/elementtextitemgroup.cpp @@ -19,6 +19,7 @@ #include "dynamicelementtextitem.h" #include "element.h" #include "diagram.h" +#include "addelementtextcommand.h" #include #include @@ -34,8 +35,7 @@ bool sorting(QGraphicsItem *qgia, QGraphicsItem *qgib) */ ElementTextItemGroup::ElementTextItemGroup(const QString &name, Element *parent) : QGraphicsItemGroup(parent), - m_name(name), - m_element(parent) + m_name(name) { setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable); } @@ -53,14 +53,14 @@ void ElementTextItemGroup::addToGroup(QGraphicsItem *item) { item->setFlag(QGraphicsItem::ItemIsSelectable, false); QGraphicsItemGroup::addToGroup(item); - updateAlignement(); + updateAlignment(); DynamicElementTextItem *deti = qgraphicsitem_cast(item); - connect(deti, &DynamicElementTextItem::fontSizeChanged, this, &ElementTextItemGroup::updateAlignement); - connect(deti, &DynamicElementTextItem::textChanged, this, &ElementTextItemGroup::updateAlignement); - connect(deti, &DynamicElementTextItem::textFromChanged, this, &ElementTextItemGroup::updateAlignement); - connect(deti, &DynamicElementTextItem::infoNameChanged, this, &ElementTextItemGroup::updateAlignement); - connect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignement); + connect(deti, &DynamicElementTextItem::fontSizeChanged, this, &ElementTextItemGroup::updateAlignment); + connect(deti, &DynamicElementTextItem::textChanged, this, &ElementTextItemGroup::updateAlignment); + connect(deti, &DynamicElementTextItem::textFromChanged, this, &ElementTextItemGroup::updateAlignment); + connect(deti, &DynamicElementTextItem::infoNameChanged, this, &ElementTextItemGroup::updateAlignment); + connect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignment); } } @@ -72,15 +72,15 @@ void ElementTextItemGroup::removeFromGroup(QGraphicsItem *item) { QGraphicsItemGroup::removeFromGroup(item); item->setFlag(QGraphicsItem::ItemIsSelectable, true); - updateAlignement(); + updateAlignment(); if(DynamicElementTextItem *deti = qgraphicsitem_cast(item)) { - disconnect(deti, &DynamicElementTextItem::fontSizeChanged, this, &ElementTextItemGroup::updateAlignement); - disconnect(deti, &DynamicElementTextItem::textChanged, this, &ElementTextItemGroup::updateAlignement); - disconnect(deti, &DynamicElementTextItem::textFromChanged, this, &ElementTextItemGroup::updateAlignement); - disconnect(deti, &DynamicElementTextItem::infoNameChanged, this, &ElementTextItemGroup::updateAlignement); - disconnect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignement); + disconnect(deti, &DynamicElementTextItem::fontSizeChanged, this, &ElementTextItemGroup::updateAlignment); + disconnect(deti, &DynamicElementTextItem::textChanged, this, &ElementTextItemGroup::updateAlignment); + disconnect(deti, &DynamicElementTextItem::textFromChanged, this, &ElementTextItemGroup::updateAlignment); + disconnect(deti, &DynamicElementTextItem::infoNameChanged, this, &ElementTextItemGroup::updateAlignment); + disconnect(deti, &DynamicElementTextItem::compositeTextChanged, this, &ElementTextItemGroup::updateAlignment); } } @@ -89,25 +89,27 @@ void ElementTextItemGroup::removeFromGroup(QGraphicsItem *item) * Set the alignement of this group * @param alignement */ -void ElementTextItemGroup::setAlignement(Qt::Alignment alignement) +void ElementTextItemGroup::setAlignment(Qt::Alignment alignement) { - m_alignement = alignement; - updateAlignement(); + m_alignment = alignement; + updateAlignment(); } Qt::Alignment ElementTextItemGroup::alignment() const { - return m_alignement; + return m_alignment; } /** - * @brief ElementTextItemGroup::setAlignement + * @brief ElementTextItemGroup::setAlignment * Update the alignement of the items in this group, according * to the current alignement. * @param alignement */ -void ElementTextItemGroup::updateAlignement() +void ElementTextItemGroup::updateAlignment() { + prepareGeometryChange(); + QList texts = childItems(); if (texts.size() > 1) { @@ -116,7 +118,7 @@ void ElementTextItemGroup::updateAlignement() qreal y_offset =0; - if(m_alignement == Qt::AlignLeft) + if(m_alignment == Qt::AlignLeft) { QPointF ref = texts.first()->pos(); @@ -127,7 +129,7 @@ void ElementTextItemGroup::updateAlignement() } return; } - else if(m_alignement == Qt::AlignVCenter) + else if(m_alignment == Qt::AlignVCenter) { QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width()/2, texts.first()->pos().y()); @@ -141,7 +143,7 @@ void ElementTextItemGroup::updateAlignement() return; } - else if (m_alignement == Qt::AlignRight) + else if (m_alignment == Qt::AlignRight) { QPointF ref(texts.first()->pos().x() + texts.first()->boundingRect().width(), texts.first()->pos().y()); @@ -193,6 +195,18 @@ Diagram *ElementTextItemGroup::diagram() const return nullptr; } +/** + * @brief ElementTextItemGroup::parentElement + * @return The parent element of this group or nullptr + */ +Element *ElementTextItemGroup::parentElement() const +{ + if(parentItem() && parentItem()->type() == Element::Type) + return static_cast(parentItem()); + else + return nullptr; +} + /** * @brief ElementTextItemGroup::toXml * Export data of this group to xml @@ -205,7 +219,7 @@ QDomElement ElementTextItemGroup::toXml(QDomDocument &dom_document) const dom_element.setAttribute("name", m_name); QMetaEnum me = QMetaEnum::fromType(); - dom_element.setAttribute("alignment", me.valueToKey(m_alignement)); + dom_element.setAttribute("alignment", me.valueToKey(m_alignment)); QDomElement dom_texts = dom_document.createElement("texts"); for(DynamicElementTextItem *deti : texts()) @@ -233,19 +247,22 @@ void ElementTextItemGroup::fromXml(QDomElement &dom_element) m_name = dom_element.attribute("name", "no name"); QMetaEnum me = QMetaEnum::fromType(); - m_alignement = Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data())); + m_alignment = Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data())); - for(QDomElement text : QET::findInDomElement(dom_element, "texts", "text")) + if(parentElement()) { - DynamicElementTextItem *deti = nullptr; - QUuid uuid(text.attribute("uuid")); - - for(DynamicElementTextItem *txt : m_element->dynamicTextItems()) - if(txt->uuid() == uuid) - deti = txt; - - if (deti) - m_element->addTextToGroup(deti, this); + for(QDomElement text : QET::findInDomElement(dom_element, "texts", "text")) + { + DynamicElementTextItem *deti = nullptr; + QUuid uuid(text.attribute("uuid")); + + for(DynamicElementTextItem *txt : parentElement()->dynamicTextItems()) + if(txt->uuid() == uuid) + deti = txt; + + if (deti) + parentElement()->addTextToGroup(deti, this); + } } } @@ -321,7 +338,11 @@ void ElementTextItemGroup::mouseMoveEvent(QGraphicsSceneMouseEvent *event) QPointF old_pos = pos(); if(m_first_move) + { m_mouse_to_origin_movement = old_pos - event->buttonDownScenePos(Qt::LeftButton); + if(parentElement()) + parentElement()->setHighlighted(true); + } QPointF expected_pos = event->scenePos() + m_mouse_to_origin_movement; setPos(Diagram::snapToGrid(expected_pos)); @@ -344,7 +365,11 @@ void ElementTextItemGroup::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void ElementTextItemGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if(diagram()) + { diagram()->endMoveElementTexts(); + if(parentElement()) + parentElement()->setHighlighted(false); + } if(!(event->modifiers() & Qt::ControlModifier)) QGraphicsItemGroup::mouseReleaseEvent(event); @@ -355,13 +380,27 @@ void ElementTextItemGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) * @param event */ void ElementTextItemGroup::keyPressEvent(QKeyEvent *event) -{ - prepareGeometryChange(); - if(event->key() == Qt::Key_A) - setAlignement(Qt::AlignLeft); - else if (event->key() == Qt::Key_Z) - setAlignement(Qt::AlignVCenter); - else if (event->key() == Qt::Key_E) - setAlignement(Qt::AlignRight); +{ + if(event->key() == Qt::Key_A && m_alignment != Qt::AlignLeft) + { + if(diagram()) + diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignLeft)); + else + setAlignment(Qt::AlignLeft); + } + else if (event->key() == Qt::Key_Z && m_alignment != Qt::AlignVCenter) + { + if(diagram()) + diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignVCenter)); + else + setAlignment(Qt::AlignVCenter); + } + else if (event->key() == Qt::Key_E && m_alignment != Qt::AlignRight) + { + if(diagram()) + diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignRight)); + else + setAlignment(Qt::AlignRight); + } } diff --git a/sources/qetgraphicsitem/elementtextitemgroup.h b/sources/qetgraphicsitem/elementtextitemgroup.h index 478d23c1d..8d8167840 100644 --- a/sources/qetgraphicsitem/elementtextitemgroup.h +++ b/sources/qetgraphicsitem/elementtextitemgroup.h @@ -35,19 +35,22 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup { Q_OBJECT + Q_PROPERTY(QPointF pos READ pos WRITE setPos) + public: ElementTextItemGroup(const QString &name, Element *parent); ~ElementTextItemGroup() override; void addToGroup(QGraphicsItem *item); void removeFromGroup(QGraphicsItem *item); - void setAlignement(Qt::Alignment alignement); + void setAlignment(Qt::Alignment alignement); Qt::Alignment alignment() const; - void updateAlignement(); + void updateAlignment(); void setName(QString name); QString name() const {return m_name;} QList texts() const; Diagram *diagram() const; + Element *parentElement() const; QDomElement toXml(QDomDocument &dom_document) const; void fromXml(QDomElement &dom_element); @@ -63,11 +66,10 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup void keyPressEvent(QKeyEvent *event) override; private: - Qt::Alignment m_alignement = Qt::AlignJustify; + Qt::Alignment m_alignment = Qt::AlignJustify; QString m_name; bool m_first_move = true; QPointF m_mouse_to_origin_movement; - Element *m_element = nullptr; }; #endif // ELEMENTTEXTITEMGROUP_H diff --git a/sources/undocommand/addelementtextcommand.cpp b/sources/undocommand/addelementtextcommand.cpp index acbf972ae..b0034fecb 100644 --- a/sources/undocommand/addelementtextcommand.cpp +++ b/sources/undocommand/addelementtextcommand.cpp @@ -18,8 +18,15 @@ #include "addelementtextcommand.h" #include "element.h" #include "dynamicelementtextitem.h" +#include "elementtextitemgroup.h" + #include + +/************************ + * AddElementTextCommand* + * **********************/ + AddElementTextCommand::AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent): QUndoCommand(parent), m_element(element), @@ -40,7 +47,6 @@ AddElementTextCommand::~AddElementTextCommand() void AddElementTextCommand::undo() { m_element->removeDynamicTextItem(m_text); - m_text->setParentItem(nullptr); if(m_text->scene()) m_text->scene()->removeItem(m_text); } @@ -51,36 +57,253 @@ void AddElementTextCommand::redo() m_element->addDynamicTextItem(m_text); } -//RemoveElementTextCommand::RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent) : -// QUndoCommand(parent), -// m_text(deti) -//{ -// setText(QObject::tr("Supprimer un texte d'élément")); -// m_element = deti->ParentElement(); -//} -//RemoveElementTextCommand::~RemoveElementTextCommand() -//{ -// if(m_element && !m_element->dynamicTextItems().contains(m_text)) -// delete m_text; -//} +/*********************** + * AddTextsGroupCommand* + * *********************/ +/** + * @brief AddTextsGroupCommand::AddTextsGroupCommand + * @param element : the element to add a new group + * @param groupe_name : the name of the group + * @param parent : parent undo + */ +AddTextsGroupCommand::AddTextsGroupCommand(Element *element, QString groupe_name, QUndoCommand *parent) : + QUndoCommand(parent), + m_element(element), + m_name(groupe_name) +{ + setText(QObject::tr("Ajouter un groupe de textes d'élément")); +} -//void RemoveElementTextCommand::undo() -//{ -// if(m_element) -// { -// m_text->setParentItem(m_element); -// m_element->addDynamicTextItem(m_text); -// } -//} +/** + * @brief AddTextsGroupCommand::~AddTextsGroupCommand + * Destructor + */ +AddTextsGroupCommand::~AddTextsGroupCommand() +{} -//void RemoveElementTextCommand::redo() -//{ -// if(m_element && m_text->scene()) -// { - -// m_element->removeDynamicTextItem(m_text); -// m_text->setParentItem(nullptr); -// m_text->scene()->removeItem(m_text); -// } -//} +void AddTextsGroupCommand::undo() +{ + if(m_element && m_group) + m_element.data()->removeTextGroup(m_group); +} + +void AddTextsGroupCommand::redo() +{ + if(m_element) + { + if(m_first_undo) + { + m_group = m_element.data()->addTextGroup(m_name); + m_first_undo = false; + } + else if(m_group) + m_element.data()->addTextGroup(m_group.data()); + } +} + + +/************************** + * RemoveTextsGroupCommand* + * ************************/ +/** + * @brief RemoveTextsGroupCommand::RemoveTextsGroupCommand + * @param element : The element where we remove a group + * @param group : the group to remove + * @param parent : the parent undo command + */ +RemoveTextsGroupCommand::RemoveTextsGroupCommand(Element *element, ElementTextItemGroup *group, QUndoCommand *parent) : + QUndoCommand(parent), + m_element(element), + m_group(group) +{ + setText(QObject::tr("Supprimer un groupe de textes d'élément")); +} + +RemoveTextsGroupCommand::~RemoveTextsGroupCommand() +{} + +void RemoveTextsGroupCommand::undo() +{ + if(m_element && m_group) + m_element.data()->addTextGroup(m_group.data()); +} + +void RemoveTextsGroupCommand::redo() +{ + if(m_element && m_group) + m_element.data()->removeTextGroup(m_group.data()); +} + + +/************************ + * AddTextToGroupCommand* + * **********************/ +/** + * @brief AddTextToGroupCommand::AddTextToGroupCommand + * @param text + * @param group + * @param parent + */ +AddTextToGroupCommand::AddTextToGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent) : + QUndoCommand(parent), + m_text(text), + m_group(group), + m_element(group->parentElement()) +{ + setText(QObject::tr("Insérer un texte d'élément dans un groupe de textes")); +} + +/** + * @brief AddTextToGroupCommand::~AddTextToGroupCommand + * Destructor + */ +AddTextToGroupCommand::~AddTextToGroupCommand() +{ + if(m_group && m_text && m_element) + { + if(!m_group.data()->texts().contains(m_text.data()) && + !m_element.data()->dynamicTextItems().contains(m_text.data())) + delete m_text.data(); + } +} + +void AddTextToGroupCommand::undo() +{ + if(m_element && m_group && m_text) + m_element.data()->removeTextFromGroup(m_text, m_group); +} + +void AddTextToGroupCommand::redo() +{ + if(m_element && m_group && m_text) + m_element.data()->addTextToGroup(m_text, m_group); +} + +/***************************** + * RemoveTextFromGroupCommand* + * ***************************/ +/** + * @brief RemoveTextFromGroupCommand::RemoveTextFromGroupCommand + * @param text : text to add to @group + * @param group + * @param parent : parent undo command + */ +RemoveTextFromGroupCommand::RemoveTextFromGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent): + QUndoCommand(parent), + m_text(text), + m_group(group), + m_element(group->parentElement()) +{ + setText(QObject::tr("Enlever un texte d'élément d'un groupe de textes")); +} + +/** + * @brief RemoveTextFromGroupCommand::~RemoveTextFromGroupCommand + * Destructor + */ +RemoveTextFromGroupCommand::~RemoveTextFromGroupCommand() +{ + if(m_group && m_text && m_element) + { + if(!m_group.data()->texts().contains(m_text.data()) && + !m_element.data()->dynamicTextItems().contains(m_text.data())) + delete m_text.data(); + } +} + +void RemoveTextFromGroupCommand::undo() +{ + if(m_element && m_group && m_text) + m_element.data()->addTextToGroup(m_text, m_group); +} + +void RemoveTextFromGroupCommand::redo() +{ + if(m_element && m_group && m_text) + m_element.data()->removeTextFromGroup(m_text, m_group); +} + + +/***************************** + * AlignmentTextsGroupCommand* + * ***************************/ +/** + * @brief AlignmentTextsGroupCommand::AlignmentTextsGroupCommand + * @param group : Group to change the alignment + * @param new_alignment : the new alignment of the group + * @param parent : the parent QUndoCommand of this undo + */ +AlignmentTextsGroupCommand::AlignmentTextsGroupCommand(ElementTextItemGroup *group, Qt::Alignment new_alignment, QUndoCommand *parent) : + QUndoCommand(parent), + m_group(group), + m_previous_alignment(group->alignment()), + m_new_alignment(new_alignment) +{ + setText(QObject::tr("Modifier l'alignement d'un groupe de textes")); + + //Text haven't got alignment + if(m_previous_alignment != Qt::AlignLeft || + m_previous_alignment != Qt::AlignVCenter || + m_previous_alignment != Qt::AlignRight) + { + for(DynamicElementTextItem *deti : group->texts()) + m_texts_pos.insert(deti, deti->pos()); + } +} + +/** + * @brief AlignmentTextsGroupCommand::~AlignmentTextsGroupCommand + * Destructor + */ +AlignmentTextsGroupCommand::~AlignmentTextsGroupCommand() +{} + +/** + * @brief AlignmentTextsGroupCommand::mergeWith + * Try to merge this command with other command + * @param other + * @return true if was merged, else false + */ +bool AlignmentTextsGroupCommand::mergeWith(const QUndoCommand *other) +{ + if (id() != other->id() || other->childCount()) + return false; + + AlignmentTextsGroupCommand const *undo = static_cast(other); + if (m_group != undo->m_group) + return false; + + m_new_alignment= undo->m_new_alignment; + return true; +} + +/** + * @brief AlignmentTextsGroupCommand::undo + */ +void AlignmentTextsGroupCommand::undo() +{ + if(m_group) + { + m_group.data()->setAlignment(m_previous_alignment); + //The alignment befor this command was free, then we must + //to restor the pos of each texts + if(!m_texts_pos.isEmpty()) + { + for(DynamicElementTextItem *deti : m_group.data()->texts()) + { + if(m_texts_pos.keys().contains(deti)) + deti->setPos(m_texts_pos.value(deti)); + } + } + } +} + +/** + * @brief AlignmentTextsGroupCommand::redo + */ +void AlignmentTextsGroupCommand::redo() +{ + if(m_group) + m_group.data()->setAlignment(m_new_alignment); +} diff --git a/sources/undocommand/addelementtextcommand.h b/sources/undocommand/addelementtextcommand.h index d0c4289db..4b570e6f2 100644 --- a/sources/undocommand/addelementtextcommand.h +++ b/sources/undocommand/addelementtextcommand.h @@ -19,10 +19,16 @@ #define ADDELEMENTTEXTCOMMAND_H #include +#include class Element; class DynamicElementTextItem; +class ElementTextItemGroup; +/** + * @brief The AddElementTextCommand class + * Manage the adding of element text + */ class AddElementTextCommand : public QUndoCommand { public: @@ -37,18 +43,90 @@ class AddElementTextCommand : public QUndoCommand DynamicElementTextItem *m_text = nullptr; }; -//class RemoveElementTextCommand : public QUndoCommand -//{ -// public: -// RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent = nullptr); -// virtual ~RemoveElementTextCommand(); +/** + * @brief The AddTextsGroupCommand class + * Manage the adding of a texts group + */ +class AddTextsGroupCommand : public QUndoCommand +{ + public: + AddTextsGroupCommand(Element *element, QString groupe_name, QUndoCommand *parent = nullptr); + ~AddTextsGroupCommand() override; -// virtual void undo(); -// virtual void redo(); - -// private: -// Element *m_element = nullptr; -// DynamicElementTextItem *m_text = nullptr; -//}; + void undo() override; + void redo() override; + + private: + QPointer m_element; + QPointer m_group; + QString m_name; + bool m_first_undo = true; +}; + +/** + * @brief The RemoveTextsGroupCommand class + * Manage the removinf of a texts group + */ +class RemoveTextsGroupCommand : public QUndoCommand +{ + public: + RemoveTextsGroupCommand(Element *element, ElementTextItemGroup *group, QUndoCommand *parent = nullptr); + ~RemoveTextsGroupCommand() override; + + void undo() override; + void redo() override; + + private: + QPointer m_element; + QPointer m_group; +}; + +class AddTextToGroupCommand : public QUndoCommand +{ + public: + AddTextToGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent = nullptr); + ~AddTextToGroupCommand() override; + + void undo() override; + void redo() override; + + private: + QPointer m_text; + QPointer m_group; + QPointer m_element; +}; + +class RemoveTextFromGroupCommand : public QUndoCommand +{ + public: + RemoveTextFromGroupCommand(DynamicElementTextItem *text, ElementTextItemGroup *group, QUndoCommand *parent = nullptr); + ~RemoveTextFromGroupCommand() override; + + void undo() override; + void redo() override; + + private: + QPointer m_text; + QPointer m_group; + QPointer m_element; +}; + +class AlignmentTextsGroupCommand : public QUndoCommand +{ + public: + AlignmentTextsGroupCommand(ElementTextItemGroup *group, Qt::Alignment new_alignment, QUndoCommand *parent = nullptr); + ~AlignmentTextsGroupCommand() override; + + int id() const override{return 6;} + bool mergeWith(const QUndoCommand *other) override; + void undo() override; + void redo() override; + + private: + QPointer m_group; + Qt::Alignment m_previous_alignment, + m_new_alignment; + QHash m_texts_pos; +}; #endif // ADDELEMENTTEXTCOMMAND_H diff --git a/sources/undocommand/deleteqgraphicsitemcommand.cpp b/sources/undocommand/deleteqgraphicsitemcommand.cpp index f361c35fc..e68d80017 100644 --- a/sources/undocommand/deleteqgraphicsitemcommand.cpp +++ b/sources/undocommand/deleteqgraphicsitemcommand.cpp @@ -21,6 +21,7 @@ #include "element.h" #include "conductor.h" #include "conductortextitem.h" +#include "elementtextitemgroup.h" /** * @brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand @@ -44,7 +45,12 @@ DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand(Diagram *diagram, const D } for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts) - m_elmt_text_hash.insert(deti, deti->parentElement()); + { + if(deti->parentGroup()) + m_grp_texts_hash.insert(deti, deti->parentGroup()); + else + m_elmt_text_hash.insert(deti, deti->parentElement()); + } setText(QString(QObject::tr("supprimer %1", "undo caption - %1 is a sentence listing the removed content")).arg(m_removed_contents.sentence(DiagramContent::All))); m_diagram->qgiManager().manage(m_removed_contents.items(DiagramContent::All)); @@ -72,8 +78,14 @@ void DeleteQGraphicsItemCommand::undo() for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts) { - deti->setParentItem(m_elmt_text_hash.value(deti)); - m_elmt_text_hash.value(deti)->addDynamicTextItem(deti); + if(m_elmt_text_hash.keys().contains(deti)) + m_elmt_text_hash.value(deti)->addDynamicTextItem(deti); + else if (m_grp_texts_hash.keys().contains(deti)) + { + Element *elmt = m_grp_texts_hash.value(deti)->parentElement(); + elmt->addDynamicTextItem(deti); + elmt->addTextToGroup(deti, m_grp_texts_hash.value(deti)); + } } } @@ -109,6 +121,9 @@ void DeleteQGraphicsItemCommand::redo() for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts) { + if(deti->parentGroup() && deti->parentGroup()->parentElement()) + deti->parentGroup()->parentElement()->removeTextFromGroup(deti, deti->parentGroup()); + deti->parentElement()->removeDynamicTextItem(deti); deti->setParentItem(nullptr); } diff --git a/sources/undocommand/deleteqgraphicsitemcommand.h b/sources/undocommand/deleteqgraphicsitemcommand.h index bd78ef785..47f0a9d0e 100644 --- a/sources/undocommand/deleteqgraphicsitemcommand.h +++ b/sources/undocommand/deleteqgraphicsitemcommand.h @@ -22,6 +22,7 @@ #include "diagramcontent.h" class Diagram; +class ElementTextItemGroup; class DeleteQGraphicsItemCommand : public QUndoCommand { @@ -41,6 +42,7 @@ class DeleteQGraphicsItemCommand : public QUndoCommand Diagram *m_diagram; QHash > m_link_hash; /// keep linked element for each removed element linked to other element. QHash m_elmt_text_hash; /// Keep the parent element of each deleted dynamic element text item + QHash m_grp_texts_hash; ///Keep the parent group of each deleted element text item }; #endif // DELETEQGRAPHICSITEMCOMMAND_H