QElectroTech  0.70
diagramcontent.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 */
18 #include "diagramcontent.h"
19 #include <QGraphicsItem>
20 #include "element.h"
21 #include "independenttextitem.h"
22 #include "conductor.h"
23 #include "diagramimageitem.h"
24 #include "qetshapeitem.h"
25 #include "dynamicelementtextitem.h"
26 #include "elementtextitemgroup.h"
27 #include "diagram.h"
28 #include "terminal.h"
29 #include "conductortextitem.h"
30 
35 
42 DiagramContent::DiagramContent(Diagram *diagram, bool selected) :
43  m_selected_items(diagram->selectedItems())
44 {
45  QList <QGraphicsItem *> item_list;
46  if (selected) {
47  item_list = m_selected_items;
48  } else {
49  item_list = diagram->items();
50  }
51 
52 
53  for (QGraphicsItem *item : item_list)
54  {
55  if (Element *elmt = qgraphicsitem_cast<Element *>(item))
56  m_elements << elmt;
57  else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
58  m_text_fields << iti;
59  else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item))
60  {
61  //Get the isolated selected conductor (= not movable, but deletable)
62  if (!c->terminal1->parentItem()->isSelected() &&\
63  !c->terminal2->parentItem()->isSelected()) {
64  m_other_conductors << c;
65  }
66 
67  if (m_potential_conductors.isEmpty()) {
69  }
70  else
71  {
72  if (!potentialIsManaged(c->relatedPotentialConductors(true).toList()))
74  }
75  }
76  else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
77  m_images << dii;
78  else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item))
79  m_shapes << dsi;
80  else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
81  m_element_texts << deti;
82  else if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(item))
83  if(ElementTextItemGroup *etig = dynamic_cast<ElementTextItemGroup *>(group))
84  m_texts_groups << etig;
85  }
86 
87 
88  //For each selected element, we determine if conductors must be moved or updated.
89  for(Element *elmt : m_elements)
90  {
91  for(Terminal *terminal : elmt->terminals())
92  {
93  for(Conductor *conductor : terminal->conductors())
94  {
95  Terminal *other_terminal;
96  if (conductor->terminal1 == terminal)
97  other_terminal = conductor->terminal2;
98  else
99  other_terminal = conductor->terminal1;
100 
101  //If the two elements of conductor are movable
102  if (m_elements.contains(other_terminal -> parentElement()) && !m_conductors_to_move.contains(conductor))
103  m_conductors_to_move << conductor;
104  else if (!m_conductors_to_update.contains(conductor))
105  m_conductors_to_update << conductor;
106  }
107  }
108  }
109 }
110 
117  m_elements(other.m_elements),
118  m_text_fields(other.m_text_fields),
119  m_images(other.m_images),
120  m_shapes(other.m_shapes),
121  m_conductors_to_update(other.m_conductors_to_update),
122  m_conductors_to_move(other.m_conductors_to_move),
123  m_other_conductors(other.m_other_conductors),
124  m_potential_conductors(other.m_potential_conductors),
125  m_element_texts(other.m_element_texts),
126  m_texts_groups(other.m_texts_groups),
127  m_selected_items(other.m_selected_items)
128 {}
129 
131 {}
132 
140 QList<DiagramTextItem *> DiagramContent::selectedTexts() const
141 {
142  QList<DiagramTextItem *> selected_texts;
143  for(QGraphicsItem *qgi : m_selected_items)
144  {
145  if (qgi->type() == ConductorTextItem::Type ||
146  qgi->type() == IndependentTextItem::Type ||
147  qgi->type() == DynamicElementTextItem::Type)
148  selected_texts << static_cast<DiagramTextItem *>(qgi);
149  }
150  return(selected_texts);
151 }
152 
160 QList<ElementTextItemGroup *> DiagramContent::selectedTextsGroup() const
161 {
162  QList<ElementTextItemGroup *> groups;
163 
164  for(QGraphicsItem *qgi : m_selected_items)
165  if(qgi->type() == QGraphicsItemGroup::Type)
166  if(ElementTextItemGroup *grp = dynamic_cast<ElementTextItemGroup *>(qgi))
167  groups << grp;
168 
169  return groups;
170 }
171 
177 QList<Conductor *> DiagramContent::conductors(int filter) const
178 {
179  QList<Conductor *> result;
180  if (filter & ConductorsToMove) result += m_conductors_to_move;
181  if (filter & ConductorsToUpdate) result += m_conductors_to_update;
182  if (filter & OtherConductors) result += m_other_conductors;
183  if (filter & SelectedOnly) {
184  for(Conductor *conductor : result)
185  {
186  if (!conductor->isSelected())
187  result.removeAll(conductor);
188  }
189  }
190  return(result);
191 }
192 
201 {
202  for(QGraphicsItem *qgi : m_selected_items)
203  {
204  if (qgi->type() == Element::Type ||
205  qgi->type() == Conductor::Type ||
206  qgi->type() == IndependentTextItem::Type ||
207  qgi->type() == QetShapeItem::Type ||
208  qgi->type() == DiagramImageItem::Type ||
209  qgi->type() == DynamicElementTextItem::Type)
210  return true;
211  if(qgi->type() == QGraphicsItemGroup::Type)
212  if(dynamic_cast<ElementTextItemGroup *>(qgi))
213  return true;
214  }
215  return(false);
216 }
217 
223 {
224  if(!m_images.isEmpty()) return true;
225  if(!m_shapes.isEmpty()) return true;
226  if(!m_elements.isEmpty()) return true;
227  if(!m_text_fields.isEmpty()) return true;
228 
229  return false;
230 }
231 
237 {
238  m_elements.clear();
239  m_text_fields.clear();
240  m_images.clear();
241  m_shapes.clear();
242  m_conductors_to_update.clear();
243  m_conductors_to_move.clear();
244  m_other_conductors.clear();
245  m_element_texts.clear();
246  m_texts_groups.clear();
247  m_selected_items.clear();
248 }
249 
256 {
257  int count_ = 0;
258 
259  const QList<Element *> elements_set = m_elements;
260  for(Element *elmt : elements_set) {
261  if (!elmt->isMovable()) {
262  m_elements.removeAll(elmt);
263  ++count_;
264  }
265  }
266 
267  const QSet<DiagramImageItem *> images_set = m_images;
268  for(DiagramImageItem *img : images_set) {
269  if (!img->isMovable()) {
270  m_images.remove(img);
271  ++count_;
272  }
273  }
274 
275  const QSet<QetShapeItem *> shapes_set = m_shapes;
276  for(QetShapeItem *shape : shapes_set) {
277  if (!shape->isMovable()) {
278  m_shapes.remove(shape);
279  ++count_;
280  }
281  }
282 
283  return count_;
284 }
285 
287 {
288  for(Element *elmt : other.m_elements)
289  if(!m_elements.contains(elmt))
290  m_elements << elmt;
291 
292  for(IndependentTextItem *iti : other.m_text_fields)
293  if(!m_text_fields.contains(iti))
294  m_text_fields << iti;
295 
296  for(DiagramImageItem *dii : other.m_images)
297  if(!m_images.contains(dii))
298  m_images << dii;
299 
300  for(QetShapeItem *qsi : other.m_shapes)
301  if(!m_shapes.contains(qsi))
302  m_shapes << qsi;
303 
304  for(Conductor *c : other.m_conductors_to_update)
305  if(!m_conductors_to_update.contains(c))
307 
308  for(Conductor *c : other.m_conductors_to_move)
309  if(!m_conductors_to_move.contains(c))
311 
312  for(Conductor *c : other.m_other_conductors)
313  if(!m_other_conductors.contains(c))
314  m_other_conductors << c;
315 
316  for(DynamicElementTextItem *deti : other.m_element_texts)
317  if(!m_element_texts.contains(deti))
318  m_element_texts << deti;
319 
320  for(ElementTextItemGroup *etig : other.m_texts_groups)
321  if(!m_texts_groups.contains(etig))
322  m_texts_groups << etig;
323 
324  for(QGraphicsItem *qgi : other.m_selected_items)
325  if(!m_selected_items.contains(qgi))
326  m_selected_items << qgi;
327 
328  for (Conductor *c : other.m_potential_conductors)
329  {
330  QList<Conductor *> c_list = c->relatedPotentialConductors(true).toList();
331  c_list << c;
332  if (!potentialIsManaged(c_list)) {
334  }
335  }
336 
337  return *this;
338 }
339 
345 bool DiagramContent::potentialIsManaged(QList<Conductor *> conductors)
346 {
347  bool b = false;
348 
349  for (Conductor *c : conductors)
350  {
351  if (m_potential_conductors.contains(c))
352  b = true;
353  }
354 
355  return b;
356 }
357 
363 {
364  for (DiagramTextItem *dti : selectedTexts()) {
365  if (dti->textInteractionFlags() == Qt::TextEditorInteraction) {
366  return true;
367  }
368  }
369 
370  return false;
371 }
372 
378 QList<QGraphicsItem *> DiagramContent::items(int filter) const
379 {
380  QList<QGraphicsItem *> items_list;
381 
382  for(QGraphicsItem *qgi : conductors(filter)) items_list << qgi;
383 
384  if (filter & Elements) for(QGraphicsItem *qgi : m_elements) items_list << qgi;
385  if (filter & TextFields) for(QGraphicsItem *qgi : m_text_fields) items_list << qgi;
386  if (filter & Images) for(QGraphicsItem *qgi : m_images) items_list << qgi;
387  if (filter & Shapes) for(QGraphicsItem *qgi : m_shapes) items_list << qgi;
388  if (filter & ElementTextFields) for(QGraphicsItem *qgi : m_element_texts) items_list << qgi;
389  if (filter & TextGroup) for(QGraphicsItem *qgi : m_texts_groups) items_list << qgi;
390 
391  if (filter & SelectedOnly) {
392  for(QGraphicsItem *qgi : items_list) {
393  if (!qgi -> isSelected()) items_list.removeOne(qgi);
394  }
395  }
396  return(items_list);
397 }
398 
404 int DiagramContent::count(int filter) const
405 {
406  int count = 0;
407  if (filter & SelectedOnly) {
408  if (filter & Elements) for(Element *element : m_elements) { if (element -> isSelected()) ++ count; }
409  if (filter & TextFields) for(DiagramTextItem *dti : m_text_fields) { if (dti -> isSelected()) ++ count; }
410  if (filter & Images) for(DiagramImageItem *dii : m_images) { if (dii -> isSelected()) ++ count; }
411  if (filter & Shapes) for(QetShapeItem *dsi : m_shapes) { if (dsi -> isSelected()) ++ count; }
412  if (filter & ConductorsToMove) for(Conductor *conductor : m_conductors_to_move) { if (conductor -> isSelected()) ++ count; }
413  if (filter & ConductorsToUpdate) for(Conductor *conductor : m_conductors_to_update) { if (conductor -> isSelected()) ++ count; }
414  if (filter & OtherConductors) for(Conductor *conductor : m_other_conductors) { if (conductor -> isSelected()) ++ count; }
415  if (filter & ElementTextFields) for(DynamicElementTextItem *deti : m_element_texts) { if (deti -> isSelected()) ++ count; }
416  if (filter & TextGroup) for(ElementTextItemGroup *etig : m_texts_groups) { if (etig -> isSelected()) ++ count; }
417  }
418  else {
419  if (filter & Elements) count += m_elements.count();
420  if (filter & TextFields) count += m_text_fields.count();
421  if (filter & Images) count += m_images.count();
422  if (filter & Shapes) count += m_shapes.count();
423  if (filter & ConductorsToMove) count += m_conductors_to_move.count();
424  if (filter & ConductorsToUpdate) count += m_conductors_to_update.count();
425  if (filter & OtherConductors) count += m_other_conductors.count();
426  if (filter & ElementTextFields) count += m_element_texts.count();
427  if (filter & TextGroup) count += m_texts_groups.count();
428  }
429  return(count);
430 }
431 
438 QString DiagramContent::sentence(int filter) const
439 {
440  int elements_count = (filter & Elements) ? m_elements.count() : 0;
441  int conductors_count = conductors(filter).count();
442  int textfields_count = (filter & TextFields) ? (m_text_fields.count()) : 0;
443  int images_count = (filter & Images) ? m_images.count() : 0;
444  int shapes_count = (filter & Shapes) ? m_shapes.count() : 0;
445  int elmt_text_count = (filter & ElementTextFields) ? m_element_texts.count() : 0;
446 
447  return(
449  elements_count,
450  conductors_count,
451  textfields_count,
452  images_count,
453  shapes_count,
454  elmt_text_count
455  )
456  );
457 }
458 
465 QDebug &operator<<(QDebug d, DiagramContent &content) {
466  Q_UNUSED(content);
467  d << "DiagramContent {" << "\n";
468  /*
469  FIXME Le double-heritage QObject / QGraphicsItem a casse cet operateur
470  d << " elements :" << c.elements << "\n";
471  d << " conductorsToUpdate :" << c.conductorsToUpdate << "\n";
472  d << " conductorsToMove :" << c.conductorsToMove << "\n";
473  d << " otherConductors :" << c.otherConductors << "\n";
474  */
475  d << "}";
476  return(d.space());
477 }
QList< Conductor * > m_potential_conductors
bool hasCopiableItems() const
DiagramContent::hasCopiableItems.
The DynamicElementTextItem class This class provide a simple text field of element who can be added o...
QList< DiagramTextItem * > selectedTexts() const
DiagramContent::selectedTexts.
QSet< QetShapeItem * > m_shapes
QString sentence(int=All) const
DiagramContent::sentence.
QSet< Conductor * > relatedPotentialConductors(const bool all_diagram=true, QList< Terminal *> *t_list=nullptr)
Conductor::relatedPotentialConductors Return all conductors at the same potential of this conductor...
Definition: conductor.cpp:1603
QList< Conductor * > m_conductors_to_move
bool potentialIsManaged(QList< Conductor *>conductors)
DiagramContent::potentialIsManaged.
QList< QGraphicsItem * > items(int=All) const
DiagramContent::items.
QSet< IndependentTextItem * > m_text_fields
int removeNonMovableItems()
DiagramContent::removeNonMovableItems Remove all non movable item.
QList< Conductor * > m_other_conductors
QString ElementsAndConductorsSentence(int, int, int=0, int=0, int=0, int=0)
Definition: qet.cpp:240
QSet< DynamicElementTextItem * > m_element_texts
QList< ElementTextItemGroup * > selectedTextsGroup() const
DiagramContent::selectedTextsGroup.
The ElementTextItemGroup class This class represent a group of element text Texts in the group can be...
QList< Element * > m_elements
QList< Conductor * > m_conductors_to_update
The QetShapeItem class this class is used to draw a basic shape (line, rectangle, ellipse) into a dia...
Definition: qetshapeitem.h:35
QList< QGraphicsItem * > m_selected_items
DiagramContent()
DiagramContent::DiagramContent.
bool hasTextEditing()
DiagramContent::hasTextEditing.
void clear()
DiagramContent::clear Remove all items from the diagram content.
QDebug & operator<<(QDebug d, DiagramContent &content)
operator << Use to debug a diagram content
QSet< DiagramImageItem * > m_images
bool hasDeletableItems() const
DiagramContent::hasDeletableItems.
QList< Conductor * > conductors(int=AnyConductor) const
DiagramContent::conductors.
int count(int=All) const
DiagramContent::count.
QSet< ElementTextItemGroup * > m_texts_groups
DiagramContent & operator+=(const DiagramContent &other)