mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-05 18:54:14 +02:00
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>
This commit is contained in:
@@ -42,10 +42,18 @@ unit conventions and decimal quantities are not changed implicitly.
|
||||
|
||||
## BOM Policy
|
||||
|
||||
The default BOM query exports one row per Simple or Master element. Slave
|
||||
contacts, terminal-strip elements, reports, thumbnails, and conductor
|
||||
definitions are excluded. A Master device is counted once and PLC I/O entries
|
||||
are not expanded. The existing `exclude_from_bom` property is honored by the
|
||||
The default BOM query exports one row per Simple, Master, Slave or Terminal
|
||||
element: an auxiliary contact block and a terminal block are parts of their
|
||||
own (discussion #847). Reports, thumbnails and conductor definitions are
|
||||
excluded. A Master device is counted once and PLC I/O entries are not
|
||||
expanded.
|
||||
|
||||
Two options leave rows out (#1178). Contact blocks: uncheck **Contacts
|
||||
esclaves** in the dialog, or pass `--no-slaves`. Junctions, the
|
||||
terminal-type symbols drawn where wires branch (`114_connections`), which
|
||||
have no label, designation, manufacturer or manufacturer reference: check
|
||||
**Laisser de côté les jonctions**, or pass `--no-junctions`. A terminal block
|
||||
with a label or a part number is kept. The existing `exclude_from_bom` property is honored by the
|
||||
SQL view, including common true representations (`true`, `1`, `yes`, `on`).
|
||||
|
||||
The default columns are:
|
||||
|
||||
@@ -678,6 +678,12 @@ Python, plus the hang guard on `addConductor` and the database refresh in
|
||||
`source_date_epoch` if given, else the server's own `SOURCE_DATE_EPOCH`,
|
||||
else 0 (1 January 1970). The result's `"reproducible"` is false, with a
|
||||
hint, when the QElectroTech build is too old to honour it.
|
||||
- **`"no_slaves"` and `"no_junctions"` shorten a `bom` export.** The first
|
||||
leaves out the contact blocks, which otherwise get a row of their own; the
|
||||
second leaves out terminal-type elements with no label, designation,
|
||||
manufacturer or manufacturer reference, such as the junction dots of
|
||||
`114_connections`. They pass `--no-slaves` and `--no-junctions`; an older
|
||||
QElectroTech ignores both and exports every row, so check the row count.
|
||||
- **`qet_export` isolates its launch.** SingleApplication keys its socket
|
||||
on `applicationFilePath()`, so a second launch of the same binary path
|
||||
forwards its request to an already-running instance and returns *that*
|
||||
|
||||
+22
-4
@@ -1059,10 +1059,13 @@ def _source_date_epoch(value) -> int:
|
||||
|
||||
def tool_export(binary: str, project: str, format: str, output: str,
|
||||
timeout: int = 180, reproducible: bool = False,
|
||||
source_date_epoch: int | None = None) -> dict:
|
||||
source_date_epoch: int | None = None,
|
||||
no_slaves: bool = False, no_junctions: bool = False) -> dict:
|
||||
if format not in EXPORT_FORMATS:
|
||||
raise ValueError(f"unknown format {format!r}; "
|
||||
f"expected one of {', '.join(sorted(EXPORT_FORMATS))}")
|
||||
if (no_slaves or no_junctions) and format != "bom":
|
||||
raise ValueError("no_slaves and no_junctions only apply to format \"bom\"")
|
||||
proj = Path(project).expanduser()
|
||||
if not proj.is_file():
|
||||
raise ValueError(f"no such project: {proj}")
|
||||
@@ -1080,8 +1083,12 @@ def tool_export(binary: str, project: str, format: str, output: str,
|
||||
if reproducible or source_date_epoch is not None:
|
||||
epoch = _source_date_epoch(source_date_epoch)
|
||||
extra_env = {"SOURCE_DATE_EPOCH": str(epoch)}
|
||||
result = _run_qet(binary, [flag, str(proj), output], timeout,
|
||||
extra_env=extra_env)
|
||||
args = [flag, str(proj), output]
|
||||
if no_slaves:
|
||||
args.append("--no-slaves")
|
||||
if no_junctions:
|
||||
args.append("--no-junctions")
|
||||
result = _run_qet(binary, args, timeout, extra_env=extra_env)
|
||||
out = Path(output).expanduser()
|
||||
result["output"] = str(out)
|
||||
result["output_exists"] = out.exists()
|
||||
@@ -4783,13 +4790,24 @@ TOOLS = [
|
||||
"carries, in seconds since 1970 UTC. "
|
||||
"Default: this server's own "
|
||||
"SOURCE_DATE_EPOCH, else 0"},
|
||||
"no_slaves": {"type": "boolean", "default": False,
|
||||
"description": "bom: leave out the contact blocks (slave "
|
||||
"elements), which otherwise get a row of "
|
||||
"their own with their master's label"},
|
||||
"no_junctions": {"type": "boolean", "default": False,
|
||||
"description": "bom: leave out the junctions: "
|
||||
"terminal-type elements with no label, "
|
||||
"designation, manufacturer or "
|
||||
"manufacturer reference"},
|
||||
},
|
||||
"required": ["project", "format", "output"],
|
||||
},
|
||||
"handler": lambda a: tool_export(a["binary"], a["project"], a["format"],
|
||||
a["output"], a.get("timeout", 180),
|
||||
a.get("reproducible", False),
|
||||
a.get("source_date_epoch")),
|
||||
a.get("source_date_epoch"),
|
||||
a.get("no_slaves", False),
|
||||
a.get("no_junctions", False)),
|
||||
},
|
||||
{
|
||||
"name": "qet_edit",
|
||||
|
||||
@@ -4025,6 +4025,36 @@ class ProjectNewValidation(unittest.TestCase):
|
||||
self.assertFalse(Path(new).exists())
|
||||
|
||||
|
||||
class BomExportOptions(unittest.TestCase):
|
||||
"""qet_export's no_slaves and no_junctions become --export-bom flags (#1178)."""
|
||||
|
||||
def run_export(self, format="bom", **kw):
|
||||
seen = []
|
||||
def fake(binary, args, timeout=180, **rest):
|
||||
seen.extend(args)
|
||||
return {"ok": True}
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
proj = Path(tmp) / "a.qet"
|
||||
proj.write_text("<project/>")
|
||||
with unittest.mock.patch.object(m, "_run_qet", fake):
|
||||
m.tool_export("qet", str(proj), format, str(Path(tmp) / "o.csv"), **kw)
|
||||
return seen
|
||||
|
||||
def test_off_by_default(self):
|
||||
args = self.run_export()
|
||||
self.assertNotIn("--no-slaves", args)
|
||||
self.assertNotIn("--no-junctions", args)
|
||||
|
||||
def test_flags_after_the_output(self):
|
||||
args = self.run_export(no_slaves=True, no_junctions=True)
|
||||
self.assertEqual(args[0], "--export-bom")
|
||||
self.assertEqual(args[3:], ["--no-slaves", "--no-junctions"])
|
||||
|
||||
def test_refused_for_other_formats(self):
|
||||
with self.assertRaises(ValueError):
|
||||
self.run_export(format="wiring", no_junctions=True)
|
||||
|
||||
|
||||
class ReproducibleExport(unittest.TestCase):
|
||||
"""qet_export's "reproducible" sets SOURCE_DATE_EPOCH for the run."""
|
||||
|
||||
|
||||
+34
-4
@@ -57,7 +57,32 @@ QStringList BomExport::defaultColumns()
|
||||
};
|
||||
}
|
||||
|
||||
QString BomExport::defaultQuery()
|
||||
/**
|
||||
@brief BomExport::junctionFilter
|
||||
@return a condition true for every row that is not a junction: a
|
||||
terminal-type element with no label and no part data. Some users draw
|
||||
the dots and bends where wires branch as their own terminal-type
|
||||
symbols, and each one became an empty row of the parts list (#1178).
|
||||
A terminal block with a label or a part number is kept.
|
||||
*/
|
||||
QString BomExport::junctionFilter()
|
||||
{
|
||||
return QStringLiteral("NOT (element_type = 'terminal' "
|
||||
"AND IFNULL(label, '') = '' "
|
||||
"AND IFNULL(designation, '') = '' "
|
||||
"AND IFNULL(manufacturer, '') = '' "
|
||||
"AND IFNULL(manufacturer_reference, '') = '')");
|
||||
}
|
||||
|
||||
/**
|
||||
@brief BomExport::defaultQuery
|
||||
@param include_slaves : false leaves out the contact blocks (slave
|
||||
elements), which otherwise appear as rows of their own
|
||||
@param include_junctions : false leaves out the junctions, see
|
||||
junctionFilter()
|
||||
@return the query of the parts list
|
||||
*/
|
||||
QString BomExport::defaultQuery(bool include_slaves, bool include_junctions)
|
||||
{
|
||||
//Slaves and terminals are included because both are routinely
|
||||
//separately orderable hardware. A circuit breaker can carry ten or
|
||||
@@ -77,11 +102,16 @@ QString BomExport::defaultQuery()
|
||||
//and the conductor definition stay out because they are not hardware.
|
||||
//
|
||||
//See discussion #847.
|
||||
const QString types = include_slaves
|
||||
? QStringLiteral("'simple', 'master', 'slave', 'terminal'")
|
||||
: QStringLiteral("'simple', 'master', 'terminal'");
|
||||
const QString junctions = include_junctions
|
||||
? QString()
|
||||
: QStringLiteral(" AND ") + junctionFilter();
|
||||
return QStringLiteral("SELECT %1 FROM element_nomenclature_view "
|
||||
"WHERE element_type IN "
|
||||
"('simple', 'master', 'slave', 'terminal') "
|
||||
"WHERE element_type IN (%2)%3 "
|
||||
"ORDER BY diagram_position, position, label")
|
||||
.arg(defaultColumns().join(QStringLiteral(", ")));
|
||||
.arg(defaultColumns().join(QStringLiteral(", ")), types, junctions);
|
||||
}
|
||||
|
||||
QByteArray BomExport::toCsv(QSqlQuery &query, const QStringList &headers,
|
||||
|
||||
+3
-1
@@ -27,7 +27,9 @@ class QSqlQuery;
|
||||
namespace BomExport
|
||||
{
|
||||
QStringList defaultColumns();
|
||||
QString defaultQuery();
|
||||
QString defaultQuery(bool include_slaves = true,
|
||||
bool include_junctions = true);
|
||||
QString junctionFilter();
|
||||
QByteArray toCsv(QSqlQuery &query, const QStringList &headers,
|
||||
bool include_headers = true, int *row_count = nullptr);
|
||||
bool writeCsv(const QString &file_path, const QByteArray &csv,
|
||||
|
||||
@@ -408,10 +408,12 @@ int exportCsv(QETProject &project, const QString &format, const QString &output)
|
||||
|
||||
/// Bill of materials from the same project database and default query as the
|
||||
/// GUI nomenclature export.
|
||||
int exportBom(QETProject &project, const QString &output)
|
||||
int exportBom(QETProject &project, const QString &output,
|
||||
bool includeSlaves, bool includeJunctions)
|
||||
{
|
||||
project.dataBase()->updateDB();
|
||||
QSqlQuery query = project.dataBase()->newQuery(BomExport::defaultQuery());
|
||||
QSqlQuery query = project.dataBase()->newQuery(
|
||||
BomExport::defaultQuery(includeSlaves, includeJunctions));
|
||||
if (!query.exec()) {
|
||||
err << "BOM query failed: " << query.lastError().text() << "\n";
|
||||
return 1;
|
||||
@@ -980,6 +982,9 @@ int run(const QStringList &args)
|
||||
// collected below.
|
||||
QStringList filtered = args;
|
||||
const bool showTerminals = filtered.removeAll("--show-terminals") > 0;
|
||||
// --no-slaves and --no-junctions leave rows out of --export-bom.
|
||||
const bool includeSlaves = filtered.removeAll("--no-slaves") == 0;
|
||||
const bool includeJunctions = filtered.removeAll("--no-junctions") == 0;
|
||||
|
||||
QString flag;
|
||||
QStringList rest;
|
||||
@@ -1037,7 +1042,7 @@ int run(const QStringList &args)
|
||||
if (format == "cables" || format == "wires")
|
||||
return exportCsv(project, format, output);
|
||||
if (format == "bom")
|
||||
return exportBom(project, output);
|
||||
return exportBom(project, output, includeSlaves, includeJunctions);
|
||||
if (format == "wiring")
|
||||
return exportWiring(project, output);
|
||||
if (format == "nets")
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace CLIExport {
|
||||
qelectrotech --export-dxf <project.qet> <output_dir> [--show-terminals]
|
||||
qelectrotech --export-cables <project.qet> <output.csv>
|
||||
qelectrotech --export-wires <project.qet> <output.csv>
|
||||
qelectrotech --export-bom <project.qet> <output.csv>
|
||||
qelectrotech --export-bom <project.qet> <output.csv> [--no-slaves] [--no-junctions]
|
||||
qelectrotech --export-wiring <project.qet> <output.csv>
|
||||
qelectrotech --export-nets <project.qet> <output.json>
|
||||
qelectrotech --export-links <project.qet> <output.csv>
|
||||
@@ -69,6 +69,11 @@ namespace CLIExport {
|
||||
cables: wiring list (one row per conductor) as CSV.
|
||||
wires: list of distinct wire numbers as CSV.
|
||||
bom: bill of materials (one row per element) as CSV.
|
||||
--no-slaves: leave the contact blocks (slave elements) out of the
|
||||
bill of materials.
|
||||
--no-junctions: leave the junctions out of the bill of materials:
|
||||
terminal-type elements with no label, designation,
|
||||
manufacturer or manufacturer reference.
|
||||
wiring: from-to wiring list (one row per conductor) as CSV, read from
|
||||
the project database. Same logical list as `cables`, which
|
||||
reads the document XML instead; the two are meant to agree,
|
||||
|
||||
@@ -56,6 +56,7 @@ ElementQueryWidget::ElementQueryWidget(QWidget *parent) :
|
||||
m_button_group.addButton(ui->m_protection_cb, 5);
|
||||
m_button_group.addButton(ui->m_thumbnail_cb, 6);
|
||||
m_button_group.addButton(ui->m_plc_cb, 7);
|
||||
m_button_group.addButton(ui->m_slave_cb, 8);
|
||||
connect(&m_button_group, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::idClicked), [this](int id)
|
||||
|
||||
{
|
||||
@@ -78,27 +79,12 @@ ElementQueryWidget::ElementQueryWidget(QWidget *parent) :
|
||||
}
|
||||
else
|
||||
{
|
||||
int checked = 0;
|
||||
for (int i=1 ; i<8 ; ++i) {
|
||||
if (m_button_group.button(i)->isChecked()) {++checked;}
|
||||
}
|
||||
|
||||
switch (checked)
|
||||
{
|
||||
case 0 :
|
||||
check_box->setCheckState(Qt::Unchecked);
|
||||
break;
|
||||
case 7:
|
||||
check_box->setCheckState(Qt::Checked);
|
||||
break;
|
||||
default:
|
||||
check_box->setCheckState(Qt::PartiallyChecked);
|
||||
break;
|
||||
}
|
||||
updateAllCheckState();
|
||||
}
|
||||
|
||||
updateQueryLine();
|
||||
});
|
||||
updateAllCheckState();
|
||||
|
||||
setUpItems();
|
||||
fillSavedQuery();
|
||||
@@ -203,8 +189,12 @@ void ElementQueryWidget::setQuery(const QString &query)
|
||||
if (ui->m_plc_cb->isChecked()) {
|
||||
++c;
|
||||
}
|
||||
ui->m_slave_cb->setChecked (str_type.contains(ElementData::typeToString(ElementData::Slave)));
|
||||
if (ui->m_slave_cb->isChecked()) {
|
||||
++c;
|
||||
}
|
||||
|
||||
if (c == 7) {
|
||||
if (c == 8) {
|
||||
ui->m_all_cb->setCheckState(Qt::Checked);
|
||||
} else if (c > 0) {
|
||||
ui->m_all_cb->setCheckState(Qt::PartiallyChecked);
|
||||
@@ -395,6 +385,11 @@ QString ElementQueryWidget::queryStr() const
|
||||
where += QStringLiteral(" element_sub_type = '") += ElementData::masterTypeToString(ElementData::PLC) += "'";
|
||||
b = true;
|
||||
}
|
||||
if (ui->m_slave_cb->isChecked()) {
|
||||
if (b) where +=" OR";
|
||||
where += QStringLiteral(" element_type = '") += ElementData::typeToString(ElementData::Slave) += "'";
|
||||
b = true;
|
||||
}
|
||||
where.append(")");
|
||||
|
||||
if (where == " WHERE ()") {
|
||||
@@ -406,6 +401,10 @@ QString ElementQueryWidget::queryStr() const
|
||||
// widget's query reads FROM that view, so a flagged element never
|
||||
// reaches this point in the first place.
|
||||
|
||||
if (!m_extra_filter.isEmpty()) {
|
||||
filter_ += QStringLiteral(" AND ") + m_extra_filter;
|
||||
}
|
||||
|
||||
if (where.isEmpty() && !filter_.isEmpty()) {
|
||||
filter_.remove(0, 4); //Remove the first " AND" of filter.
|
||||
filter_.prepend( " WHERE");
|
||||
@@ -456,6 +455,64 @@ void ElementQueryWidget::setCount(QString text, bool set)
|
||||
updateQueryLine();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementQueryWidget::setSlavesIncluded
|
||||
Check or uncheck the contact blocks (slave elements) in the element
|
||||
type filter. The box is unchecked by default, which keeps the tables
|
||||
made before it existed as they were.
|
||||
@param included
|
||||
*/
|
||||
void ElementQueryWidget::setSlavesIncluded(bool included)
|
||||
{
|
||||
ui->m_slave_cb->setChecked(included);
|
||||
updateAllCheckState();
|
||||
updateQueryLine();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementQueryWidget::updateAllCheckState
|
||||
Set the "all" check box from the element type check boxes.
|
||||
*/
|
||||
void ElementQueryWidget::updateAllCheckState()
|
||||
{
|
||||
int checked = 0;
|
||||
for (int i=1 ; i<9 ; ++i) {
|
||||
if (m_button_group.button(i)->isChecked()) {++checked;}
|
||||
}
|
||||
|
||||
switch (checked)
|
||||
{
|
||||
case 0 :
|
||||
ui->m_all_cb->setCheckState(Qt::Unchecked);
|
||||
break;
|
||||
case 8:
|
||||
ui->m_all_cb->setCheckState(Qt::Checked);
|
||||
break;
|
||||
default:
|
||||
ui->m_all_cb->setCheckState(Qt::PartiallyChecked);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementQueryWidget::setExtraFilter
|
||||
Add a condition every row of the query must meet, on top of the filters
|
||||
chosen in this widget.
|
||||
@param text : the condition, ex : "label != ''"
|
||||
@param set :
|
||||
true by default -> the condition is used.
|
||||
false -> the condition is removed.
|
||||
*/
|
||||
void ElementQueryWidget::setExtraFilter(const QString &text, bool set)
|
||||
{
|
||||
if (set) {
|
||||
m_extra_filter = text;
|
||||
} else {
|
||||
m_extra_filter.clear();
|
||||
}
|
||||
updateQueryLine();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementQueryWidget::updateQueryLine
|
||||
*/
|
||||
|
||||
@@ -45,6 +45,8 @@ class ElementQueryWidget : public QWidget
|
||||
QString queryStr() const;
|
||||
void setGroupBy(QString text, bool set = true);
|
||||
void setCount(QString text, bool set = true);
|
||||
void setSlavesIncluded(bool included);
|
||||
void setExtraFilter(const QString &text, bool set = true);
|
||||
|
||||
static QString modelIdentifier() {return "nomenclature";}
|
||||
|
||||
@@ -67,6 +69,7 @@ class ElementQueryWidget : public QWidget
|
||||
void on_m_choosen_list_itemDoubleClicked(QListWidgetItem *item);
|
||||
|
||||
void updateQueryLine();
|
||||
void updateAllCheckState();
|
||||
QStringList selectedKeys() const;
|
||||
void setUpItems();
|
||||
QPair<int, QString> FilterFor(const QString &key) const;
|
||||
@@ -82,7 +85,8 @@ class ElementQueryWidget : public QWidget
|
||||
QList <QListWidgetItem *> m_items_list;
|
||||
QString m_custom_query,
|
||||
m_group_by,
|
||||
m_count;
|
||||
m_count,
|
||||
m_extra_filter;
|
||||
QHash <QString, QPair<int, QString>> m_filter;
|
||||
};
|
||||
|
||||
|
||||
@@ -318,6 +318,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="m_slave_cb">
|
||||
<property name="text">
|
||||
<string>Contacts esclaves</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -323,9 +323,13 @@ bool QetScriptApi::exportWires(const QString &output)
|
||||
return runFlag(QStringLiteral("--export-wires"), {output});
|
||||
}
|
||||
|
||||
bool QetScriptApi::exportBom(const QString &output)
|
||||
bool QetScriptApi::exportBom(const QString &output, bool noSlaves,
|
||||
bool noJunctions)
|
||||
{
|
||||
return runFlag(QStringLiteral("--export-bom"), {output});
|
||||
QStringList args{output};
|
||||
if (noSlaves) args << QStringLiteral("--no-slaves");
|
||||
if (noJunctions) args << QStringLiteral("--no-junctions");
|
||||
return runFlag(QStringLiteral("--export-bom"), args);
|
||||
}
|
||||
|
||||
bool QetScriptApi::exportWiring(const QString &output)
|
||||
|
||||
@@ -384,7 +384,8 @@ class QetScriptApi : public QObject
|
||||
Q_INVOKABLE bool exportDxf(const QString &outDir, bool showTerminals = false);
|
||||
Q_INVOKABLE bool exportCables(const QString &output);
|
||||
Q_INVOKABLE bool exportWires(const QString &output);
|
||||
Q_INVOKABLE bool exportBom(const QString &output);
|
||||
Q_INVOKABLE bool exportBom(const QString &output, bool noSlaves = false,
|
||||
bool noJunctions = false);
|
||||
Q_INVOKABLE bool exportWiring(const QString &output);
|
||||
Q_INVOKABLE bool exportNets(const QString &output);
|
||||
Q_INVOKABLE bool exportLinks(const QString &output);
|
||||
|
||||
@@ -46,6 +46,9 @@ BOMExportDialog::BOMExportDialog(QETProject *project, QWidget *parent) :
|
||||
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);
|
||||
@@ -145,6 +148,15 @@ void BOMExportDialog::on_m_format_as_bom_clicked(bool 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
|
||||
|
||||
@@ -45,6 +45,7 @@ class BOMExportDialog : public QDialog
|
||||
|
||||
private slots:
|
||||
void on_m_format_as_bom_clicked(bool checked);
|
||||
void on_m_no_junctions_clicked(bool checked);
|
||||
void on_m_preview_pb_clicked();
|
||||
|
||||
private:
|
||||
|
||||
@@ -40,6 +40,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_no_junctions">
|
||||
<property name="toolTip">
|
||||
<string>Bornes sans repère, désignation, fabricant ni référence fabricant</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Laisser de côté les jonctions</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -120,6 +120,34 @@ void SmartDeviceTest::defaultQueryAndCsv()
|
||||
QVERIFY(csv.contains("Terminal block"));
|
||||
QVERIFY(!csv.contains("Must not be exported"));
|
||||
QVERIFY(csv.indexOf("-K1") < csv.indexOf("-K2"));
|
||||
|
||||
//#1178: a junction -- a terminal-type symbol drawn where wires
|
||||
//branch -- has no label and no part data. It can be left out, and
|
||||
//so can the contact blocks; a terminal block with only a part
|
||||
//number stays.
|
||||
QSqlQuery raw(db);
|
||||
QVERIFY(raw.exec(QStringLiteral(
|
||||
"INSERT INTO element_nomenclature_view "
|
||||
"(label, element_type, diagram_position, position) "
|
||||
"VALUES (NULL, 'terminal', 1, 6)")));
|
||||
QVERIFY(raw.exec(QStringLiteral(
|
||||
"INSERT INTO element_nomenclature_view "
|
||||
"(label, designation, manufacturer, manufacturer_reference, "
|
||||
"element_type, diagram_position, position) "
|
||||
"VALUES ('', '', '', 'PT 2,5', 'terminal', 1, 7)")));
|
||||
auto count = [&db](const QString &sql) {
|
||||
QSqlQuery q(db);
|
||||
if (!q.exec(sql))
|
||||
return -1;
|
||||
int n = 0;
|
||||
while (q.next())
|
||||
++n;
|
||||
return n;
|
||||
};
|
||||
QCOMPARE(count(BomExport::defaultQuery()), 6);
|
||||
QCOMPARE(count(BomExport::defaultQuery(true, false)), 5);
|
||||
QCOMPARE(count(BomExport::defaultQuery(false, true)), 5);
|
||||
QCOMPARE(count(BomExport::defaultQuery(false, false)), 4);
|
||||
}
|
||||
QSqlDatabase::removeDatabase(connection);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user