Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
8a92ff80bThis file is pinned to the selected release. Download the original to open it in your design tool.
/*
* LibrePCB - Professional EDA for everyone!
* Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
* https://librepcb.org/
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "electricalrulecheckmessages.h"
#include "../../library/cmp/componentsignal.h"
#include "../../library/cmp/componentsymbolvariantitem.h"
#include "../../library/sym/symbolpin.h"
#include "../circuit/bus.h"
#include "../circuit/componentinstance.h"
#include "../circuit/componentsignalinstance.h"
#include "../circuit/netclass.h"
#include "../circuit/netsignal.h"
#include "../schematic/items/si_busjunction.h"
#include "../schematic/items/si_bussegment.h"
#include "../schematic/items/si_netpoint.h"
#include "../schematic/items/si_netsegment.h"
#include "../schematic/items/si_symbol.h"
#include "../schematic/items/si_symbolpin.h"
#include "../schematic/schematic.h"
/*******************************************************************************
* Namespace
******************************************************************************/
namespace librepcb {
/*******************************************************************************
* ErcMsgBase
******************************************************************************/
bool ErcMsgBase::setLocation(const NetSignal& net) noexcept {
for (const SI_NetSegment* seg : net.getSchematicNetSegments()) {
if (setLocation(*seg)) {
return true;
}
}
for (const ComponentSignalInstance* cmpSig : net.getComponentSignals()) {
if (setLocation(*cmpSig)) {
return true;
}
}
return false;
}
bool ErcMsgBase::setLocation(const ComponentInstance& component) noexcept {
for (const SI_Symbol* sym : component.getSymbols()) {
setLocation(*sym);
return true;
}
return false;
}
bool ErcMsgBase::setLocation(const ComponentSignalInstance& signal) noexcept {
for (const SI_SymbolPin* pin : signal.getRegisteredSymbolPins()) {
setLocation(*pin);
return true;
}
return setLocation(signal.getComponentInstance());
}
void ErcMsgBase::setLocation(const SI_Symbol& symbol) noexcept {
mSchematic = symbol.getSchematic().getUuid();
mLocations.append(
Path::circle(PositiveLength(2000000)).translated(symbol.getPosition()));
}
void ErcMsgBase::setLocation(const SI_SymbolPin& pin) noexcept {
mLocations.append(
Path::circle(PositiveLength(1100000)).translated(pin.getPosition()));
mSchematic = pin.getSchematic().getUuid();
}
bool ErcMsgBase::setLocation(const SI_NetSegment& segment) noexcept {
for (const SI_NetLine* nl : segment.getNetLines()) {
mLocations.append(Path::obround(nl->getP1().getPosition(),
nl->getP2().getPosition(),
PositiveLength(nl->getWidth() + 1)));
}
if (!segment.getNetLines().isEmpty()) {
mSchematic = segment.getSchematic().getUuid();
return true;
}
return false;
}
void ErcMsgBase::setLocation(const SI_NetPoint& netPoint) noexcept {
mSchematic = netPoint.getSchematic().getUuid();
mLocations.append(
Path::circle(PositiveLength(1100000)).translated(netPoint.getPosition()));
}
void ErcMsgBase::setLocation(const SI_NetLine& netLine) noexcept {
mSchematic = netLine.getSchematic().getUuid();
mLocations.append(Path::obround(netLine.getP1().getPosition(),
netLine.getP2().getPosition(),
PositiveLength(netLine.getWidth() + 1)));
}
void ErcMsgBase::setLocation(const SI_BusJunction& junction) noexcept {
mSchematic = junction.getSchematic().getUuid();
mLocations.append(
Path::circle(PositiveLength(2000000)).translated(junction.getPosition()));
}
/*******************************************************************************
* ErcMsgUnusedNetClass
******************************************************************************/
ErcMsgUnusedNetClass::ErcMsgUnusedNetClass(const NetClass& netClass) noexcept
: ErcMsgBase(Severity::Hint,
tr("Unused net class: '%1'").arg(*netClass.getName()),
tr("There are no nets assigned to the net class, so you "
"could remove it."),
"unused_netclass") {
mApproval->appendChild("netclass", netClass.getUuid());
}
/*******************************************************************************
* ErcMsgUnusedBus
******************************************************************************/
ErcMsgUnusedBus::ErcMsgUnusedBus(const Bus& bus) noexcept
: ErcMsgBase(Severity::Hint, tr("Unused bus: '%1'").arg(*bus.getName()),
"There's a bus in the circuit without any schematics using it. "
"This should not happen, please report it as a bug. But "
"no worries, this issue is not harmful at all so you can safely "
"ignore this message.",
"unused_bus") {
mApproval->appendChild("bus", bus.getUuid());
}
/*******************************************************************************
* ErcMsgOpenNet
******************************************************************************/
ErcMsgOpenNet::ErcMsgOpenNet(const NetSignal& net) noexcept
: ErcMsgBase(Severity::Warning,
tr("Less than two pins in net: '%1'").arg(*net.getName()),
tr("The net is connected to less than two pins, so it "
"does not represent an electrical connection. Check if "
"you missed to connect more pins."),
"open_net") {
mApproval->appendChild("net", net.getUuid());
setLocation(net);
}
/*******************************************************************************
* ErcMsgOpenNetInBus
******************************************************************************/
ErcMsgOpenNetInBus::ErcMsgOpenNetInBus(const Bus& bus,
const SI_NetSegment& netSegment) noexcept
: ErcMsgBase(Severity::Hint, // Not sure if a warning would be justified...
tr("Bus contains unused net: '%1:%2'")
.arg(*bus.getName(), *netSegment.getNetSignal().getName()),
tr("The net is connected to the bus, but is not leaving the bus "
"^anywhere. Check if you missed to make a connection."),
"open_net_in_bus") {
mApproval->ensureLineBreak();
mApproval->appendChild("bus", bus.getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("net", netSegment.getNetSignal().getUuid());
mApproval->ensureLineBreak();
setLocation(netSegment);
}
/*******************************************************************************
* ErcMsgUnnamedNetInBus
******************************************************************************/
ErcMsgUnnamedNetInBus::ErcMsgUnnamedNetInBus(
const Bus& bus, const SI_NetSegment& netSegment) noexcept
: ErcMsgBase(
Severity::Warning,
tr("Bus contains unnamed net: '%1:%2'")
.arg(*bus.getName(), *netSegment.getNetSignal().getName()),
tr("A wire without a net label is connected to the bus, which makes it "
"impossible for this net to leave the bus somewhere else. Add a net "
"label to the wire to explicitly specify the net."),
"unnamed_net_in_bus") {
mApproval->ensureLineBreak();
mApproval->appendChild("bus", bus.getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("net", netSegment.getNetSignal().getUuid());
mApproval->ensureLineBreak();
setLocation(netSegment);
}
/*******************************************************************************
* ErcMsgOpenWireInSegment
******************************************************************************/
ErcMsgOpenWireInSegment::ErcMsgOpenWireInSegment(
const SI_NetSegment& segment, const SI_NetLine& openWire) noexcept
: ErcMsgBase(
Severity::Warning,
tr("Open wire in net: '%1'").arg(*segment.getNetSignal().getName()),
tr("The wire has an open (unconnected) end with no net "
"label attached, thus is looks like a mistake. Check "
"if a connection to another wire or pin is missing (denoted by a "
"cross mark)."),
"open_wire") {
mApproval->appendChild("segment", segment.getUuid());
setLocation(openWire);
}
/*******************************************************************************
* ErcMsgUnconnectedRequiredSignal
******************************************************************************/
ErcMsgUnconnectedRequiredSignal::ErcMsgUnconnectedRequiredSignal(
const ComponentSignalInstance& signal) noexcept
: ErcMsgBase(Severity::Error,
tr("Unconnected component signal: '%1:%2'")
.arg(*signal.getComponentInstance().getName(),
*signal.getCompSignal().getName()),
tr("The component signal is marked as required, but is "
"not connected to any net. Add a wire to the "
"corresponding symbol pin to connect it to a net."),
"unconnected_required_signal") {
mApproval->ensureLineBreak();
mApproval->appendChild("component", signal.getComponentInstance().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("signal", signal.getCompSignal().getUuid());
mApproval->ensureLineBreak();
setLocation(signal);
}
/*******************************************************************************
* ErcMsgForcedNetSignalNameConflict
******************************************************************************/
ErcMsgForcedNetSignalNameConflict::ErcMsgForcedNetSignalNameConflict(
const ComponentSignalInstance& signal) noexcept
: ErcMsgBase(
Severity::Error,
tr("Net name conflict: '%1' != '%2' ('%3:%4')")
.arg(getSignalNet(signal), signal.getForcedNetSignalName(),
*signal.getComponentInstance().getName(),
*signal.getCompSignal().getName()),
tr("The component signal requires the attached net to be named '%1', "
"but it is named '%2'. Either rename the net manually or remove "
"this connection.")
.arg(signal.getForcedNetSignalName(), getSignalNet(signal)),
"forced_net_name_conflict") {
mApproval->ensureLineBreak();
mApproval->appendChild("component", signal.getComponentInstance().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("signal", signal.getCompSignal().getUuid());
mApproval->ensureLineBreak();
setLocation(signal);
}
QString ErcMsgForcedNetSignalNameConflict::getSignalNet(
const ComponentSignalInstance& signal) noexcept {
return (signal.getNetSignal() ? (*signal.getNetSignal()->getName())
: QString());
}
/*******************************************************************************
* ErcMsgUnplacedRequiredGate
******************************************************************************/
ErcMsgUnplacedRequiredGate::ErcMsgUnplacedRequiredGate(
const ComponentInstance& component,
const ComponentSymbolVariantItem& gate) noexcept
: ErcMsgBase(Severity::Error,
tr("Unplaced required gate: '%1:%2'")
.arg(*component.getName(), *gate.getSuffix()),
tr("The gate '%1' of '%2' is marked as required, but it "
"is not added to the schematic.")
.arg(*gate.getSuffix(), *component.getName()),
"unplaced_required_gate") {
mApproval->ensureLineBreak();
mApproval->appendChild("component", component.getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("gate", gate.getUuid());
mApproval->ensureLineBreak();
setLocation(component);
}
/*******************************************************************************
* ErcMsgUnplacedOptionalGate
******************************************************************************/
ErcMsgUnplacedOptionalGate::ErcMsgUnplacedOptionalGate(
const ComponentInstance& component,
const ComponentSymbolVariantItem& gate) noexcept
: ErcMsgBase(
Severity::Warning,
tr("Unplaced gate: '%1:%2'")
.arg(*component.getName(), *gate.getSuffix()),
tr("The optional gate '%1' of '%2' is not added to the schematic.")
.arg(*gate.getSuffix(), *component.getName()),
"unplaced_optional_gate") {
mApproval->ensureLineBreak();
mApproval->appendChild("component", component.getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("gate", gate.getUuid());
mApproval->ensureLineBreak();
setLocation(component);
}
/*******************************************************************************
* ErcMsgConnectedPinWithoutWire
******************************************************************************/
ErcMsgConnectedPinWithoutWire::ErcMsgConnectedPinWithoutWire(
const SI_SymbolPin& pin) noexcept
: ErcMsgBase(
Severity::Warning,
tr("Connected pin without wire: '%1:%2'")
.arg(pin.getSymbol().getName(), pin.getName()),
tr("The pin is electrically connected to a net, but has no wire "
"attached so this connection is not visible in the schematic. Add a "
"wire to make the connection visible."),
"connected_pin_without_wire") {
mApproval->ensureLineBreak();
mApproval->appendChild("schematic", pin.getSchematic().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("symbol", pin.getSymbol().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("pin", pin.getLibPin().getUuid());
mApproval->ensureLineBreak();
setLocation(pin);
}
/*******************************************************************************
* ErcMsgUnconnectedJunction
******************************************************************************/
ErcMsgUnconnectedJunction::ErcMsgUnconnectedJunction(
const SI_NetPoint& netPoint) noexcept
: ErcMsgBase(
Severity::Hint,
tr("Unconnected junction in net: '%1'")
.arg(*netPoint.getNetSegment().getNetSignal().getName()),
"There's an invisible junction in the schematic without any wire "
"attached. This should not happen, please report it as a bug. But "
"no worries, this issue is not harmful at all so you can safely "
"ignore this message.",
"unconnected_junction") {
mApproval->ensureLineBreak();
mApproval->appendChild("schematic", netPoint.getSchematic().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("netsegment", netPoint.getNetSegment().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("junction", netPoint.getUuid());
mApproval->ensureLineBreak();
setLocation(netPoint);
}
ErcMsgUnconnectedJunction::ErcMsgUnconnectedJunction(
const SI_BusJunction& junction) noexcept
: ErcMsgBase(
Severity::Hint,
tr("Unconnected junction in bus: '%1'")
.arg(*junction.getBusSegment().getBus().getName()),
"There's an invisible junction in the schematic without any line "
"attached. This should not happen, please report it as a bug. But "
"no worries, this issue is not harmful at all so you can safely "
"ignore this message.",
"unconnected_junction") {
mApproval->ensureLineBreak();
mApproval->appendChild("schematic", junction.getSchematic().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("bussegment", junction.getBusSegment().getUuid());
mApproval->ensureLineBreak();
mApproval->appendChild("junction", junction.getUuid());
mApproval->ensureLineBreak();
setLocation(junction);
}
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace librepcb