QElectroTech  0.70
linkelementcommand.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 "linkelementcommand.h"
19 #include "element.h"
20 #include "diagram.h"
22 #include "conductor.h"
24 
31 LinkElementCommand::LinkElementCommand(Element *element_, QUndoCommand *parent):
32  QUndoCommand(parent),
33  m_element(element_),
34  m_first_redo (true)
35 {
37  setText(QObject::tr("Éditer les référence croisé", "edite the cross reference"));
38 }
39 
45 bool LinkElementCommand::mergeWith(const QUndoCommand *other)
46 {
47  if (id() != other->id() || other->childCount()) return false;
48  LinkElementCommand const *undo = static_cast<const LinkElementCommand *> (other);
49  if (m_element != undo->m_element) return false;
50  m_linked_after = undo->m_linked_after;
51  return true;
52 }
53 
66 bool LinkElementCommand::isLinkable(Element *element_a, Element *element_b, bool already_linked)
67 {
68  switch(element_a->linkType())
69  {
70  case Element::Simple: return false;
71 
73  {
74  //Type isn't good
75  if (element_b->linkType() != Element::PreviousReport) return false;
76  //two report is free
77  if (element_a->isFree() && element_b->isFree()) return true;
78  //Reports aren't free but are already linked between them and and already_linked is true
79  if (element_a->linkedElements().contains(element_b) && already_linked) return true;
80 
81  return false;
82  }
83 
85  {
86  //Type isn't good
87  if (element_b->linkType() != Element::NextReport) return false;
88  //two report is free
89  if (element_a->isFree() && element_b->isFree()) return true;
90  //Reports aren't free but are already linked between them and and already_linked is true
91  if (element_a->linkedElements().contains(element_b) && already_linked) return true;
92 
93  return false;
94  }
95 
96  case Element::Master:
97  {
98  //Type isn't good
99  if (element_b->linkType() != Element::Slave) return false;
100  //element_b is free
101  if (element_b->isFree()) return true;
102  //element_b isn't free but already linked to element_a and already_linked is true
103  if (element_a->linkedElements().contains(element_b) && already_linked) return true;
104 
105  return false;
106  }
107 
108  case Element::Slave:
109  {
110  //Type isn't good
111  if (element_b->linkType() != Element::Master) return false;
112  //Element_a is free
113  if (element_a->isFree()) return true;
114  //element_a isn't free but already linked to element_b and already_linked is true;
115  if (element_b->linkedElements().contains(element_a) && already_linked) return true;
116 
117  return false;
118  }
119 
120  case Element::Terminale: return false;
121 
122  default: return false;
123  }
124 }
125 
132 void LinkElementCommand::setLink(const QList<Element *>& element_list)
133 {
134  m_linked_after.clear();
135  setUpNewLink(element_list, true);
136 }
137 
144 {
145  QList<Element *> list;
146  list << element_;
147  setLink(list);
148 }
149 
155 void LinkElementCommand::unlink(QList<Element *> element_list)
156 {
157  foreach(Element *elmt, element_list)
158  m_linked_after.removeAll(elmt);
159 }
160 
166  m_linked_after.clear();
167 }
168 
174 {
177  QUndoCommand::undo();
178 }
179 
185 {
188 
189  //If the action is to link two reports together, we check if the conductors
190  //of the new potential have the same text, function, and protocol.
191  //if not, a dialog ask what do to.
193  && m_element->conductors().size() \
194  && m_linked_after.size() && m_linked_after.first()->conductors().size())
195  {
196  //fill list of potential
197  QSet <Conductor *> c_list = m_element->conductors().first()->relatedPotentialConductors();
198  c_list << m_element->conductors().first();
199  //fill list of text
200  QStringList str_txt;
201  QStringList str_funct;
202  QStringList str_tens;
203  for (const Conductor *c : c_list)
204  {
205  str_txt << c->properties().text;
206  str_funct << c->properties().m_function;
207  str_tens << c->properties().m_tension_protocol;
208  }
209 
210  //check text list, isn't same in potential, ask user what to do
211  if (!QET::eachStrIsEqual(str_txt) || !QET::eachStrIsEqual(str_funct) || !QET::eachStrIsEqual(str_tens))
212  {
214  psd.exec();
215  }
216  m_first_redo = false;
217  }
218  QUndoCommand::redo();
219 }
220 
229 void LinkElementCommand::setUpNewLink(const QList<Element *> &element_list, bool already_link)
230 {
231  //m_element is a master we can connect several element to it
232  //if m_element isn't master (may be a report or slave) we can connect only one element
233  if (m_element->linkType() == Element::Master || element_list.size() == 1)
234  {
235  foreach(Element *elmt, element_list)
236  if (isLinkable(m_element, elmt, already_link))
237  m_linked_after << elmt;
238  }
239  else
240  {
241  qDebug() << "LinkElementCommand::setUpNewLink : try to link several elements to a report element or slave element,"
242  " only the first element of the list will be taken to be linked";
243  foreach(Element *elmt, element_list)
244  if (isLinkable(m_element, elmt, already_link))
245  {
246  m_linked_after << elmt;
247  return;
248  }
249  }
250 }
251 
258 void LinkElementCommand::makeLink(const QList<Element *> &element_list)
259 {
260  //List is empty, that mean m_element must be free, so we unlink all elements
261  if (element_list.isEmpty())
262  {
264  return;
265  }
266 
267  //We link all element from element_list
268  foreach(Element *elmt, element_list)
269  m_element->linkToElement(elmt);
270 
271  //At this point may be there are unwanted linked elements to m_element. We must to unlink it.
272  //Elements from @element_list are wanted so we compare @element_list to current linked element of @m_element
273  QList<Element *> to_unlink = m_element->linkedElements();
274  foreach(Element *elmt, element_list)
275  to_unlink.removeAll(elmt);
276 
277  //All elements stored in to_unlink is unwanted we unlink it from m_element
278  if (!to_unlink.isEmpty())
279  foreach(Element *elmt, to_unlink)
280  m_element->unlinkElement(elmt);
281 }
virtual void linkToElement(Element *)
Definition: element.h:133
virtual kind linkType() const
Definition: element.h:138
QList< Element * > linkedElements()
Element::linkedElements.
Definition: element.h:229
bool isFree() const
Definition: element.h:201
virtual void unlinkElement(Element *)
Definition: element.h:135
void unlink(QList< Element *> element_list)
LinkElementCommand::unlink Unlink all elements of element_list from the edited element.
Diagram * diagram() const
QetGraphicsItem::diagram return the diagram of this item.
void setUpNewLink(const QList< Element *> &element_list, bool already_link)
LinkElementCommand::setUpNewLink Update the content of m_link_after with the content of ...
void makeLink(const QList< Element *> &element_list)
LinkElementCommand::makeLink Make the link between m_element and element_list; This method unlink ele...
bool mergeWith(const QUndoCommand *other) override
LinkElementCommand::mergeWith.
QList< Element * > m_linked_before
QList< Conductor * > conductors() const
Element::conductors.
Definition: element.cpp:134
void unlinkAll()
LinkElementCommand::unlinkAll Unlink all element of the edited element.
The LinkElementCommand class This undo class manage link between elements. In the same instance of th...
void undo() override
LinkElementCommand::undo Undo this command.
virtual void unlinkAllElements()
Definition: element.h:134
QIcon tr
Definition: qeticons.cpp:204
void redo() override
LinkElementCommand::redo Redo this command.
static bool isLinkable(Element *element_a, Element *element_b, bool already_linked=false)
LinkElementCommand::isLinkable.
LinkElementCommand(Element *element_, QUndoCommand *parent=nullptr)
LinkElementCommand::LinkElementCommand Constructor.
void setLink(const QList< Element *> &element_list)
LinkElementCommand::setLink Replace all linked elements of edited element by elements stored in This...
The PotentialSelectorDialog class This dialog is used when user try to connect two existing potential...
QList< Element * > m_linked_after
void showMe()
Definition: diagram.h:150
bool eachStrIsEqual(const QStringList &qsl)
QET::eachStrIsEqual.
Definition: qet.cpp:584