QElectroTech  0.70
potentialselectordialog.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 "ui_potentialselectordialog.h"
20 #include "conductor.h"
21 #include "terminal.h"
22 #include <QRadioButton>
24 #include "diagram.h"
25 #include "element.h"
26 #include "reportelement.h"
27 #include "assignvariables.h"
28 #include "formulaassistantdialog.h"
29 
30 //### BEGIN PRIVATE CLASS ###//
31 
37 {
38  public:
40  m_is_valid(false)
41  {
42  Terminal *terminal_1 = conductor->terminal1;
43  Terminal *terminal_2 = conductor->terminal2;
44  //We temporarily remove the conductor of his two terminals, to get the two existing potential
45  terminal_1->removeConductor(conductor);
46  terminal_2->removeConductor(conductor);
47 
50 
51  //There isn't a potential at terminal 1 or 2.
52  if (m_conductor_number_1 == 0 && m_conductor_number_2 == 0) return;
53 
54  //Re-add conductor to his terminals.
55  terminal_1->addConductor(conductor);
56  terminal_2->addConductor(conductor);
57  m_is_valid = true;
58  }
59 
60  bool isValid() const override {return m_is_valid;}
61 
69  void getPotential(Terminal *terminal, autonum::sequentialNumbers &seq_num , int &number, QList<ConductorProperties> &properties_list, QList<Conductor*> &c_list)
70  {
71  Conductor *conductor_in_potential = nullptr;
72 
73  //Terminal have conductor linked to, we get it.
74  if (!terminal->conductors().isEmpty())
75  conductor_in_potential = terminal->conductors().first();
76 
77  //Terminal haven't got a conductor, but if parent element is a folio report or a terminal element, we search a potential
78  //through the report or in another terminal of the terminal element.
79  else if (terminal->parentElement()->linkType() & (Element::Terminale | Element::AllReport))
80  {
81  Element *elmt_ = terminal->parentElement();
82 
83  if ((elmt_->linkType() & Element::Terminale) && !elmt_->terminals().isEmpty())
84  {
85  foreach(Terminal *t, elmt_->terminals())
86  {
87  if (t->conductors().isEmpty()) continue;
88  conductor_in_potential = t->conductors().first();
89  break;
90  }
91  }
92  else if ((elmt_->linkType() & Element::AllReport) && !elmt_->isFree())
93  {
94  Element *other_report = elmt_->linkedElements().first();
95  if (other_report->terminals().isEmpty()) return;
96  Terminal *t = other_report->terminals().first();
97  if (t->conductors().isEmpty()) return;
98  conductor_in_potential= t->conductors().first();
99  }
100  }
101 
102  if (!conductor_in_potential)
103  return;
104  seq_num = conductor_in_potential->sequenceNum();
105  number = conductor_in_potential->relatedPotentialConductors().size()+1; //We add +1 because conductor_in_potential isn't count by relatedPotentialConductors
106 
107  c_list = conductor_in_potential->relatedPotentialConductors().toList();
108  c_list.append(conductor_in_potential);
109  foreach(Conductor *c, c_list)
110  properties_list.append(c->properties());
111  }
112 
114 
115  private :
117 };
118 
124 {
125  public:
127  m_is_valid(false)
128  {
129  if ((report->linkType() & Element::AllReport) && !report->isFree())
130  {
131  //We temporarily unlink report to get the two existing potential
132  Element *other_report = report->linkedElements().first();
133  report->unlinkAllElements();
134 
135  if (report->conductors().isEmpty() || other_report->conductors().isEmpty())
136  return;
137 
138  m_conductor_number_1 = report->conductors().first()->relatedPotentialConductors().size() + 1;
139  m_seq_num_1 = report->conductors().first()->sequenceNum();
140  m_conductors_list_1.append(report->conductors().first()->relatedPotentialConductors().toList());
141  m_conductors_list_1.append(report->conductors().first());
142  foreach(Conductor *c, m_conductors_list_1)
144 
145  m_conductor_number_2 = other_report->conductors().first()->relatedPotentialConductors().size() + 1;
146  m_seq_num_2 = other_report->conductors().first()->sequenceNum();
147  m_conductors_list_2.append(other_report->conductors().first()->relatedPotentialConductors().toList());
148  m_conductors_list_2.append(other_report->conductors().first());
149  foreach(Conductor *c, m_conductors_list_2)
151 
152  //We relink the report
153  report->linkToElement(other_report);
154  m_is_valid = true;
155  }
156  }
157 
159 
160  bool isValid() const override {return m_is_valid;}
161 
162  private:
164 };
165 
166 //### END PRIVATE CLASS ###//
167 
168 
169 ConductorProperties PotentialSelectorDialog::chosenProperties(QList<ConductorProperties> list, QWidget *widget)
170 {
171  if (list.isEmpty()) {
172  return ConductorProperties() ;
173  } else if (list.size() == 1) {
174  return list.first();
175  }
176 
177  QDialog dialog(widget);
178  QVBoxLayout layout(widget);
179  dialog.setLayout(&layout);
180  QLabel label(tr("Veuillez choisir un potentiel électrique de la liste \n"
181  "à utiliser pour le nouveau potentiel"));
182  layout.addWidget(&label);
183 
184  QHash <QRadioButton *, ConductorProperties> H;
185  for (ConductorProperties cp : list)
186  {
187  QString text;
188  if(!cp.text.isEmpty())
189  text.append(tr("\nNuméro : %1").arg(cp.text));
190  if(!cp.m_function.isEmpty())
191  text.append(tr("\nFonction : %1").arg(cp.m_function));
192  if(!cp.m_tension_protocol.isEmpty())
193  text.append(tr("\nTension/protocole : %1").arg(cp.m_tension_protocol));
194 
195  QRadioButton *b = new QRadioButton(text, &dialog);
196  layout.addWidget(b);
197  H.insert(b, cp);
198  }
199  QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok, &dialog);
200  layout.addWidget(button_box);
201  connect(button_box, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
202 
203  dialog.exec();
204  for (QRadioButton *b : H.keys()) {
205  if(b->isChecked()) {
206  return H.value(b);
207  }
208  }
209 
210  return ConductorProperties();
211 }
212 
220 PotentialSelectorDialog::PotentialSelectorDialog(Conductor *conductor, QUndoCommand *parent_undo, QWidget *parent) :
221  QDialog(parent),
222  ui(new Ui::PotentialSelectorDialog),
223  m_conductor(conductor),
224  m_report(nullptr),
225  m_parent_undo(parent_undo)
226 {
227  ui->setupUi(this);
229  buildWidget();
230 }
231 
239 PotentialSelectorDialog::PotentialSelectorDialog(Element *report, QUndoCommand *parent_undo, QWidget *parent) :
240  QDialog(parent),
241  ui(new Ui::PotentialSelectorDialog),
242  m_conductor(nullptr),
243  m_report(report),
244  m_parent_undo(parent_undo)
245 {
246  ui->setupUi(this);
248  buildWidget();
249 }
250 
252 {
253  delete ui;
254  delete m_potential_selector;
255 }
256 
262 {
263  QString text1(tr("%n conducteurs composent le potentiel suivant :", "", m_potential_selector->m_conductor_number_1));
264 
268 
269  if(!cp1.text.isEmpty())
270  text1.append(tr("\nNuméro : %1").arg(cp1.text));
271  if(!cp1.m_function.isEmpty())
272  text1.append(tr("\nFonction : %1").arg(cp1.m_function));
273  if(!cp1.m_tension_protocol.isEmpty())
274  text1.append(tr("\nTension/protocole : %1").arg(cp1.m_tension_protocol));
275 
276  QString text2(tr("%n conducteurs composent le potentiel suivant :", "", m_potential_selector->m_conductor_number_2));
280 
281  if(!cp2.text.isEmpty())
282  text2.append(tr("\nNuméro : %1").arg(cp2.text));
283  if(!cp2.m_function.isEmpty())
284  text2.append(tr("\nFonction : %1").arg(cp2.m_function));
285  if(!cp2.m_tension_protocol.isEmpty())
286  text2.append(tr("\nTension/protocole : %1").arg(cp2.m_tension_protocol));
287 
288  QRadioButton *rb1 = new QRadioButton(text1, this);
289  QRadioButton *rb2 = new QRadioButton(text2, this);
290 
291  connect(rb1, &QRadioButton::toggled, [this](bool t)
292  {
293  if(t)
294  {
298  }
299  });
300  connect(rb2, &QRadioButton::toggled, [this](bool t)
301  {
302  if(t)
303  {
307  }
308  });
309 
310  //Set the radio button of potential with the bigger number of conductors,
311  //at first position, and check it
313  {
314  ui->verticalLayout->insertWidget(1, rb1);
315  ui->verticalLayout->insertWidget(2, rb2);
316  rb1->setChecked(true);
317  }
318  else
319  {
320  ui->verticalLayout->insertWidget(1, rb2);
321  ui->verticalLayout->insertWidget(2, rb1);
322  rb2->setChecked(true);
323  }
324 }
325 
331 {
333  return;
334 
335  QUndoCommand *undo = nullptr;
336  if (m_parent_undo)
337  undo = m_parent_undo;
338  else
339  undo = new QUndoCommand(tr("Modifier les propriétés de plusieurs conducteurs", "undo caption"));
340 
341  Diagram * diagram = nullptr;
342 
343  if (m_report)
344  {
346  {
347  if (m_report->diagram())
348  diagram = m_report->diagram();
349 
350  QVariant old_value, new_value;
351  QVariant old_seq, new_seq;
352  new_seq.setValue(m_sequential_num);
353 
354  //Set the new properties for each conductors of the new potential
355  foreach(Conductor *cond, m_conductors_to_change)
356  {
357  ConductorProperties new_properties = cond->properties();
359  old_value.setValue(cond->properties());
360  new_value.setValue(new_properties);
361  old_seq.setValue(cond->sequenceNum());
362  new QPropertyUndoCommand(cond, "sequenceNum", old_seq, new_seq, undo);
363  new QPropertyUndoCommand(cond, "properties", old_value, new_value, undo);
364  }
365 
366  //Check if formula of the new potential have incompatible variable with folio report
367  QRegularExpression rx ("%sequf_|%seqtf_|%seqhf_|%id|%F|%M|%LM");
369  {
370  if (cp.m_formula.contains(rx))
371  {
372  QStringList forbidden_str;
373  forbidden_str << "%sequf_" << "%seqtf_" << "%seqhf_" << "%id" << "%F" << "%M" << "%LM";
374 
375  QString text(tr("La formule du nouveau potentiel contient des variables incompatibles avec les reports de folio.\n"
376  "Veuillez saisir une formule compatible pour ce potentiel.\n"
377  "Les variables suivantes sont incompatibles :\n"
378  "%sequf_ %seqtf_ %seqhf_ %id %F %M %LM"));
379  FormulaAssistantDialog fag(this);
380  fag.setForbiddenVariables(forbidden_str);
381  fag.setText(text);
382  fag.setFormula(cp.m_formula);
383  fag.exec();
384 
385  QString new_formula = fag.formula();
386  QSet <Conductor *> c_list = m_report->conductors().first()->relatedPotentialConductors();
387  c_list.insert(m_report->conductors().first());
388  foreach(Conductor *cond, c_list)
389  {
390  old_value.setValue(cond->properties());
391  ConductorProperties new_properties = cond->properties();
392  new_properties.m_formula = new_formula;
393  new_value.setValue(new_properties);
394  new QPropertyUndoCommand(cond, "properties", old_value, new_value, undo);
395  }
396 
397  break;
398  }
399  }
400  }
401  }
402 
403  else if (m_conductor)
404  {
405  if (m_conductor->diagram())
406  diagram = m_conductor->diagram();
407 
408  ConductorProperties new_properties = m_conductor->properties();
410 
411  QVariant old_value, new_value;
412  old_value.setValue(m_conductor->properties());
413  new_value.setValue(new_properties);
414 
415  QVariant old_seq, new_seq;
416  old_seq.setValue(m_conductor->sequenceNum());
417  new_seq.setValue(m_sequential_num);
418 
419  new QPropertyUndoCommand(m_conductor, "sequenceNum", old_seq, new_seq, undo);
420  new QPropertyUndoCommand(m_conductor, "properties", old_value, new_value, undo);
421 
422  //Set the new properties for each conductors of the new potential
424  {
425  new_properties = cond->properties();
427  old_value.setValue(cond->properties());
428  new_value.setValue(new_properties);
429  old_seq.setValue(cond->sequenceNum());
430  new QPropertyUndoCommand(cond, "sequenceNum", old_seq, new_seq, undo);
431  new QPropertyUndoCommand(cond, "properties", old_value, new_value, undo);
432  }
433  }
434 
435  //There is an undo parent, we stop here, the owner of m_parent_undo will push it to an undo stack
436  if (m_parent_undo)
437  return;
438  //There isn't a parent, we push the undo command to diagram undo stack.
439  if (diagram)
440  diagram->undoStack().push(undo);
441 }
The QPropertyUndoCommand class This undo command manage QProperty of a QObject. This undo command can...
QList< ConductorProperties > m_properties_list_1
virtual void linkToElement(Element *)
Definition: element.h:133
QList< Conductor * > conductors() const
Definition: terminal.cpp:677
ConductorProperties properties
Conductor::properties.
Definition: conductor.h:48
virtual kind linkType() const
Definition: element.h:138
QList< Element * > linkedElements()
Element::linkedElements.
Definition: element.h:229
bool addConductor(Conductor *conductor)
Terminal::addConductor Add a conductor to this terminal.
Definition: terminal.cpp:191
bool isFree() const
Definition: element.h:201
autonum::sequentialNumbers m_seq_num_2
void setForbiddenVariables(const QStringList &list)
void on_buttonBox_accepted()
PotentialSelectorDialog::on_buttonBox_accepted Action when user click on OK button.
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
autonum::sequentialNumbers m_sequential_num
Diagram * diagram() const
QetGraphicsItem::diagram return the diagram of this item.
AbstractPotentialSelector * m_potential_selector
autonum::sequentialNumbers sequenceNum
Definition: conductor.h:49
The NewConductorPotentialSelector class Use for get the conductor propertie when two potentials is li...
QList< Conductor * > m_conductors_list_2
QList< Conductor * > conductors() const
Element::conductors.
Definition: element.cpp:134
Terminal * terminal2
Definition: conductor.h:68
Element * parentElement() const
Definition: terminal.cpp:759
QList< Terminal * > terminals() const
Element::terminals.
Definition: element.cpp:124
void setFormula(const QString &text)
Diagram * diagram() const
Definition: conductor.cpp:557
Terminal * terminal1
Definition: conductor.h:67
PotentialSelectorDialog(Conductor *conductor, QUndoCommand *parent_undo=nullptr, QWidget *parent=nullptr)
PotentialSelectorDialog::PotentialSelectorDialog Constructor when we link two potentiels together...
QList< ConductorProperties > m_properties_list
virtual void unlinkAllElements()
Definition: element.h:134
NewConductorPotentialSelector(Conductor *conductor)
QIcon tr
Definition: qeticons.cpp:204
autonum::sequentialNumbers m_seq_num_1
The LinkReportPotentialSelector class Use for get the conductor propertie when two potentials is link...
void getPotential(Terminal *terminal, autonum::sequentialNumbers &seq_num, int &number, QList< ConductorProperties > &properties_list, QList< Conductor *> &c_list)
getPotential Get the conductor propertie of the potential at terminal, and the number of wire in this...
void setText(const QString &text)
Ui::PotentialSelectorDialog * ui
QList< Conductor * > m_conductors_to_change
The PotentialSelectorDialog class This dialog is used when user try to connect two existing potential...
QList< ConductorProperties > m_properties_list_2
QUndoStack & undoStack()
Definition: diagram.h:337
void removeConductor(Conductor *conductor)
Terminal::removeConductor Remove a conductor from this terminal.
Definition: terminal.cpp:215
static ConductorProperties chosenProperties(QList< ConductorProperties > list, QWidget *parent=nullptr)
virtual bool isValid() const =0
void applyForEqualAttributes(QList< ConductorProperties > list)
ConductorProperties::applyForEqualAttributes Test each attribute of properties in the list separatly...
void buildWidget()
PotentialSelectorDialog::buildWidget Build the dialog.
QList< Conductor * > m_conductors_list_1