QElectroTech  0.70
qetdiagrameditor.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 "qetdiagrameditor.h"
19 #include "qetapp.h"
20 #include "diagramcontent.h"
21 #include "diagramview.h"
22 #include "diagram.h"
24 #include "elementspanelwidget.h"
26 #include "qetproject.h"
27 #include "projectview.h"
28 #include "recentfiles.h"
29 #include "qeticons.h"
30 #include "qetelementeditor.h"
31 #include "qetmessagebox.h"
32 #include "qetresult.h"
33 #include "genericpanel.h"
34 #include "nomenclature.h"
35 #include "diagramfoliolist.h"
36 #include "qetshapeitem.h"
37 #include "reportproperties.h"
39 #include "diagrameventaddshape.h"
40 #include "diagrameventaddimage.h"
41 #include "diagrameventaddtext.h"
44 #include "dynamicelementtextitem.h"
45 #include "conductortextitem.h"
47 #include "rotatetextscommand.h"
48 #include "diagramcommands.h"
49 #include "dialogwaiting.h"
50 #include "addelementtextcommand.h"
51 
52 #include <QMessageBox>
53 #include <QStandardPaths>
54 #include <KAutoSaveFile>
55 
57 
58 
65 QETDiagramEditor::QETDiagramEditor(const QStringList &files, QWidget *parent) :
66  QETMainWindow(parent),
67  m_row_column_actions_group (this),
68  m_selection_actions_group (this),
69  m_add_item_actions_group (this),
70  m_zoom_actions_group (this),
71  m_select_actions_group (this),
72  m_file_actions_group (this),
73  open_dialog_dir (QStandardPaths::writableLocation(QStandardPaths::DesktopLocation))
74 {
76 
77  QSplitter *splitter_ = new QSplitter(this);
78  splitter_->setChildrenCollapsible(false);
79  splitter_->setOrientation(Qt::Vertical);
80  splitter_->addWidget(&m_workspace);
81  splitter_->addWidget(&m_search_and_replace_widget);
82  m_search_and_replace_widget.setHidden(true);
84  setCentralWidget(splitter_);
85 
86  //Set object name to be retrieved by the stylesheets
87  m_workspace.setBackground(QBrush(Qt::NoBrush));
88  m_workspace.setObjectName("mdiarea");
89  m_workspace.setTabsClosable(true);
90 
91  //Set the signal mapper
92  connect(&windowMapper, SIGNAL(mapped(QWidget *)), this, SLOT(activateWidget(QWidget *)));
93 
94  setWindowTitle(tr("QElectroTech", "window title"));
95  setWindowIcon(QET::Icons::QETLogo);
96  statusBar() -> showMessage(tr("QElectroTech", "status bar message"));
97 
100  setUpUndoStack();
103 
104  setUpActions();
105  setUpToolBar();
106  setUpMenu();
107 
108  tabifyDockWidget(qdw_undo, qdw_pa);
109 
110  //By default the windows is maximised
111  setMinimumSize(QSize(500, 350));
112  setWindowState(Qt::WindowMaximized);
113 
114  connect (&m_workspace, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(subWindowActivated(QMdiSubWindow*)));
115  connect (QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slot_updatePasteAction()));
116 
117  readSettings();
118  show();
119 
120  //If valid file path is given as arguments
121  uint opened_projects = 0;
122  if (files.count())
123  {
124  //So we open this files
125  foreach(QString file, files)
126  if (openAndAddProject(file))
127  ++ opened_projects;
128  }
129 
131 }
132 
137 }
138 
144  //Add the element panel as a QDockWidget
145  qdw_pa = new QDockWidget(tr("Projets", "dock title"), this);
146 
147  qdw_pa -> setObjectName ("projects panel");
148  qdw_pa -> setAllowedAreas (Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
149  qdw_pa -> setFeatures (QDockWidget::AllDockWidgetFeatures);
150  qdw_pa -> setMinimumWidth (160);
151  qdw_pa -> setWidget (pa = new ElementsPanelWidget(qdw_pa));
152 
153  addDockWidget(Qt::LeftDockWidgetArea, qdw_pa);
154 
155  connect(pa, SIGNAL(requestForProject (QETProject *)), this, SLOT(activateProject(QETProject *)));
156  connect(pa, SIGNAL(requestForProjectClosing (QETProject *)), this, SLOT(closeProject(QETProject *)));
157  connect(pa, SIGNAL(requestForProjectPropertiesEdition (QETProject *)), this, SLOT(editProjectProperties(QETProject *)));
158  connect(pa, SIGNAL(requestForNewDiagram (QETProject *)), this, SLOT(addDiagramToProject(QETProject *)));
159 
160  connect(pa, SIGNAL(requestForDiagram (Diagram *)), this, SLOT(activateDiagram(Diagram *)));
161  connect(pa, SIGNAL(requestForDiagramPropertiesEdition (Diagram *)), this, SLOT(editDiagramProperties(Diagram *)));
162  connect(pa, SIGNAL(requestForDiagramDeletion (Diagram *)), this, SLOT(removeDiagram(Diagram *)));
163  connect(pa, SIGNAL(requestForDiagramMoveUp (Diagram *)), this, SLOT(moveDiagramUp(Diagram *)));
164  connect(pa, SIGNAL(requestForDiagramMoveDown (Diagram *)), this, SLOT(moveDiagramDown(Diagram *)));
165  connect(pa, SIGNAL(requestForDiagramMoveUpTop (Diagram *)), this, SLOT(moveDiagramUpTop(Diagram *)));
166  connect(pa, SIGNAL(requestForDiagramMoveUpx10 (Diagram *)), this, SLOT(moveDiagramUpx10(Diagram *)));
167  connect(pa, SIGNAL(requestForDiagramMoveDownx10 (Diagram *)), this, SLOT(moveDiagramDownx10(Diagram *)));
168 }
169 
175 {
176  m_qdw_elmt_collection = new QDockWidget(tr("Collections"), this);
177  m_qdw_elmt_collection->setObjectName("elements_collection_widget");
178  m_qdw_elmt_collection->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
179  m_qdw_elmt_collection->setFeatures(QDockWidget::AllDockWidgetFeatures);
180 
184 
185  addDockWidget(Qt::RightDockWidgetArea, m_qdw_elmt_collection);
186 }
187 
193 
194  QUndoView *undo_view = new QUndoView(&undo_group, this);
195 
196  undo_view -> setEmptyLabel (tr("Aucune modification"));
197  undo_view -> setStatusTip (tr("Cliquez sur une action pour revenir en arrière dans l'édition de votre schéma", "Status tip"));
198  undo_view -> setWhatsThis (tr("Ce panneau liste les différentes actions effectuées sur le folio courant. Cliquer sur une action permet de revenir à l'état du schéma juste après son application.", "\"What's this\" tip"));
199 
200  qdw_undo = new QDockWidget(tr("Annulations", "dock title"), this);
201  qdw_undo -> setObjectName("diagram_undo");
202 
203  qdw_undo -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
204  qdw_undo -> setFeatures(QDockWidget::AllDockWidgetFeatures);
205  qdw_undo -> setMinimumWidth(160);
206  qdw_undo -> setWidget(undo_view);
207 
208  addDockWidget(Qt::LeftDockWidgetArea, qdw_undo);
209 }
210 
216 {
218  m_selection_properties_editor -> setObjectName("diagram_properties_editor_dock_widget");
219  addDockWidget(Qt::RightDockWidgetArea, m_selection_properties_editor);
220 }
221 
227 {
229  m_autonumbering_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
230  m_autonumbering_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
231  addDockWidget(Qt::RightDockWidgetArea, m_autonumbering_dock);
232 }
233 
239 {
240  //Export to another file type (jpeg, dxf etc...)
241  m_export_diagram = new QAction(QET::Icons::DocumentExport, tr("E&xporter"), this);
242  m_export_diagram->setShortcut(QKeySequence(tr("Ctrl+Shift+X")));
243  m_export_diagram->setStatusTip(tr("Exporte le folio courant dans un autre format", "status bar tip"));
244  connect(m_export_diagram, &QAction::triggered, [this]() {
245  ProjectView *current_project = currentProjectView();
246  if (current_project) {
247  current_project -> exportProject();
248  }
249  });
250 
251  //Print
252  m_print = new QAction(QET::Icons::DocumentPrint, tr("Imprimer"), this);
253  m_print->setShortcut(QKeySequence(QKeySequence::Print));
254  m_print->setStatusTip(tr("Imprime un ou plusieurs folios du projet courant", "status bar tip"));
255  connect(m_print, &QAction::triggered, [this]() {
256  ProjectView *current_project = currentProjectView();
257  if (current_project) {
258  current_project -> printProject();
259  }
260  });
261 
262  //Quit editor
263  m_quit_editor = new QAction(QET::Icons::ApplicationExit, tr("&Quitter"), this);
264  m_quit_editor->setShortcut(QKeySequence(tr("Ctrl+Q")));
265  m_quit_editor->setStatusTip(tr("Ferme l'application QElectroTech", "status bar tip"));
266  connect(m_quit_editor, &QAction::triggered, this, &QETDiagramEditor::close);
267 
268  //Undo
269  undo = undo_group.createUndoAction(this, tr("Annuler"));
270  undo->setIcon(QET::Icons::EditUndo);
271  undo->setShortcut(QKeySequence::Undo);
272  undo->setStatusTip(tr("Annule l'action précédente", "status bar tip"));
273  //Redo
274  redo = undo_group.createRedoAction(this, tr("Refaire"));
275  redo->setIcon(QET::Icons::EditRedo);
276  redo->setShortcut(QKeySequence::Redo);
277  redo->setStatusTip(tr("Restaure l'action annulée", "status bar tip"));
278 
279  //cut copy past
280  m_cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this);
281  m_copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this);
282  m_paste = new QAction(QET::Icons::EditPaste, tr("C&oller"), this);
283 
284  m_cut -> setShortcut(QKeySequence::Cut);
285  m_copy -> setShortcut(QKeySequence::Copy);
286  m_paste -> setShortcut(QKeySequence::Paste);
287 
288  m_cut -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip"));
289  m_copy -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip"));
290  m_paste -> setStatusTip(tr("Place les éléments du presse-papier sur le folio", "status bar tip"));
291 
292  connect(m_cut, &QAction::triggered, [this]() {
293  if (currentDiagramView())
294  currentDiagramView()->cut();
295  });
296  connect(m_copy, &QAction::triggered, [this]() {
297  if (currentDiagramView())
298  currentDiagramView()->copy();
299  });
300  connect(m_paste, &QAction::triggered, [this]() {
301  if(currentDiagramView())
302  currentDiagramView()->paste();
303  });
304 
305  //Reset conductor path
306  m_conductor_reset = new QAction(QET::Icons::ConductorSettings, tr("Réinitialiser les conducteurs"), this);
307  m_conductor_reset->setShortcut( QKeySequence( tr("Ctrl+K") ) );
308  m_conductor_reset->setStatusTip(tr("Recalcule les chemins des conducteurs sans tenir compte des modifications", "status bar tip"));
309  connect(m_conductor_reset, &QAction::triggered, [this]() {
310  if (DiagramView *dv = currentDiagramView())
311  dv->resetConductors();
312  });
313 
314  //AutoConductor
315  m_auto_conductor = new QAction (QET::Icons::Autoconnect, tr("Création automatique de conducteur(s)","Tool tip of auto conductor"), this);
316  m_auto_conductor->setStatusTip (tr("Utiliser la création automatique de conducteur(s) quand cela est possible", "Status tip of auto conductor"));
317  m_auto_conductor->setCheckable (true);
318  connect(m_auto_conductor, &QAction::triggered, [this](bool ac) {
319  if (ProjectView *pv = currentProjectView())
320  pv->project()->setAutoConductor(ac);
321  });
322 
323  //Switch background color
324  m_grey_background = new QAction (QET::Icons::DiagramBg, tr("Couleur de fond blanc/gris","Tool tip of white/grey background button"), this);
325  m_grey_background -> setStatusTip (tr("Affiche la couleur de fond du folio en blanc ou en gris", "Status tip of white/grey background button"));
326  m_grey_background -> setCheckable (true);
327  connect (m_grey_background, &QAction::triggered, [this](bool checked) {
328  Diagram::background_color = checked ? Qt::darkGray : Qt::white;
329  if (this->currentDiagramView() && this->currentDiagramView()->diagram())
330  this->currentDiagramView()->diagram()->update();
331  });
332 
333  //Draw or not the background grid
334  m_draw_grid = new QAction ( QET::Icons::Grid, tr("Afficher la grille"), this);
335  m_draw_grid->setStatusTip(tr("Affiche ou masque la grille des folios"));
336  m_draw_grid->setCheckable(true);
337  m_draw_grid->setChecked(true);
338  connect(m_draw_grid, &QAction::triggered, [this](bool checked) {
339  foreach (ProjectView *prjv, this->openedProjects())
340  foreach (Diagram *d, prjv->project()->diagrams()) {
341  d->setDisplayGrid(checked);
342  d->update();
343  }
344  });
345 
346  //Edit current diagram properties
347  m_edit_diagram_properties = new QAction(QET::Icons::DialogInformation, tr("Propriétés du folio"), this);
348  m_edit_diagram_properties->setShortcut( QKeySequence( tr("Ctrl+L")));
349  m_edit_diagram_properties -> setStatusTip(tr("Édite les propriétés du folio (dimensions, informations du cartouche, propriétés des conducteurs...)", "status bar tip"));
350  connect(m_edit_diagram_properties, &QAction::triggered, [this]() {
351  if (ProjectView *project_view = currentProjectView())
352  {
353  activateProject(project_view);
354  project_view->editCurrentDiagramProperties();
355  }
356  });
357 
358  //Edit current project properties
359  m_project_edit_properties = new QAction(QET::Icons::ProjectProperties, tr("Propriétés du projet"), this);
360  connect(m_project_edit_properties, &QAction::triggered, [this]() {
362  });
363 
364  //Add new folio to current project
365  m_project_add_diagram = new QAction(QET::Icons::DiagramAdd, tr("Ajouter un folio"), this);
366  m_project_add_diagram->setShortcut(QKeySequence(tr("Ctrl+T")));
367  connect(m_project_add_diagram, &QAction::triggered, [this]() {
368  if (ProjectView *current_project = currentProjectView()) {
369  current_project->addNewDiagram();
370  }
371  });
372 
373  //Remove current folio from current project
374  m_remove_diagram_from_project = new QAction(QET::Icons::DiagramDelete, tr("Supprimer le folio"), this);
376 
377  //Clean the current project
378  m_clean_project = new QAction(QET::Icons::EditClear, tr("Nettoyer le projet"), this);
379  connect(m_clean_project, &QAction::triggered, [this]() {
380  if (ProjectView *current_project = currentProjectView()) {
381  if (current_project->cleanProject()) {
382  pa -> reloadAndFilter();
383  }
384  }
385  });
386 
387  //Add folio list to current project
388  m_project_folio_list = new QAction(QET::Icons::TableOfContent, tr("Ajouter un sommaire"), this);
389  connect(m_project_folio_list, &QAction::triggered, [this]() {
390  if (ProjectView *current_project = currentProjectView()) {
391  current_project->addNewDiagramFolioList();
392  }
393  });
394 
395  //Export nomenclature to CSV
396  m_project_nomenclature = new QAction(QET::Icons::DocumentSpreadsheet, tr("Exporter une nomenclature"), this);
397  connect(m_project_nomenclature, &QAction::triggered, [this]() {
398  nomenclature nomencl(currentProjectView()->project(), this);
399  nomencl.saveToCSVFile();
400  });
401 
402  //Lauch the plugin of terminal generator
403  m_project_terminalBloc = new QAction(QET::Icons::TerminalStrip, tr("Lancer le plugin de création de borniers"), this);
404  connect(m_project_terminalBloc, &QAction::triggered, this, &QETDiagramEditor::generateTerminalBlock);
405 
406  //MDI view style
407  m_tabbed_view_mode = new QAction(tr("en utilisant des onglets"), this);
408  m_tabbed_view_mode->setStatusTip(tr("Présente les différents projets ouverts des onglets", "status bar tip"));
409  m_tabbed_view_mode->setCheckable(true);
410  connect(m_tabbed_view_mode, &QAction::triggered, this, &QETDiagramEditor::setTabbedMode);
411 
412  m_windowed_view_mode = new QAction(tr("en utilisant des fenêtres"), this);
413  m_windowed_view_mode->setStatusTip(tr("Présente les différents projets ouverts dans des sous-fenêtres", "status bar tip"));
414  m_windowed_view_mode->setCheckable(true);
415  connect(m_windowed_view_mode, &QAction::triggered, this, &QETDiagramEditor::setWindowedMode);
416 
417  m_group_view_mode = new QActionGroup(this);
420  m_group_view_mode -> setExclusive(true);
421 
422  m_tile_window = new QAction(tr("&Mosaïque"), this);
423  m_tile_window->setStatusTip(tr("Dispose les fenêtres en mosaïque", "status bar tip"));
424  connect(m_tile_window, &QAction::triggered, &m_workspace, &QMdiArea::tileSubWindows);
425 
426  m_cascade_window = new QAction(tr("&Cascade"), this);
427  m_cascade_window->setStatusTip(tr("Dispose les fenêtres en cascade", "status bar tip"));
428  connect(m_cascade_window, &QAction::triggered, &m_workspace, &QMdiArea::cascadeSubWindows);
429 
430  //Switch selection/view mode
431  m_mode_selection = new QAction(QET::Icons::PartSelect, tr("Mode Selection"), this);
432  m_mode_selection->setStatusTip(tr("Permet de sélectionner les éléments", "status bar tip"));
433  m_mode_selection->setCheckable(true);
434  m_mode_selection->setChecked(true);
435  connect(m_mode_selection, &QAction::triggered, [this]() {
436  if (ProjectView *pv = currentProjectView()) {
437  for (DiagramView *dv : pv->diagram_views()) {
438  dv->setSelectionMode();
439  }
440  }
441  });
442 
443  m_mode_visualise = new QAction(QET::Icons::ViewMove, tr("Mode Visualisation"), this);
444  m_mode_visualise->setStatusTip(tr("Permet de visualiser le folio sans pouvoir le modifier", "status bar tip"));
445  m_mode_visualise->setCheckable(true);
446  connect(m_mode_visualise, &QAction::triggered, [this]() {
447  if (ProjectView *pv = currentProjectView()) {
448  for(DiagramView *dv : pv->diagram_views()) {
449  dv->setVisualisationMode();
450  }
451  }
452  });
453 
454  grp_visu_sel = new QActionGroup(this);
455  grp_visu_sel->addAction(m_mode_selection);
456  grp_visu_sel->addAction(m_mode_visualise);
457  grp_visu_sel->setExclusive(true);
458 
459  //Navigate next/previous project
460  m_next_window = new QAction(tr("Projet suivant"), this);
461  m_next_window->setShortcut(QKeySequence::NextChild);
462  m_next_window->setStatusTip(tr("Active le projet suivant", "status bar tip"));
463  connect(m_next_window, &QAction::triggered, &m_workspace, &QMdiArea::activateNextSubWindow);
464 
465  m_previous_window = new QAction(tr("Projet précédent"), this);
466  m_previous_window->setShortcut(QKeySequence::PreviousChild);
467  m_previous_window->setStatusTip(tr("Active le projet précédent", "status bar tip"));
468  connect(m_previous_window, &QAction::triggered, &m_workspace, &QMdiArea::activatePreviousSubWindow);
469 
470  //Files action
471  QAction *new_file = m_file_actions_group.addAction(QET::Icons::ProjectNew, tr("&Nouveau"));
472  QAction *open_file = m_file_actions_group.addAction(QET::Icons::DocumentOpen, tr("&Ouvrir"));
473  m_save_file = m_file_actions_group.addAction(QET::Icons::DocumentSave, tr("&Enregistrer"));
474  m_save_file_as = m_file_actions_group.addAction(QET::Icons::DocumentSaveAs, tr("Enregistrer sous"));
476 
477  new_file ->setShortcut(QKeySequence::New);
478  open_file ->setShortcut(QKeySequence::Open);
479  m_close_file ->setShortcut(QKeySequence::Close);
480  m_save_file ->setShortcut(QKeySequence::Save);
481 
482  new_file ->setStatusTip( tr("Crée un nouveau projet", "status bar tip") );
483  open_file ->setStatusTip( tr("Ouvre un projet existant", "status bar tip") );
484  m_close_file ->setStatusTip( tr("Ferme le projet courant", "status bar tip") );
485  m_save_file ->setStatusTip( tr("Enregistre le projet courant et tous ses folios", "status bar tip") );
486  m_save_file_as ->setStatusTip( tr("Enregistre le projet courant avec un autre nom de fichier", "status bar tip") );
487 
488  connect(m_save_file_as, &QAction::triggered, this, &QETDiagramEditor::saveAs);
489  connect(m_save_file, &QAction::triggered, this, &QETDiagramEditor::save);
490  connect(new_file, &QAction::triggered, this, &QETDiagramEditor::newProject);
491  connect(open_file, &QAction::triggered, this, &QETDiagramEditor::openProject);
492  connect(m_close_file, &QAction::triggered, [this]() {
493  if (ProjectView *project_view = currentProjectView()) {
494  closeProject(project_view);
495  }
496  });
497 
498  //Rows and Columns
499  QAction *add_column = m_row_column_actions_group.addAction( QET::Icons::EditTableInsertColumnRight, tr("Ajouter une colonne") );
500  QAction *remove_column = m_row_column_actions_group.addAction( QET::Icons::EditTableDeleteColumn, tr("Enlever une colonne") );
501  QAction *add_row = m_row_column_actions_group.addAction( QET::Icons::EditTableInsertRowUnder, tr("Ajouter une ligne", "Add row") );
502  QAction *remove_row = m_row_column_actions_group.addAction( QET::Icons::EditTableDeleteRow, tr("Enlever une ligne","Remove row") );
503 
504  add_column -> setStatusTip( tr("Ajoute une colonne au folio", "status bar tip"));
505  remove_column -> setStatusTip( tr("Enlève une colonne au folio", "status bar tip"));
506  add_row -> setStatusTip( tr("Agrandit le folio en hauteur", "status bar tip"));
507  remove_row -> setStatusTip( tr("Rétrécit le folio en hauteur", "status bar tip"));
508 
509  add_column ->setData("add_column");
510  remove_column->setData("remove_column");
511  add_row ->setData("add_row");
512  remove_row ->setData("remove_row");
513 
514  connect(&m_row_column_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::rowColumnGroupTriggered);
515 
516  //Selections Actions (related to a selected item)
519  m_rotate_texts = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes") );
520  m_find_element = m_selection_actions_group.addAction( QET::Icons::ZoomDraw, tr("Retrouver dans le panel") );
521  m_edit_selection = m_selection_actions_group.addAction( QET::Icons::ElementEdit, tr("Éditer l'item sélectionné") );
522  m_group_selected_texts = m_selection_actions_group.addAction(QET::Icons::textGroup, tr("Grouper les textes sélectionnés"));
523 
524  m_delete_selection->setShortcut(QKeySequence::Delete);
525  m_rotate_selection->setShortcut(QKeySequence( tr("Space")));
526  m_rotate_texts ->setShortcut(QKeySequence( tr("Ctrl+Space")));
527  m_edit_selection ->setShortcut(QKeySequence( tr("Ctrl+E")));
528 
529  m_delete_selection->setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
530  m_rotate_selection->setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
531  m_rotate_texts ->setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "status bar tip"));
532  m_find_element ->setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip"));
533 
534  m_delete_selection ->setData("delete_selection");
535  m_rotate_selection ->setData("rotate_selection");
536  m_rotate_texts ->setData("rotate_selected_text");
537  m_find_element ->setData("find_selected_element");
538  m_edit_selection ->setData("edit_selected_element");
539  m_group_selected_texts->setData("group_selected_texts");
540 
541  connect(&m_selection_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::selectionGroupTriggered);
542 
543  //Select Action
544  QAction *select_all = m_select_actions_group.addAction( QET::Icons::EditSelectAll, tr("Tout sélectionner") );
545  QAction *select_nothing = m_select_actions_group.addAction( QET::Icons::EditSelectNone, tr("Désélectionner tout") );
546  QAction *select_invert = m_select_actions_group.addAction( QET::Icons::EditSelectInvert, tr("Inverser la sélection") );
547 
548  select_all ->setShortcut(QKeySequence::SelectAll);
549  select_nothing->setShortcut(QKeySequence::Deselect);
550  select_invert ->setShortcut(QKeySequence( tr("Ctrl+I")));
551 
552  select_all ->setStatusTip( tr("Sélectionne tous les éléments du folio", "status bar tip") );
553  select_nothing->setStatusTip( tr("Désélectionne tous les éléments du folio", "status bar tip") );
554  select_invert ->setStatusTip( tr("Désélectionne les éléments sélectionnés et sélectionne les éléments non sélectionnés", "status bar tip") );
555 
556  select_all ->setData("select_all");
557  select_nothing->setData("deselect");
558  select_invert ->setData("invert_selection");
559 
560  connect(&m_select_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::selectGroupTriggered);
561 
562  //Zoom actions
563  QAction *zoom_in = m_zoom_actions_group.addAction( QET::Icons::ZoomIn, tr("Zoom avant"));
564  QAction *zoom_out = m_zoom_actions_group.addAction( QET::Icons::ZoomOut, tr("Zoom arrière"));
565  QAction *zoom_content = m_zoom_actions_group.addAction( QET::Icons::ZoomDraw, tr("Zoom sur le contenu"));
566  QAction *zoom_fit = m_zoom_actions_group.addAction( QET::Icons::ZoomFitBest, tr("Zoom adapté"));
567  QAction *zoom_reset = m_zoom_actions_group.addAction( QET::Icons::ZoomOriginal, tr("Pas de zoom"));
568  m_zoom_action_toolBar << zoom_content << zoom_fit << zoom_reset;
569 
570  zoom_in ->setShortcut(QKeySequence::ZoomIn);
571  zoom_out ->setShortcut(QKeySequence::ZoomOut);
572  zoom_content->setShortcut(QKeySequence( tr("Ctrl+8")));
573  zoom_fit ->setShortcut(QKeySequence( tr("Ctrl+9")));
574  zoom_reset ->setShortcut(QKeySequence( tr("Ctrl+0")));
575 
576  zoom_in ->setStatusTip(tr("Agrandit le folio", "status bar tip"));
577  zoom_out ->setStatusTip(tr("Rétrécit le folio", "status bar tip"));
578  zoom_content->setStatusTip(tr("Adapte le zoom de façon à afficher tout le contenu du folio indépendamment du cadre"));
579  zoom_fit ->setStatusTip(tr("Adapte le zoom exactement sur le cadre du folio", "status bar tip"));
580  zoom_reset ->setStatusTip(tr("Restaure le zoom par défaut", "status bar tip"));
581 
582  zoom_in ->setData("zoom_in");
583  zoom_out ->setData("zoom_out");
584  zoom_content->setData("zoom_content");
585  zoom_fit ->setData("zoom_fit");
586  zoom_reset ->setData("zoom_reset");
587 
588  connect(&m_zoom_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::zoomGroupTriggered);
589 
590  //Adding action (add text, image, shape...)
591  QAction *add_text = m_add_item_actions_group.addAction(QET::Icons::PartTextField, tr("Ajouter un champ de texte"));
592  QAction *add_image = m_add_item_actions_group.addAction(QET::Icons::adding_image, tr("Ajouter une image"));
593  QAction *add_line = m_add_item_actions_group.addAction(QET::Icons::PartLine, tr("Ajouter une ligne", "Draw line"));
594  QAction *add_rectangle = m_add_item_actions_group.addAction(QET::Icons::PartRectangle, tr("Ajouter un rectangle"));
595  QAction *add_ellipse = m_add_item_actions_group.addAction(QET::Icons::PartEllipse, tr("Ajouter une ellipse"));
596  QAction *add_polyline = m_add_item_actions_group.addAction(QET::Icons::PartPolygon, tr("Ajouter une polyligne"));
597 
598  add_text ->setStatusTip(tr("Ajoute un champ de texte sur le folio actuel"));
599  add_image ->setStatusTip(tr("Ajoute une image sur le folio actuel"));
600  add_line ->setStatusTip(tr("Ajoute une ligne sur le folio actuel"));
601  add_rectangle->setStatusTip(tr("Ajoute un rectangle sur le folio actuel"));
602  add_ellipse ->setStatusTip(tr("Ajoute une ellipse sur le folio actuel"));
603  add_polyline ->setStatusTip(tr("Ajoute une polyligne sur le folio actuel"));
604 
605  add_text ->setData("text");
606  add_image ->setData("image");
607  add_line ->setData("line");
608  add_rectangle->setData("rectangle");
609  add_ellipse ->setData("ellipse");
610  add_polyline ->setData("polyline");
611 
612  for(QAction *action : m_add_item_actions_group.actions()) {
613  action->setCheckable(true);
614  }
615  connect(&m_add_item_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::addItemGroupTriggered);
616 
617  //Depth action
619  m_depth_action_group->setDisabled(true);
620 
621  connect(m_depth_action_group, &QActionGroup::triggered, [this](QAction *action) {
622  this->currentDiagramView()->diagram()->changeZValue(action->data().value<QET::DepthOption>());
623  });
624 
625  m_find = new QAction(tr("Chercher/remplacer"), this);
626  m_find->setShortcut(QKeySequence::Find);
627  connect(m_find, &QAction::triggered, [this]() {
628  this->m_search_and_replace_widget.setHidden(!m_search_and_replace_widget.isHidden());
629  });
630 }
631 
636 {
637  main_tool_bar = new QToolBar(tr("Outils"), this);
638  main_tool_bar -> setObjectName("toolbar");
639 
640  view_tool_bar = new QToolBar(tr("Affichage"), this);
641  view_tool_bar -> setObjectName("display");
642 
643  diagram_tool_bar = new QToolBar(tr("Schéma"), this);
644  diagram_tool_bar -> setObjectName("diagram");
645 
646  main_tool_bar -> addActions(m_file_actions_group.actions());
647  main_tool_bar -> addAction(m_print);
648  main_tool_bar -> addSeparator();
649  main_tool_bar -> addAction(undo);
650  main_tool_bar -> addAction(redo);
651  main_tool_bar -> addSeparator();
652  main_tool_bar -> addAction(m_cut);
653  main_tool_bar -> addAction(m_copy);
654  main_tool_bar -> addAction(m_paste);
655  main_tool_bar -> addSeparator();
656  main_tool_bar -> addAction(m_delete_selection);
657  main_tool_bar -> addAction(m_rotate_selection);
658 
659  // Modes selection / visualisation et zoom
660  view_tool_bar -> addAction(m_mode_selection);
661  view_tool_bar -> addAction(m_mode_visualise);
662  view_tool_bar -> addSeparator();
663  view_tool_bar -> addAction(m_draw_grid);
664  view_tool_bar -> addAction (m_grey_background);
665  view_tool_bar -> addSeparator();
666  view_tool_bar -> addActions(m_zoom_action_toolBar);
667 
669  diagram_tool_bar -> addAction (m_conductor_reset);
670  diagram_tool_bar -> addAction (m_auto_conductor);
671 
672  m_add_item_tool_bar = new QToolBar(tr("Ajouter"), this);
673  m_add_item_tool_bar->setObjectName("adding");
674  m_add_item_tool_bar->addActions(m_add_item_actions_group.actions());
675 
676  m_depth_tool_bar = new QToolBar(tr("Profondeur", "toolbar title"));
677  m_depth_tool_bar->setObjectName("diagram_depth_toolbar");
678  m_depth_tool_bar->addActions(m_depth_action_group->actions());
679 
680  addToolBar(Qt::TopToolBarArea, main_tool_bar);
681  addToolBar(Qt::TopToolBarArea, view_tool_bar);
682  addToolBar(Qt::TopToolBarArea, diagram_tool_bar);
683  addToolBar(Qt::TopToolBarArea, m_add_item_tool_bar);
684  addToolBar(Qt::TopToolBarArea, m_depth_tool_bar);
685 }
686 
691 
692  QMenu *menu_fichier = new QMenu(tr("&Fichier"));
693  QMenu *menu_edition = new QMenu(tr("&Édition"));
694  QMenu *menu_project = new QMenu(tr("&Projet"));
695  QMenu *menu_affichage = new QMenu(tr("Afficha&ge"));
696  //QMenu *menu_outils = new QMenu(tr("O&utils"));
697  windows_menu = new QMenu(tr("Fe&nêtres"));
698 
699  insertMenu(settings_menu_, menu_fichier);
700  insertMenu(settings_menu_, menu_edition);
701  insertMenu(settings_menu_, menu_project);
702  insertMenu(settings_menu_, menu_affichage);
704 
705  // File menu
706  QMenu *recentfile = menu_fichier -> addMenu(QET::Icons::DocumentOpenRecent, tr("&Récemment ouverts"));
707  recentfile->addActions(QETApp::projectsRecentFiles()->menu()->actions());
708  connect(QETApp::projectsRecentFiles(), SIGNAL(fileOpeningRequested(const QString &)), this, SLOT(openRecentFile(const QString &)));
709  menu_fichier -> addActions(m_file_actions_group.actions());
710  menu_fichier -> addSeparator();
711  //menu_fichier -> addAction(import_diagram);
712  menu_fichier -> addAction(m_export_diagram);
713  //menu_fichier -> addSeparator();
714  menu_fichier -> addAction(m_print);
715  menu_fichier -> addSeparator();
716  menu_fichier -> addAction(m_quit_editor);
717 
718  // menu Edition
719  menu_edition -> addAction(undo);
720  menu_edition -> addAction(redo);
721  menu_edition -> addSeparator();
722  menu_edition -> addAction(m_cut);
723  menu_edition -> addAction(m_copy);
724  menu_edition -> addAction(m_paste);
725  menu_edition -> addSeparator();
726  menu_edition -> addActions(m_select_actions_group.actions());
727  menu_edition -> addSeparator();
728  menu_edition -> addActions(m_selection_actions_group.actions());
729  menu_edition -> addSeparator();
730  menu_edition -> addAction(m_conductor_reset);
731  menu_edition -> addSeparator();
732  menu_edition -> addAction(m_edit_diagram_properties);
733  menu_edition -> addActions(m_row_column_actions_group.actions());
734  menu_edition -> addSeparator();
735  menu_edition -> addActions(m_depth_action_group->actions());
736  menu_edition -> addSeparator();
737  menu_edition -> addAction(m_find);
738 
739  // menu Projet
740  menu_project -> addAction(m_project_edit_properties);
741  menu_project -> addAction(m_project_add_diagram);
742  menu_project -> addAction(m_remove_diagram_from_project);
743  menu_project -> addAction(m_clean_project);
744  menu_project -> addSeparator();
745  menu_project -> addAction(m_project_folio_list);
746  menu_project -> addAction(m_project_nomenclature);
747  menu_project -> addAction(m_project_terminalBloc);
748 
749  main_tool_bar -> toggleViewAction() -> setStatusTip(tr("Affiche ou non la barre d'outils principale"));
750  view_tool_bar -> toggleViewAction() -> setStatusTip(tr("Affiche ou non la barre d'outils Affichage"));
751  diagram_tool_bar -> toggleViewAction() -> setStatusTip(tr("Affiche ou non la barre d'outils Schéma"));
752  qdw_pa -> toggleViewAction() -> setStatusTip(tr("Affiche ou non le panel d'appareils"));
753  qdw_undo -> toggleViewAction() -> setStatusTip(tr("Affiche ou non la liste des modifications"));
754 
755 
756  // menu Affichage
757  QMenu *projects_view_mode = menu_affichage -> addMenu(QET::Icons::ConfigureToolbars, tr("Afficher les projets"));
758  projects_view_mode -> setTearOffEnabled(true);
759  projects_view_mode -> addAction(m_windowed_view_mode);
760  projects_view_mode -> addAction(m_tabbed_view_mode);
761 
762  menu_affichage -> addSeparator();
763  menu_affichage -> addAction(m_mode_selection);
764  menu_affichage -> addAction(m_mode_visualise);
765  menu_affichage -> addSeparator();
766  menu_affichage -> addAction(m_draw_grid);
767  menu_affichage -> addAction(m_grey_background);
768  menu_affichage -> addSeparator();
769  menu_affichage -> addActions(m_zoom_actions_group.actions());
770 
771  // menu Fenetres
773 }
774 
779 void QETDiagramEditor::closeEvent(QCloseEvent *qce) {
780  // quitte directement s'il n'y a aucun projet ouvert
781  bool can_quit = true;
782  if (openedProjects().count()) {
783  // s'assure que la fenetre soit visible s'il y a des projets a fermer
784  if (!isVisible() || isMinimized()) {
785  if (isMaximized()) showMaximized();
786  else showNormal();
787  }
788  // sinon demande la permission de fermer chaque projet
789  foreach(ProjectView *project, openedProjects()) {
790  if (!closeProject(project)) {
791  can_quit = false;
792  qce -> ignore();
793  break;
794  }
795  }
796  }
797  if (can_quit) {
798  writeSettings();
799  setAttribute(Qt::WA_DeleteOnClose);
800  qce -> accept();
801  }
802 }
803 
811 bool QETDiagramEditor::event(QEvent *e)
812 {
813  if (m_first_show && e->type() == QEvent::WindowActivate)
814  {
815  m_first_show = false;
816  QTimer::singleShot(250, m_element_collection_widget, SLOT(reload()));
817  }
818  return(QETMainWindow::event(e));
819 }
820 
826  if (ProjectView *project_view = currentProjectView()) {
827  QETResult saved = project_view -> save();
828 
829  if (saved.isOk()) {
830  //save_file -> setDisabled(true);
831  QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath());
832 
833  QString title = (project_view -> project() -> title ());
834  if (title.isEmpty()) title = "QElectroTech ";
835  QString filePath = (project_view -> project() -> filePath ());
836  statusBar()-> showMessage(tr("Projet %1 enregistré dans le repertoire: %2.").arg(title).arg (filePath), 2000);
838  }
839  else {
840  showError(saved);
841  }
842  }
843 }
844 
850  if (ProjectView *project_view = currentProjectView()) {
851  QETResult save_file = project_view -> saveAs();
852  if (save_file.isOk()) {
853  QETApp::projectsRecentFiles() -> fileWasOpened(project_view -> project() -> filePath());
854 
855  QString title = (project_view -> project() -> title ());
856  if (title.isEmpty()) title = "QElectroTech ";
857  QString filePath = (project_view -> project() -> filePath ());
858  statusBar()->showMessage(tr("Projet %1 enregistré dans le repertoire: %2.").arg(title).arg (filePath), 2000);
860  }
861  else {
862  showError(save_file);
863  }
864  }
865 }
866 
873  // create new project without diagram
874  QETProject *new_project = new QETProject(this);
875 
876  // Set default properties for new diagram
877  new_project -> setDefaultBorderProperties (BorderProperties:: defaultProperties());
878  new_project -> setDefaultConductorProperties (ConductorProperties:: defaultProperties());
879  new_project -> setDefaultTitleBlockProperties (TitleBlockProperties::defaultProperties());
880  new_project -> setDefaultReportProperties (ReportProperties:: defaultProperties());
881  new_project -> setDefaultXRefProperties (XRefProperties:: defaultProperties());
882 
883  // add new diagram
884  new_project -> addNewDiagram();
885 
886  return(addProject(new_project));
887 }
888 
896 bool QETDiagramEditor::openRecentFile(const QString &filepath) {
897  // small hack to prevent all diagram editors from trying to topen the required
898  // recent file at the same time
899  if (qApp -> activeWindow() != this) return(false);
900  return(openAndAddProject(filepath));
901 }
902 
908  // demande un chemin de fichier a ouvrir a l'utilisateur
909  QString filepath = QFileDialog::getOpenFileName(
910  this,
911  tr("Ouvrir un fichier"),
912  open_dialog_dir.absolutePath(),
913  tr("Projets QElectroTech (*.qet);;Fichiers XML (*.xml);;Tous les fichiers (*)")
914  );
915  if (filepath.isEmpty()) return(false);
916 
917  // retient le dossier contenant le dernier projet ouvert
918  open_dialog_dir = QDir(filepath);
919 
920  // ouvre le fichier
921  return(openAndAddProject(filepath));
922 }
923 
931  if (project_view) {
932  activateProject(project_view);
933  if (QMdiSubWindow *sub_window = subWindowForWidget(project_view)){
934  return(sub_window -> close());
935  }
936  }
937  return(true);
938 }
939 
947  if (ProjectView *project_view = findProject(project)) {
948  return(closeProject(project_view));
949  }
950  return(true);
951 }
952 
959 bool QETDiagramEditor::openAndAddProject(const QString &filepath, bool interactive)
960 {
961  if (filepath.isEmpty()) return(false);
962 
963  QFileInfo filepath_info(filepath);
964 
965  //Check if project is not open in another editor
966  if (QETDiagramEditor *diagram_editor = QETApp::diagramEditorForFile(filepath))
967  {
968  if (diagram_editor == this)
969  {
970  if (ProjectView *project_view = viewForFile(filepath))
971  {
972  activateWidget(project_view);
973  show();
974  activateWindow();
975  }
976  return(false);
977  }
978  else
979  {
980  //Ask to the other editor to display the file
981  return(diagram_editor -> openAndAddProject(filepath));
982  }
983  }
984 
985  // check the file exists
986  if (!filepath_info.exists())
987  {
988  if (interactive)
989  {
991  this,
992  tr("Impossible d'ouvrir le fichier", "message box title"),
993  QString(
994  tr("Il semblerait que le fichier %1 que vous essayez d'ouvrir"
995  " n'existe pas ou plus.")
996  ).arg(filepath)
997  );
998  }
999  return(false);
1000  }
1001 
1002  //Check if file readable
1003  if (!filepath_info.isReadable())
1004  {
1005  if (interactive) {
1007  this,
1008  tr("Impossible d'ouvrir le fichier", "message box title"),
1009  tr("Il semblerait que le fichier que vous essayez d'ouvrir ne "
1010  "soit pas accessible en lecture. Il est donc impossible de "
1011  "l'ouvrir. Veuillez vérifier les permissions du fichier.")
1012  );
1013  }
1014  return(false);
1015  }
1016 
1017  //Check if file is read only
1018  if (!filepath_info.isWritable())
1019  {
1020  if (interactive) {
1022  this,
1023  tr("Ouverture du projet en lecture seule", "message box title"),
1024  tr("Il semblerait que le projet que vous essayez d'ouvrir ne "
1025  "soit pas accessible en écriture. Il sera donc ouvert en "
1026  "lecture seule.")
1027  );
1028  }
1029  }
1030 
1031  //Create the project
1033 
1034  QETProject *project = new QETProject(filepath);
1035  if (project -> state() != QETProject::Ok)
1036  {
1037  if (interactive && project -> state() != QETProject::FileOpenDiscard)
1038  {
1040  this,
1041  tr("Échec de l'ouverture du projet", "message box title"),
1042  QString(
1043  tr(
1044  "Il semblerait que le fichier %1 ne soit pas un fichier"
1045  " projet QElectroTech. Il ne peut donc être ouvert.",
1046  "message box content"
1047  )
1048  ).arg(filepath)
1049  );
1050  }
1051  delete project;
1053  return(false);
1054  }
1055 
1056  QETApp::projectsRecentFiles() -> fileWasOpened(filepath);
1057  addProject(project);
1059  return true;
1060 }
1061 
1068 bool QETDiagramEditor::addProject(QETProject *project, bool update_panel) {
1069  // enregistre le projet
1070  QETApp::registerProject(project);
1071 
1072  // cree un ProjectView pour visualiser le projet
1073  ProjectView *project_view = new ProjectView(project);
1074  addProjectView(project_view);
1075 
1076  undo_group.addStack(project -> undoStack());
1077 
1079 
1080  // met a jour le panel d'elements
1081  if (update_panel) {
1082  pa -> elementsPanel().projectWasOpened(project);
1083  if (currentDiagramView() != nullptr)
1084  m_autonumbering_dock->setProject(project, project_view);
1085  }
1086 
1087  return(true);
1088 }
1089 
1093 QList<ProjectView *> QETDiagramEditor::openedProjects() const {
1094  QList<ProjectView *> result;
1095  QList<QMdiSubWindow *> window_list(m_workspace.subWindowList());
1096  foreach(QMdiSubWindow *window, window_list) {
1097  if (ProjectView *project_view = qobject_cast<ProjectView *>(window -> widget())) {
1098  result << project_view;
1099  }
1100  }
1101  return(result);
1102 }
1103 
1109  QMdiSubWindow *current_window = m_workspace.activeSubWindow();
1110  if (!current_window) return(nullptr);
1111 
1112  QWidget *current_widget = current_window -> widget();
1113  if (!current_widget) return(nullptr);
1114 
1115  if (ProjectView *project_view = qobject_cast<ProjectView *>(current_widget)) {
1116  return(project_view);
1117  }
1118  return(nullptr);
1119 }
1120 
1127 {
1128  ProjectView *view = currentProjectView();
1129  if (view) {
1130  return view->project();
1131  }
1132  else {
1133  return nullptr;
1134  }
1135 }
1136 
1142  if (ProjectView *project_view = currentProjectView()) {
1143  return(project_view -> currentDiagram());
1144  }
1145  return(nullptr);
1146 }
1147 
1155 {
1157  if (!dv)
1158  return(nullptr);
1159 
1160  QList<Element *> selected_elements = DiagramContent(dv->diagram()).m_elements;
1161  if (selected_elements.count() != 1)
1162  return(nullptr);
1163 
1164  return(selected_elements.first());
1165 }
1166 
1173  foreach(ProjectView *project_view, openedProjects()) {
1174  if (project_view -> diagram_views().contains(diagram_view)) {
1175  return(project_view);
1176  }
1177  }
1178  return(nullptr);
1179 }
1180 
1187  foreach(ProjectView *project_view, openedProjects()) {
1188  foreach(DiagramView *diagram_view, project_view -> diagram_views()) {
1189  if (diagram_view -> diagram() == diagram) {
1190  return(project_view);
1191  }
1192  }
1193  }
1194  return(nullptr);
1195 }
1196 
1202  foreach(ProjectView *opened_project, openedProjects()) {
1203  if (opened_project -> project() == project) {
1204  return(opened_project);
1205  }
1206  }
1207  return(nullptr);
1208 }
1209 
1215 ProjectView *QETDiagramEditor::findProject(const QString &filepath) const {
1216  foreach(ProjectView *opened_project, openedProjects()) {
1217  if (QETProject *project = opened_project -> project()) {
1218  if (project -> filePath() == filepath) {
1219  return(opened_project);
1220  }
1221  }
1222  }
1223  return(nullptr);
1224 }
1225 
1231 QMdiSubWindow *QETDiagramEditor::subWindowForWidget(QWidget *widget) const {
1232  foreach(QMdiSubWindow *sub_window, m_workspace.subWindowList()) {
1233  if (sub_window -> widget() == widget) {
1234  return(sub_window);
1235  }
1236  }
1237  return(nullptr);
1238 }
1239 
1243 void QETDiagramEditor::activateWidget(QWidget *widget) {
1244  QMdiSubWindow *sub_window = subWindowForWidget(widget);
1245  if (sub_window) {
1246  m_workspace.setActiveSubWindow(sub_window);
1247  }
1248 }
1249 
1251 {
1252  QString value = action->data().toString();
1254 
1255  if (!dv || value.isEmpty()) return;
1256 
1257  if (value == "zoom_in")
1258  dv->zoom(1.15);
1259  else if (value == "zoom_out")
1260  dv->zoom(0.85);
1261  else if (value == "zoom_content")
1262  dv->zoomContent();
1263  else if (value == "zoom_fit")
1264  dv->zoomFit();
1265  else if (value == "zoom_reset")
1266  dv->zoomReset();
1267 }
1268 
1275 {
1276  QString value = action->data().toString();
1278 
1279  if (!dv || value.isEmpty()) return;
1280 
1281  if (value == "select_all")
1282  dv->selectAll();
1283  else if (value == "deselect")
1284  dv->selectNothing();
1285  else if (value == "invert_selection")
1286  dv->selectInvert();
1287 }
1288 
1296 {
1297  QString value = action->data().toString();
1298 
1299  if (Q_UNLIKELY (!currentDiagramView() || !currentDiagramView()->diagram() || value.isEmpty())) return;
1300 
1302  DiagramEventInterface *diagram_event = nullptr;
1303 
1304  if (value == "line")
1305  diagram_event = new DiagramEventAddShape (d, QetShapeItem::Line);
1306  else if (value == "rectangle")
1307  diagram_event = new DiagramEventAddShape (d, QetShapeItem::Rectangle);
1308  else if (value == "ellipse")
1309  diagram_event = new DiagramEventAddShape (d, QetShapeItem::Ellipse);
1310  else if (value == "polyline")
1311  {
1312  diagram_event = new DiagramEventAddShape (d, QetShapeItem::Polygon);
1313  statusBar()-> showMessage(tr("Double-click pour terminer la forme, Click droit pour annuler le dernier point"));
1314  connect(diagram_event, &DiagramEventInterface::destroyed, [this]() {
1315  statusBar()->clearMessage();
1316  });
1317  }
1318  else if (value == "image")
1319  {
1321  if (deai->isNull())
1322  {
1323  delete deai;
1324  action->setChecked(false);
1325  return;
1326  }
1327  else
1328  diagram_event = deai;
1329  }
1330  else if (value == "text")
1331  diagram_event = new DiagramEventAddText(d);
1332 
1333  if (diagram_event)
1334  {
1335  d->setEventInterface(diagram_event);
1336  connect(diagram_event, &DiagramEventInterface::destroyed, [action]() {action->setChecked(false);});
1337  }
1338 }
1339 
1346 {
1347  QString value = action->data().toString();
1349  Diagram *diagram = dv->diagram();
1350  DiagramContent dc(diagram);
1351 
1352  if (!dv || value.isEmpty()) return;
1353 
1354  if (value == "delete_selection")
1355  {
1356  diagram->clearSelection();
1357  diagram->undoStack().push(new DeleteQGraphicsItemCommand(diagram, dc));
1358  dv->adjustSceneRect();
1359  }
1360  else if (value == "rotate_selection")
1361  {
1363  if(c->isValid())
1364  diagram->undoStack().push(c);
1365  }
1366  else if (value == "rotate_selected_text")
1367  diagram->undoStack().push(new RotateTextsCommand(diagram));
1368  else if (value == "find_selected_element" && currentElement())
1369  findElementInPanel(currentElement()->location());
1370  else if (value == "edit_selected_element")
1371  dv->editSelection();
1372  else if (value == "group_selected_texts")
1373  {
1374  QList<DynamicElementTextItem *> deti_list = dc.m_element_texts.toList();
1375  if(deti_list.size() <= 1)
1376  return;
1377 
1378  diagram->undoStack().push(new AddTextsGroupCommand(deti_list.first()->parentElement(), tr("Groupe"), deti_list));
1379  }
1380 }
1381 
1383 {
1384  QString value = action->data().toString();
1386 
1387  if (!dv || value.isEmpty() || dv->diagram()->isReadOnly()) return;
1388 
1389  Diagram *d = dv->diagram();
1392 
1393  if (value == "add_column")
1394  new_bp.columns_count += 1;
1395  else if (value == "remove_column")
1396  new_bp.columns_count -= 1;
1397  else if (value == "add_row")
1398  new_bp.rows_count += 1;
1399  else if (value == "remove_row")
1400  new_bp.rows_count -= 1;
1401 
1402  d->undoStack().push(new ChangeBorderCommand(d, old_bp, new_bp));
1403 }
1404 
1410 {
1413 
1414  bool opened_project = pv;
1415  bool opened_diagram = dv;
1416  bool editable_project = (pv && !pv -> project() -> isReadOnly());
1417 
1418  m_close_file -> setEnabled(opened_project);
1419  m_save_file -> setEnabled(opened_project);
1420  m_save_file_as -> setEnabled(opened_project);
1421  m_project_edit_properties -> setEnabled(opened_project);
1422  //prj_terminalBloc -> setEnabled(opened_project);
1423  m_rotate_texts -> setEnabled(editable_project);
1424  m_project_add_diagram -> setEnabled(editable_project);
1425  m_remove_diagram_from_project -> setEnabled(editable_project);
1426  m_clean_project -> setEnabled(editable_project);
1427  m_project_folio_list -> setEnabled(opened_project);
1428  m_project_nomenclature -> setEnabled(editable_project);
1429  m_export_diagram -> setEnabled(opened_diagram);
1430  m_print -> setEnabled(opened_diagram);
1431  m_edit_diagram_properties -> setEnabled(opened_diagram);
1432  m_project_nomenclature -> setEnabled(editable_project);
1433  m_zoom_actions_group. setEnabled(opened_diagram);
1434  m_select_actions_group. setEnabled(opened_diagram);
1435  m_add_item_actions_group. setEnabled(editable_project);
1436  m_row_column_actions_group.setEnabled(editable_project);
1437  m_grey_background->setEnabled(opened_diagram);
1438 
1439 
1445 }
1446 
1452  if ( m_workspace.subWindowList().indexOf(m_workspace.activeSubWindow()) != activeSubWindowIndex) {
1453  activeSubWindowIndex = m_workspace.subWindowList().indexOf(m_workspace.activeSubWindow());
1454  if (currentProjectView() != nullptr && currentDiagramView() != nullptr) {
1456  }
1457  }
1458 }
1459 
1465 {
1466  if(currentProjectView())
1467  undo_group.setActiveStack(currentProjectView()->project()->undoStack());
1468 }
1469 
1476 {
1478  if(!dv)
1479  {
1480  QList <QAction *> action_list;
1482  for(QAction *action : action_list)
1483  action->setEnabled(false);
1484 
1485  return;
1486  }
1487 
1488  Diagram *diagram_ = dv->diagram();
1489  DiagramContent dc(diagram_);
1490  bool ro = diagram_->isReadOnly();
1491 
1492 
1493  //Number of selected conductors
1494  int selected_conductors_count = diagram_->selectedConductors().count();
1495  m_conductor_reset->setEnabled(!ro && selected_conductors_count);
1496 
1497  // number of selected elements
1498  int selected_elements_count = dc.count(DiagramContent::Elements);
1499  m_find_element->setEnabled(selected_elements_count == 1);
1500 
1501  //Action that need items (elements, conductors, texts...) selected, to be enabled
1502  bool copiable_items = dc.hasCopiableItems();
1503  bool deletable_items = dc.hasDeletableItems();
1504  m_cut -> setEnabled(!ro && copiable_items);
1505  m_copy -> setEnabled(copiable_items);
1506  m_delete_selection -> setEnabled(!ro && deletable_items);
1507  m_rotate_selection -> setEnabled(!ro && diagram_->canRotateSelection());
1508 
1509  //Action that need selected texts or texts group
1510  QList<DiagramTextItem *> texts = DiagramContent(diagram_).selectedTexts();
1511  QList<ElementTextItemGroup *> groups = DiagramContent(diagram_).selectedTextsGroup();
1512  int selected_texts = texts.count();
1513  int selected_conductor_texts = 0; for(DiagramTextItem *dti : texts) {if(dti->type() == ConductorTextItem::Type) selected_conductor_texts++;}
1514  int selected_dynamic_elmt_text = 0; for(DiagramTextItem *dti : texts) {if(dti->type() == DynamicElementTextItem::Type) selected_dynamic_elmt_text++;}
1515  m_rotate_texts->setEnabled(!ro && (selected_texts || groups.size()));
1516 
1517  //Action that need only element text selected
1518  QList<DynamicElementTextItem *> deti_list = dc.m_element_texts.toList();
1519  if(deti_list.size() > 1 && dc.count() == deti_list.count())
1520  {
1521  Element *elmt = deti_list.first()->parentElement();
1522  bool ok = true;
1523  for(DynamicElementTextItem *deti : deti_list)
1524  {
1525  if(elmt != deti->parentElement())
1526  ok = false;
1527  }
1528  m_group_selected_texts->setEnabled(!ro && ok);
1529  }
1530  else
1531  m_group_selected_texts->setDisabled(true);
1532 
1533  // actions need only one editable item
1534  int selected_image = dc.count(DiagramContent::Images);
1535 
1536  int selected_shape = dc.count(DiagramContent::Shapes);
1537  int selected_editable = selected_elements_count +
1538  (selected_texts - selected_conductor_texts - selected_dynamic_elmt_text) +
1539  selected_image +
1540  selected_shape +
1541  selected_conductors_count;
1542 
1543  if (selected_editable == 1)
1544  {
1545  m_edit_selection -> setEnabled(true);
1546  //edit element
1547  if (selected_elements_count)
1548  {
1549  m_edit_selection -> setText(tr("Éditer l'élement", "edit element"));
1551  }
1552  //edit text field
1553  else if (selected_texts)
1554  {
1555  m_edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
1557  }
1558  //edit image
1559  else if (selected_image)
1560  {
1561  m_edit_selection -> setText(tr("Éditer l'image", "edit image"));
1563  }
1564  //edit conductor
1565  else if (selected_conductors_count)
1566  {
1567  m_edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
1569  }
1570  }
1571  //not an editable item
1572  else
1573  {
1574  m_edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
1576  m_edit_selection -> setEnabled(false);
1577  }
1578 
1579  //Actions for edit Z value
1580  QList<QGraphicsItem *> list = dc.items(DiagramContent::SelectedOnly | \
1584  m_depth_action_group->setEnabled(list.isEmpty()? false : true);
1585 }
1586 
1592 {
1594 
1595  if (!dv)
1596  grp_visu_sel -> setEnabled(false);
1597  else
1598  {
1599  switch((int)(dv -> dragMode()))
1600  {
1601  case QGraphicsView::NoDrag:
1602  grp_visu_sel -> setEnabled(false);
1603  break;
1604  case QGraphicsView::ScrollHandDrag:
1605  grp_visu_sel -> setEnabled(true);
1606  m_mode_visualise -> setChecked(true);
1607  break;
1608  case QGraphicsView::RubberBandDrag:
1609  grp_visu_sel -> setEnabled(true);
1610  m_mode_selection -> setChecked(true);
1611  break;
1612  }
1613  }
1614 
1615  if (ProjectView *pv = currentProjectView())
1616  {
1617  m_auto_conductor -> setEnabled (true);
1618  m_auto_conductor -> setChecked (pv -> project() -> autoConductor());
1619  }
1620  else
1621  m_auto_conductor -> setDisabled(true);
1622 }
1623 
1629  bool editable_diagram = (dv && !dv -> diagram() -> isReadOnly());
1630 
1631  // pour coller, il faut un schema ouvert et un schema dans le presse-papier
1632  m_paste -> setEnabled(editable_diagram && Diagram::clipboardMayContainDiagram());
1633 }
1634 
1642 {
1643  if (!project_view) return;
1644 
1645  foreach(DiagramView *dv, project_view -> diagram_views())
1646  diagramWasAdded(dv);
1647 
1648  //Manage the close event of project
1649  connect(project_view, SIGNAL(projectClosed(ProjectView*)), this, SLOT(projectWasClosed(ProjectView *)));
1650  //Manage the adding of diagram
1651  connect(project_view, SIGNAL(diagramAdded(DiagramView *)), this, SLOT(diagramWasAdded(DiagramView *)));
1652 
1653  if (QETProject *project = project_view -> project())
1654  connect(project, SIGNAL(readOnlyChanged(QETProject *, bool)), this, SLOT(slot_updateActions()));
1655 
1656  //Manage request for edit or find element and titleblock
1659 
1660  // display error messages sent by the project view
1661  connect(project_view, SIGNAL(errorEncountered(QString)), this, SLOT(showError(const QString &)));
1662 
1663  //We maximise the new window if the current window is inexistent or maximized
1664  QWidget *current_window = m_workspace.activeSubWindow();
1665  bool maximise = ((!current_window) || (current_window -> windowState() & Qt::WindowMaximized));
1666 
1667  //Add the new window
1668  QMdiSubWindow *sub_window = m_workspace.addSubWindow(project_view);
1669  sub_window -> setWindowIcon(project_view -> windowIcon());
1670  sub_window -> systemMenu() -> clear();
1671 
1672  //By defaut QMdiSubWindow have a QAction "close" with shortcut QKeySequence::Close
1673  //But the QAction m_close_file of this class have the same shortcut too.
1674  //We remove the shortcut of the QAction of QMdiSubWindow for avoid conflic
1675  for(QAction *act : sub_window->actions())
1676  {
1677  if(act->shortcut() == QKeySequence::Close)
1678  act->setShortcut(QKeySequence());
1679  }
1680 
1681  //Display the new window
1682  if (maximise) project_view -> showMaximized();
1683  else project_view -> show();
1684 }
1685 
1689 QList<QString> QETDiagramEditor::editedFiles() const {
1690  QList<QString> edited_files_list;
1691  foreach (ProjectView *project_view, openedProjects()) {
1692  QString diagram_file(project_view -> project() -> filePath());
1693  if (!diagram_file.isEmpty()) {
1694  edited_files_list << QFileInfo(diagram_file).canonicalFilePath();
1695  }
1696  }
1697  return(edited_files_list);
1698 }
1699 
1706 ProjectView *QETDiagramEditor::viewForFile(const QString &filepath) const {
1707  if (filepath.isEmpty()) return(nullptr);
1708 
1709  QString searched_can_file_path = QFileInfo(filepath).canonicalFilePath();
1710  if (searched_can_file_path.isEmpty()) {
1711  // QFileInfo returns an empty path for non-existent files
1712  return(nullptr);
1713  }
1714  foreach (ProjectView *project_view, openedProjects()) {
1715  QString project_can_file_path = QFileInfo(project_view -> project() -> filePath()).canonicalFilePath();
1716  if (project_can_file_path == searched_can_file_path) {
1717  return(project_view);
1718  }
1719  }
1720  return(nullptr);
1721 }
1722 
1728  return m_draw_grid->isChecked();
1729 }
1730 
1735 void QETDiagramEditor::openBackupFiles(QList<KAutoSaveFile *> backup_files)
1736 {
1737  for (KAutoSaveFile *file : backup_files)
1738  {
1739  //Create the project
1741 
1742  QETProject *project = new QETProject(file, this);
1743  if (project->state() != QETProject::Ok)
1744  {
1745  if (project -> state() != QETProject::FileOpenDiscard)
1746  {
1747  QET::QetMessageBox::warning(this, tr("Échec de l'ouverture du projet", "message box title"),
1748  QString(tr("Une erreur est survenue lors de l'ouverture du fichier %1.",
1749  "message box content")).arg(file->managedFile().fileName()));
1750  }
1751  delete project;
1753  }
1754  addProject(project);
1756  }
1757 }
1758 
1763  // nettoyage du menu
1764  foreach(QAction *a, windows_menu -> actions()) windows_menu -> removeAction(a);
1765 
1766  // actions de fermeture
1767  windows_menu -> addAction(m_close_file);
1768  //windows_menu -> addAction(closeAllAct);
1769 
1770  // actions de reorganisation des fenetres
1771  windows_menu -> addSeparator();
1772  windows_menu -> addAction(m_tile_window);
1773  windows_menu -> addAction(m_cascade_window);
1774 
1775  // actions de deplacement entre les fenetres
1776  windows_menu -> addSeparator();
1777  windows_menu -> addAction(m_next_window);
1778  windows_menu -> addAction(m_previous_window);
1779 
1780  // liste des fenetres
1781  QList<ProjectView *> windows = openedProjects();
1782 
1783  m_tile_window -> setEnabled(!windows.isEmpty() && m_workspace.viewMode() == QMdiArea::SubWindowView);
1784  m_cascade_window -> setEnabled(!windows.isEmpty() && m_workspace.viewMode() == QMdiArea::SubWindowView);
1785  m_next_window -> setEnabled(windows.count() > 1);
1786  m_previous_window -> setEnabled(windows.count() > 1);
1787 
1788  if (!windows.isEmpty()) windows_menu -> addSeparator();
1789  QActionGroup *windows_actions = new QActionGroup(this);
1790  foreach(ProjectView *project_view, windows) {
1791  QString pv_title = project_view -> windowTitle();
1792  QAction *action = windows_menu -> addAction(pv_title);
1793  windows_actions -> addAction(action);
1794  action -> setStatusTip(QString(tr("Active le projet « %1 »")).arg(pv_title));
1795  action -> setCheckable(true);
1796  action -> setChecked(project_view == currentProjectView());
1797  connect(action, SIGNAL(triggered()), &windowMapper, SLOT(map()));
1798  windowMapper.setMapping(action, project_view);
1799  }
1800 }
1801 
1807  if (ProjectView *project_view = findProject(diagram_view)) {
1808  activateProject(project_view);
1809  project_view -> editDiagramProperties(diagram_view);
1810  }
1811 }
1812 
1818  if (ProjectView *project_view = findProject(diagram)) {
1819  activateProject(project_view);
1820  project_view -> editDiagramProperties(diagram);
1821  }
1822 }
1823 
1828  m_workspace.setViewMode(QMdiArea::SubWindowView);
1829  m_windowed_view_mode -> setChecked(true);
1831 }
1832 
1837  m_workspace.setViewMode(QMdiArea::TabbedView);
1838  m_tabbed_view_mode -> setChecked(true);
1840 }
1841 
1847 {
1848  QSettings settings;
1849 
1850  // dimensions et position de la fenetre
1851  QVariant geometry = settings.value("diagrameditor/geometry");
1852  if (geometry.isValid()) restoreGeometry(geometry.toByteArray());
1853 
1854  // etat de la fenetre (barres d'outils, docks...)
1855  QVariant state = settings.value("diagrameditor/state");
1856  if (state.isValid()) restoreState(state.toByteArray());
1857 
1858  // gestion des projets (onglets ou fenetres)
1859  bool tabbed = settings.value("diagrameditor/viewmode", "tabbed") == "tabbed";
1860  if (tabbed) {
1861  setTabbedMode();
1862  } else {
1863  setWindowedMode();
1864  }
1865 }
1866 
1872 {
1873  QSettings settings;
1874  settings.setValue("diagrameditor/geometry", saveGeometry());
1875  settings.setValue("diagrameditor/state", saveState());
1876 }
1877 
1883  if (QETProject *project = diagram -> project()) {
1884  if (ProjectView *project_view = findProject(project)) {
1885  activateWidget(project_view);
1886  project_view -> showDiagram(diagram);
1887  }
1888  } else {
1890  }
1891 }
1892 
1898  activateProject(findProject(project));
1899 }
1900 
1906  if (!project_view) return;
1907  activateWidget(project_view);
1908 }
1909 
1915  QETProject *project = project_view -> project();
1916  if (project) {
1917  pa -> elementsPanel().projectWasClosed(project);
1919  undo_group.removeStack(project -> undoStack());
1920  QETApp::unregisterProject(project);
1921  }
1922  project_view -> deleteLater();
1923  project -> deleteLater();
1924 }
1925 
1931  if (!project_view) return;
1932  activateProject(project_view);
1933  project_view -> editProjectProperties();
1934 }
1935 
1942 }
1943 
1949  if (!project) return;
1950 
1951  // recupere le ProjectView visualisant ce projet
1952  if (ProjectView *project_view = findProject(project)) {
1953 
1954  // affiche le projet en question
1955  activateProject(project);
1956 
1957  // ajoute un schema au projet
1958  project_view -> addNewDiagram();
1959  }
1960 }
1961 
1967  if (!diagram) return;
1968 
1969  // recupere le projet contenant le schema
1970  if (QETProject *diagram_project = diagram -> project()) {
1971  // recupere la vue sur ce projet
1972  if (ProjectView *project_view = findProject(diagram_project)) {
1973 
1974  // affiche le schema en question
1975  project_view -> showDiagram(diagram);
1976 
1977  // supprime le schema
1978  project_view -> removeDiagram(diagram);
1979  }
1980  }
1981 }
1982 
1989  if (!diagram) return;
1990 
1991  // recupere le projet contenant le schema
1992  if (QETProject *diagram_project = diagram -> project()) {
1993  if (diagram_project -> isReadOnly()) return;
1994 
1995  // recupere la vue sur ce projet
1996  if (ProjectView *project_view = findProject(diagram_project)) {
1997  project_view -> moveDiagramUp(diagram);
1998  }
1999  }
2000 }
2001 
2008  if (!diagram) return;
2009 
2010  // recupere le projet contenant le schema
2011  if (QETProject *diagram_project = diagram -> project()) {
2012  if (diagram_project -> isReadOnly()) return;
2013 
2014  // recupere la vue sur ce projet
2015  if (ProjectView *project_view = findProject(diagram_project)) {
2016  project_view -> moveDiagramDown(diagram);
2017  }
2018  }
2019 }
2020 
2027  if (!diagram) return;
2028 
2029  // recupere le projet contenant le schema
2030  if (QETProject *diagram_project = diagram -> project()) {
2031  if (diagram_project -> isReadOnly()) return;
2032 
2033  // recupere la vue sur ce projet
2034  if (ProjectView *project_view = findProject(diagram_project)) {
2035  project_view -> moveDiagramUpTop(diagram);
2036  }
2037  }
2038 }
2039 
2040 
2047  if (!diagram) return;
2048 
2049  // recupere le projet contenant le schema
2050  if (QETProject *diagram_project = diagram -> project()) {
2051  if (diagram_project -> isReadOnly()) return;
2052 
2053  // recupere la vue sur ce projet
2054  if (ProjectView *project_view = findProject(diagram_project)) {
2055  project_view -> moveDiagramUpx10(diagram);
2056  }
2057  }
2058 }
2059 
2066  if (!diagram) return;
2067 
2068  // recupere le projet contenant le schema
2069  if (QETProject *diagram_project = diagram -> project()) {
2070  if (diagram_project -> isReadOnly()) return;
2071 
2072  // recupere la vue sur ce projet
2073  if (ProjectView *project_view = findProject(diagram_project)) {
2074  project_view -> moveDiagramDownx10(diagram);
2075  }
2076  }
2077 }
2078 
2080  pa->reloadAndFilter();
2081 }
2082 
2087  if (ProjectView *current_project = currentProjectView()) {
2088  if (DiagramView *current_diagram = current_project -> currentDiagram()) {
2089  bool isFolioList = false;
2090 
2091  // if diagram to remove is a "folio list sheet", then set a flag.
2092  if (dynamic_cast<DiagramFolioList *>(current_diagram -> diagram()))
2093  isFolioList = true;
2094 
2095  current_project -> removeDiagram(current_diagram);
2096 
2097  // if the removed diagram was a folio sheet, then delete all the remaining folio sheets also.
2098  if (isFolioList) {
2099  foreach (DiagramView *diag, current_project -> diagram_views()) {
2100  if (dynamic_cast<DiagramFolioList *>(diag -> diagram())) {
2101  current_project -> removeDiagram(diag);
2102  }
2103  }
2104 
2105  // else if after diagram removal, the total diagram quantity becomes a factor of 58, then
2106  // remove one (last) folio sheet.
2107  } else if (current_project -> diagram_views().size() % 58 == 0) {
2108  foreach (DiagramView *diag, current_project -> diagram_views()) {
2109  DiagramFolioList *ptr = dynamic_cast<DiagramFolioList *>(diag -> diagram());
2110  if (ptr && ptr -> getId() == current_project -> project() -> getFolioSheetsQuantity() - 1) {
2111  current_project -> removeDiagram(diag);
2112  }
2113  }
2114  }
2115  }
2116  }
2117 }
2118 
2125 {
2126  connect(dv, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
2127  connect(dv, SIGNAL(modeChanged()), this, SLOT(slot_updateModeActions()));
2128 }
2129 
2136 {
2138 }
2139 
2145  QETApp::instance() -> openElementLocations(QList<ElementsLocation>() << location);
2146 }
2147 
2153  if (Element *selected_element = currentElement()) {
2154  editElementInEditor(selected_element -> location());
2155  }
2156 }
2157 
2162  if (result.isOk()) return;
2163  showError(result.errorMessage());
2164 }
2165 
2169 void QETDiagramEditor::showError(const QString &error) {
2170  if (error.isEmpty()) return;
2171  QET::QetMessageBox::critical(this, tr("Erreur", "message box title"), error);
2172 }
2173 
2179 void QETDiagramEditor::subWindowActivated(QMdiSubWindow *subWindows)
2180 {
2181  Q_UNUSED(subWindows);
2182 
2185 }
2186 
2192 {
2194 
2196  if (dv && dv->diagram())
2198 }
2199 
2200 
2205 {
2206  bool success;
2207  QProcess *process = new QProcess(qApp);
2208 
2209  // If launched under control:
2210  //connect(process, SIGNAL(errorOcurred(int error)), this, SLOT(slot_generateTerminalBlock_error()));
2211  //process->start("qet_tb_generator");
2212 
2213 #ifdef Q_OS_MAC
2214  if (openedProjects().count()){
2215  success = process->startDetached("/Library/Frameworks/Python.framework/Versions/3.5/bin/qet_tb_generator", {(QETDiagramEditor::currentProjectView()->project()->filePath())});
2216  }
2217  else {
2218  success = process->startDetached("/Library/Frameworks/Python.framework/Versions/3.5/bin/qet_tb_generator");
2219  }
2220 #else
2221  if (openedProjects().count()){
2222  success = process->startDetached("qet_tb_generator", {(QETDiagramEditor::currentProjectView()->project()->filePath())});
2223  }
2224  else {
2225  success = process->startDetached("qet_tb_generator");
2226  }
2227 
2228 #endif
2229  if ( !success ) {
2230  #if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
2231  QMessageBox::warning(nullptr,
2232  tr("Error launching qet_tb_generator plugin"),
2233  QObject::tr("To install the plugin qet_tb_generator"
2234  "<br>"
2235  "Visit :"
2236  "<br>"
2237  "<a href='https://pypi.python.org/pypi/qet-tb-generator'>qet-tb-generator</a>"
2238  "<br>"
2239  "Requires python 3.5 or above."
2240  "<br>"
2241  "<B>""<U>"
2242  " First install on Windows"
2243  "</B>""</U>"
2244  "<br>"
2245  "1. Install, if required, python 3.5 or above"
2246  "<br>"
2247  " Visit :"
2248  "<br>"
2249  "<a href='https://www.python.org/downloads/'>python.org</a>"
2250  "<br>"
2251  "2. pip install qet_tb_generator"
2252  "<br>"
2253  "<B>""<U>"
2254  " Update on Windows"
2255  "</B>""</U>"
2256  "<br>"
2257  "python -m pip install --upgrade qet_tb_generator"
2258  "<br>"
2259  ">>user could launch in a terminal this script in this directory"
2260  "<br>"
2261  " C:\\users\\XXXX\\AppData\\Local\\Programs\\Python\\Python36-32\\Scripts "
2262  "<br>"
2263  ));
2264  }
2265 }
2266 #elif defined(Q_OS_MAC)
2267  QMessageBox::warning(nullptr,
2268  tr("Error launching qet_tb_generator plugin"),
2269  QObject::tr("To install the plugin qet_tb_generator"
2270  "<br>"
2271  "Visit :"
2272  "<br>"
2273  "<a href='https://pypi.python.org/pypi/qet-tb-generator'>qet-tb-generator</a>"
2274  "<br>"
2275  "<B>""<U>"
2276  " First install on macOSX"
2277  "</B>""</U>"
2278  "<br>"
2279  "1. Install, if required, python 3.5 "
2280  "<br>"
2281  " Visit :"
2282  "<br>"
2283  "<a href='https://qelectrotech.org/forum/viewtopic.php?pid=5674#p5674'>howto</a>"
2284  "<br>"
2285  "2. pip3 install qet_tb_generator"
2286  "<br>"
2287  "<B>""<U>"
2288  " Update on macOSX"
2289  "</B>""</U>"
2290  "<br>"
2291  " pip3 install --upgrade qet_tb_generator"
2292  "<br>"
2293  ));
2294  }
2295 }
2296 
2297 #else
2298  QMessageBox::warning(nullptr,
2299  tr("Error launching qet_tb_generator plugin"),
2300  QObject::tr("To install the plugin qet_tb_generator"
2301  "<br>"
2302  "Visit : "
2303  "<br>"
2304  "<a href='https://pypi.python.org/pypi/qet-tb-generator'>qet-tb-generator</a>"
2305  "<br>"
2306  "<br>"
2307  "Requires python 3.5 or above."
2308  "<br>"
2309  "<br>"
2310  "<B>""<U>"
2311  " First install on Linux"
2312  "</B>""</U>"
2313  "<br>"
2314  "1. check you have pip3 installed: pip3 --version"
2315  "<br>"
2316  "If not install with: sudo apt-get install python3-pip"
2317  "<br>"
2318  "2. Install the program: sudo pip3 install qet_tb_generator"
2319  "<br>"
2320  "3. Run the program: qet_tb_generator"
2321  "<br>"
2322  "<br>"
2323  "<B>""<U>"
2324  " Update on Linux"
2325  "</B>""</U>"
2326  "<br>"
2327  "sudo pip3 install --upgrade qet_tb_generator"
2328  "<br>"
2329  ));
2330  }
2331 }
2332 
2333 #endif
2334 
QIcon ObjectRotateRight
Definition: qeticons.cpp:124
QIcon PartEllipse
Definition: qeticons.cpp:129
QIcon DialogInformation
Definition: qeticons.cpp:47
QActionGroup m_row_column_actions_group
QList< ProjectView * > openedProjects() const
static ConductorProperties defaultProperties()
ConductorProperties::defaultProperties.
DiagramPropertiesEditorDockWidget * m_selection_properties_editor
QAction * m_group_selected_texts
static bool unregisterProject(QETProject *)
Definition: qetapp.cpp:1976
void setUpToolBar()
QETDiagramEditor::setUpToolBar.
QAction * m_paste
Paste clipboard content on the current diagram.
QList< Diagram * > diagrams() const
Definition: qetproject.cpp:210
bool hasCopiableItems() const
DiagramContent::hasCopiableItems.
DiagramView * currentDiagramView() const
QAction * m_cut
Cut selection to clipboard.
void setDisplayGrid(bool)
Definition: diagram.h:283
void addProject(QETProject *project)
ElementsCollectionWidget::addProject Add to be displayed.
void changeZValue(QET::DepthOption option)
Diagram::changeZValue Change the Z value of the current selected item, according to ...
Definition: diagram.cpp:1300
void zoomFit()
QAction * m_export_diagram
Export diagrams of the current project as imagess.
The DynamicElementTextItem class This class provide a simple text field of element who can be added o...
ElementsPanelWidget * pa
Elements panel.
void slot_updateComplexActions()
QETDiagramEditor::slot_updateComplexActions Manage the actions who need some conditions to be enable ...
bool saveToCSVFile()
void zoom(const qreal zoom_factor)
DiagramView::zoom Zomm the view. A zoom_factor > 1 zoom in. A zoom_factor < 1 zoom out...
QString errorMessage() const
Definition: qetresult.cpp:61
void setEditor(QETDiagramEditor *editor)
SearchAndReplaceWidget::setEditor Set the diagram editor of this widget.
QList< DiagramTextItem * > selectedTexts() const
DiagramContent::selectedTexts.
void editDiagramProperties(DiagramView *)
void moveDiagramDownx10(Diagram *)
QSignalMapper windowMapper
QIcon EditTableDeleteColumn
Definition: qeticons.cpp:75
QActionGroup * grp_visu_sel
Action group for visualisation vs edition mode.
QIcon EditTableDeleteRow
Definition: qeticons.cpp:76
Diagram * diagram()
Definition: diagramview.h:67
void setUpAutonumberingWidget()
QETDiagramEditor::setUpAutonumberingWidget Setup the dock for AutoNumbering Selection.
QIcon EditRedo
Definition: qeticons.cpp:68
QIcon DocumentSpreadsheet
Definition: qeticons.cpp:51
QIcon DiagramAdd
Definition: qeticons.cpp:42
void setUpElementsCollectionWidget()
QETDiagramEditor::setUpElementsCollectionWidget Set up the dock widget of element collection...
QAction * m_print
Print diagrams of the current project.
QAction * m_edit_diagram_properties
Show a dialog to edit diagram properties.
QIcon QETLogo
Definition: qeticons.cpp:151
void editElementInEditor(const ElementsLocation &)
QSet< Conductor * > selectedConductors() const
Definition: diagram.cpp:1695
QAction * m_grey_background
Switch the background color in white or grey.
QIcon EditTableInsertColumnRight
Definition: qeticons.cpp:78
void slot_updateActions()
QETDiagramEditor::slot_updateActions Manage actions.
bool closeProject(ProjectView *)
QIcon ConductorEdit
Definition: qeticons.cpp:36
QIcon ZoomOut
Definition: qeticons.cpp:181
QIcon PartRectangle
Definition: qeticons.cpp:132
QIcon resize_image
Definition: qeticons.cpp:183
QDockWidget * qdw_undo
void setProject(QETProject *, ProjectView *)
AutoNumberingDockWidget::setProject.
QAction * m_tabbed_view_mode
Actions related to file (open, close, save...)
QAction * m_rotate_texts
Direct selected text items to a specific angle.
void moveDiagramUpx10(Diagram *)
QAction * m_next_window
Switch to the next document.
The DiagramEventAddText class This diagram event handle the creation of a new text in a diagram...
QIcon EditUndo
Definition: qeticons.cpp:82
QIcon TerminalStrip
Definition: qeticons.cpp:208
ProjectView * viewForFile(const QString &) const
void setUpElementsPanel()
QETDiagramEditor::setUpElementsPanel Setup the element panel and element panel widget.
QIcon TransformRotate
Definition: qeticons.cpp:168
QMenu * settings_menu_
Settings menu.
Definition: qetmainwindow.h:65
Element * currentElement() const
QIcon EditText
Definition: qeticons.cpp:81
bool isReadOnly() const
Diagram::isReadOnly.
Definition: diagram.cpp:1764
QDockWidget * m_qdw_elmt_collection
Dock for the elements panel.
AutoNumberingDockWidget * m_autonumbering_dock
void showError(const QETResult &)
QToolBar * m_add_item_tool_bar
The ElementsCollectionWidget class This widget embedd a tree view that display the element collection...
void addProjectView(ProjectView *)
QETDiagramEditor::addProjectView Add a new project view to workspace and build the connection between...
QAction * m_mode_selection
Set edition mode.
QToolBar * diagram_tool_bar
static bool registerProject(QETProject *)
Definition: qetapp.cpp:1958
QMdiSubWindow * subWindowForWidget(QWidget *) const
bool event(QEvent *) override
bool isValid()
RotateSelectionCommand::isValid.
QETDiagramEditor(const QStringList &=QStringList(), QWidget *=nullptr)
QETDiagramEditor::QETDiagramEditor Constructor.
void zoomContent()
QIcon EditSelectNone
Definition: qeticons.cpp:72
QIcon ProjectProperties
Definition: qeticons.cpp:149
QActionGroup * m_group_view_mode
Action group for project.
QToolBar * view_tool_bar
QIcon EditSelectInvert
Definition: qeticons.cpp:71
void zoomReset()
QAction * m_project_terminalBloc
generate terminal block
QList< QGraphicsItem * > items(int=All) const
DiagramContent::items.
void moveDiagramUpTop(Diagram *)
QAction * m_save_file_as
Save current project as a specific file.
bool isNull() const
DiagramEventAddImage::isNull.
QAction * m_save_file
Save current project.
void addItemGroupTriggered(QAction *action)
QETDiagramEditor::addItemGroupTriggered This slot is called when an item must be added to the curent ...
void editSelection()
DiagramView::editSelection Edit the selected item if he can be edited and if only one item is selecte...
void selectInvert()
void adjustSceneRect()
DiagramView::adjustSceneRect Calcul and set the area of the scene visualized by this view...
QIcon ZoomIn
Definition: qeticons.cpp:179
QIcon EditCopy
Definition: qeticons.cpp:64
void moveDiagramDown(Diagram *)
QIcon DocumentSave
Definition: qeticons.cpp:58
QIcon Autoconnect
Definition: qeticons.cpp:32
void setDiagram(Diagram *diagram)
DiagramPropertiesEditorDockWidget::setDiagram Set the diagram to edit the selection. Connect the diagram signal selectionChanged() to this slot selectionChanged(); If diagram = nullptr, we just disconnect all signal and remove editor.
QIcon EditTableInsertRowUnder
Definition: qeticons.cpp:80
QIcon Grid
Definition: qeticons.cpp:112
The RotateTextsCommand class Open a dialog for edit the rotation of the current selected texts and te...
bool openAndAddProject(const QString &, bool=true)
void removeProject(QETProject *project)
void setUpUndoStack()
QETDiagramEditor::setUpUndoStack Setup the undostack and undo stack widget.
QAction * m_cascade_window
Show MDI subwindows as cascade.
QDockWidget * qdw_pa
Directory to use for file dialogs such as File > save.
bool drawGrid() const
QETDiagramEditor::drawGrid.
void removeDiagram(Diagram *)
QIcon PartPolygon
Definition: qeticons.cpp:131
QIcon PartTextField
Definition: qeticons.cpp:135
void setUpActions()
QETDiagramEditor::setUpActions Set up all Qaction.
void zoomGroupTriggered(QAction *action)
static RecentFiles * projectsRecentFiles()
Definition: qetapp.cpp:1166
void findElementRequired(const ElementsLocation &)
ElementsCollectionWidget * m_element_collection_widget
Dock for the undo list.
QAction * undo
Cancel the latest action.
QAction * m_project_nomenclature
generate nomenclature
QAction * m_edit_selection
To edit selected item.
QActionGroup m_zoom_actions_group
Action related to adding (add text image shape...)
Vertical segment.
Definition: qet.h:88
void closeEvent(QCloseEvent *) override
QAction * redo
Redo the latest cancelled operation.
void writeSettings()
QETDiagramEditor::writeSettings Write the settings.
QIcon DocumentExport
Definition: qeticons.cpp:50
QMenu * help_menu_
Help menu.
Definition: qetmainwindow.h:66
The DiagramEventAddShape class This event manage the creation of a shape.
void slot_updateModeActions()
QETDiagramEditor::slot_updateModeActions Manage action who need an opened diagram or project to be up...
QAction * m_project_folio_list
Sommaire des schemas.
ProjectState state() const
Definition: qetproject.cpp:187
QSet< DynamicElementTextItem * > m_element_texts
QIcon DocumentPrint
Definition: qeticons.cpp:56
void highlightUnusedElement()
ElementsCollectionWidget::highlightUnusedElement highlight the unused element ElementsCollectionMode...
ProjectView * currentProjectView() const
QIcon tr
Definition: qeticons.cpp:204
QIcon EditSelectAll
Definition: qeticons.cpp:70
QAction * m_quit_editor
Quit the diagram editor.
void generateTerminalBlock()
QETDiagramEditor::generateTerminalBlock.
QIcon EditPaste
Definition: qeticons.cpp:67
The DiagramEventAddImage class This diagram event, handle the adding of an image in a diagram...
static DialogWaiting * instance(QWidget *parent=nullptr)
Definition: dialogwaiting.h:33
DepthOption
List the various kind of changes for the zValue.
Definition: qet.h:43
void slot_updateAutoNumDock()
QETDiagramEditor::slot_updateAutoNumDock Update Auto Num Dock Widget when changing Project...
QList< ElementTextItemGroup * > selectedTextsGroup() const
DiagramContent::selectedTextsGroup.
void setEventInterface(DiagramEventInterface *event_interface)
Diagram::setEventInterface Set event_interface has current interface. Diagram become the ownership of...
Definition: diagram.cpp:455
void setUpMenu()
QETDiagramEditor::setUpMenu.
static void dropInstance()
Definition: dialogwaiting.h:54
QETProject * project()
Definition: projectview.cpp:69
QIcon textGroup
Definition: qeticons.cpp:215
void slot_updateUndoStack()
QETDiagramEditor::slot_updateUndoStack Update the undo stack view.
void setCurrentLocation(const ElementsLocation &location)
ElementsCollectionWidget::setCurrentLocation Set the current item to be the item for ...
BorderProperties exportBorder()
The RotateSelectionCommand class Rotate the selected items in the given diagram.
QIcon TableOfContent
Definition: qeticons.cpp:163
QString filePath()
Definition: qetproject.cpp:243
QIcon ProjectClose
Definition: qeticons.cpp:144
QIcon DocumentSaveAs
Definition: qeticons.cpp:60
QIcon PartSelect
Definition: qeticons.cpp:133
void addDiagramToProject(QETProject *)
QIcon EditClear
Definition: qeticons.cpp:62
bool newProject()
QETDiagramEditor::newProject Create an empty project.
QActionGroup m_selection_actions_group
Action related to add/remove rows/column in diagram.
QAction * m_find_element
Find the selected element in the panel.
void save()
QETDiagramEditor::save Ask the current active project to save.
void setUpSelectionPropertiesEditor()
QETDiagramEditor::setUpSelectionPropertiesEditor Setup the dock for edit the current selection...
void activateWidget(QWidget *)
void selectionGroupTriggered(QAction *action)
QETDiagramEditor::selectionGroupTriggered This slot is called when an action should be made on the cu...
~QETDiagramEditor() override
QActionGroup m_file_actions_group
Action related to global selections.
QIcon DocumentOpen
Definition: qeticons.cpp:54
QAction * m_delete_selection
Only zoom action must displayed in the toolbar.
QIcon ZoomOriginal
Definition: qeticons.cpp:180
void projectWasClosed(ProjectView *)
static QColor background_color
background color of diagram
Definition: diagram.h:91
SearchAndReplaceWidget m_search_and_replace_widget
QIcon ConfigureToolbars
Definition: qeticons.cpp:39
QList< QString > editedFiles() const
QAction * m_clean_project
Clean the content of the curent project by removing useless items.
QIcon EditCut
Definition: qeticons.cpp:65
QToolBar * m_depth_tool_bar
QActionGroup * m_depth_action_group
Action related to edit a selected item.
void selectAll()
void openBackupFiles(QList< KAutoSaveFile *> backup_files)
QETDiagramEditor::openBackupFiles.
QIcon DiagramBg
Definition: qeticons.cpp:44
QIcon PartLine
Definition: qeticons.cpp:130
void selectGroupTriggered(QAction *action)
QETDiagramEditor::selectGroupTriggered This slot is called when selection need to change...
void moveDiagramUp(Diagram *)
void saveAs()
QETDiagramEditor::saveAs Ask the current active project to save as.
QUndoStack & undoStack()
Definition: diagram.h:337
bool isOk() const
Definition: qetresult.cpp:47
QIcon ro
Definition: qeticons.cpp:199
QList< QAction * > m_zoom_action_toolBar
QAction * m_tile_window
Show MDI subwindows as tile.
QAction * m_mode_visualise
Set visualisation mode.
QToolBar * main_tool_bar
QActionGroup m_add_item_actions_group
QAction * m_auto_conductor
Enable/Disable the use of auto conductor.
void rowColumnGroupTriggered(QAction *action)
QIcon ViewMove
Definition: qeticons.cpp:172
static bool clipboardMayContainDiagram()
Definition: diagram.cpp:1706
void diagramWasAdded(DiagramView *)
QETDiagramEditor::diagramWasAdded Manage the adding of diagram view in a project. ...
QIcon ApplicationExit
Definition: qeticons.cpp:27
QIcon ElementEdit
Definition: qeticons.cpp:85
QAction * m_windowed_view_mode
Display projects as windows.
The DiagramEventInterface class isRunning() return true if action is running (do something). By default return false.
bool openRecentFile(const QString &)
int columns_count
Columns count.
void insertMenu(QMenu *, QMenu *, bool=true)
void editProjectProperties(ProjectView *)
QIcon ZoomFitBest
Definition: qeticons.cpp:178
QETProject * currentProject() const
QETDiagramEditor::currentProject.
the parsing of the XML content failed
Definition: qetproject.h:57
QAction * m_project_add_diagram
Add a diagram to the current project.
QAction * m_previous_window
Switch to the previous document.
The AddTextsGroupCommand class Manage the adding of a texts group.
bool hasDeletableItems() const
DiagramContent::hasDeletableItems.
bool addProject(QETProject *, bool=true)
void expandFirstItems()
ElementsCollectionWidget::expandFirstItems Expand each first item in the tree view.
QAction * m_copy
Copy selection to clipboard.
BorderTitleBlock border_and_titleblock
Diagram dimensions and title block.
Definition: diagram.h:74
QIcon DocumentOpenRecent
Definition: qeticons.cpp:55
QMessageBox::StandardButton critical(QWidget *, const QString &, const QString &, QMessageBox::StandardButtons=QMessageBox::Ok, QMessageBox::StandardButton=QMessageBox::NoButton)
void editElementRequired(const ElementsLocation &)
QIcon adding_image
Definition: qeticons.cpp:182
bool canRotateSelection() const
Diagram::canRotateSelection.
Definition: diagram.cpp:1791
QIcon ZoomDraw
Definition: qeticons.cpp:177
QIcon DiagramDelete
Definition: qeticons.cpp:45
void readSettings()
QETDiagramEditor::readSettings Read the settings.
QActionGroup * depthActionGroup(QObject *parent=nullptr)
QET::depthActionGroup.
Definition: qet.cpp:636
void activateDiagram(Diagram *)
QAction * m_remove_diagram_from_project
Delete a diagram from the current project.
static TitleBlockProperties defaultProperties()
TitleBlockProperties::defaultProperties Return the default properties stored in the setting file...
QAction * m_conductor_reset
Reset paths of selected conductors.
void subWindowActivated(QMdiSubWindow *subWindows)
QETDiagramEditor::subWindowActivated Slot used to update menu and undo stack when subwindows of MDIar...
int count(int=All) const
DiagramContent::count.
QIcon ConductorSettings
Definition: qeticons.cpp:37
void activateProject(QETProject *)
ProjectView * findProject(DiagramView *) const
bool event(QEvent *) override
QETDiagramEditor::event Reimplemented to : -Load elements collection when WindowActivate.
static QETApp * instance()
Definition: qetapp.cpp:143
int rows_count
Rows count.
QAction * m_project_edit_properties
Edit the properties of the current project.
QIcon ProjectNew
Definition: qeticons.cpp:145
QAction * m_rotate_selection
Rotate selected elements and text items by 90 degrees.
QAction * m_draw_grid
Switch the background grid display or not.
QIcon EditDelete
Definition: qeticons.cpp:66
QAction * m_close_file
Close current project file.
static QETDiagramEditor * diagramEditorForFile(const QString &)
Definition: qetapp.cpp:777
QMessageBox::StandardButton warning(QWidget *, const QString &, const QString &, QMessageBox::StandardButtons=QMessageBox::Ok, QMessageBox::StandardButton=QMessageBox::NoButton)
void findElementInPanel(const ElementsLocation &)
QETDiagramEditor::findElementInPanel Find the item for in the element panel.
void selectionChanged()
QETDiagramEditor::selectionChanged This slot is called when a diagram selection was changed...
QActionGroup m_select_actions_group
Action related to zoom for diagram.
void selectNothing()