Element text item group : Add new property for edit the adjustment of the space between texts

Dynamic element text item editor : Add new entry for edit the alignment, rotation and vertical adjustment of a group
Element Mover : Minor, remove the group texts from the moved content


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5165 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2017-12-10 14:31:27 +00:00
parent c8efc1102f
commit 292c45166a
7 changed files with 345 additions and 55 deletions

View File

@@ -99,7 +99,7 @@ void ElementsMover::continueMovement(const QPointF &movement) {
//Move every movable item, except conductor
typedef DiagramContent dc;
for (QGraphicsItem *qgi : m_moved_content.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes | dc::TextGroup))
for (QGraphicsItem *qgi : m_moved_content.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes))
{
if (qgi == m_movement_driver)
continue;

View File

@@ -52,10 +52,18 @@ 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);
QGraphicsItemGroup::addToGroup(item);
updateAlignment();
this->setRotation(rot);
DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item);
connect(deti, &DynamicElementTextItem::fontSizeChanged, this, &ElementTextItemGroup::updateAlignment);
connect(deti, &DynamicElementTextItem::textChanged, this, &ElementTextItemGroup::updateAlignment);
@@ -72,6 +80,10 @@ void ElementTextItemGroup::addToGroup(QGraphicsItem *item)
void ElementTextItemGroup::removeFromGroup(QGraphicsItem *item)
{
QGraphicsItemGroup::removeFromGroup(item);
//the item transformation is not reseted, we must to do it, because for exemple if the group rotation is 45°
//When item is removed from group, visually the item is unchanged (so 45°) but if we call item->rotation() the returned value is 0.
item->resetTransform();
item->setRotation(this->rotation());
item->setFlag(QGraphicsItem::ItemIsSelectable, true);
updateAlignment();
@@ -94,6 +106,7 @@ void ElementTextItemGroup::setAlignment(Qt::Alignment alignement)
{
m_alignment = alignement;
updateAlignment();
emit alignmentChanged(alignement);
}
Qt::Alignment ElementTextItemGroup::alignment() const
@@ -117,7 +130,7 @@ void ElementTextItemGroup::updateAlignment()
prepareGeometryChange();
std::sort(texts.begin(), texts.end(), sorting);
qreal y_offset =0;
qreal y_offset = 0;
if(m_alignment == Qt::AlignLeft)
{
@@ -126,7 +139,7 @@ void ElementTextItemGroup::updateAlignment()
for(QGraphicsItem *item : texts)
{
item->setPos(ref.x(), ref.y()+y_offset);
y_offset+=item->boundingRect().height();
y_offset+=item->boundingRect().height() + m_vertical_adjustment;
}
}
else if(m_alignment == Qt::AlignVCenter)
@@ -138,7 +151,7 @@ void ElementTextItemGroup::updateAlignment()
{
item->setPos(ref.x() - item->boundingRect().width()/2,
ref.y() + y_offset);
y_offset+=item->boundingRect().height();
y_offset+=item->boundingRect().height() + m_vertical_adjustment;
}
}
else if (m_alignment == Qt::AlignRight)
@@ -150,7 +163,7 @@ void ElementTextItemGroup::updateAlignment()
{
item->setPos(ref.x() - item->boundingRect().width(),
ref.y() + y_offset);
y_offset+=item->boundingRect().height();
y_offset+=item->boundingRect().height() + m_vertical_adjustment;
}
}
@@ -158,6 +171,23 @@ void ElementTextItemGroup::updateAlignment()
}
}
/**
* @brief ElementTextItemGroup::setVerticalAdjustment
* Set the value of the vertical adjustment to @v.
* The vertical adjutment is use to adjust the space between the texts of this group.
* @param v
*/
void ElementTextItemGroup::setVerticalAdjustment(int v)
{
if(m_vertical_adjustment != v)
{
prepareGeometryChange();
m_vertical_adjustment = v;
updateAlignment();
emit verticalAdjustmentChanged(v);
}
}
/**
* @brief ElementTextItemGroup::setName
* @param name Set the name of this group
@@ -220,6 +250,9 @@ QDomElement ElementTextItemGroup::toXml(QDomDocument &dom_document) const
QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
dom_element.setAttribute("alignment", me.valueToKey(m_alignment));
dom_element.setAttribute("rotation", this->rotation());
dom_element.setAttribute("vertical_adjustment", m_vertical_adjustment);
QDomElement dom_texts = dom_document.createElement("texts");
for(DynamicElementTextItem *deti : texts())
{
@@ -248,6 +281,9 @@ void ElementTextItemGroup::fromXml(QDomElement &dom_element)
QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
m_alignment = Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data()));
setRotation(dom_element.attribute("rotation", QString::number(0)).toDouble());
m_vertical_adjustment = dom_element.attribute("vertical_adjustment").toInt();
if(parentElement())
{
for(QDomElement text : QET::findInDomElement(dom_element, "texts", "text"))
@@ -308,6 +344,12 @@ QRectF ElementTextItemGroup::boundingRect() const
return rect;
}
void ElementTextItemGroup::setRotation(qreal angle)
{
QGraphicsItemGroup::setRotation(angle);
emit rotationChanged(angle);
}
/**
* @brief ElementTextItemGroup::mousePressEvent
* @param event
@@ -344,7 +386,7 @@ void ElementTextItemGroup::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
}
QPointF expected_pos = event->scenePos() + m_mouse_to_origin_movement;
setPos(Diagram::snapToGrid(expected_pos));
event->modifiers() == Qt::ControlModifier ? setPos(expected_pos) : setPos(Diagram::snapToGrid(expected_pos));
QPointF effective_movement = pos() - old_pos;
if(diagram())

View File

@@ -36,7 +36,15 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup
Q_OBJECT
Q_PROPERTY(QPointF pos READ pos WRITE setPos)
Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
Q_PROPERTY(int verticalAdjustment READ verticalAdjustment WRITE setVerticalAdjustment NOTIFY verticalAdjustmentChanged)
Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
public:
signals:
void rotationChanged(qreal);
void verticalAdjustmentChanged(int);
void alignmentChanged(Qt::Alignment);
public:
ElementTextItemGroup(const QString &name, Element *parent);
@@ -47,6 +55,8 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup
void setAlignment(Qt::Alignment alignement);
Qt::Alignment alignment() const;
void updateAlignment();
int verticalAdjustment() const {return m_vertical_adjustment;}
void setVerticalAdjustment(int v);
void setName(QString name);
QString name() const {return m_name;}
QList<DynamicElementTextItem *> texts() const;
@@ -59,6 +69,7 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QRectF boundingRect() const override;
void setRotation(qreal angle);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
@@ -71,6 +82,7 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup
QString m_name;
bool m_first_move = true;
QPointF m_mouse_to_origin_movement;
int m_vertical_adjustment = 0;
};
#endif // ELEMENTTEXTITEMGROUP_H

View File

@@ -65,7 +65,7 @@ void DynamicElementTextItemEditor::setElement(Element *element)
DynamicElementTextModel *old_model = m_model;
m_model = new DynamicElementTextModel(element, m_tree_view);
connect(m_model, &DynamicElementTextModel::dataForTextChanged, this, &DynamicElementTextItemEditor::dataEdited);
connect(m_model, &DynamicElementTextModel::dataChanged, this, &DynamicElementTextItemEditor::dataEdited);
m_tree_view->setModel(m_model);
if(old_model)
@@ -106,6 +106,25 @@ void DynamicElementTextItemEditor::apply()
delete undo;
}
//Get all texts groups of the edited element
for (ElementTextItemGroup *group : m_element.data()->textGroups())
{
QUndoCommand *undo = m_model->undoForEditedGroup(group);
if (undo->childCount() == 1)
{
QPropertyUndoCommand *quc = new QPropertyUndoCommand(static_cast<const QPropertyUndoCommand *>(undo->child(0)));
if (quc->text().isEmpty())
quc->setText(undo->text());
undo_list << quc;
delete undo;
}
else if(undo->childCount() > 1)
undo_list << undo;
else
delete undo;
}
if(!undo_list.isEmpty() && m_element->diagram())
{
if (undo_list.size() == 1)
@@ -172,9 +191,8 @@ QUndoCommand *DynamicElementTextItemEditor::associatedUndo() const
return nullptr;
}
void DynamicElementTextItemEditor::dataEdited(DynamicElementTextItem *deti)
void DynamicElementTextItemEditor::dataEdited()
{
Q_UNUSED(deti)
if (m_live_edit)
apply();
}

View File

@@ -47,7 +47,7 @@ class DynamicElementTextItemEditor : public AbstractElementPropertiesEditorWidge
QUndoCommand *associatedUndo() const override;
private:
void dataEdited(DynamicElementTextItem *deti);
void dataEdited();
void treeViewClicked(const QModelIndex &index);
private slots:

View File

@@ -64,6 +64,8 @@ DynamicElementTextModel::~DynamicElementTextModel()
//because was not connected to a slot, but a lambda
for(DynamicElementTextItem *deti : m_hash_text_connect.keys())
setConnection(deti, false);
for(ElementTextItemGroup *group : m_hash_group_connect.keys())
setConnection(group, false);
}
/**
@@ -485,6 +487,46 @@ QUndoCommand *DynamicElementTextModel::undoForEditedText(DynamicElementTextItem
return undo;
}
/**
* @brief DynamicElementTextModel::undoForEditedGroup
* @param group
* @param parent_undo
* @return A QUndoCommand that describe all changes made for @group.
* Each change made for @group is append as a child of the returned QUndoCommand.
* In other word, if the returned QUndoCommand have no child, that mean there is no change.
*/
QUndoCommand *DynamicElementTextModel::undoForEditedGroup(ElementTextItemGroup *group, QUndoCommand *parent_undo) const
{
QUndoCommand *undo = nullptr;
if(parent_undo)
undo = parent_undo;
else
undo = new QUndoCommand(tr("Éditer un groupe de textes"));
if (!m_groups_list.contains(group))
return undo;
QStandardItem *group_qsi = m_groups_list.value(group);
QString alignment = group_qsi->child(0,1)->data(Qt::DisplayRole).toString();
if((alignment == tr("Gauche")) && (group->alignment() != Qt::AlignLeft))
new QPropertyUndoCommand(group, "alignment", QVariant(group->alignment()), QVariant(Qt::AlignLeft), undo);
else if((alignment == tr("Droite")) && (group->alignment() != Qt::AlignRight))
new QPropertyUndoCommand(group, "alignment", QVariant(group->alignment()), QVariant(Qt::AlignRight), undo);
else if((alignment == tr("Centre")) && (group->alignment() != Qt::AlignVCenter))
new QPropertyUndoCommand(group, "alignment", QVariant(group->alignment()), QVariant(Qt::AlignVCenter), undo);
qreal rotation = group_qsi->child(1,1)->data(Qt::EditRole).toDouble();
if(group->rotation() != rotation)
new QPropertyUndoCommand(group, "rotation", QVariant(group->rotation()), QVariant(rotation), undo);
int v_adjustment = group_qsi->child(2,1)->data(Qt::EditRole).toInt();
if(group->verticalAdjustment() != v_adjustment)
new QPropertyUndoCommand(group, "verticalAdjustment", QVariant(group->verticalAdjustment()), QVariant(v_adjustment), undo);
return undo;
}
/**
* @brief DynamicElementTextModel::AddGroup
* Add a text item group to this model
@@ -495,6 +537,7 @@ void DynamicElementTextModel::addGroup(ElementTextItemGroup *group)
if(m_groups_list.keys().contains(group))
return;
//Group
QStandardItem *grp = new QStandardItem(group->name());
grp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
grp->setIcon(QET::Icons::textGroup);
@@ -508,12 +551,56 @@ void DynamicElementTextModel::addGroup(ElementTextItemGroup *group)
this->insertRow(0, qsi_list);
m_groups_list.insert(group, grp);
//Alignment
QStandardItem *alignment = new QStandardItem(tr("Alignement"));
alignment->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QString text;
switch (group->alignment()) {
case Qt::AlignLeft: text = tr("Gauche"); break;
case Qt::AlignRight: text = tr("Droite"); break;
case Qt::AlignVCenter: text = tr("Centre"); break;
default: break;}
QStandardItem *alignment_a = new QStandardItem(text);
alignment_a->setData(DynamicElementTextModel::grp_alignment, Qt::UserRole+1);
alignment_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
qsi_list.clear();
qsi_list << alignment << alignment_a;
grp->appendRow(qsi_list);
//Rotation
QStandardItem *rot = new QStandardItem(tr("Rotation"));
rot->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QStandardItem *rot_a = new QStandardItem;
rot_a->setData(group->rotation(), Qt::EditRole);
rot_a->setData(DynamicElementTextModel::grp_rotation, Qt::UserRole+1);
rot_a->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
qsi_list.clear();
qsi_list << rot << rot_a;
grp->appendRow(qsi_list);
//Vertical adjustment
QStandardItem *v_adj = new QStandardItem(tr("Ajustement vertical"));
v_adj->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
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->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
qsi_list.clear();
qsi_list << v_adj << v_adj_a;
grp->appendRow(qsi_list);
//Add the texts of the group
for(DynamicElementTextItem *deti : group->texts())
{
QStandardItem *group_item = m_groups_list.value(group);
group_item->appendRow(itemsForText(deti));
}
setConnection(group, true);
}
/**
@@ -528,6 +615,7 @@ void DynamicElementTextModel::removeGroup(ElementTextItemGroup *group)
QModelIndex group_index = m_groups_list.value(group)->index();
this->removeRow(group_index.row(), group_index.parent());
m_groups_list.remove(group);
setConnection(group, false);
}
}
@@ -883,9 +971,12 @@ void DynamicElementTextModel::enableSourceText(DynamicElementTextItem *deti, Dyn
void DynamicElementTextModel::itemDataChanged(QStandardItem *qsi)
{
DynamicElementTextItem *deti = textFromItem(qsi);
if (!deti)
ElementTextItemGroup *etig = groupFromItem(qsi);
if (!deti && !etig)
return;
if(deti)
{
QStandardItem *text_qsi = m_texts_list.value(deti);
DiagramContext dc;
if(deti->elementUseForInfo())
@@ -931,11 +1022,12 @@ void DynamicElementTextModel::itemDataChanged(QStandardItem *qsi)
QString compo = qsi->data(Qt::UserRole+2).toString();
text_qsi->setData(autonum::AssignVariables::replaceVariable(compo, dc), Qt::DisplayRole);
}
}
//We emit the signal only if @qsi is in the second column, because the data are stored on this column
//the first column is use only for display the title of the property
if(qsi->column() == 1 && !m_block_dataForTextChanged)
emit dataForTextChanged(deti);
if(qsi->column() == 1 && !m_block_dataChanged)
emit dataChanged();
}
/**
@@ -979,13 +1071,46 @@ void DynamicElementTextModel::setConnection(DynamicElementTextItem *deti, bool s
}
}
/**
* @brief DynamicElementTextModel::setConnection
* Set up the connection for @group to keep up to date the data of this model and the group.
* Is notably use with the use of QUndoCommand.
* @param group group to setup the connection
* @param set true = set connection - false unset connection
*/
void DynamicElementTextModel::setConnection(ElementTextItemGroup *group, bool set)
{
if(set)
{
if(m_hash_group_connect.keys().contains(group))
return;
QList<QMetaObject::Connection> 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);});
m_hash_group_connect.insert(group, connection_list);
}
else
{
if(!m_hash_group_connect.keys().contains(group))
return;
for (QMetaObject::Connection con : m_hash_group_connect.value(group))
disconnect(con);
m_hash_group_connect.remove(group);
}
}
void DynamicElementTextModel::updateDataFromText(DynamicElementTextItem *deti, ValueType type)
{
QStandardItem *qsi = m_texts_list.value(deti);
if (!qsi)
return;
m_block_dataForTextChanged = true;
m_block_dataChanged = true;
switch (type)
{
@@ -1058,9 +1183,54 @@ void DynamicElementTextModel::updateDataFromText(DynamicElementTextItem *deti, V
qsi->child(7,1)->setData(deti->rotation(), Qt::EditRole);
break;
}
case grp_alignment: break;
case grp_rotation: break;
case grp_v_adjust: break;
}
m_block_dataForTextChanged = false;
m_block_dataChanged = false;
}
void DynamicElementTextModel::updateDataFromGroup(ElementTextItemGroup *group, DynamicElementTextModel::ValueType type)
{
QStandardItem *qsi = m_groups_list.value(group);
if (!qsi)
return;
m_block_dataChanged = true;
switch (type)
{
case textFrom: break;
case userText: break;
case infoText: break;
case compositeText: break;
case size: break;
case tagg: break;
case color: break;
case pos: break;
case frame: break;
case rotation: break;
case grp_alignment:
{
switch (group->alignment())
{
case Qt::AlignLeft: qsi->child(0,1)->setData(tr("Gauche"), Qt::DisplayRole); break;
case Qt::AlignRight : qsi->child(0,1)->setData(tr("Droite"), Qt::DisplayRole); break;
case Qt::AlignVCenter : qsi->child(0,1)->setData(tr("Centre"), Qt::DisplayRole); break;
default: qsi->child(0,1)->setData("", Qt::DisplayRole); break;
}
break;
}
case grp_rotation:
qsi->child(1,1)->setData(group->rotation(), Qt::EditRole);
break;
case grp_v_adjust:
qsi->child(2,1)->setData(group->verticalAdjustment(), Qt::EditRole);
break;
}
m_block_dataChanged = false;
}
@@ -1160,6 +1330,35 @@ QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOpti
sb->setSuffix(" °");
return sb;
}
case DynamicElementTextModel::grp_alignment:
{
QComboBox *qcb = new QComboBox(parent);
qcb->setFrame(false);
qcb->setObjectName("group_alignment");
qcb->addItem(tr("Gauche"));
qcb->addItem(tr("Centre"));
qcb->addItem(tr("Droite"));
return qcb;
}
case DynamicElementTextModel::grp_rotation:
{
QSpinBox *sb = new QSpinBox(parent);
sb->setObjectName("group_rotation");
sb->setRange(0, 359);
sb->setWrapping(true);
sb->setFrame(false);
sb->setSuffix(" °");
return sb;
}
case DynamicElementTextModel::grp_v_adjust:
{
QSpinBox *sb = new QSpinBox(parent);
sb->setObjectName("group_v_adjustment");
sb->setRange(-20, 20);
sb->setFrame(false);
sb->setSuffix(" px");
return sb;
}
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
@@ -1224,6 +1423,17 @@ void DynamicTextItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *
}
}
}
else if (editor->objectName() == "group_alignment")
{
if(QStandardItemModel *qsim = dynamic_cast<QStandardItemModel *>(model))
{
if(QStandardItem *qsi = qsim->itemFromIndex(index))
{
QComboBox *cb = static_cast<QComboBox *>(editor);
qsi->setData(cb->currentText(), Qt::DisplayRole);
}
}
}
}
QStyledItemDelegate::setModelData(editor, model, index);
@@ -1235,7 +1445,8 @@ bool DynamicTextItemDelegate::eventFilter(QObject *object, QEvent *event)
//in normal behavior, the value is commited when the spinbox lose focus or enter key is pressed
//With this hack the value is commited each time the value change, so the text is moved in live.
//We also use this hack for the font size spinbox
if(object->objectName() == "pos_dialog" || object->objectName() == "font_size" || object->objectName() == "rot_spinbox")
if(object->objectName() == "pos_dialog" || object->objectName() == "font_size" || object->objectName() == "rot_spinbox" || \
object->objectName() == "group_rotation" || object->objectName() == "group_v_adjustment")
{
QSpinBox *sb = static_cast<QSpinBox *>(object);
if(event->type() == QEvent::KeyRelease)

View File

@@ -47,7 +47,10 @@ class DynamicElementTextModel : public QStandardItemModel
color,
pos,
frame,
rotation
rotation,
grp_alignment,
grp_rotation,
grp_v_adjust
};
DynamicElementTextModel(Element *element, QObject *parent = nullptr);
@@ -58,6 +61,7 @@ class DynamicElementTextModel : public QStandardItemModel
DynamicElementTextItem *textFromItem(QStandardItem *item) const;
QModelIndex indexFromText(DynamicElementTextItem *text) const;
QUndoCommand *undoForEditedText(DynamicElementTextItem *deti, QUndoCommand *parent_undo = nullptr) const;
QUndoCommand *undoForEditedGroup(ElementTextItemGroup *group, QUndoCommand *parent_undo = nullptr) const;
ElementTextItemGroup *groupFromIndex(const QModelIndex &index) const;
ElementTextItemGroup *groupFromItem(QStandardItem *item) const;
@@ -71,7 +75,7 @@ class DynamicElementTextModel : public QStandardItemModel
QStringList mimeTypes() const override;
signals:
void dataForTextChanged(DynamicElementTextItem *text);
void dataChanged();
private:
QList<QStandardItem *> itemsForText(DynamicElementTextItem *deti);
@@ -84,14 +88,17 @@ class DynamicElementTextModel : public QStandardItemModel
void enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf );
void itemDataChanged(QStandardItem *qsi);
void setConnection(DynamicElementTextItem *deti, bool set);
void setConnection(ElementTextItemGroup *group, bool set);
void updateDataFromText(DynamicElementTextItem *deti, DynamicElementTextModel::ValueType type);
void updateDataFromGroup(ElementTextItemGroup *group, DynamicElementTextModel::ValueType type);
private:
QPointer<Element> m_element;
QHash <DynamicElementTextItem *, QStandardItem *> m_texts_list;
QHash <ElementTextItemGroup *, QStandardItem *> m_groups_list;
QHash <DynamicElementTextItem *, QList<QMetaObject::Connection>> m_hash_text_connect;
bool m_block_dataForTextChanged = false;
QHash <ElementTextItemGroup *, QList<QMetaObject::Connection>> m_hash_group_connect;
bool m_block_dataChanged = false;
};
class DynamicTextItemDelegate : public QStyledItemDelegate