Files
qelectrotech-source-mirror/sources/ui/bomexportdialog.cpp
T
ispyisail 8434b88eb8 Add options to leave junctions and contact blocks out of the parts list (#1178)
Since #849 the parts list has a row for every contact block (slave) and
terminal-type element. Users who draw the dots and bends where wires
branch as terminal-type symbols (114_connections) get one empty row per
junction: 109 of 151 rows on one reported cabinet.

Two options, both off by default so existing exports are unchanged:
- leave out the contact blocks: --no-slaves, "no_slaves" in qet_export,
  or uncheck the new "Contacts esclaves" element type in the dialog;
- leave out the junctions: terminal-type elements with no label,
  designation, manufacturer or manufacturer reference. --no-junctions,
  "no_junctions", or "Laisser de côté les jonctions" in the dialog.
  A terminal block with a label or a part number stays.

The element type filter had no box for slaves, so every query it built
left them out: the export dialog never listed contact blocks, although
the command line has since #849. The dialog now checks the new box by
default and gives the same rows as --export-bom. The box is unchecked by
default elsewhere, so nomenclature tables keep their rows.

docs/smart-device-bom.md still said slaves and terminals were excluded;
corrected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 22:08:44 +13:00

195 lines
5.6 KiB
C++

/*
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 <http://www.gnu.org/licenses/>.
*/
#include "bomexportdialog.h"
#include "../dataBase/ui/elementquerywidget.h"
#include "../bomexport.h"
#include "../qetapp.h"
#include "../qetinformation.h"
#include "../qetproject.h"
#include "ui_bomexportdialog.h"
#include "../qet.h"
#include <QMessageBox>
#include <QSqlError>
#include <QSqlQueryModel>
#include <QSqlRecord>
/**
@brief BOMExportDialog::BOMExportDialog
@param project
@param parent
*/
BOMExportDialog::BOMExportDialog(QETProject *project, QWidget *parent) :
QDialog(parent),
ui(new Ui::BOMExportDialog),
m_project(project)
{
ui->setupUi(this);
QET::trackDialogGeometry(this);
m_query_widget = new ElementQueryWidget(this);
ui->m_main_layout->insertWidget(0, m_query_widget);
m_query_widget->setQuery(BomExport::defaultQuery());
//The contact blocks are parts of their own, as in the command line
//export; unchecking "Contacts esclaves" leaves them out.
m_query_widget->setSlavesIncluded(true);
on_m_format_as_bom_clicked(false);
m_preview_model = new QSqlQueryModel(this);
ui->m_preview_table->setModel(m_preview_model);
}
/**
@brief BOMExportDialog::~BOMExportDialog
*/
BOMExportDialog::~BOMExportDialog()
{
delete ui;
}
/**
@brief BOMExportDialog::exec
@return
*/
int BOMExportDialog::exec()
{
auto r = QDialog::exec();
if (r == QDialog::Accepted)
{
//save in csv file in same directory as project by default
QString dir = m_project->currentDir();
if (dir.isEmpty()) dir = QETApp::documentDir();
QString file_name = dir % "/" % tr("nomenclature_") % QString(m_project ->title() % ".csv");
QString file_path = QFileDialog::getSaveFileName(this, tr("Enregister sous... "), file_name, tr("Fichiers csv (*.csv)"));
if (!file_path.isEmpty())
{
QString error;
const auto csv = getBom(&error);
if (!error.isEmpty() || !BomExport::writeCsv(file_path, csv, &error)) {
QMessageBox::critical(
this, tr("Erreur"),
tr("Impossible d'enregistrer la nomenclature dans %1.\n%2")
.arg(file_path, error));
}
}
}
return r;
}
QByteArray BOMExportDialog::getBom(QString *error)
{
if (error) {
error->clear();
}
m_project->dataBase()->updateDB();
QString rejection;
auto query_ = m_project->dataBase()->newQuery(m_query_widget->queryStr(), &rejection);
if (!rejection.isEmpty()) {
if (error) {
*error = rejection;
}
return {};
}
if (!query_.exec()) {
qDebug() << "BOMExportDialog::getBom : query errir : " << query_.lastError();
if (error) {
*error = query_.lastError().text();
}
return {};
}
QStringList header_names;
if (ui->m_include_headers->isChecked())
{
const auto record_ = query_.record();
for (int i = 0; i < record_.count(); ++i)
{
const auto field_name = record_.fieldName(i);
if (field_name == QLatin1String("position")) {
header_names << tr("Position");
} else if (field_name == QLatin1String("diagram_position")) {
header_names << tr("Position du folio");
} else if (field_name == QLatin1String("designation_qty")) {
header_names << tr("Quantité numéro d'article", "Special field with name : designation quantity");
} else {
const auto translated = QETInformation::translatedInfoKey(field_name);
header_names << (translated.isEmpty() ? field_name : translated);
}
}
}
return BomExport::toCsv(
query_, header_names, ui->m_include_headers->isChecked());
}
/**
@brief BOMExportDialog::on_m_format_as_bom_clicked
@param checked
*/
void BOMExportDialog::on_m_format_as_bom_clicked(bool checked) {
m_query_widget->setGroupBy("designation", checked);
m_query_widget->setCount("COUNT(*) AS designation_qty", checked);
}
/**
@brief BOMExportDialog::on_m_no_junctions_clicked
@param checked : true leaves out the junctions, see
BomExport::junctionFilter()
*/
void BOMExportDialog::on_m_no_junctions_clicked(bool checked) {
m_query_widget->setExtraFilter(BomExport::junctionFilter(), checked);
}
/**
@brief BOMExportDialog::on_m_preview_pb_clicked
Run the current query and show its result live, without going through
the CSV round-trip -- lets a report be checked and adjusted before
committing to a file (qelectrotech-source-mirror#886).
*/
void BOMExportDialog::on_m_preview_pb_clicked()
{
m_project->dataBase()->updateDB();
QString rejection;
auto query_ = m_project->dataBase()->newQuery(m_query_widget->queryStr(), &rejection);
if (!rejection.isEmpty()) {
QMessageBox::warning(this, tr("Requête refusée"), rejection);
return;
}
if (!query_.exec()) {
QMessageBox::warning(
this, tr("Erreur"),
tr("Erreur dans la requête :\n%1").arg(query_.lastError().text()));
return;
}
m_preview_model->setQuery(std::move(query_));
for (int i = 0; i < m_preview_model->columnCount(); ++i)
{
const auto field_name = m_preview_model->record().fieldName(i);
const auto translated = QETInformation::translatedInfoKey(field_name);
if (!translated.isEmpty()) {
m_preview_model->setHeaderData(i, Qt::Horizontal, translated);
}
}
ui->m_preview_table->resizeColumnsToContents();
}