mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-11 22:54:12 +02:00
Add cable management: drawing, cores, numbering, cross-references and cable list
Cables are drawn line objects (toolbar button next to the auto break/reconnect button, click-move-click, right click cancels), not components. The type comes from a CSV catalog following the material list pattern (designation, cores, core colours, editable through the entry dialog with "Nouvelle entrée" / "Modifier l'entrée"). Each core is bound to the wire its colour label stands on, and the cable reference is generated per core and written into the Conductor entry via Conductor::setCableReference(label, cable uuid, slot). The conductor entry is where it has to live because the terminal strip plan (Klemmenplan) consumes it in the next step. Numbering: "Cables" rule under Programmeinstellungen/Neues Projekt/Nummerierung auto (mirrored in project properties), literal "W" fallback without a rule, French gate dialog when no rule exists, Nummerierung menu with the renumber dialog (preferred axis, per-folio counter, rule and counter state written back, hand-typed names ask, whole-project scope). Also included: label block and under-line texts with per-text font and alignment plus the material-list cell margins, free-core placement and right-click removal, claim questions for wires of other cables, multi-selection drag as one undo step, type change with confirmation, cross-references for type "Cable" (%f-%l%c, own font, clickable links in exported PDFs), report propagation of the cable definition, Listes menu (table of contents, material list, terminal strip manager, terminal generator plugin, cable list), cable list with freely selectable columns (installation/localisation of cable, start and end, Blatt start/end, length, used cores...), CSV export dialog with column pick and preview in the Projekt menu, script API (addTable kind "cable_list", exportCableList) and a unit test for the type catalog.
This commit is contained in:
@@ -17,6 +17,10 @@
|
||||
*/
|
||||
#include "diagrameventaddpaste.h"
|
||||
|
||||
#include "../cable/addcablecommand.h"
|
||||
#include "../cable/cablecopy.h"
|
||||
#include "../cable/cablepart.h"
|
||||
#include "../cable/editcablecommand.h"
|
||||
#include "../diagram.h"
|
||||
#include "../diagramcommands.h"
|
||||
#include "../qetapp.h"
|
||||
@@ -28,10 +32,34 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QCoreApplication>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QStatusBar>
|
||||
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
@brief batchWith
|
||||
Keep the cable lines of a paste together with the rest of it, so one
|
||||
Ctrl+Z takes the whole thing back in one go. Mirrors the helper
|
||||
DiagramView uses for its one-step paste; BatchCommand's own name
|
||||
says "Supprimer", so the name of what the user actually did is put
|
||||
back onto the batch.
|
||||
@param first the step already assembled, may be null
|
||||
@param second the step to add; ownership goes to the result
|
||||
@return both steps as one command, or the only one of them
|
||||
*/
|
||||
static QUndoCommand *batchWith(QUndoCommand *first, QUndoCommand *second)
|
||||
{
|
||||
if (!first) return second;
|
||||
if (!second) return first;
|
||||
|
||||
auto *batched = new BatchCommand(first, second);
|
||||
if (!first->text().isEmpty()) batched->setText(first->text());
|
||||
return batched;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramEventAddPaste::DiagramEventAddPaste
|
||||
@param diagram : diagram to paste into
|
||||
@@ -63,17 +91,27 @@
|
||||
db->setUpdateBlocked(true);
|
||||
}
|
||||
|
||||
//Load items at their original XML coordinates.
|
||||
m_diagram->fromXml(document_xml, QPointF(), false, &m_content);
|
||||
//Load items at their original XML coordinates. A cable line
|
||||
//comes back through its own list rather than through the
|
||||
//content: the cable owns it, so it is not one of the folio's
|
||||
//items -- and it travels as a whole, colour labels and all,
|
||||
//whether or not the place it is going to holds a wire.
|
||||
m_diagram->fromXml(document_xml, QPointF(), false, &m_content, &m_cables);
|
||||
|
||||
if (db) {
|
||||
db->blockSignals(false);
|
||||
db->setUpdateBlocked(false);
|
||||
db->updateDB();
|
||||
}
|
||||
if (!m_content.count()) return;
|
||||
if (!m_content.count() && m_cables.isEmpty()) return;
|
||||
|
||||
const QList<QGraphicsItem *> movable = m_content.items(MovableItems);
|
||||
QList<QGraphicsItem *> movable = m_content.items(MovableItems);
|
||||
for (CablePart *part : std::as_const(m_cables)) {
|
||||
if (part) {
|
||||
movable << part;
|
||||
m_cable_items.insert(part);
|
||||
}
|
||||
}
|
||||
if (movable.isEmpty()) return;
|
||||
|
||||
//Compute the top-left of all items' actual on-screen bounding
|
||||
@@ -260,11 +298,24 @@ void DiagramEventAddPaste::moveTo(const QPointF &scene_pos)
|
||||
|
||||
const QPointF delta = snapGrid(scene_pos) - m_initial_cursor;
|
||||
|
||||
//A cable line is handed a step rather than a place to stand: it
|
||||
//folds a translation into its own geometry and into the colour
|
||||
//labels it carries and keeps its own pos() at (0, 0)
|
||||
//(CablePart::itemChange), so the position stored above -- always
|
||||
//(0, 0) for it -- would be an addition again on every mouse move
|
||||
//and the line would run away from the group it was pasted with.
|
||||
//The difference to the last step keeps the translation the same
|
||||
//one the rest of the paste gets, expressed their way: a place.
|
||||
const QPointF cable_step = delta - m_cable_delta;
|
||||
for (auto it = m_relative_pos.constBegin() ; it != m_relative_pos.constEnd() ; ++it) {
|
||||
if (it.key()) {
|
||||
if (!it.key()) continue;
|
||||
if (m_cable_items.contains(it.key())) {
|
||||
it.key()->setPos(cable_step);
|
||||
} else {
|
||||
it.key()->setPos(it.value() + delta);
|
||||
}
|
||||
}
|
||||
m_cable_delta = delta;
|
||||
|
||||
//Update conductor paths so they follow the moved terminals.
|
||||
const QList<Conductor *> conductors = m_content.conductors(DiagramContent::AnyConductor);
|
||||
@@ -328,6 +379,11 @@ void DiagramEventAddPaste::keyPressEvent(QKeyEvent *event)
|
||||
PasteDiagramCommand's first redo() does not add the items to the scene --
|
||||
it assumes they are already there, which is what Diagram::fromXml did when
|
||||
this started. So pushing it here adopts them rather than duplicating them.
|
||||
|
||||
The cable lines are wired just before that, which is the first moment
|
||||
the place they will occupy is final: each colour label takes the wire
|
||||
it happens to stand on, and a line the user refuses to let take wires
|
||||
away from another cable goes away again on its own.
|
||||
*/
|
||||
void DiagramEventAddPaste::commit()
|
||||
{
|
||||
@@ -335,7 +391,32 @@ void DiagramEventAddPaste::commit()
|
||||
m_finished = true;
|
||||
m_running = false;
|
||||
|
||||
m_diagram->undoStack().push(new PasteDiagramCommand(m_diagram, m_content));
|
||||
const QList<CableCopy::Wired> wired = CableCopy::wire(
|
||||
m_diagram, m_cables,
|
||||
m_content.conductors(DiagramContent::AnyConductor));
|
||||
m_cables.clear();
|
||||
|
||||
QUndoCommand *command = nullptr;
|
||||
if (m_content.count()) {
|
||||
command = new PasteDiagramCommand(m_diagram, m_content);
|
||||
}
|
||||
for (const CableCopy::Wired &line : std::as_const(wired))
|
||||
{
|
||||
if (!line.part) continue;
|
||||
|
||||
auto *added = new AddCableCommand(line.part->cable(), line.part.data(),
|
||||
m_diagram, true, line.taken);
|
||||
added->setText(QCoreApplication::translate("CableCopy", "Coller un câble"));
|
||||
command = batchWith(command, added);
|
||||
}
|
||||
if (command) {
|
||||
m_diagram->undoStack().push(command);
|
||||
}
|
||||
|
||||
//The undo stack has just run its first redo, which may have
|
||||
//renewed the identity of a pasted conductor: the cores are
|
||||
//pointed at the wires again so their cable field survives it.
|
||||
CableCopy::repoint(wired);
|
||||
emit finish();
|
||||
}
|
||||
|
||||
@@ -367,6 +448,15 @@ void DiagramEventAddPaste::removeItems()
|
||||
delete item;
|
||||
}
|
||||
|
||||
//The cable lines never reached the undo stack either, so they
|
||||
//are taken back the way they were built: off the folio, out of
|
||||
//the project and deleted, leaving no trace of having been
|
||||
//there -- not even a project asking to be saved for nothing.
|
||||
for (CablePart *part : std::as_const(m_cables)) {
|
||||
CableCopy::discard(m_diagram, part);
|
||||
}
|
||||
m_cables.clear();
|
||||
|
||||
m_content.clear();
|
||||
m_relative_pos.clear();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user