QElectroTech  0.70
elementspanelwidget.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 "elementspanelwidget.h"
19 #include "qetelementeditor.h"
20 #include "elementscategoryeditor.h"
21 #include "qetapp.h"
22 #include "qetproject.h"
23 #include "diagram.h"
24 #include "qeticons.h"
25 #include "templatedeleter.h"
26 
27 /*
28  Lorsque le flag ENABLE_PANEL_WIDGET_DND_CHECKS est defini, le panel
29  effectue des verifications lors des drag'n drop d'elements et categories.
30  Par exemple, il verifie qu'une categorie cible est accessible en ecriture
31  avant d'y autoriser le drop d'un element.
32  Supprimer ce flag permet de tester le comportement des fonctions de gestion
33  des items (copy, move, etc.).
34 */
35 #define ENABLE_PANEL_WIDGET_DND_CHECKS
36 
41 ElementsPanelWidget::ElementsPanelWidget(QWidget *parent) : QWidget(parent) {
42  // initalise le panel d'elements
43  elements_panel = new ElementsPanel(this);
44 
45  // initialise les actions
46  open_directory = new QAction(QET::Icons::FolderOpen, tr("Ouvrir le dossier correspondant"), this);
47  copy_path = new QAction(QET::Icons::IC_CopyFile, tr("Copier le chemin"), this);
48  prj_activate = new QAction(QET::Icons::ProjectFile, tr("Basculer vers ce projet"), this);
49  prj_close = new QAction(QET::Icons::DocumentClose, tr("Fermer ce projet"), this);
50  prj_edit_prop = new QAction(QET::Icons::DialogInformation, tr("Propriétés du projet"), this);
51  prj_prop_diagram = new QAction(QET::Icons::DialogInformation, tr("Propriétés du folio"), this);
52  prj_add_diagram = new QAction(QET::Icons::DiagramAdd, tr("Ajouter un folio"), this);
53  prj_del_diagram = new QAction(QET::Icons::DiagramDelete, tr("Supprimer ce folio"), this);
54  prj_move_diagram_up = new QAction(QET::Icons::GoUp, tr("Remonter ce folio"), this);
55  prj_move_diagram_down = new QAction(QET::Icons::GoDown, tr("Abaisser ce folio"), this);
56  prj_move_diagram_upx10 = new QAction(QET::Icons::GoUpDouble, tr("Remonter ce folio x10"), this);
57  prj_move_diagram_top = new QAction(QET::Icons::GoTop, tr("Remonter ce folio au debut"), this);
58  prj_move_diagram_downx10 = new QAction(QET::Icons::GoDownDouble, tr("Abaisser ce folio x10"), this);
59  tbt_add = new QAction(QET::Icons::TitleBlock, tr("Nouveau modèle"), this);
60  tbt_edit = new QAction(QET::Icons::TitleBlock, tr("Éditer ce modèle"), this);
61  tbt_remove = new QAction(QET::Icons::TitleBlock, tr("Supprimer ce modèle"), this);
62 
63 
64  prj_del_diagram -> setShortcut(QKeySequence(Qt::Key_Delete));
65  prj_move_diagram_up -> setShortcut(QKeySequence(Qt::Key_F3));
66  prj_move_diagram_down -> setShortcut(QKeySequence(Qt::Key_F4));
67  prj_move_diagram_top -> setShortcut(QKeySequence(Qt::Key_F5));
68 
69 
70  // initialise le champ de texte pour filtrer avec une disposition horizontale
71  filter_textfield = new QLineEdit(this);
72  filter_textfield -> setClearButtonEnabled(true);
73  filter_textfield -> setPlaceholderText(tr("Filtrer"));
74 
75 
76  context_menu = new QMenu(this);
77 
78  connect(open_directory, SIGNAL(triggered()), this, SLOT(openDirectoryForSelectedItem()));
79  connect(copy_path, SIGNAL(triggered()), this, SLOT(copyPathForSelectedItem()));
80  connect(prj_activate, SIGNAL(triggered()), this, SLOT(activateProject()));
81  connect(prj_close, SIGNAL(triggered()), this, SLOT(closeProject()));
82  connect(prj_edit_prop, SIGNAL(triggered()), this, SLOT(editProjectProperties()));
83  connect(prj_prop_diagram, SIGNAL(triggered()), this, SLOT(editDiagramProperties()));
84  connect(prj_add_diagram, SIGNAL(triggered()), this, SLOT(newDiagram()));
85  connect(prj_del_diagram, SIGNAL(triggered()), this, SLOT(deleteDiagram()));
86  connect(prj_move_diagram_up, SIGNAL(triggered()), this, SLOT(moveDiagramUp()));
87  connect(prj_move_diagram_down, SIGNAL(triggered()), this, SLOT(moveDiagramDown()));
88  connect(prj_move_diagram_top, SIGNAL(triggered()), this, SLOT(moveDiagramUpTop()));
89  connect(prj_move_diagram_upx10, SIGNAL(triggered()), this, SLOT(moveDiagramUpx10()));
90  connect(prj_move_diagram_downx10, SIGNAL(triggered()), this, SLOT(moveDiagramDownx10()));
91  connect(tbt_add, SIGNAL(triggered()), this, SLOT(addTitleBlockTemplate()));
92  connect(tbt_edit, SIGNAL(triggered()), this, SLOT(editTitleBlockTemplate()));
93  connect(tbt_remove, SIGNAL(triggered()), this, SLOT(removeTitleBlockTemplate()));
94 
95  connect(filter_textfield, SIGNAL(textChanged(const QString &)), this, SLOT(filterEdited(const QString &)));
96 
97  connect(elements_panel, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(updateButtons()));
98  connect(elements_panel, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(handleContextMenu(const QPoint &)));
99  connect(elements_panel, SIGNAL(requestForDiagram(Diagram*)), this, SIGNAL(requestForDiagram(Diagram*)));
100  connect(
102  SIGNAL(requestForTitleBlockTemplate(const TitleBlockTemplateLocation &)),
104  SLOT(openTitleBlockTemplate(const TitleBlockTemplateLocation &))
105  );
106 
107  // disposition verticale
108  QVBoxLayout *vlayout = new QVBoxLayout(this);
109  vlayout -> setMargin(0);
110  vlayout -> setSpacing(0);
111  vlayout -> addWidget(filter_textfield);
112  vlayout -> addWidget(elements_panel);
113  vlayout -> setStretchFactor(elements_panel, 75000);
114  setLayout(vlayout);
115 }
116 
121 }
122 
128  if (QTreeWidgetItem *qtwi = elements_panel -> currentItem()) {
129  QString dir_path = elements_panel -> dirPathForItem(qtwi);
130  if (!dir_path.isEmpty()) {
131  QDesktopServices::openUrl(QUrl::fromLocalFile(dir_path));
132  }
133  }
134 }
135 
141  if (QTreeWidgetItem *qtwi = elements_panel -> currentItem()) {
142  QString file_path = elements_panel -> filePathForItem(qtwi);
143  file_path = QDir::toNativeSeparators(file_path);
144  if (!file_path.isEmpty()) {
145  QApplication::clipboard() -> setText(file_path);
146  }
147  }
148 }
149 
154  // recharge tous les elements
155  elements_panel -> reload(true);
156  // reapplique le filtre
157  if (!filter_textfield -> text().isEmpty()) {
158  elements_panel -> filter(filter_textfield -> text());
159  }
160 }
161 
166  if (QETProject *selected_project = elements_panel -> selectedProject()) {
167  emit(requestForProject(selected_project));
168  }
169 }
170 
175  if (QETProject *selected_project = elements_panel -> selectedProject()) {
176  emit(requestForProjectClosing(selected_project));
177  }
178 }
179 
184  if (QETProject *selected_project = elements_panel -> selectedProject()) {
185  emit(requestForProjectPropertiesEdition(selected_project));
186  }
187 }
188 
193  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
194  emit(requestForDiagramPropertiesEdition(selected_diagram));
195  }
196 }
197 
202  if (QETProject *selected_project = elements_panel -> selectedProject()) {
203  emit(requestForNewDiagram(selected_project));
204  }
205 }
206 
211  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
212  emit(requestForDiagramDeletion(selected_diagram));
213  }
214 }
215 
220  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
221  emit(requestForDiagramMoveUpTop(selected_diagram));
222  }
223 }
224 
225 
226 
231  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
232  emit(requestForDiagramMoveUp(selected_diagram));
233  }
234 }
235 
240  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
241  emit(requestForDiagramMoveDown(selected_diagram));
242  }
243 }
244 
249  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
250  emit(requestForDiagramMoveUpx10(selected_diagram));
251  }
252 }
253 
258  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
259  emit(requestForDiagramMoveDownx10(selected_diagram));
260  }
261 }
262 
263 
268  QTreeWidgetItem *current_item = elements_panel -> currentItem();
269  if (!current_item) return;
270 
271  if (current_item -> type() == QET::TitleBlockTemplatesCollection) {
272  QETApp::instance() -> openTitleBlockTemplate(
273  elements_panel -> templateLocationForItem(current_item)
274  );
275  }
276 }
277 
282  QTreeWidgetItem *current_item = elements_panel -> currentItem();
283  if (current_item && current_item -> type() == QET::TitleBlockTemplate) {
284  QETApp::instance() -> openTitleBlockTemplate(
285  elements_panel -> templateLocationForItem(current_item)
286  );
287  }
288 }
289 
294  QTreeWidgetItem *current_item = elements_panel -> currentItem();
295  if (current_item && current_item -> type() == QET::TitleBlockTemplate) {
297  elements_panel -> templateLocationForItem(current_item),
298  this
299  ).exec();
300  }
301 }
302 
307  QTreeWidgetItem *current_item = elements_panel -> currentItem();
308  int current_type = elements_panel -> currentItemType();
309 
310  if (current_type == QET::Project) {
311  bool is_writable = !(elements_panel -> selectedProject() -> isReadOnly());
312  prj_add_diagram -> setEnabled(is_writable);
313  } else if (current_type == QET::Diagram) {
314  Diagram *selected_diagram = elements_panel -> selectedDiagram();
315  QETProject *selected_diagram_project = selected_diagram -> project();
316 
317  bool is_writable = !(selected_diagram_project -> isReadOnly());
318  int project_diagrams_count = selected_diagram_project -> diagrams().count();
319  int diagram_position = selected_diagram_project -> diagrams().indexOf(selected_diagram);
320 
321  prj_del_diagram -> setEnabled(is_writable);
322  prj_move_diagram_up -> setEnabled(is_writable && diagram_position > 0);
323  prj_move_diagram_down -> setEnabled(is_writable && diagram_position < project_diagrams_count - 1);
324  prj_move_diagram_top -> setEnabled(is_writable && diagram_position > 0);
325  prj_move_diagram_upx10 -> setEnabled(is_writable && diagram_position > 10);
326  prj_move_diagram_downx10 -> setEnabled(is_writable && diagram_position < project_diagrams_count - 10);
327  } else if (current_type == QET::TitleBlockTemplatesCollection) {
328  TitleBlockTemplateLocation location = elements_panel -> templateLocationForItem(current_item);
329  tbt_add -> setEnabled(!location.isReadOnly());
330  tbt_edit -> setEnabled(false); // would not make sense
331  tbt_remove -> setEnabled(false); // would not make sense
332  } else if (current_type == QET::TitleBlockTemplate) {
333  QTreeWidgetItem *item = elements_panel -> currentItem();
334  TitleBlockTemplateLocation location = elements_panel -> templateLocationForItem(item);
335  tbt_add -> setEnabled(false); // would not make sense
336  tbt_edit -> setEnabled(true); // the tbt editor has a read-only mode
337  // deleting a tbt requires its parent collection to be writable
338  tbt_remove -> setEnabled(location.parentCollection() && !(location.parentCollection() -> isReadOnly()));
339  }
340 }
341 
346 void ElementsPanelWidget::handleContextMenu(const QPoint &pos) {
347  // recupere l'item concerne par l'evenement ainsi que son chemin
348  QTreeWidgetItem *item = elements_panel -> itemAt(pos);
349  if (!item) return;
350 
351  updateButtons();
352  context_menu -> clear();
353 
354  QString dir_path = elements_panel -> dirPathForItem(item);
355  if (!dir_path.isEmpty()) {
356  context_menu -> addAction(open_directory);
357  context_menu -> addAction(copy_path);
358  context_menu -> addSeparator();
359  }
360 
361  switch(item -> type()) {
362  case QET::Project:
363  context_menu -> addAction(prj_activate);
364  context_menu -> addAction(prj_edit_prop);
365  context_menu -> addAction(prj_add_diagram);
366  context_menu -> addAction(prj_close);
367  break;
368  case QET::Diagram:
369  context_menu -> addAction(prj_prop_diagram);
370  context_menu -> addAction(prj_del_diagram);
371  context_menu -> addAction(prj_move_diagram_top);
372  context_menu -> addAction(prj_move_diagram_upx10);
373  context_menu -> addAction(prj_move_diagram_up);
374  context_menu -> addAction(prj_move_diagram_down);
376  break;
378  context_menu -> addAction(tbt_add);
379  break;
381  context_menu -> addAction(tbt_edit);
382  context_menu -> addAction(tbt_remove);
383  break;
384  }
385 
386  // affiche le menu
387  if (!context_menu -> isEmpty()) {
388  context_menu -> popup(mapToGlobal(elements_panel -> mapTo(this, pos + QPoint(2, 2))));
389  }
390 }
391 
392 void ElementsPanelWidget::filterEdited(const QString &next_text) {
393  if (previous_filter_.isEmpty() && next_text.length() == 1) {
394  // the field is not empty anymore: begin filtering
395  elements_panel -> filter(next_text, QET::BeginFilter);
396  } else if (!previous_filter_.isEmpty() && next_text.isEmpty()) {
397  // the field is now empty again: end of filtering
398  elements_panel -> filter(QString(), QET::EndFilter);
399  } else {
400  // regular filtering
401  elements_panel -> filter(next_text, QET::RegularFilter);
402  }
403  previous_filter_ = next_text;
404 }
405 
410  switch(e -> key()) {
411  case Qt::Key_Delete: //delete diagram through elements panel widget
412  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
413  emit(requestForDiagramDeletion(selected_diagram));
414  }
415  break;
416  case Qt::Key_F3:
417  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
418  emit(requestForDiagramMoveUp(selected_diagram));
419  }
420  break;
421  case Qt::Key_F4:
422  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
423  emit(requestForDiagramMoveDown(selected_diagram));
424  }
425  break;
426  case Qt::Key_F5:
427  if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) {
428  emit(requestForDiagramMoveUpTop(selected_diagram));
429  }
430  break;
431  }
432  return;
433 }
QIcon DialogInformation
Definition: qeticons.cpp:47
QIcon GoTop
Definition: qeticons.cpp:108
ElementsPanel * elements_panel
void requestForDiagramPropertiesEdition(Diagram *)
QIcon DiagramAdd
Definition: qeticons.cpp:42
void requestForDiagramDeletion(Diagram *)
QIcon GoUpDouble
Definition: qeticons.cpp:110
void requestForNewDiagram(QETProject *)
QIcon TitleBlock
Definition: qeticons.cpp:165
void requestForProjectClosing(QETProject *)
void requestForDiagramMoveUpTop(Diagram *)
QIcon GoDownDouble
Definition: qeticons.cpp:107
void requestForDiagramMoveDown(Diagram *)
QIcon GoUp
Definition: qeticons.cpp:109
void requestForDiagramMoveUp(Diagram *)
void filterEdited(const QString &)
void requestForDiagram(Diagram *)
QIcon tr
Definition: qeticons.cpp:204
QIcon GoDown
Definition: qeticons.cpp:106
QIcon ProjectFile
Definition: qeticons.cpp:147
void handleContextMenu(const QPoint &)
void requestForProjectPropertiesEdition(QETProject *)
ElementsPanelWidget(QWidget *=nullptr)
void requestForDiagramMoveDownx10(Diagram *)
void requestForDiagramMoveUpx10(Diagram *)
QIcon DocumentClose
Definition: qeticons.cpp:49
QIcon IC_CopyFile
Definition: qeticons.cpp:40
void keyPressEvent(QKeyEvent *e) override
void requestForProject(QETProject *)
QAction * prj_move_diagram_downx10
TitleBlockTemplatesCollection * parentCollection() const
QIcon DiagramDelete
Definition: qeticons.cpp:45
static QETApp * instance()
Definition: qetapp.cpp:143
QIcon FolderOpen
Definition: qeticons.cpp:99