1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /*******************************************************************************
21  *  Includes
22  ******************************************************************************/
23 #include "circlepropertiesdialog.h"
24 
25 #include "../geometry/circle.h"
26 #include "../geometry/cmd/cmdcircleedit.h"
27 #include "../graphics/graphicslayer.h"
28 #include "../undostack.h"
29 #include "ui_circlepropertiesdialog.h"
30 
31 #include <QtCore>
32 #include <QtWidgets>
33 
34 /*******************************************************************************
35  *  Namespace
36  ******************************************************************************/
37 namespace librepcb {
38 
CirclePropertiesDialog(Circle & circle,UndoStack & undoStack,QList<GraphicsLayer * > layers,const LengthUnit & lengthUnit,const QString & settingsPrefix,QWidget * parent)39 CirclePropertiesDialog::CirclePropertiesDialog(Circle& circle,
40                                                UndoStack& undoStack,
41                                                QList<GraphicsLayer*> layers,
42                                                const LengthUnit& lengthUnit,
43                                                const QString& settingsPrefix,
44                                                QWidget* parent) noexcept
45   : QDialog(parent),
46     mCircle(circle),
47     mUndoStack(undoStack),
48     mUi(new Ui::CirclePropertiesDialog) {
49   mUi->setupUi(this);
50   mUi->edtLineWidth->configure(lengthUnit, LengthEditBase::Steps::generic(),
51                                settingsPrefix % "/line_width");
52   mUi->edtDiameter->configure(lengthUnit, LengthEditBase::Steps::generic(),
53                               settingsPrefix % "/diameter");
54   mUi->edtPosX->configure(lengthUnit, LengthEditBase::Steps::generic(),
55                           settingsPrefix % "/pos_x");
56   mUi->edtPosY->configure(lengthUnit, LengthEditBase::Steps::generic(),
57                           settingsPrefix % "/pos_y");
58 
59   foreach (const GraphicsLayer* layer, layers) {
60     mUi->cbxLayer->addItem(layer->getNameTr(), layer->getName());
61   }
62 
63   connect(mUi->buttonBox, &QDialogButtonBox::clicked, this,
64           &CirclePropertiesDialog::buttonBoxClicked);
65 
66   // load circle attributes
67   selectLayerNameInCombobox(*mCircle.getLayerName());
68   mUi->edtLineWidth->setValue(mCircle.getLineWidth());
69   mUi->cbxFillArea->setChecked(mCircle.isFilled());
70   mUi->cbxIsGrabArea->setChecked(mCircle.isGrabArea());
71   mUi->edtDiameter->setValue(mCircle.getDiameter());
72   mUi->edtPosX->setValue(mCircle.getCenter().getX());
73   mUi->edtPosY->setValue(mCircle.getCenter().getY());
74 }
75 
~CirclePropertiesDialog()76 CirclePropertiesDialog::~CirclePropertiesDialog() noexcept {
77 }
78 
79 /*******************************************************************************
80  *  Setters
81  ******************************************************************************/
82 
setReadOnly(bool readOnly)83 void CirclePropertiesDialog::setReadOnly(bool readOnly) noexcept {
84   mUi->cbxLayer->setDisabled(readOnly);
85   mUi->edtLineWidth->setReadOnly(readOnly);
86   mUi->cbxFillArea->setCheckable(!readOnly);
87   mUi->cbxIsGrabArea->setCheckable(!readOnly);
88   mUi->edtDiameter->setReadOnly(readOnly);
89   mUi->edtPosX->setReadOnly(readOnly);
90   mUi->edtPosY->setReadOnly(readOnly);
91   if (readOnly) {
92     mUi->buttonBox->setStandardButtons(QDialogButtonBox::StandardButton::Close);
93   } else {
94     mUi->buttonBox->setStandardButtons(
95         QDialogButtonBox::StandardButton::Apply |
96         QDialogButtonBox::StandardButton::Cancel |
97         QDialogButtonBox::StandardButton::Ok);
98   }
99 }
100 
101 /*******************************************************************************
102  *  Private Methods
103  ******************************************************************************/
104 
buttonBoxClicked(QAbstractButton * button)105 void CirclePropertiesDialog::buttonBoxClicked(
106     QAbstractButton* button) noexcept {
107   switch (mUi->buttonBox->buttonRole(button)) {
108     case QDialogButtonBox::ApplyRole:
109       applyChanges();
110       break;
111     case QDialogButtonBox::AcceptRole:
112       if (applyChanges()) {
113         accept();
114       }
115       break;
116     case QDialogButtonBox::RejectRole:
117       reject();
118       break;
119     default:
120       Q_ASSERT(false);
121       break;
122   }
123 }
124 
applyChanges()125 bool CirclePropertiesDialog::applyChanges() noexcept {
126   try {
127     QScopedPointer<CmdCircleEdit> cmd(new CmdCircleEdit(mCircle));
128     if (mUi->cbxLayer->currentIndex() >= 0 &&
129         mUi->cbxLayer->currentData().isValid()) {
130       cmd->setLayerName(
131           GraphicsLayerName(mUi->cbxLayer->currentData().toString()),
132           false);  // can throw
133     }
134     cmd->setIsFilled(mUi->cbxFillArea->isChecked(), false);
135     cmd->setIsGrabArea(mUi->cbxIsGrabArea->isChecked(), false);
136     cmd->setLineWidth(mUi->edtLineWidth->getValue(), false);
137     cmd->setDiameter(mUi->edtDiameter->getValue(), false);
138     cmd->setCenter(Point(mUi->edtPosX->getValue(), mUi->edtPosY->getValue()),
139                    false);
140     mUndoStack.execCmd(cmd.take());
141     return true;
142   } catch (const Exception& e) {
143     QMessageBox::critical(this, tr("Error"), e.getMsg());
144     return false;
145   }
146 }
147 
selectLayerNameInCombobox(const QString & name)148 void CirclePropertiesDialog::selectLayerNameInCombobox(
149     const QString& name) noexcept {
150   mUi->cbxLayer->setCurrentIndex(mUi->cbxLayer->findData(name));
151 }
152 
153 /*******************************************************************************
154  *  End of File
155  ******************************************************************************/
156 
157 }  // namespace librepcb
158