QElectroTech  0.70
masterpropertieswidget.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 "masterpropertieswidget.h"
19 #include "ui_masterpropertieswidget.h"
20 #include <QListWidgetItem>
21 #include <diagramposition.h>
22 #include <elementprovider.h>
23 #include <diagram.h>
24 #include <element.h>
25 #include <linkelementcommand.h>
26 
35  ui(new Ui::MasterPropertiesWidget),
36  m_project(nullptr)
37 {
38  ui->setupUi(this);
39 
40  ui->m_free_tree_widget->setContextMenuPolicy(Qt::CustomContextMenu);
41  ui->m_link_tree_widget->setContextMenuPolicy(Qt::CustomContextMenu);
42 
43  QStringList list;
44  QSettings settings;
45  if (settings.value("genericpanel/folio", false).toBool()) {
46  list << tr("Vignette") << tr("Label de folio") << tr("Titre de folio") << tr("Position");
47  }
48  else {
49  list << tr("Vignette") << tr("N° de folio") << tr("Titre de folio") << tr("Position");
50  }
51  ui->m_free_tree_widget->setHeaderLabels(list);
52  ui->m_link_tree_widget->setHeaderLabels(list);
53 
54  m_context_menu = new QMenu(this);
55  m_link_action = new QAction(tr("Lier l'élément"), this);
56  m_unlink_action = new QAction(tr("Délier l'élément"), this);
57  m_show_qtwi = new QAction(tr("Montrer l'élément"), this);
58  m_show_element = new QAction(tr("Montrer l'élément maître"), this);
59  m_save_header_state = new QAction(tr("Enregistrer la disposition"), this);
60 
61  connect(ui->m_free_tree_widget, &QTreeWidget::itemDoubleClicked, this, &MasterPropertiesWidget::showElementFromTWI);
62  connect(ui->m_link_tree_widget, &QTreeWidget::itemDoubleClicked, this, &MasterPropertiesWidget::showElementFromTWI);
63 
64  connect(ui->m_free_tree_widget, &QTreeWidget::customContextMenuRequested, [this](QPoint point) {this->customContextMenu(point, 1);});
65  connect(ui->m_link_tree_widget, &QTreeWidget::customContextMenuRequested, [this](QPoint point) {this->customContextMenu(point, 2);});
66 
67  connect(m_link_action, &QAction::triggered, this, &MasterPropertiesWidget::on_link_button_clicked);
68  connect(m_unlink_action, &QAction::triggered, this, &MasterPropertiesWidget::on_unlink_button_clicked);
69  connect(m_show_qtwi, &QAction::triggered, [this]() {this->showElementFromTWI(this->m_qtwi_at_context_menu,0);});
70 
71  connect(m_show_element, &QAction::triggered, [this]()
72  {
73  this->m_element->diagram()->showMe();
74  this->m_element->setHighlighted(true);
75  if(this->m_showed_element)
76  m_showed_element->setHighlighted(false);
77  });
78 
79  QHeaderView *qhv = ui->m_free_tree_widget->header();
80  qhv->setContextMenuPolicy(Qt::CustomContextMenu);
81  connect(qhv, &QHeaderView::customContextMenuRequested, this, &MasterPropertiesWidget::headerCustomContextMenuRequested);
82  connect(m_save_header_state, &QAction::triggered, [qhv]()
83  {
84  QByteArray qba = qhv->saveState();
85  QSettings settings;
86  settings.setValue("link-element-widget/master-state", qba);
87  });
88 
89  setElement(elmt);
90 }
91 
97 {
98  if (m_showed_element)
99  m_showed_element->setHighlighted(false);
100 
101  if(m_element)
102  m_element->setHighlighted(false);
103 
104  delete ui;
105 }
106 
113 {
114  if (m_element == element)
115  return;
116 
117  if (m_showed_element)
118  {
119  m_showed_element->setHighlighted(false);
120  m_showed_element = nullptr;
121  }
122  if (m_element)
123  m_element->setHighlighted(false);
124 
125  if (m_project)
126  disconnect(m_project, SIGNAL(diagramRemoved(QETProject*,Diagram*)), this, SLOT(diagramWasdeletedFromProject()));
127 
128  if(Q_LIKELY(element->diagram() && element->diagram()->project()))
129  {
130  m_project = element->diagram()->project();
131  connect(m_project, SIGNAL(diagramRemoved(QETProject*,Diagram*)), this, SLOT(diagramWasdeletedFromProject()));
132  }
133  else
134  m_project = nullptr;
135 
136  //Keep up to date this widget when the linked elements of m_element change
137  if (m_element)
139 
140  m_element = element;
142 
143  updateUi();
144 }
145 
154  if (QUndoCommand *undo = associatedUndo())
155  m_element -> diagram() -> undoStack().push(undo);
156 }
157 
163 {
164  foreach (QTreeWidgetItem *qtwi, m_qtwi_hash.keys())
165  delete qtwi;
166 
167  m_qtwi_hash.clear();
168  updateUi();
169 }
170 
179 {
180  QList <Element *> to_link;
181  QList <Element *> linked_ = m_element->linkedElements();
182 
183  for (int i=0; i<ui->m_link_tree_widget->topLevelItemCount(); i++)
184  to_link << m_qtwi_hash[ui->m_link_tree_widget->topLevelItem(i)];
185 
186  //The two list contain the same element, there is no change
187  if (to_link.size() == linked_.size())
188  {
189  bool equal = true;
190 
191  foreach(Element *elmt, to_link)
192  if (!linked_.contains(elmt))
193  equal = false;
194 
195  if(equal)
196  return nullptr;
197  }
198 
200 
201  if (to_link.isEmpty())
202  undo->unlinkAll();
203  else
204  undo->setLink(to_link);
205 
206  return undo;
207 }
208 
216 {
217  m_live_edit = live_edit;
218  return true;
219 }
220 
226 {
227  ui->m_free_tree_widget->clear();
228  ui->m_link_tree_widget->clear();
229  m_qtwi_hash.clear();
230 
231  if (Q_UNLIKELY(!m_project))
232  return;
233 
234  ElementProvider elmt_prov(m_project);
235  QSettings settings;
236 
237  //Build the list of free available element
238  QList <QTreeWidgetItem *> items_list;
239  const QList<Element *> free_list = elmt_prov.freeElement(Element::Slave);
240  for(Element *elmt : free_list)
241  {
242  QTreeWidgetItem *qtwi = new QTreeWidgetItem(ui->m_free_tree_widget);
243  qtwi->setIcon(0, elmt->pixmap());
244 
245  if(settings.value("genericpanel/folio", false).toBool())
246  {
248  QString F =autonum::AssignVariables::formulaToLabel(elmt->diagram()->border_and_titleblock.folio(), seq, elmt->diagram(), elmt);
249  qtwi->setText(1, F);
250  }
251  else
252  {
253  qtwi->setText(1, QString::number(elmt->diagram()->folioIndex() + 1));
254  }
255 
256 
257  qtwi->setText(2, elmt->diagram()->title());
258  qtwi->setText(4, elmt->diagram()->convertPosition(elmt->scenePos()).toString());
259  items_list.append(qtwi);
260  m_qtwi_hash.insert(qtwi, elmt);
261  }
262 
263  ui->m_free_tree_widget->addTopLevelItems(items_list);
264  items_list.clear();
265 
266  //Build the list of already linked element
267  const QList<Element *> link_list = m_element->linkedElements();
268  for(Element *elmt : link_list)
269  {
270  QTreeWidgetItem *qtwi = new QTreeWidgetItem(ui->m_link_tree_widget);
271  qtwi->setIcon(0, elmt->pixmap());
272 
273  if(settings.value("genericpanel/folio", false).toBool())
274  {
276  QString F =autonum::AssignVariables::formulaToLabel(elmt->diagram()->border_and_titleblock.folio(), seq, elmt->diagram(), elmt);
277  qtwi->setText(1, F);
278  }
279  else
280  {
281  qtwi->setText(1, QString::number(elmt->diagram()->folioIndex() + 1));
282  }
283 
284  qtwi->setText(2, elmt->diagram()->title());
285  qtwi->setText(3, elmt->diagram()->convertPosition(elmt->scenePos()).toString());
286  items_list.append(qtwi);
287  m_qtwi_hash.insert(qtwi, elmt);
288  }
289 
290  if(items_list.count())
291  ui->m_link_tree_widget->addTopLevelItems(items_list);
292 
293  QVariant v = settings.value("link-element-widget/master-state");
294  if(!v.isNull())
295  {
296  ui->m_free_tree_widget->header()->restoreState(v.toByteArray());
297  ui->m_link_tree_widget->header()->restoreState(v.toByteArray());
298  }
299 }
300 
302 {
303  m_context_menu->clear();
305  m_context_menu->popup(ui->m_free_tree_widget->header()->mapToGlobal(pos));
306 }
307 
313 {
314  //take the curent item from free_list and push it to linked_list
315  QTreeWidgetItem *qtwi = ui->m_free_tree_widget->currentItem();
316  if (qtwi)
317  {
318  ui->m_free_tree_widget->takeTopLevelItem(ui->m_free_tree_widget->indexOfTopLevelItem(qtwi));
319  ui->m_link_tree_widget->insertTopLevelItem(0, qtwi);
320 
321  if(m_live_edit)
322  apply();
323  }
324 }
325 
331 {
332  //take the curent item from linked_list and push it to free_list
333  QTreeWidgetItem *qtwi = ui->m_link_tree_widget->currentItem();
334  if(qtwi)
335  {
336  ui->m_link_tree_widget->takeTopLevelItem(ui->m_link_tree_widget->indexOfTopLevelItem(qtwi));
337  ui->m_free_tree_widget->insertTopLevelItem(0, qtwi);
338 
339  if(m_live_edit)
340  apply();
341  }
342 }
343 
350 void MasterPropertiesWidget::showElementFromTWI(QTreeWidgetItem *qtwi, int column)
351 {
352  Q_UNUSED(column);
353  if (m_showed_element)
354  {
355  disconnect(m_showed_element, SIGNAL(destroyed()), this, SLOT(showedElementWasDeleted()));
356  m_showed_element -> setHighlighted(false);
357  }
358  if (m_element)
359  m_element->setHighlighted(false);
360 
362  m_showed_element->diagram()->showMe();
363  m_showed_element->setHighlighted(true);
364  connect(m_showed_element, SIGNAL(destroyed()), this, SLOT(showedElementWasDeleted()));
365 }
366 
372  m_showed_element = nullptr;
373 }
374 
381 {
382  //We use a timer because if the removed diagram contain slave element linked to the edited element
383  //we must to wait for this elements be unlinked, else the linked list provide deleted elements.
384  QTimer::singleShot(10, this, SLOT(updateUi()));
385 }
386 
393 void MasterPropertiesWidget::customContextMenu(const QPoint &pos, int i)
394 {
395  //add the size of the header to display the topleft of the QMenu at the position of the mouse.
396  //See doc about QWidget::customContextMenuRequested section related to QAbstractScrollArea
397  QPoint point = pos;
398  point.ry()+=ui->m_free_tree_widget->header()->height();
399 
400  m_context_menu->clear();
401 
402  if (i == 1)
403  {
404  point = ui->m_free_tree_widget->mapToGlobal(point);
405 
406  //Context at for free tree widget
407  if (ui->m_free_tree_widget->currentItem())
408  {
409  m_qtwi_at_context_menu = ui->m_free_tree_widget->currentItem();
410  m_context_menu->addAction(m_link_action);
411  m_context_menu->addAction(m_show_qtwi);
412  }
413  }
414  else
415  {
416  point = ui->m_link_tree_widget->mapToGlobal(point);
417 
418  //context at for link tre widget
419  if (ui->m_link_tree_widget->currentItem())
420  {
421  m_qtwi_at_context_menu = ui->m_link_tree_widget->currentItem();
422  m_context_menu->addAction(m_unlink_action);
423  m_context_menu->addAction(m_show_qtwi);
424  }
425  }
426 
427  m_context_menu->addAction(m_show_element);
428  m_context_menu->popup(point);
429 }
void setElement(Element *element) override
MasterPropertiesWidget::setElement Set the element to be edited.
static QString formulaToLabel(QString formula, sequentialNumbers &seqStruct, Diagram *diagram, const Element *elmt=nullptr)
AssignVariables::formulaToLabel Return the with variable assigned (ready to be displayed) ...
QUndoCommand * associatedUndo() const override
MasterPropertiesWidget::associatedUndo If link between the edited element and other change...
QPointer< Element > m_showed_element
MasterPropertiesWidget(Element *elmt, QWidget *parent=nullptr)
MasterPropertiesWidget::MasterPropertiesWidget Default constructor.
The MasterPropertiesWidget class This class is a widget for make link between a master element with s...
Diagram * diagram() const
QetGraphicsItem::diagram return the diagram of this item.
void linkedElementChanged()
void reset() override
MasterPropertiesWidget::reset Reset curent widget, clear eveything and rebuild widget.
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...
The AbstractElementPropertiesEditorWidget class This class provide common method for all widget used ...
void headerCustomContextMenuRequested(const QPoint &pos)
QHash< QTreeWidgetItem *, Element * > m_qtwi_hash
QIcon tr
Definition: qeticons.cpp:204
bool setLiveEdit(bool live_edit) override
MasterPropertiesWidget::setLiveEdit.
void apply() override
MasterPropertiesWidget::apply If link betwen edited element and other change, apply the change with a...
Ui::MasterPropertiesWidget * ui
~MasterPropertiesWidget() override
MasterPropertiesWidget::~MasterPropertiesWidget Destructor.
QList< Element * > freeElement(const int filter) const
ElementProvider::FreeElement Search and return the asked element corresponding with the given filter ...
void showedElementWasDeleted()
MasterPropertiesWidget::showedElementWasDeleted Set to nullptr the current showed element when he was...
QTreeWidgetItem * m_qtwi_at_context_menu
void showElementFromTWI(QTreeWidgetItem *qtwi, int column)
MasterPropertiesWidget::showElementFromTWI Show the element corresponding to the given QTreeWidgetIte...
void setLink(const QList< Element *> &element_list)
LinkElementCommand::setLink Replace all linked elements of edited element by elements stored in This...
void on_link_button_clicked()
MasterPropertiesWidget::on_link_button_clicked move curent item in the free_list to linked_list...
QETProject * project() const
Definition: diagram.cpp:1716
void diagramWasdeletedFromProject()
MasterPropertiesWidget::diagramWasdeletedFromProject This slot is called when a diagram is removed fr...
void updateUi() override
MasterPropertiesWidget::updateUi Build the interface of the widget.
void customContextMenu(const QPoint &pos, int i=0)
MasterPropertiesWidget::customContextMenu Display a context menu.
void on_unlink_button_clicked()
MasterPropertiesWidget::on_unlink_button_clicked move curent item in linked_list to free_list...