diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake index 57a012916..ffde16f63 100644 --- a/cmake/qet_compilation_vars.cmake +++ b/cmake/qet_compilation_vars.cmake @@ -155,6 +155,8 @@ set(QET_SRC_FILES ${QET_DIR}/sources/conductornumexport.cpp ${QET_DIR}/sources/wiringlistexport.h ${QET_DIR}/sources/wiringlistexport.cpp + ${QET_DIR}/sources/ui/wiringlistdialog.h + ${QET_DIR}/sources/ui/wiringlistdialog.cpp ${QET_DIR}/sources/conductornumexport.h ${QET_DIR}/sources/conductorprofile.cpp ${QET_DIR}/sources/conductorprofile.h diff --git a/sources/dataBase/projectdatabase.cpp b/sources/dataBase/projectdatabase.cpp index f2b3df670..942691af7 100644 --- a/sources/dataBase/projectdatabase.cpp +++ b/sources/dataBase/projectdatabase.cpp @@ -111,6 +111,42 @@ QSqlQuery projectDataBase::newQuery(const QString &query) { return QSqlQuery(query, m_data_base); } +/** + @brief projectDataBase::excludedConductorCount + @return how many conductors of the project are deliberately absent from + the conductor table because at least one of their terminals has no uuid. + + Counted from the live scene rather than from the database, precisely + because the database is where these conductors are *not*. See + addConductor() for why they are omitted: a terminal uuid comes from the + catalog .elmt definition, so an element whose definition predates that + field yields terminals with no stable identity to key on. + + This is what lets a caller tell the user "N wires are missing and here + is why", instead of silently presenting a short list as if it were + complete. +*/ +int projectDataBase::excludedConductorCount() const +{ + if (!m_project) { + return 0; + } + + int count = 0; + for (auto *diagram : m_project->diagrams()) + { + const auto conductor_list = diagram->conductors(); + for (auto *conductor : conductor_list) + { + if (conductor->terminal1->uuid().isNull() + || conductor->terminal2->uuid().isNull()) { + ++count; + } + } + } + return count; +} + /** @brief projectDataBase::addElement @param element diff --git a/sources/dataBase/projectdatabase.h b/sources/dataBase/projectdatabase.h index 65ca17950..5873d825f 100644 --- a/sources/dataBase/projectdatabase.h +++ b/sources/dataBase/projectdatabase.h @@ -49,6 +49,8 @@ class projectDataBase : public QObject void updateDB(); QETProject *project() const; QSqlQuery newQuery(const QString &query = QString()); + QSqlDatabase database() const {return m_data_base;} + int excludedConductorCount() const; void addElement (Element *element); void removeElement (Element *element); diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 5b2ba6779..f686f6daf 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -53,6 +53,7 @@ #include "ui/diagrameditorhandlersizewidget.h" #include "TerminalStrip/ui/addterminalstripitemdialog.h" #include "wiringlistexport.h" +#include "ui/wiringlistdialog.h" #include "ui/terminalnumberingdialog.h" #include #include @@ -503,6 +504,17 @@ void QETDiagramEditor::setUpActions() } }); + // Show the wiring list read from the project database + m_project_wiring_list_view = new QAction(QET::Icons::DocumentSpreadsheet, tr("Liste de câblage (base de données)"), this); + connect(m_project_wiring_list_view, &QAction::triggered, [this]() { + QETProject *project = this->currentProject(); + if (project) + { + WiringListDialog dialog(project, this); + dialog.exec(); + } + }); + // Terminal Numbering m_terminal_numbering = new QAction(QET::Icons::TerminalStrip, tr("Numérotation automatique des bornes"), this); connect(m_terminal_numbering, &QAction::triggered, this, &QETDiagramEditor::slot_terminalNumbering); @@ -892,6 +904,7 @@ void QETDiagramEditor::setUpMenu() menu_project -> addAction(m_terminal_strip_dialog); menu_project -> addAction(m_project_terminalBloc); menu_project -> addAction(m_project_export_wiring_list); + menu_project -> addAction(m_project_wiring_list_view); menu_project -> addAction(m_terminal_numbering); #ifdef QET_EXPORT_PROJECT_DB menu_project -> addSeparator(); @@ -1680,6 +1693,7 @@ void QETDiagramEditor::slot_updateActions() m_project_export_conductor_num-> setEnabled(opened_project); m_terminal_strip_dialog -> setEnabled(editable_project); m_project_export_wiring_list -> setEnabled(opened_project); + m_project_wiring_list_view -> setEnabled(opened_project); m_terminal_numbering -> setEnabled(editable_project); #ifdef QET_EXPORT_PROJECT_DB m_export_project_db -> setEnabled(editable_project); diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index 0114a186e..7efa706a9 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -207,6 +207,7 @@ class QETDiagramEditor : public QETMainWindow *m_project_terminalBloc, ///< generate terminal block *m_project_export_conductor_num,///. +*/ +#include "wiringlistdialog.h" + +#include "../dataBase/projectdatabase.h" +#include "../qetproject.h" + +#include +#include +#include +#include +#include +#include + +/** + @brief WiringListDialog::WiringListDialog + @param project : project whose wiring list is shown + @param parent : parent widget +*/ +WiringListDialog::WiringListDialog(QETProject *project, QWidget *parent) : + QDialog(parent), + m_project(project) +{ + setWindowTitle(tr("Liste de câblage", "window title")); + resize(900, 500); + + auto *layout = new QVBoxLayout(this); + + auto *model = new QSqlQueryModel(this); + model->setQuery(QStringLiteral( + "SELECT wire_number, from_element_label, from_terminal," + " to_element_label, to_terminal, diagram_position" + " FROM wiring_list_view" + " ORDER BY diagram_position, wire_number"), + m_project->dataBase()->database()); + + model->setHeaderData(0, Qt::Horizontal, tr("Fil", "column title")); + model->setHeaderData(1, Qt::Horizontal, tr("Composant 1", "column title")); + model->setHeaderData(2, Qt::Horizontal, tr("Borne 1", "column title")); + model->setHeaderData(3, Qt::Horizontal, tr("Composant 2", "column title")); + model->setHeaderData(4, Qt::Horizontal, tr("Borne 2", "column title")); + model->setHeaderData(5, Qt::Horizontal, tr("Folio", "column title")); + + const int excluded = m_project->dataBase()->excludedConductorCount(); + const int listed = model->rowCount(); + + auto *summary = new QLabel(this); + summary->setWordWrap(true); + if (excluded > 0) + { + //The count matters more than it looks: a project whose elements + //all predate terminal uuids yields an entirely empty list, and + //without this line that is indistinguishable from a project with + //no wires in it. + summary->setText(tr("%n conducteur(s) listé(s).", "wiring list summary", listed) + % QStringLiteral(" ") + % tr("%n conducteur(s) exclu(s) : leurs éléments ne définissent pas" + " d'identifiant de borne (définition d'élément trop ancienne).", + "wiring list exclusion warning", excluded)); + } + else { + summary->setText(tr("%n conducteur(s) listé(s).", "wiring list summary", listed)); + } + layout->addWidget(summary); + + auto *view = new QTableView(this); + view->setModel(model); + view->setEditTriggers(QAbstractItemView::NoEditTriggers); + view->setSelectionBehavior(QAbstractItemView::SelectRows); + view->setAlternatingRowColors(true); + view->verticalHeader()->setVisible(false); + view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + layout->addWidget(view); + + auto *buttons = new QDialogButtonBox(QDialogButtonBox::Close, this); + connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); + layout->addWidget(buttons); +} diff --git a/sources/ui/wiringlistdialog.h b/sources/ui/wiringlistdialog.h new file mode 100644 index 000000000..73251473c --- /dev/null +++ b/sources/ui/wiringlistdialog.h @@ -0,0 +1,48 @@ +/* + Copyright 2006-2026 The QElectroTech Team + This file is part of QElectroTech. + + QElectroTech is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + QElectroTech is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QElectroTech. If not, see . +*/ +#ifndef WIRINGLISTDIALOG_H +#define WIRINGLISTDIALOG_H + +#include + +class QETProject; + +/** + @brief The WiringListDialog class + Read-only view of the project's from-to wiring list, read from the + wiring_list_view of projectDataBase. + + Deliberately not an exporter: QET already ships a wiring-list CSV export + (Projet > Exporter le plan de câblage, and --export-cables), which walks + the project XML and covers that need. This dialog exists to make the + database view inspectable, and above all to state how many conductors + are missing from it and why -- a count the CSV export cannot give, + because it never excludes anything in the first place. +*/ +class WiringListDialog : public QDialog +{ + Q_OBJECT + + public: + explicit WiringListDialog(QETProject *project, QWidget *parent = nullptr); + + private: + QETProject *m_project = nullptr; +}; + +#endif // WIRINGLISTDIALOG_H