From 0b79dfd149d4a022511814aeae716872bc504ba9 Mon Sep 17 00:00:00 2001 From: Kellermorph Date: Wed, 13 May 2026 19:42:11 +0200 Subject: [PATCH] Fix and Improve Multi-selection for Diagram Operations --- sources/elementspanel.cpp | 31 +++- sources/elementspanel.h | 1 + sources/elementspanelwidget.cpp | 303 +++++++++++++++++++------------- sources/elementspanelwidget.h | 15 +- sources/projectview.cpp | 95 +++++++--- sources/projectview.h | 8 +- sources/qetdiagrameditor.cpp | 248 ++++++++++++++++---------- sources/qetdiagrameditor.h | 15 +- 8 files changed, 459 insertions(+), 257 deletions(-) diff --git a/sources/elementspanel.cpp b/sources/elementspanel.cpp index f1823ef11..3f1ce10a2 100644 --- a/sources/elementspanel.cpp +++ b/sources/elementspanel.cpp @@ -22,6 +22,7 @@ #include "qeticons.h" #include "qetproject.h" #include "titleblock/templatescollection.h" +#include /* Lorsque le flag ENABLE_PANEL_DND_CHECKS est defini, le panel d'elements @@ -42,7 +43,7 @@ ElementsPanel::ElementsPanel(QWidget *parent) : first_reload_(true) { // selection unique - setSelectionMode(QAbstractItemView::SingleSelection); + setSelectionMode(QAbstractItemView::ExtendedSelection); setColumnCount(1); setExpandsOnDoubleClick(true); setMouseTracking(true); @@ -299,11 +300,14 @@ void ElementsPanel::reload() } /** - @brief ElementsPanel::slot_clicked - handle click on qtwi - @param qtwi item that was clickerd on -*/ + * @brief ElementsPanel::slot_clicked + * handle click on qtwi + * @param qtwi item that was clickerd on + */ void ElementsPanel::slot_clicked(QTreeWidgetItem *clickedItem, int) { + if (QApplication::keyboardModifiers() & (Qt::ShiftModifier | Qt::ControlModifier)) { + return; + } requestForItem(clickedItem); } @@ -553,3 +557,20 @@ void ElementsPanel::keyPressEvent(QKeyEvent *event) QTreeView::keyPressEvent(event); } } + +/** + * @brief ElementsPanel::selectedDiagrams + * @return A list of all currently selected diagrams in the panel. + */ +QList ElementsPanel::selectedDiagrams() const +{ + QList diagrams; + foreach (QTreeWidgetItem *item, selectedItems()) { + if (item->type() == QET::Diagram) { + if (Diagram *diagram = valueForItem(item)) { + diagrams.append(diagram); + } + } + } + return diagrams; +} diff --git a/sources/elementspanel.h b/sources/elementspanel.h index 7aa1143e5..8cb3e1e12 100644 --- a/sources/elementspanel.h +++ b/sources/elementspanel.h @@ -49,6 +49,7 @@ class ElementsPanel : public GenericPanel { // methods used to get what is represented by a particular visual item QString dirPathForItem(QTreeWidgetItem *); QString filePathForItem(QTreeWidgetItem *); + QList selectedDiagrams() const; signals: void requestForProject(QETProject *); diff --git a/sources/elementspanelwidget.cpp b/sources/elementspanelwidget.cpp index 610d9c5cc..906413286 100644 --- a/sources/elementspanelwidget.cpp +++ b/sources/elementspanelwidget.cpp @@ -25,6 +25,7 @@ #include "qetproject.h" #include "titleblock/templatedeleter.h" #include +#include /* When the ENABLE_PANEL_WIDGET_DND_CHECKS flag is set, the panel @@ -242,85 +243,134 @@ void ElementsPanelWidget::newDiagram() } /** - Emet le signal requestForDiagramDeletion avec le schema selectionne -*/ + * Emet le signal requestForDiagramsDeletion avec les schemas selectionnes + */ void ElementsPanelWidget::deleteDiagram() { - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramDeletion(selected_diagram)); - elements_panel->reload(); + QList diagrams_to_delete = elements_panel->selectedDiagrams(); + + if (diagrams_to_delete.isEmpty()) return; + + emit(requestForDiagramsDeletion(diagrams_to_delete)); + + elements_panel->reload(); +} +/** + * Emits the requestForDiagramMoveUpTop signal with all selected diagrams. + */ +void ElementsPanelWidget::moveDiagramUpTop() { + QList diagrams_to_move = elements_panel->selectedDiagrams(); + if (diagrams_to_move.isEmpty()) return; + + // Emit the entire list at once + emit requestForDiagramMoveUpTop(diagrams_to_move); + + // Clear messy tree selection caused by moving items, then restore clean selection + elements_panel->clearSelection(); + for (Diagram *d : diagrams_to_move) { + if (auto item = elements_panel->getItemForDiagram(d)) item->setSelected(true); } } /** - Emet le signal requestForDiagramMoveUpTop avec le schema selectionne -+*/ -void ElementsPanelWidget::moveDiagramUpTop() -{ - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramMoveUpTop(selected_diagram)); - } -} + * Emits the requestForDiagramMoveUp signal with all selected diagrams. + */ +void ElementsPanelWidget::moveDiagramUp() { + QList diagrams_to_move = elements_panel->selectedDiagrams(); + if (diagrams_to_move.isEmpty()) return; + // Emit the entire list at once + emit requestForDiagramMoveUp(diagrams_to_move); - -/** - Emet le signal requestForDiagramMoveUp avec le schema selectionne -*/ -void ElementsPanelWidget::moveDiagramUp() -{ - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramMoveUp(selected_diagram)); + // Clear messy tree selection caused by moving items, then restore clean selection + elements_panel->clearSelection(); + for (Diagram *d : diagrams_to_move) { + if (auto item = elements_panel->getItemForDiagram(d)) item->setSelected(true); } } /** - Emet le signal requestForDiagramMoveDown avec le schema selectionne -*/ -void ElementsPanelWidget::moveDiagramDown() -{ - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramMoveDown(selected_diagram)); + * Emits the requestForDiagramMoveDown signal with all selected diagrams. + */ +void ElementsPanelWidget::moveDiagramDown() { + QList diagrams_to_move = elements_panel->selectedDiagrams(); + if (diagrams_to_move.isEmpty()) return; + + // Emit the entire list at once + emit requestForDiagramMoveDown(diagrams_to_move); + + // Clear messy tree selection caused by moving items, then restore clean selection + elements_panel->clearSelection(); + for (Diagram *d : diagrams_to_move) { + if (auto item = elements_panel->getItemForDiagram(d)) item->setSelected(true); } } /** - Emet le signal requestForDiagramMoveUpx10 avec le schema selectionne -*/ -void ElementsPanelWidget::moveDiagramUpx10() -{ - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramMoveUpx10(selected_diagram)); + * Emits the requestForDiagramMoveUpx10 signal with all selected diagrams. + */ +void ElementsPanelWidget::moveDiagramUpx10() { + QList diagrams_to_move = elements_panel->selectedDiagrams(); + if (diagrams_to_move.isEmpty()) return; + + // Emit the entire list at once + emit requestForDiagramMoveUpx10(diagrams_to_move); + + // Clear messy tree selection caused by moving items, then restore clean selection + elements_panel->clearSelection(); + for (Diagram *d : diagrams_to_move) { + if (auto item = elements_panel->getItemForDiagram(d)) item->setSelected(true); } } /** - Emet le signal requestForDiagramMoveUpx100 avec le schema selectionne -*/ -void ElementsPanelWidget::moveDiagramUpx100() -{ - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramMoveUpx100(selected_diagram)); + * Emits the requestForDiagramMoveUpx100 signal with all selected diagrams. + */ +void ElementsPanelWidget::moveDiagramUpx100() { + QList diagrams_to_move = elements_panel->selectedDiagrams(); + if (diagrams_to_move.isEmpty()) return; + + // Emit the entire list at once + emit requestForDiagramMoveUpx100(diagrams_to_move); + + // Clear messy tree selection caused by moving items, then restore clean selection + elements_panel->clearSelection(); + for (Diagram *d : diagrams_to_move) { + if (auto item = elements_panel->getItemForDiagram(d)) item->setSelected(true); } } /** - Emet le signal requestForDiagramMoveDownx10 avec le schema selectionne -*/ -void ElementsPanelWidget::moveDiagramDownx10() -{ - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramMoveDownx10(selected_diagram)); + * Emits the requestForDiagramMoveDownx10 signal with all selected diagrams. + */ +void ElementsPanelWidget::moveDiagramDownx10() { + QList diagrams_to_move = elements_panel->selectedDiagrams(); + if (diagrams_to_move.isEmpty()) return; + + // Emit the entire list at once + emit requestForDiagramMoveDownx10(diagrams_to_move); + + // Clear messy tree selection caused by moving items, then restore clean selection + elements_panel->clearSelection(); + for (Diagram *d : diagrams_to_move) { + if (auto item = elements_panel->getItemForDiagram(d)) item->setSelected(true); } } /** - Emet le signal requestForDiagramMoveDownx100 avec le schema selectionne -*/ -void ElementsPanelWidget::moveDiagramDownx100() -{ - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramMoveDownx100(selected_diagram)); + * Emits the requestForDiagramMoveDownx100 signal with all selected diagrams. + */ +void ElementsPanelWidget::moveDiagramDownx100() { + QList diagrams_to_move = elements_panel->selectedDiagrams(); + if (diagrams_to_move.isEmpty()) return; + + // Emit the entire list at once + emit requestForDiagramMoveDownx100(diagrams_to_move); + + // Clear messy tree selection caused by moving items, then restore clean selection + elements_panel->clearSelection(); + for (Diagram *d : diagrams_to_move) { + if (auto item = elements_panel->getItemForDiagram(d)) item->setSelected(true); } } @@ -378,21 +428,35 @@ void ElementsPanelWidget::updateButtons() bool is_writable = !(elements_panel -> selectedProject() -> isReadOnly()); prj_add_diagram -> setEnabled(is_writable); } else if (current_type == QET::Diagram) { - Diagram *selected_diagram = elements_panel -> selectedDiagram(); - QETProject *selected_diagram_project = selected_diagram -> project(); + // Fetch ALL selected diagrams instead of just one + QList selected_diagrams = elements_panel -> selectedDiagrams(); - bool is_writable = !(selected_diagram_project -> isReadOnly()); - int project_diagrams_count = selected_diagram_project -> diagrams().count(); - int diagram_position = selected_diagram_project -> diagrams().indexOf(selected_diagram); + if (!selected_diagrams.isEmpty()) { + QETProject *selected_diagram_project = selected_diagrams.first() -> project(); + bool is_writable = !(selected_diagram_project -> isReadOnly()); + int project_diagrams_count = selected_diagram_project -> diagrams().count(); - prj_del_diagram -> setEnabled(is_writable); - prj_move_diagram_up -> setEnabled(is_writable && diagram_position > 0); - prj_move_diagram_down -> setEnabled(is_writable && diagram_position < project_diagrams_count - 1); - prj_move_diagram_top -> setEnabled(is_writable && diagram_position > 0); - prj_move_diagram_upx10 -> setEnabled(is_writable && diagram_position > 10); - prj_move_diagram_upx100 -> setEnabled(is_writable && diagram_position > 100); - prj_move_diagram_downx10 -> setEnabled(is_writable && diagram_position < project_diagrams_count - 10); - prj_move_diagram_downx100 -> setEnabled(is_writable && diagram_position < project_diagrams_count - 100); + // Find the highest (min) and lowest (max) index among the selection + int min_position = project_diagrams_count; + int max_position = -1; + + for (Diagram *diagram : selected_diagrams) { + int pos = selected_diagram_project -> diagrams().indexOf(diagram); + if (pos < min_position) min_position = pos; + if (pos > max_position) max_position = pos; + } + + prj_del_diagram -> setEnabled(is_writable); + prj_move_diagram_up -> setEnabled(is_writable && min_position > 0); + prj_move_diagram_down -> setEnabled(is_writable && max_position < project_diagrams_count - 1); + prj_move_diagram_top -> setEnabled(is_writable && min_position > 0); + + // Adjusted to >= to allow exactly 10 or 100 steps if space permits + prj_move_diagram_upx10 -> setEnabled(is_writable && min_position > 10); + prj_move_diagram_upx100 -> setEnabled(is_writable && min_position > 100); + prj_move_diagram_downx10 -> setEnabled(is_writable && max_position < project_diagrams_count - 10); + prj_move_diagram_downx100 -> setEnabled(is_writable && max_position < project_diagrams_count - 100); + } } else if (current_type == QET::TitleBlockTemplatesCollection) { TitleBlockTemplateLocation location = elements_panel -> templateLocationForItem(current_item); tbt_add -> setEnabled(!location.isReadOnly()); @@ -475,62 +539,57 @@ void ElementsPanelWidget::filterEdited(const QString &next_text) { } /** - Treat key press event inside elements panel widget -*/ -void ElementsPanelWidget::keyPressEvent (QKeyEvent *e) { - switch(e -> key()) { - case Qt::Key_Delete: //delete diagram through elements panel widget - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - emit(requestForDiagramDeletion(selected_diagram)); - } - break; - case Qt::Key_F3: - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - elements_panel->setSelectedItem(elements_panel->getItemForDiagram(selected_diagram)); - emit(requestForDiagramMoveUp(selected_diagram)); - } - break; - case Qt::Key_F4: - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - elements_panel->setSelectedItem(elements_panel->getItemForDiagram(selected_diagram)); - emit(requestForDiagramMoveDown(selected_diagram)); - } - break; - case Qt::Key_F5: - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - elements_panel->setSelectedItem(elements_panel->getItemForDiagram(selected_diagram)); - emit(requestForDiagramMoveUpTop(selected_diagram)); - } - - break; - case Qt::Key_F6: - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - elements_panel->setSelectedItem(elements_panel->getItemForDiagram(selected_diagram)); - emit(requestForDiagramMoveDownx10(selected_diagram)); - } - - break; - case Qt::Key_F7: - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - elements_panel->setSelectedItem(elements_panel->getItemForDiagram(selected_diagram)); - emit(requestForDiagramMoveDownx100(selected_diagram)); - } - - - break; - case Qt::Key_F8: - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - elements_panel->setSelectedItem(elements_panel->getItemForDiagram(selected_diagram)); - emit(requestForDiagramMoveUpx10(selected_diagram)); - } - - break; - case Qt::Key_F9: - if (Diagram *selected_diagram = elements_panel -> selectedDiagram()) { - elements_panel->setSelectedItem(elements_panel->getItemForDiagram(selected_diagram)); - emit(requestForDiagramMoveUpx100(selected_diagram)); - } - break; - } - return; + * Treat key press event inside elements panel widget + */ +/** + * Treat key press event inside elements panel widget. + * Respects the enabled/disabled state of the corresponding QActions. + */ +void ElementsPanelWidget::keyPressEvent(QKeyEvent *e) { + switch(e->key()) { + case Qt::Key_Delete: + if (prj_del_diagram && prj_del_diagram->isEnabled()) { + deleteDiagram(); + } + break; + case Qt::Key_F3: + if (prj_move_diagram_up && prj_move_diagram_up->isEnabled()) { + moveDiagramUp(); + } + break; + case Qt::Key_F4: + if (prj_move_diagram_down && prj_move_diagram_down->isEnabled()) { + moveDiagramDown(); + } + break; + case Qt::Key_F5: + if (prj_move_diagram_top && prj_move_diagram_top->isEnabled()) { + moveDiagramUpTop(); + } + break; + case Qt::Key_F6: + if (prj_move_diagram_downx10 && prj_move_diagram_downx10->isEnabled()) { + moveDiagramDownx10(); + } + break; + case Qt::Key_F7: + if (prj_move_diagram_downx100 && prj_move_diagram_downx100->isEnabled()) { + moveDiagramDownx100(); + } + break; + case Qt::Key_F8: + if (prj_move_diagram_upx10 && prj_move_diagram_upx10->isEnabled()) { + moveDiagramUpx10(); + } + break; + case Qt::Key_F9: + if (prj_move_diagram_upx100 && prj_move_diagram_upx100->isEnabled()) { + moveDiagramUpx100(); + } + break; + default: + // Pass unhandled key events to the base class + QWidget::keyPressEvent(e); + break; + } } diff --git a/sources/elementspanelwidget.h b/sources/elementspanelwidget.h index 6f3a7c4e1..4eb82a673 100644 --- a/sources/elementspanelwidget.h +++ b/sources/elementspanelwidget.h @@ -69,13 +69,14 @@ class ElementsPanelWidget : public QWidget { void requestForProjectPropertiesEdition(QETProject *); void requestForDiagramPropertiesEdition(Diagram *); void requestForDiagramDeletion(Diagram *); - void requestForDiagramMoveUp(Diagram *); - void requestForDiagramMoveDown(Diagram *); - void requestForDiagramMoveUpTop(Diagram *); - void requestForDiagramMoveUpx10(Diagram *); - void requestForDiagramMoveUpx100(Diagram *); - void requestForDiagramMoveDownx10(Diagram *); - void requestForDiagramMoveDownx100(Diagram *); + void requestForDiagramsDeletion(const QList &diagrams); + void requestForDiagramMoveUp(const QList &diagrams); + void requestForDiagramMoveDown(const QList &diagrams); + void requestForDiagramMoveUpTop(const QList &diagrams); + void requestForDiagramMoveUpx10(const QList &diagrams); + void requestForDiagramMoveUpx100(const QList &diagrams); + void requestForDiagramMoveDownx10(const QList &diagrams); + void requestForDiagramMoveDownx100(const QList &diagrams); public slots: void openDirectoryForSelectedItem(); diff --git a/sources/projectview.cpp b/sources/projectview.cpp index 9535dcdf5..740092ac5 100644 --- a/sources/projectview.cpp +++ b/sources/projectview.cpp @@ -364,11 +364,12 @@ QETResult ProjectView::noProjectResult() const } /** - @brief ProjectView::removeDiagram - Remove a diagram (folio) of the project - @param diagram_view : diagram view to remove -*/ -void ProjectView::removeDiagram(DiagramView *diagram_view) + * @brief ProjectView::removeDiagram + * Remove a diagram (folio) of the project + * @param diagram_view : diagram view to remove + * @param silent : if true, bypasses the confirmation message box + */ +void ProjectView::removeDiagram(DiagramView *diagram_view, bool silent) { if (!diagram_view) return; @@ -377,17 +378,18 @@ void ProjectView::removeDiagram(DiagramView *diagram_view) if (!m_diagram_ids.values().contains(diagram_view)) return; - - //Ask confirmation to user. - int answer = QET::QetMessageBox::question( - this, - tr("Supprimer le folio ?", "message box title"), - tr("Êtes-vous sûr de vouloir supprimer ce folio du projet ? Ce changement est irréversible.", "message box content"), - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, - QMessageBox::No - ); - if (answer != QMessageBox::Yes) { - return; + if (!silent) { + //Ask confirmation to user. + int answer = QET::QetMessageBox::question( + this, + tr("Supprimer le folio ?", "message box title"), + tr("Êtes-vous sûr de vouloir supprimer ce folio du projet ? Ce changement est irréversible.", "message box content"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, + QMessageBox::No + ); + if (answer != QMessageBox::Yes) { + return; + } } //Remove the diagram view of the tabs widget @@ -405,14 +407,15 @@ void ProjectView::removeDiagram(DiagramView *diagram_view) } /** - Enleve un schema du ProjectView - @param diagram Schema a enlever -*/ -void ProjectView::removeDiagram(Diagram *diagram) { + * Enleve un schema du ProjectView + * @param diagram Schema a enlever + * @param silent Si vrai, supprime sans demander confirmation + */ +void ProjectView::removeDiagram(Diagram *diagram, bool silent) { if (!diagram) return; if (DiagramView *diagram_view = findDiagram(diagram)) { - removeDiagram(diagram_view); + removeDiagram(diagram_view, silent); } } @@ -557,6 +560,56 @@ void ProjectView::moveDiagramUpx10(Diagram *diagram) { moveDiagramUpx10(findDiagram(diagram)); } +/** + * @brief ProjectView::moveDiagramUpx100 + * Moves the diagram_view up / left x100 + * @param diagram_view View to move + */ +void ProjectView::moveDiagramUpx100(DiagramView *diagram_view) { + if (!diagram_view) return; + + int diagram_view_position = m_diagram_ids.key(diagram_view); + if (!diagram_view_position) { + // The diagram is the first of the project + return; + } + m_tab->tabBar()->moveTab(diagram_view_position, diagram_view_position - 100); +} + +/** + * @brief ProjectView::moveDiagramUpx100 + * Moves the diagram up / left x100 + * @param diagram Diagram to move + */ +void ProjectView::moveDiagramUpx100(Diagram *diagram) { + moveDiagramUpx100(findDiagram(diagram)); +} + +/** + * @brief ProjectView::moveDiagramDownx100 + * Moves the diagram_view down / right x100 + * @param diagram_view View to move + */ +void ProjectView::moveDiagramDownx100(DiagramView *diagram_view) { + if (!diagram_view) return; + + int diagram_view_position = m_diagram_ids.key(diagram_view); + if (diagram_view_position + 1 == m_diagram_ids.count()) { + // The diagram is the last of the project + return; + } + m_tab->tabBar()->moveTab(diagram_view_position, diagram_view_position + 100); +} + +/** + * @brief ProjectView::moveDiagramDownx100 + * Moves the diagram down / right x100 + * @param diagram Diagram to move + */ +void ProjectView::moveDiagramDownx100(Diagram *diagram) { + moveDiagramDownx100(findDiagram(diagram)); +} + /** Deplace le schema diagram_view vers le bas / la droite x10 */ diff --git a/sources/projectview.h b/sources/projectview.h index 7537d2867..4b9a33e74 100644 --- a/sources/projectview.h +++ b/sources/projectview.h @@ -104,8 +104,8 @@ class ProjectView : public QWidget void changeLastTab(); public slots: - void removeDiagram(DiagramView *); - void removeDiagram(Diagram *); + void removeDiagram(DiagramView *diagram_view, bool silent = false); + void removeDiagram(Diagram *diagram, bool silent = false); void showDiagram(DiagramView *); void showDiagram(Diagram *); void editProjectProperties(); @@ -122,6 +122,10 @@ class ProjectView : public QWidget void moveDiagramUpx10(Diagram *); void moveDiagramDownx10(DiagramView *); void moveDiagramDownx10(Diagram *); + void moveDiagramUpx100(DiagramView *); + void moveDiagramUpx100(Diagram *); + void moveDiagramDownx100(DiagramView *); + void moveDiagramDownx100(Diagram *); void exportProject(); QETResult save(); QETResult saveAs(); diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 398b15014..335f6cb3c 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -16,7 +16,7 @@ along with QElectroTech. If not, see . */ #include "qetdiagrameditor.h" - +#include #include "ElementsCollection/elementscollectionwidget.h" #include "QWidgetAnimation/qwidgetanimation.h" #include "autoNum/ui/autonumberingdockwidget.h" @@ -47,7 +47,7 @@ #include "TerminalStrip/ui/addterminalstripitemdialog.h" #include "wiringlistexport.h" #include "ui/terminalnumberingdialog.h" - +#include #ifdef BUILD_WITHOUT_KF5 #else # include @@ -176,12 +176,14 @@ void QETDiagramEditor::setUpElementsPanel() connect(pa, SIGNAL(requestForProjectPropertiesEdition (QETProject *)), this, SLOT(editProjectProperties(QETProject *))); connect(pa, SIGNAL(requestForNewDiagram (QETProject *)), this, SLOT(addDiagramToProject(QETProject *))); connect(pa, SIGNAL(requestForDiagramPropertiesEdition (Diagram *)), this, SLOT(editDiagramProperties(Diagram *))); - connect(pa, SIGNAL(requestForDiagramDeletion (Diagram *)), this, SLOT(removeDiagram(Diagram *))); - connect(pa, SIGNAL(requestForDiagramMoveUp (Diagram *)), this, SLOT(moveDiagramUp(Diagram *))); - connect(pa, SIGNAL(requestForDiagramMoveDown (Diagram *)), this, SLOT(moveDiagramDown(Diagram *))); - connect(pa, SIGNAL(requestForDiagramMoveUpTop (Diagram *)), this, SLOT(moveDiagramUpTop(Diagram *))); - connect(pa, SIGNAL(requestForDiagramMoveUpx10 (Diagram *)), this, SLOT(moveDiagramUpx10(Diagram *))); - connect(pa, SIGNAL(requestForDiagramMoveDownx10 (Diagram *)), this, SLOT(moveDiagramDownx10(Diagram *))); + connect(pa, SIGNAL(requestForDiagramsDeletion (const QList &)), this, SLOT(removeDiagrams(const QList &))); + connect(pa, SIGNAL(requestForDiagramMoveUp (const QList &)), this, SLOT(moveDiagramUp(const QList&))); + connect(pa, SIGNAL(requestForDiagramMoveDown (const QList &)), this, SLOT(moveDiagramDown(const QList&))); + connect(pa, SIGNAL(requestForDiagramMoveUpTop (const QList &)), this, SLOT(moveDiagramUpTop(const QList&))); + connect(pa, SIGNAL(requestForDiagramMoveUpx10 (const QList &)), this, SLOT(moveDiagramUpx10(const QList&))); + connect(pa, SIGNAL(requestForDiagramMoveDownx10 (const QList &)), this, SLOT(moveDiagramDownx10(const QList&))); + connect(pa, SIGNAL(requestForDiagramMoveUpx100 (const QList &)), this, SLOT(moveDiagramUpx100(const QList&))); + connect(pa, SIGNAL(requestForDiagramMoveDownx100 (const QList &)), this, SLOT(moveDiagramDownx100(const QList&))); } /** @@ -2183,126 +2185,182 @@ void QETDiagramEditor::addDiagramToProject(QETProject *project) project_view->project()->addNewDiagram(); } } +/** + * @brief QETDiagramEditor::removeDiagram + * Wrapper für einzelne Diagramme, um Abwärtskompatibilität zu erhalten. + */ +void QETDiagramEditor::removeDiagram(Diagram *diagram) +{ + if (!diagram) return; + QList list; + list << diagram; + removeDiagrams(list); +} + +/** + * @brief QETDiagramEditor::removeDiagrams + * Deletes a list of folios with a single query. + */ +void QETDiagramEditor::removeDiagrams(const QList &diagrams) +{ + if (diagrams.isEmpty()) return; + + if (diagrams.count() == 1) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(this, tr("Supprimer le folio"), + tr("Êtes-vous sûr de vouloir supprimer ce folio ?"), + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::No) return; + } else { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(this, tr("Supprimer les folios"), + tr("Êtes-vous sûr de vouloir supprimer les %1 folios sélectionnés ?").arg(diagrams.count()), + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::No) return; + } + + ProjectView *project_view = nullptr; + if (QETProject *diagram_project = diagrams.first()->project()) { + project_view = findProject(diagram_project); + } + + if (project_view) project_view->setUpdatesEnabled(false); + if (pa) pa->setUpdatesEnabled(false); + + foreach (Diagram *diagram, diagrams) { + removeDiagramSilent(diagram); + } + + if (pa) pa->setUpdatesEnabled(true); + if (project_view) project_view->setUpdatesEnabled(true); + + emit syncElementsPanel(); +} /** Supprime un schema de son projet @param diagram Schema a supprimer */ -void QETDiagramEditor::removeDiagram(Diagram *diagram) +void QETDiagramEditor::removeDiagramSilent(Diagram *diagram) { if (!diagram) return; - // recupere le projet contenant le schema if (QETProject *diagram_project = diagram -> project()) { - // recupere la vue sur ce projet if (ProjectView *project_view = findProject(diagram_project)) { - // affiche le schema en question - project_view -> showDiagram(diagram); - // supprime le schema - project_view -> removeDiagram(diagram); + project_view -> removeDiagram(diagram, true); + } + } +} +void QETDiagramEditor::moveDiagramUp(const QList &diagrams) { + if (diagrams.isEmpty()) return; + QList safeDiagrams = diagrams; + if (QETProject *diagram_project = safeDiagrams.first()->project()) { + if (!diagram_project->isReadOnly()) { + if (ProjectView *project_view = findProject(diagram_project)) { + // Forward loop for moving up + for (int i = 0; i < safeDiagrams.size(); ++i) { + project_view->moveDiagramUp(safeDiagrams.at(i)); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + } } } } -/** - Change l'ordre des schemas d'un projet, en decalant le schema vers le haut / - la gauche - @param diagram Schema a decaler vers le haut / la gauche -*/ -void QETDiagramEditor::moveDiagramUp(Diagram *diagram) -{ - if (!diagram) return; - - // recupere le projet contenant le schema - if (QETProject *diagram_project = diagram -> project()) { - if (diagram_project -> isReadOnly()) return; - - // recupere la vue sur ce projet - if (ProjectView *project_view = findProject(diagram_project)) { - project_view -> moveDiagramUp(diagram); +void QETDiagramEditor::moveDiagramDown(const QList &diagrams) { + if (diagrams.isEmpty()) return; + QList safeDiagrams = diagrams; + if (QETProject *diagram_project = safeDiagrams.first()->project()) { + if (!diagram_project->isReadOnly()) { + if (ProjectView *project_view = findProject(diagram_project)) { + // Backward loop for moving down + for (int i = safeDiagrams.size() - 1; i >= 0; --i) { + project_view->moveDiagramDown(safeDiagrams.at(i)); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + } } } } -/** - Change l'ordre des schemas d'un projet, en decalant le schema vers le bas / - la droite - @param diagram Schema a decaler vers le bas / la droite -*/ -void QETDiagramEditor::moveDiagramDown(Diagram *diagram) -{ - if (!diagram) return; - - // recupere le projet contenant le schema - if (QETProject *diagram_project = diagram -> project()) { - if (diagram_project -> isReadOnly()) return; - - // recupere la vue sur ce projet - if (ProjectView *project_view = findProject(diagram_project)) { - project_view -> moveDiagramDown(diagram); +void QETDiagramEditor::moveDiagramUpTop(const QList &diagrams) { + if (diagrams.isEmpty()) return; + QList safeDiagrams = diagrams; + if (QETProject *diagram_project = safeDiagrams.first()->project()) { + if (!diagram_project->isReadOnly()) { + if (ProjectView *project_view = findProject(diagram_project)) { + // Backward loop to preserve relative order of the selected items when moving to top + for (int i = safeDiagrams.size() - 1; i >= 0; --i) { + project_view->moveDiagramUpTop(safeDiagrams.at(i)); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + } } } } -/** - Change l'ordre des schemas d'un projet, en decalant le schema vers le haut / - la gauche en position 0 - @param diagram Schema a decaler vers le haut / la gauche en position 0 -*/ -void QETDiagramEditor::moveDiagramUpTop(Diagram *diagram) -{ - if (!diagram) return; - - // recupere le projet contenant le schema - if (QETProject *diagram_project = diagram -> project()) { - if (diagram_project -> isReadOnly()) return; - - // recupere la vue sur ce projet - if (ProjectView *project_view = findProject(diagram_project)) { - project_view -> moveDiagramUpTop(diagram); +void QETDiagramEditor::moveDiagramUpx10(const QList &diagrams) { + if (diagrams.isEmpty()) return; + QList safeDiagrams = diagrams; + if (QETProject *diagram_project = safeDiagrams.first()->project()) { + if (!diagram_project->isReadOnly()) { + if (ProjectView *project_view = findProject(diagram_project)) { + // Forward loop for moving up + for (int i = 0; i < safeDiagrams.size(); ++i) { + project_view->moveDiagramUpx10(safeDiagrams.at(i)); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + } } } } - -/** - Change l'ordre des schemas d'un projet, en decalant le schema vers le haut / - la gauche x10 - @param diagram Schema a decaler vers le haut / la gauche x10 -*/ -void QETDiagramEditor::moveDiagramUpx10(Diagram *diagram) -{ - if (!diagram) return; - - // recupere le projet contenant le schema - if (QETProject *diagram_project = diagram -> project()) { - if (diagram_project -> isReadOnly()) return; - - // recupere la vue sur ce projet - if (ProjectView *project_view = findProject(diagram_project)) { - project_view -> moveDiagramUpx10(diagram); +void QETDiagramEditor::moveDiagramDownx10(const QList &diagrams) { + if (diagrams.isEmpty()) return; + QList safeDiagrams = diagrams; + if (QETProject *diagram_project = safeDiagrams.first()->project()) { + if (!diagram_project->isReadOnly()) { + if (ProjectView *project_view = findProject(diagram_project)) { + // Backward loop for moving down + for (int i = safeDiagrams.size() - 1; i >= 0; --i) { + project_view->moveDiagramDownx10(safeDiagrams.at(i)); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + } } } } -/** - Change l'ordre des schemas d'un projet, en decalant le schema vers le bas / - la droite x10 - @param diagram Schema a decaler vers le bas / la droite x10 -*/ -void QETDiagramEditor::moveDiagramDownx10(Diagram *diagram) -{ - if (!diagram) return; +void QETDiagramEditor::moveDiagramUpx100(const QList &diagrams) { + if (diagrams.isEmpty()) return; + QList safeDiagrams = diagrams; + if (QETProject *diagram_project = safeDiagrams.first()->project()) { + if (!diagram_project->isReadOnly()) { + if (ProjectView *project_view = findProject(diagram_project)) { + // Forward loop for moving up + for (int i = 0; i < safeDiagrams.size(); ++i) { + project_view->moveDiagramUpx100(safeDiagrams.at(i)); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + } + } + } +} - // recupere le projet contenant le schema - if (QETProject *diagram_project = diagram -> project()) { - if (diagram_project -> isReadOnly()) return; - - // recupere la vue sur ce projet - if (ProjectView *project_view = findProject(diagram_project)) { - project_view -> moveDiagramDownx10(diagram); +void QETDiagramEditor::moveDiagramDownx100(const QList &diagrams) { + if (diagrams.isEmpty()) return; + QList safeDiagrams = diagrams; + if (QETProject *diagram_project = safeDiagrams.first()->project()) { + if (!diagram_project->isReadOnly()) { + if (ProjectView *project_view = findProject(diagram_project)) { + // Backward loop for moving down + for (int i = safeDiagrams.size() - 1; i >= 0; --i) { + project_view->moveDiagramDownx100(safeDiagrams.at(i)); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } + } } } } diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index f456a162a..d5139ed5a 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -138,12 +138,15 @@ class QETDiagramEditor : public QETMainWindow void editDiagramProperties(Diagram *); void addDiagramToProject(QETProject *); void removeDiagram(Diagram *); + void removeDiagrams(const QList &diagrams); void removeDiagramFromProject(); - void moveDiagramUp(Diagram *); - void moveDiagramDown(Diagram *); - void moveDiagramUpTop(Diagram *); - void moveDiagramUpx10(Diagram *); - void moveDiagramDownx10(Diagram *); + void moveDiagramUp(const QList &diagrams); + void moveDiagramDown(const QList &diagrams); + void moveDiagramUpTop(const QList &diagrams); + void moveDiagramUpx10(const QList &diagrams); + void moveDiagramDownx10(const QList &diagrams); + void moveDiagramUpx100(const QList &diagrams); + void moveDiagramDownx100(const QList &diagrams); void reloadOldElementPanel(); void diagramWasAdded(DiagramView *); void findElementInPanel(const ElementsLocation &); @@ -222,6 +225,8 @@ class QETDiagramEditor : public QETMainWindow QList m_zoom_action_toolBar; ///Only zoom action must displayed in the toolbar + void removeDiagramSilent(Diagram *diagram); + QMdiArea m_workspace; QSignalMapper windowMapper; QDir open_dialog_dir; /// Directory to use for file dialogs such as File > save