mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-06 11:14:14 +02:00
Add a wires-per-terminal limit, with an application master switch
Discussion #1158: a real terminal takes one or two wires (four with double ferrules), a folio report is a virtual point that carries one, but QElectroTech lets any number of wires be connected anywhere. Project properties > General gets a "Conducteurs par borne" group: - the most wires a terminal may take (0, the default, is no limit); - "one wire per folio report". When set, a new wire that would go past the limit is refused: the terminal shows red while dragging, as for any refused link, and a tooltip says why on release. Auto-connect on placing, moving or multi-pasting a symbol skips full terminals, and qet.addConductor() refuses with its own message. Wires already drawn, opening, pasting and undo are never refused. Settings > General gets a master switch, on by default, that turns every rule of this feature off in every project; the project group is greyed with a note while it is off. The rules live in wiringrules.cpp. The project setting is saved as <wiring_rules .../> only when a rule is on, so a project that never used it saves exactly as before; an older version drops it, which means "off". tst_wiringrules covers the rules, the save round trip and, through the real binary, that a wire past the limit is refused unless the master switch is off (checked to fail with the limit check removed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015FPuYPS4T7QuEwjNu22rXD
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include "wiringrules.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QSettings>
|
||||
|
||||
namespace {
|
||||
const QString element_name = QStringLiteral("wiring_rules");
|
||||
const QString max_wires_attribute = QStringLiteral("max_wires_per_terminal");
|
||||
const QString report_attribute = QStringLiteral("one_wire_per_report");
|
||||
|
||||
//The master switch is read on every wire drawn, so it is read from
|
||||
//the settings once and kept; setMasterEnabled() keeps both in step.
|
||||
int master_cache = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::masterEnabled
|
||||
@return false when the user turned every rule of this feature off for
|
||||
every project (Settings > General). On by default: a project still has
|
||||
to turn a rule on before anything changes.
|
||||
*/
|
||||
bool WiringRules::masterEnabled()
|
||||
{
|
||||
if (master_cache < 0) {
|
||||
master_cache = QSettings().value(settings_key, true).toBool() ? 1 : 0;
|
||||
}
|
||||
return master_cache == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::setMasterEnabled
|
||||
Save the master switch.
|
||||
@param enabled
|
||||
*/
|
||||
void WiringRules::setMasterEnabled(bool enabled)
|
||||
{
|
||||
QSettings().setValue(settings_key, enabled);
|
||||
master_cache = enabled ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::fromXml
|
||||
@param project_root : the root element of a project
|
||||
@return the rules stored in the <wiring_rules> child of \a project_root,
|
||||
the default (no rule) when there is none.
|
||||
*/
|
||||
WiringRules::Settings WiringRules::fromXml(const QDomElement &project_root)
|
||||
{
|
||||
Settings settings;
|
||||
const QDomElement rules = project_root.firstChildElement(element_name);
|
||||
if (rules.isNull()) {
|
||||
return settings;
|
||||
}
|
||||
settings.max_wires = qMax(0, rules.attribute(max_wires_attribute, QStringLiteral("0")).toInt());
|
||||
settings.one_wire_per_report = rules.attribute(report_attribute) == QLatin1String("true");
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::toXml
|
||||
Write \a settings as a <wiring_rules> child of \a project_root. Nothing
|
||||
is written when no rule is on, so a project that never used them saves
|
||||
exactly as before.
|
||||
*/
|
||||
void WiringRules::toXml(const Settings &settings, QDomElement &project_root)
|
||||
{
|
||||
if (settings.isDefault()) {
|
||||
return;
|
||||
}
|
||||
QDomElement rules = project_root.ownerDocument().createElement(element_name);
|
||||
if (settings.max_wires > 0) {
|
||||
rules.setAttribute(max_wires_attribute, settings.max_wires);
|
||||
}
|
||||
if (settings.one_wire_per_report) {
|
||||
rules.setAttribute(report_attribute, QStringLiteral("true"));
|
||||
}
|
||||
project_root.appendChild(rules);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::limit
|
||||
@param settings : the project's rules
|
||||
@param master_enabled : the master switch, masterEnabled()
|
||||
@param is_report : the terminal belongs to a folio report
|
||||
@return the most wires the terminal may take, 0 for no limit.
|
||||
*/
|
||||
int WiringRules::limit(const Settings &settings, bool master_enabled, bool is_report)
|
||||
{
|
||||
if (!master_enabled) {
|
||||
return 0;
|
||||
}
|
||||
if (is_report && settings.one_wire_per_report) {
|
||||
return 1;
|
||||
}
|
||||
return settings.max_wires;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::hasRoom
|
||||
@param limit : WiringRules::limit()
|
||||
@param wires : the wires the terminal already has
|
||||
@return true if one more wire may be connected
|
||||
*/
|
||||
bool WiringRules::hasRoom(int limit, int wires)
|
||||
{
|
||||
return limit <= 0 || wires < limit;
|
||||
}
|
||||
Reference in New Issue
Block a user