Wire terminals one after another under a wires-per-terminal limit

Discussion #1158, stacked on the limit itself. Two of QElectroTech's own
tools wire several terminals as a star, every terminal to one of them:
"create wires in a drawn polygon" (also qet.addConductor()), and deleting
a symbol, which rewires the far ends to keep the potential. Six terminals
give the hub five wires, which the project's limit forbids.

When the project sets a limit (and the master switch is on), both now
wire the terminals one after another instead, from the top left one to
the nearest not yet wired (WiringRules::chainOrder()). The polygon tool
also skips a wire whose terminal is already full. Without a limit, both
build the star as before.

tst_wiringrules: the chain order, and through the real binary that
deleting a symbol wired to four others leaves them with at most two
wires each under a limit, three on one of them without (checked to fail
with chaining turned off).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FPuYPS4T7QuEwjNu22rXD
This commit is contained in:
ispyisail
2026-10-03 21:49:06 +13:00
parent ee8e7c3450
commit 5d27ed8156
6 changed files with 234 additions and 12 deletions
@@ -16,8 +16,10 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "deleteqgraphicsitemcommand.h"
#include "../wiringrules.h"
#include "../diagram.h"
#include "../qetproject.h"
#include "addgraphicsobjectcommand.h"
#include "../qetdiagrameditor.h"
#include "../qetgraphicsitem/ViewItem/qetgraphicstableitem.h"
@@ -206,17 +208,44 @@ void DeleteQGraphicsItemCommand::setPotentialsOfRemovedElements()
}
ConductorProperties properties = hub_terminal->conductors().first()->properties();
for (Terminal *t : terminals_to_connect_list)
//Every terminal to the hub (a star), or, when the project
//limits the wires per terminal (discussion #1158), one after
//another (a chain): a star gives the hub a wire per other
//terminal, which the limit forbids.
QList<std::pair<Terminal *, Terminal *>> pairs;
const QETProject *project = hub_terminal->diagram() ? hub_terminal->diagram()->project() : nullptr;
if (project && WiringRules::chainsWires(project->wiringRules(), WiringRules::masterEnabled()))
{
QList<Terminal *> chain {hub_terminal};
chain << terminals_to_connect_list;
QList<QPointF> points;
for (Terminal *ct : std::as_const(chain)) {
points << ct->scenePos();
}
const QList<int> order = WiringRules::chainOrder(points);
for (int i = 1 ; i < order.size() ; ++i) {
pairs.append(std::make_pair(chain.at(order.at(i - 1)), chain.at(order.at(i))));
}
}
else
{
for (Terminal *t : std::as_const(terminals_to_connect_list)) {
pairs.append(std::make_pair(hub_terminal, t));
}
}
for (const auto &new_pair : std::as_const(pairs))
{
//If a conductor was already created between these two terminals
//in this undo command, from another removed element, we do nothing
bool exist_ = false;
for (std::pair<Terminal *, Terminal *> pair : m_connected_terminals)
{
if (pair.first == hub_terminal && pair.second == t) {
if (pair.first == new_pair.first && pair.second == new_pair.second) {
exist_ = true;
continue;
} else if (pair.first == t && pair.second == hub_terminal) {
} else if (pair.first == new_pair.second && pair.second == new_pair.first) {
exist_ = true;
continue;
}
@@ -224,11 +253,11 @@ void DeleteQGraphicsItemCommand::setPotentialsOfRemovedElements()
if (exist_ == false)
{
m_connected_terminals.append(std::make_pair<Terminal *, Terminal *>((Terminal *)hub_terminal, (Terminal *)t));
m_connected_terminals.append(new_pair);
qInfo() << "m_connected_terminals" << m_connected_terminals;
Conductor *new_cond = new Conductor(hub_terminal, t);
Conductor *new_cond = new Conductor(new_pair.first, new_pair.second);
new_cond->setProperties(properties);
new AddGraphicsObjectCommand(new_cond, t->diagram(), QPointF(), this);
new AddGraphicsObjectCommand(new_cond, new_pair.second->diagram(), QPointF(), this);
}
}
}