Loading files
This 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 "boardplanepropertiesdialog.h"
#include "../../project/cmd/cmdboardplaneedit.h"
#include "../../undostack.h"
#include "ui_boardplanepropertiesdialog.h"
#include <librepcb/core/project/board/board.h>
#include <librepcb/core/project/board/items/bi_plane.h>
#include <librepcb/core/project/circuit/circuit.h>
#include <librepcb/core/project/circuit/netsignal.h>
#include <librepcb/core/types/layer.h>
#include <librepcb/core/utils/toolbox.h>
#include <QtCore>
#include <QtWidgets>
/*******************************************************************************
* Namespace
******************************************************************************/
namespace librepcb {
namespace editor {
/*******************************************************************************
* Constructors / Destructor
******************************************************************************/
BoardPlanePropertiesDialog::BoardPlanePropertiesDialog(
Project& project, BI_Plane& plane, UndoStack& undoStack,
const LengthUnit& lengthUnit, const QString& settingsPrefix,
QWidget* parent) noexcept
: QDialog(parent),
mProject(project),
mPlane(plane),
mUi(new Ui::BoardPlanePropertiesDialog),
mUndoStack(undoStack) {
mUi->setupUi(this);
mUi->edtMinWidth->configure(lengthUnit, LengthEditBase::Steps::generic(),
settingsPrefix % "/min_width");
mUi->edtMinClearanceToCopper->configure(
lengthUnit, LengthEditBase::Steps::generic(),
settingsPrefix % "/min_copper_clearance");
mUi->edtMinClearanceToBoard->configure(
lengthUnit, LengthEditBase::Steps::generic(),
settingsPrefix % "/min_board_clearance");
mUi->edtMinClearanceToNpth->configure(lengthUnit,
LengthEditBase::Steps::generic(),
settingsPrefix % "/min_npth_clearance");
mUi->edtThermalGap->configure(lengthUnit, LengthEditBase::Steps::generic(),
settingsPrefix % "/thermal_gap");
mUi->edtThermalSpokeWidth->configure(lengthUnit,
LengthEditBase::Steps::generic(),
settingsPrefix % "/thermal_spoke");
mUi->pathEditorWidget->setLengthUnit(lengthUnit);
connect(mUi->buttonBox, &QDialogButtonBox::clicked, this,
&BoardPlanePropertiesDialog::buttonBoxClicked);
// net signal combobox
connect(
mUi->cbxNetSignal,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, [this](int index) {
const bool hasNet =
!mUi->cbxNetSignal->itemData(index).toString().isEmpty();
mUi->cbxConnectStyle->setEnabled(hasNet);
mUi->cbKeepIslands->setEnabled(hasNet);
});
QList<NetSignal*> netSignals = mPlane.getCircuit().getNetSignals().values();
Toolbox::sortNumeric(
netSignals,
[](const QCollator& cmp, const NetSignal* lhs, const NetSignal* rhs) {
return cmp(*lhs->getName(), *rhs->getName());
},
Qt::CaseInsensitive, false);
mUi->cbxNetSignal->addItem("[" % tr("None") % "]", QString());
foreach (NetSignal* netsignal, netSignals) {
mUi->cbxNetSignal->addItem(*netsignal->getName(),
netsignal->getUuid().toStr());
}
mUi->cbxNetSignal->setCurrentIndex(mUi->cbxNetSignal->findData(
mPlane.getNetSignal() ? mPlane.getNetSignal()->getUuid().toStr()
: QString()));
// layer combobox
mUi->cbxLayer->setLayers(mPlane.getBoard().getCopperLayers());
mUi->cbxLayer->setCurrentLayer(mPlane.getLayer());
// minimum width / clearance spinboxes
mUi->edtMinWidth->setValue(mPlane.getMinWidth());
mUi->edtMinClearanceToCopper->setValue(mPlane.getMinClearanceToCopper());
mUi->edtMinClearanceToBoard->setValue(mPlane.getMinClearanceToBoard());
mUi->edtMinClearanceToNpth->setValue(mPlane.getMinClearanceToNpth());
// connect style combobox
mUi->cbxConnectStyle->addItem(tr("None"),
static_cast<int>(BI_Plane::ConnectStyle::None));
mUi->cbxConnectStyle->addItem(
tr("Thermal Relief"),
static_cast<int>(BI_Plane::ConnectStyle::ThermalRelief));
mUi->cbxConnectStyle->addItem(
tr("Solid"), static_cast<int>(BI_Plane::ConnectStyle::Solid));
mUi->cbxConnectStyle->setCurrentIndex(mUi->cbxConnectStyle->findData(
static_cast<int>(mPlane.getConnectStyle())));
// thermal gap/width spinbox
mUi->edtThermalGap->setValue(mPlane.getThermalGap());
mUi->edtThermalSpokeWidth->setValue(mPlane.getThermalSpokeWidth());
// priority spinbox
mUi->spbPriority->setValue(mPlane.getPriority());
// checkboxes
mUi->cbKeepIslands->setChecked(mPlane.getKeepIslands());
mUi->cbxLock->setChecked(mPlane.isLocked());
// vertices
mUi->pathEditorWidget->setPath(mPlane.getOutline());
// Make sure the thermal spoke width is >= minimum plane width.
connect(mUi->edtMinWidth, &UnsignedLengthEdit::valueChanged, this,
[this](const UnsignedLength& value) {
if (value > 0) {
mUi->edtThermalSpokeWidth->clipToMinimum(PositiveLength(*value));
}
});
connect(mUi->edtThermalSpokeWidth, &PositiveLengthEdit::valueChanged, this,
[this](const PositiveLength& value) {
mUi->edtMinWidth->clipToMaximum(positiveToUnsigned(value));
});
}
BoardPlanePropertiesDialog::~BoardPlanePropertiesDialog() noexcept {
mUi.reset();
}
/*******************************************************************************
* Private Methods
******************************************************************************/
void BoardPlanePropertiesDialog::buttonBoxClicked(
QAbstractButton* button) noexcept {
switch (mUi->buttonBox->buttonRole(button)) {
case QDialogButtonBox::ApplyRole:
applyChanges();
break;
case QDialogButtonBox::AcceptRole:
if (applyChanges()) {
accept();
}
break;
case QDialogButtonBox::RejectRole:
reject();
break;
default:
Q_ASSERT(false);
break;
}
}
bool BoardPlanePropertiesDialog::applyChanges() noexcept {
try {
std::unique_ptr<CmdBoardPlaneEdit> cmd(new CmdBoardPlaneEdit(mPlane));
// net signal
const std::optional<Uuid> netSignalUuid =
Uuid::tryFromString(mUi->cbxNetSignal->currentData().toString());
if (!netSignalUuid) {
cmd->setNetSignal(nullptr);
} else if (NetSignal* netsignal =
mPlane.getCircuit().getNetSignals().value(*netSignalUuid)) {
cmd->setNetSignal(netsignal);
} else {
qWarning() << "No valid netsignal selected in plane properties dialog!";
}
// layer
if (auto layer = mUi->cbxLayer->getCurrentLayer()) {
cmd->setLayer(*layer, false); // can throw
}
// min width/clearances
cmd->setMinWidth(mUi->edtMinWidth->getValue());
cmd->setMinClearanceToCopper(mUi->edtMinClearanceToCopper->getValue());
cmd->setMinClearanceToBoard(mUi->edtMinClearanceToBoard->getValue());
cmd->setMinClearanceToNpth(mUi->edtMinClearanceToNpth->getValue());
// connect style
cmd->setConnectStyle(static_cast<BI_Plane::ConnectStyle>(
mUi->cbxConnectStyle->currentData().toInt()));
// thermal gap & spoke width spinbox
cmd->setThermalGap(mUi->edtThermalGap->getValue());
cmd->setThermalSpokeWidth(mUi->edtThermalSpokeWidth->getValue());
// priority
cmd->setPriority(mUi->spbPriority->value());
// booleans
cmd->setKeepIslands(mUi->cbKeepIslands->isChecked());
cmd->setLocked(mUi->cbxLock->isChecked());
// vertices
cmd->setOutline(mUi->pathEditorWidget->getPath(), false); // can throw
// apply changes
mUndoStack.execCmd(cmd.release());
return true;
} catch (const Exception& e) {
QMessageBox::critical(this, tr("Error"), e.getMsg());
return false;
}
}
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace editor
} // namespace librepcb
94ec4b8feThis file is pinned to the selected release. Download the original to open it in your design tool.