QElectroTech  0.70
deleteqgraphicsitemcommand.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2006-2019 The QElectroTech Team
3  This file is part of QElectroTech.
4 
5  QElectroTech is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 2 of the License, or
8  (at your option) any later version.
9 
10  QElectroTech is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17 */
19 #include "dynamicelementtextitem.h"
20 #include "diagram.h"
21 #include "element.h"
22 #include "conductor.h"
23 #include "conductortextitem.h"
24 #include "elementtextitemgroup.h"
25 #include "addelementtextcommand.h"
26 #include "terminal.h"
27 #include "diagramcommands.h"
28 
35 DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand *parent) :
36  QUndoCommand(parent),
37  m_removed_contents(content),
38  m_diagram(diagram)
39 {
40  //If parent element of a dynamic element text item is also in @m_removed_content,
41  //we remove it, because when the element will be removed from the scene every child's will also be removed.
42  const QSet<DynamicElementTextItem *> elmt_set = m_removed_contents.m_element_texts;
43  for(DynamicElementTextItem *deti : elmt_set)
44  {
45  if (m_removed_contents.m_elements.contains(deti->parentElement()))
47 
48  }
49 
50  //When remove a deti we must to know his parent item, for re-add deti as child of the parent
51  //when undo this command
53  {
54  if(deti->parentGroup())
55  m_grp_texts_hash.insert(deti, deti->parentGroup());
56  else
57  m_elmt_text_hash.insert(deti, deti->parentElement());
58  }
59 
60  //If parent element of ElementTextItemGroup is also in @m_removed_content,
61  //we remove it, because when the element will be removed from the scene every child's will also be removed.
62  const QSet<ElementTextItemGroup *> group_set = m_removed_contents.m_texts_groups;
63  for(ElementTextItemGroup *group : group_set)
64  {
65  if(m_removed_contents.m_elements.contains(group->parentElement()))
66  m_removed_contents.m_texts_groups.remove(group);
67  }
68 
69  //The deletion of the groups is not managed by this undo, but by a RemoveTextsGroupCommand
71  new RemoveTextsGroupCommand(group->parentElement(), group, this);
72  }
73 
76 
77  setText(QString(QObject::tr("supprimer %1", "undo caption - %1 is a sentence listing the removed content")).arg(m_removed_contents.sentence(DiagramContent::All)));
79 }
80 
83 }
84 
91 {
93  {
94  //a list of terminals who have at least two conductors docked in.
95  QList<Terminal *> terminals_list;
96  for (Terminal *t : elmt->terminals()) {
97  if (t->conductors().size() >= 2) {
98  terminals_list.append(t);
99  }
100  }
101  if (terminals_list.isEmpty()) {
102  continue;
103  }
104 
105  for (Terminal *t : terminals_list)
106  {
107  //All new created conductors will be docked to hub_terminal
108  Terminal *hub_terminal = nullptr;
109  QList<Terminal *> terminals_to_connect_list;
110 
111  for (Conductor *c : t->conductors())
112  {
113  Terminal *other_terminal = c->terminal1 == t ? c->terminal2 : c->terminal1;
114 
115  if (m_removed_contents.items(DiagramContent::Elements).contains(other_terminal->parentElement()))
116  {
117  other_terminal = terminalInSamePotential(other_terminal, c);
118  if (other_terminal == nullptr) {
119  continue;
120  }
121  }
122 
123  terminals_to_connect_list.append(other_terminal);
124  if (hub_terminal == nullptr) {
125  hub_terminal = other_terminal;
126  }
127  //hub_terminal must be the terminal the more at top left of the diagram.
128  else if (other_terminal->scenePos().x() < hub_terminal->scenePos().x()) {
129  hub_terminal = other_terminal;
130  }
131  else if (other_terminal->scenePos().x() == hub_terminal->scenePos().x()) {
132  if (other_terminal->scenePos().y() < hub_terminal->scenePos().y()) {
133  hub_terminal = other_terminal;
134  }
135  }
136  }
137 
138  terminals_to_connect_list.removeAll(hub_terminal);
139  if (hub_terminal == nullptr || terminals_to_connect_list.isEmpty()) {
140  continue;
141  }
142 
143  ConductorProperties properties = hub_terminal->conductors().first()->properties();
144  for (Terminal *t : terminals_to_connect_list)
145  {
146  //If a conductor was already created between these two terminals
147  //in this undo command, from another removed element, we do nothing
148  bool exist_ = false;
149  for (QPair<Terminal *, Terminal *> pair : m_connected_terminals)
150  {
151  if (pair.first == hub_terminal && pair.second == t) {
152  exist_ = true;
153  continue;
154  } else if (pair.first == t && pair.second == hub_terminal) {
155  exist_ = true;
156  continue;
157  }
158  }
159 
160  if (exist_ == false)
161  {
162  m_connected_terminals.append(qMakePair<Terminal *, Terminal *>(hub_terminal, t));
163  Conductor *new_cond = new Conductor(hub_terminal, t);
164  new_cond->setProperties(properties);
165  new AddItemCommand<Conductor*>(new_cond, t->diagram(), QPointF(), this);
166  }
167  }
168  }
169  }
170 }
171 
182 {
183  QList<Conductor *> conductor_list = terminal->conductors();
184  conductor_list.removeAll(conductor_to_exclude);
185  for(Conductor *c : conductor_list)
186  {
187  Terminal *other_terminal = c->terminal1 == terminal ? c->terminal2 : c->terminal1;
188  if(!m_removed_contents.items(DiagramContent::Elements).contains(other_terminal->parentElement())) {
189  return other_terminal;
190  }
191  }
192  //No one of direct conductor of terminal are docked to an element which is not removed
193  for(Conductor *c : conductor_list)
194  {
195  Terminal *other_terminal = c->terminal1 == terminal ? c->terminal2 : c->terminal1;
196  Terminal *terminal_to_return = terminalInSamePotential(other_terminal, c);
197  if (terminal_to_return != nullptr) {
198  return terminal_to_return;
199  }
200  }
201 
202  return nullptr;
203 }
204 
210 {
211  m_diagram->showMe();
212 
213  for(QGraphicsItem *item : m_removed_contents.items())
214  m_diagram->addItem(item);
215 
216  //We relink element after every element was added to diagram
218  for(Element *elmt : m_link_hash[e])
219  e->linkToElement(elmt);
220 
222  {
223  if(m_elmt_text_hash.keys().contains(deti))
224  m_elmt_text_hash.value(deti)->addDynamicTextItem(deti);
225  else if (m_grp_texts_hash.keys().contains(deti))
226  {
227  Element *elmt = m_grp_texts_hash.value(deti)->parentElement();
228  elmt->addDynamicTextItem(deti);
229  elmt->addTextToGroup(deti, m_grp_texts_hash.value(deti));
230  }
231  }
232 
233  QUndoCommand::undo();
234 }
235 
241 {
242  m_diagram -> showMe();
243 
245  {
246  //If option one text per folio is enable, and the text item of
247  //current conductor is visible (that mean the conductor have the single displayed text)
248  //We call adjustTextItemPosition to other conductor at the same potential to keep
249  //a visible text on this potential.
250  if (m_diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
251  {
252  QList <Conductor *> conductor_list;
253  conductor_list << c -> relatedPotentialConductors(false).toList();
254  if (conductor_list.count())
255  conductor_list.first() -> calculateTextItemPosition();
256  }
257  }
258 
260  {
261  //Get linked element, for relink it at undo
262  if (!e->linkedElements().isEmpty())
263  m_link_hash.insert(e, e->linkedElements());
264  }
265 
267  {
268  if(deti->parentGroup() && deti->parentGroup()->parentElement())
269  deti->parentGroup()->parentElement()->removeTextFromGroup(deti, deti->parentGroup());
270 
271  deti->parentElement()->removeDynamicTextItem(deti);
272  deti->setParentItem(nullptr);
273  }
274 
275 
276  for(QGraphicsItem *item : m_removed_contents.items())
277  m_diagram->removeItem(item);
278 
279  QUndoCommand::redo();
280 }
ElementTextItemGroup * parentGroup() const
DynamicElementTextItem::parentGroup.
QList< Conductor * > conductors() const
Definition: terminal.cpp:677
QList< Element * > linkedElements()
Element::linkedElements.
Definition: element.h:229
The DynamicElementTextItem class This class provide a simple text field of element who can be added o...
QString sentence(int=All) const
DiagramContent::sentence.
void release(QGraphicsItem *)
Definition: qgimanager.cpp:60
void undo() override
DeleteQGraphicsItemCommand::undo Undo this command.
The AddItemCommand class This command add an item in a diagram The item to add is template...
void setProperties(const ConductorProperties &property)
Definition: conductor.cpp:1495
Element * parentElement() const
Definition: terminal.cpp:759
QIcon Conductor
Definition: qeticons.cpp:35
QList< QGraphicsItem * > items(int=All) const
DiagramContent::items.
QList< Terminal * > terminals() const
Element::terminals.
Definition: element.cpp:124
virtual void removeItem(QGraphicsItem *item)
Diagram::removeItem Réimplemented from QGraphicsScene::removeItem(QGraphicsItem *item) Do some specif...
Definition: diagram.cpp:1133
QList< QPair< Terminal *, Terminal * > > m_connected_terminals
Keep the parent group of each deleted element text item.
Diagram * diagram() const
Definition: conductor.cpp:557
void addDynamicTextItem(DynamicElementTextItem *deti=nullptr)
Element::addDynamiqueTextItem Add as a dynamic text item of this element, is reparented to this If ...
Definition: element.cpp:1146
void removeDynamicTextItem(DynamicElementTextItem *deti)
Element::removeDynamicTextItem Remove , no matter if is a child of this element or a child of a group...
Definition: element.cpp:1168
bool removeTextFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group)
Element::removeTextFromGroup Remove the text from the group , en reparent to this element...
Definition: element.cpp:1331
QHash< Element *, QList< Element * > > m_link_hash
QSet< DynamicElementTextItem * > m_element_texts
QGIManager & qgiManager()
Definition: diagram.h:342
QIcon tr
Definition: qeticons.cpp:204
Element * parentElement() const
DynamicElementTextItem::ParentElement.
The ElementTextItemGroup class This class represent a group of element text Texts in the group can be...
QList< Element * > m_elements
QHash< DynamicElementTextItem *, ElementTextItemGroup * > m_grp_texts_hash
Keep the parent element of each deleted dynamic element text item.
Element * parentElement() const
ElementTextItemGroup::parentElement.
QHash< DynamicElementTextItem *, Element * > m_elmt_text_hash
keep linked element for each removed element linked to other element.
void setPotentialsOfRemovedElements()
DeleteQGraphicsItemCommand::setPotentialsOfRemovedElements This function creates new conductors (if n...
void redo() override
DeleteQGraphicsItemCommand::redo Redo the delete command.
The RemoveTextsGroupCommand class Manage the removinf of a texts group.
virtual void addItem(QGraphicsItem *item)
Diagram::addItem Réimplemented from QGraphicsScene::addItem(QGraphicsItem *item) Do some specific ope...
Definition: diagram.cpp:1108
QList< Conductor * > conductors(int=AnyConductor) const
DiagramContent::conductors.
void manage(QGraphicsItem *)
Definition: qgimanager.cpp:48
bool addTextToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group)
Element::addTextToGroup Add the text to the group ; If isn&#39;t owned by this element return false...
Definition: element.cpp:1310
DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand *parent=nullptr)
DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand.
void showMe()
Definition: diagram.h:150
QSet< ElementTextItemGroup * > m_texts_groups
Terminal * terminalInSamePotential(Terminal *terminal, Conductor *conductor_to_exclude)
DeleteQGraphicsItemCommand::terminalInSamePotential Return a terminal at the same potential of ...