1 /*
2 VeroRoute - Qt based Veroboard/Perfboard/PCB layout & routing application.
3
4 Copyright (C) 2017 Alex Lawrow ( dralx@users.sourceforge.net )
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 #include "controldialog.h"
21 #include "ui_controldialog.h"
22 #include "mainwindow.h"
23
ControlDialog(QWidget * parent)24 ControlDialog::ControlDialog(QWidget* parent)
25 : QWidget(parent)
26 , ui(new Ui_ControlDialog)
27 , m_pMainWindow(nullptr)
28 {
29 ui->setupUi( reinterpret_cast<QDialog*>(this) );
30
31 QFont font = ui->rotateCCW->font();
32 font.setFamily(QString("Arial Unicode MS"));
33 font.setPointSize(12);
34 ui->rotateCCW->setFont(font);
35 ui->rotateCW->setFont(font);
36 ui->textL->setFont(font);
37 ui->textR->setFont(font);
38 ui->textT->setFont(font);
39 ui->textB->setFont(font);
40
41 // Unicode arrowed circles...
42 ui->rotateCCW->setText(QChar(0x21ba));
43 ui->rotateCW->setText(QChar(0x21bb));
44
45 // Unicode triangles ...
46 ui->textL->setText(QChar(0x25c0));
47 ui->textR->setText(QChar(0x25b6));
48 ui->textT->setText(QChar(0x25b2));
49 ui->textB->setText(QChar(0x25bc));
50 }
51
SetMainWindow(MainWindow * p)52 void ControlDialog::SetMainWindow(MainWindow* p)
53 {
54 m_pMainWindow = p;
55
56 QObject::connect(ui->trackSlider, SIGNAL(valueChanged(int)), m_pMainWindow, SLOT(TrackSliderChanged(int)));
57 QObject::connect(ui->saturationSlider, SIGNAL(valueChanged(int)), m_pMainWindow, SLOT(SaturationSliderChanged(int)));
58 QObject::connect(ui->compSlider, SIGNAL(valueChanged(int)), m_pMainWindow, SLOT(CompSliderChanged(int)));
59 QObject::connect(ui->fillSlider, SIGNAL(valueChanged(int)), m_pMainWindow, SLOT(FillSliderChanged(int)));
60 QObject::connect(ui->crop, SIGNAL(clicked()), m_pMainWindow, SLOT(Crop()));
61 QObject::connect(ui->margin, SIGNAL(valueChanged(int)), m_pMainWindow, SLOT(MarginChanged(int)));
62
63 QObject::connect(ui->nameEdit, SIGNAL(textChanged(QString)), m_pMainWindow, SLOT(SetCompName(QString)));
64 QObject::connect(ui->valueEdit, SIGNAL(textChanged(QString)), m_pMainWindow, SLOT(SetCompValue(QString)));
65 QObject::connect(ui->typeComboBox, SIGNAL(currentTextChanged(QString)), m_pMainWindow, SLOT(SetCompType(QString)));
66 QObject::connect(ui->rotateCCW, SIGNAL(clicked()), m_pMainWindow, SLOT(CompRotateCCW()));
67 QObject::connect(ui->rotateCW, SIGNAL(clicked()), m_pMainWindow, SLOT(CompRotateCW()));
68 QObject::connect(ui->grow, SIGNAL(clicked()), m_pMainWindow, SLOT(CompGrow()));
69 QObject::connect(ui->shrink, SIGNAL(clicked()), m_pMainWindow, SLOT(CompShrink()));
70 QObject::connect(ui->grow_2, SIGNAL(clicked()), m_pMainWindow, SLOT(CompGrow2()));
71 QObject::connect(ui->shrink_2, SIGNAL(clicked()), m_pMainWindow, SLOT(CompShrink2()));
72 QObject::connect(ui->textC, SIGNAL(clicked()), m_pMainWindow, SLOT(CompTextCentre()));
73 QObject::connect(ui->textL, SIGNAL(clicked()), m_pMainWindow, SLOT(CompTextL()));
74 QObject::connect(ui->textR, SIGNAL(clicked()), m_pMainWindow, SLOT(CompTextR()));
75 QObject::connect(ui->textT, SIGNAL(clicked()), m_pMainWindow, SLOT(CompTextT()));
76 QObject::connect(ui->textB, SIGNAL(clicked()), m_pMainWindow, SLOT(CompTextB()));
77
78 QObject::connect(ui->custom, SIGNAL(toggled(bool)), m_pMainWindow, SLOT(SetCompCustomFlag(bool)));
79 QObject::connect(ui->padWidth, SIGNAL(valueChanged(int)), m_pMainWindow, SLOT(SetCompPadWidth(int)));
80 QObject::connect(ui->holeWidth, SIGNAL(valueChanged(int)), m_pMainWindow, SLOT(SetCompHoleWidth(int)));
81 QObject::connect(ui->brokenList, SIGNAL(itemClicked(QListWidgetItem*)), m_pMainWindow, SLOT(SetNodeId(QListWidgetItem*)));
82
83 QObject::connect(ui->autoRoute, SIGNAL(toggled(bool)), m_pMainWindow, SLOT(EnableRouting(bool)));
84 QObject::connect(ui->autoRoute, SIGNAL(toggled(bool)), ui->paste, SLOT(setEnabled(bool)));
85 QObject::connect(ui->fast, SIGNAL(toggled(bool)), m_pMainWindow, SLOT(EnableFastRouting(bool)));
86 QObject::connect(ui->paste, SIGNAL(clicked()), m_pMainWindow, SLOT(Paste()));
87 QObject::connect(ui->tidy, SIGNAL(clicked()), m_pMainWindow, SLOT(Tidy()));
88 QObject::connect(ui->wipe, SIGNAL(clicked()), m_pMainWindow, SLOT(WipeTracks()));
89
90 QObject::connect(ui->autoColor, SIGNAL(toggled(bool)), m_pMainWindow, SLOT(AutoColor(bool)));
91 QObject::connect(ui->setColor, SIGNAL(clicked()), m_pMainWindow, SLOT(SelectNodeColor()));
92 }
93
~ControlDialog()94 ControlDialog::~ControlDialog()
95 {
96 delete ui;
97 }
98
ClearList()99 void ControlDialog::ClearList()
100 {
101 auto* pList = ui->brokenList;
102 for (int i = 0; i < pList->count(); i++)
103 {
104 QListWidgetItem* p = pList->takeItem(i);
105 if ( p ) delete p;
106 }
107 pList->clear();
108 }
109
SetListItem(const int nodeId)110 void ControlDialog::SetListItem(const int nodeId)
111 {
112 auto* pList = ui->brokenList;
113 bool bFound(false);
114 for (int i = 0; i < pList->count() && !bFound; i++)
115 {
116 const QString& str = pList->item(i)->text();
117 bFound = ( str.leftRef(str.size() - 11).toInt() == nodeId ); // 11 because of " (Floating)" suffix below
118 if ( bFound ) pList->setCurrentRow(i);
119 }
120 if ( !bFound && pList->count() > 0 ) pList->setCurrentRow(0, QItemSelectionModel::Clear);
121
122 ui->tidy->setEnabled( !ui->autoRoute->isChecked() && pList->count() == 0 );
123 }
124
AddListItem(const int nodeId,bool bFloating)125 void ControlDialog::AddListItem(const int nodeId, bool bFloating)
126 {
127 const std::string str = std::to_string(nodeId) + ( bFloating ? " (Floating)" : " " );
128 ui->brokenList->addItem( str.c_str() );
129 }
130
UpdateCompControls()131 void ControlDialog::UpdateCompControls() // Component controls
132 {
133 Board& board = m_pMainWindow->m_board;
134
135 std::string nameStr(""), valueStr(""), typeStr("");
136 bool bCustom(false);
137 int iPadWidth(0), iHoleWidth(0);
138
139 if ( board.GetGroupMgr().GetNumUserComps() == 1 )
140 {
141 const Component& comp = board.GetUserComponent();
142 nameStr = comp.GetNameStr();
143 valueStr = comp.GetValueStr();
144 typeStr = comp.GetTypeStr();
145 bCustom = comp.GetCustomPads();
146 iPadWidth = comp.GetPadWidth();
147 iHoleWidth = comp.GetHoleWidth();
148
149 int currentIndex = ui->typeComboBox->findText( QString::fromStdString( typeStr ));
150 if ( currentIndex != -1 )
151 ui->typeComboBox->setCurrentIndex(currentIndex);
152 else
153 {
154 currentIndex = 0;
155
156 // Wipe the Type combobox and repopulate it
157 ui->typeComboBox->blockSignals(true); // Block signals while populating box
158 ui->typeComboBox->clear();
159 if ( board.GetDisableChangeType() )
160 ui->typeComboBox->addItem(QString::fromStdString(typeStr)); // Single item
161 else
162 {
163 int index(0);
164 for (const auto& compType : CompTypes::GetListCompTypes())
165 {
166 if ( CompTypes::AllowTypeChange(comp.GetType(), compType) ) // Only put allowed types in combo
167 {
168 ui->typeComboBox->addItem(QString::fromStdString( CompTypes::GetDefaultTypeStr(compType) ));
169 if ( compType == comp.GetType() ) currentIndex = index;
170 index++;
171 }
172 }
173 }
174 ui->typeComboBox->blockSignals(false); // We're done populating, so unblock signals
175 ui->typeComboBox->setCurrentIndex(currentIndex);
176 }
177 }
178 else
179 ui->typeComboBox->clear();
180
181 ui->nameEdit->setText(nameStr.c_str());
182 ui->valueEdit->setText(valueStr.c_str());
183 ui->nameEdit->show();
184 ui->valueEdit->show();
185
186 if ( ui->custom->isChecked() != bCustom ) ui->custom->setChecked(bCustom);
187 if ( bCustom )
188 {
189 if ( ui->padWidth->value() != iPadWidth ) ui->padWidth->setValue(iPadWidth);
190 if ( ui->holeWidth->value() != iHoleWidth ) ui->holeWidth->setValue(iHoleWidth);
191 ui->padWidth->show();
192 ui->holeWidth->show();
193 ui->label_pad->show();
194 ui->label_hole->show();
195 }
196 else
197 {
198 ui->padWidth->hide();
199 ui->holeWidth->hide();
200 ui->label_pad->hide();
201 ui->label_hole->hide();
202 }
203
204 const bool bCompEdit = board.GetCompEdit();
205 const bool bNoTrackOptions = board.GetTrackMode() == TRACKMODE::OFF;
206 const bool bVero = board.GetVeroTracks();
207 const bool bNoText = bCompEdit || board.GetDisableCompText();
208 const bool bNoRotate = bCompEdit || board.GetDisableRotate();
209
210 // Disable controls ...
211 ui->nameEdit->setDisabled( bNoText );
212 ui->valueEdit->setDisabled( bNoText );
213 ui->textC->setDisabled( bNoText );
214 ui->textL->setDisabled( bNoText );
215 ui->textR->setDisabled( bNoText );
216 ui->textT->setDisabled( bNoText );
217 ui->textB->setDisabled( bNoText );
218 ui->rotateCCW->setDisabled( bNoRotate );
219 ui->rotateCW->setDisabled( bNoRotate );
220 ui->shrink->setDisabled( bCompEdit || board.GetDisableStretch(false) );
221 ui->grow->setDisabled( bCompEdit || board.GetDisableStretch(true) );
222 ui->shrink_2->setDisabled( bCompEdit || board.GetDisableStretchWidth(false) );
223 ui->grow_2->setDisabled( bCompEdit || board.GetDisableStretchWidth(true) );
224 ui->typeComboBox->setDisabled( bCompEdit || board.GetDisableChangeType() );
225 ui->custom->setDisabled( bCompEdit || bNoTrackOptions || bVero || board.GetDisableChangeCustom() );
226 ui->padWidth->setDisabled( bCompEdit || bNoTrackOptions || bVero || board.GetDisableChangeCustom() || !ui->custom->isChecked() );
227 ui->holeWidth->setDisabled( bCompEdit || bNoTrackOptions || bVero || board.GetDisableChangeCustom() || !ui->custom->isChecked() );
228
229 // ... and the corresponding labels
230 ui->label_name->setDisabled( bNoText );
231 ui->label_value->setDisabled( bNoText );
232 ui->label_label->setDisabled( bNoText );
233 ui->label_rotate->setDisabled( bNoRotate );
234 ui->label_length->setDisabled( bCompEdit || (board.GetDisableStretch(false) && board.GetDisableStretch(true)) );
235 ui->label_width->setDisabled( bCompEdit || (board.GetDisableStretchWidth(false) && board.GetDisableStretchWidth(true)) );
236 ui->label_type->setDisabled( bCompEdit || board.GetDisableChangeType() );
237 ui->label_pad->setDisabled( bCompEdit || bNoTrackOptions || bVero || board.GetDisableChangeCustom() );
238 ui->label_hole->setDisabled( bCompEdit || bNoTrackOptions || bVero || board.GetDisableChangeCustom() );
239 }
240
UpdateControls()241 void ControlDialog::UpdateControls() // Non-component controls
242 {
243 Board& board = m_pMainWindow->m_board;
244
245 const bool bCompEdit = board.GetCompEdit();
246 const bool bNoTracks = board.GetTrackMode() == TRACKMODE::OFF;
247 const bool bColor = board.GetTrackMode() == TRACKMODE::COLOR;
248 const bool bComps = board.GetCompMode() != COMPSMODE::OFF;
249
250 ui->crop->setDisabled( bCompEdit );
251 ui->margin->setDisabled( bCompEdit );
252 ui->margin->setValue( board.GetCropMargin() );
253
254 ui->label_saturation->setEnabled( !bCompEdit && bColor );
255 ui->label_fill->setEnabled( !bCompEdit && bComps && ( bColor || bNoTracks) );
256
257 ui->autoRoute->setChecked( board.GetRoutingEnabled() );
258 ui->autoRoute->setDisabled( bCompEdit );
259 ui->fast->setChecked( board.GetRoutingMethod() == 0 );
260 ui->fast->setDisabled( bCompEdit );
261 ui->wipe->setDisabled( bCompEdit || board.GetDisableWipe() );
262
263 // Do sliders last (they can trigger a redraw)
264 ui->trackSlider->setEnabled( !bCompEdit );
265 ui->saturationSlider->setEnabled( !bCompEdit && bColor );
266 ui->compSlider->setEnabled( !bCompEdit );
267 ui->fillSlider->setEnabled( !bCompEdit && bComps && ( bColor || bNoTracks) );
268 ui->trackSlider->setValue( board.GetTrackSliderValue() );
269 ui->saturationSlider->setValue( board.GetSaturation() );
270 ui->compSlider->setValue( board.GetCompSliderValue() );
271 ui->fillSlider->setValue( board.GetFillSaturation() );
272
273 const bool bNodeIdOK = board.GetCurrentNodeId() != BAD_NODEID;
274 ui->autoColor->setEnabled( bColor && bNodeIdOK );
275 ui->setColor->setEnabled( bColor && bNodeIdOK );
276 ui->autoColor->setChecked( bNodeIdOK && !board.GetColorMgr().GetIsFixed( board.GetCurrentNodeId() ) );
277
278 QColor color = bColor ? board.GetColorMgr().GetColorFromNodeId( board.GetCurrentNodeId(), false ) : Qt::black;
279 ui->setColor->setStyleSheet("border:2px solid " + color.name());
280 }
281
wheelEvent(QWheelEvent * event)282 void ControlDialog::wheelEvent(QWheelEvent* event)
283 {
284 QWidget::wheelEvent(event);
285 event->accept();
286 }
287
mousePressEvent(QMouseEvent * event)288 void ControlDialog::mousePressEvent(QMouseEvent* event)
289 {
290 QWidget::mousePressEvent(event);
291 event->accept();
292 }
293
mouseDoubleClickEvent(QMouseEvent * event)294 void ControlDialog::mouseDoubleClickEvent(QMouseEvent* event)
295 {
296 QWidget::mouseDoubleClickEvent(event);
297 event->accept();
298 }
299
mouseMoveEvent(QMouseEvent * event)300 void ControlDialog::mouseMoveEvent(QMouseEvent* event)
301 {
302 QWidget::mouseMoveEvent(event);
303 event->accept();
304 }
305
mouseReleaseEvent(QMouseEvent * event)306 void ControlDialog::mouseReleaseEvent(QMouseEvent* event)
307 {
308 QWidget::mouseReleaseEvent(event);
309 event->accept();
310 }
311
keyPressEvent(QKeyEvent * event)312 void ControlDialog::keyPressEvent(QKeyEvent* event)
313 {
314 m_pMainWindow->specialKeyPressEvent(event);
315 QWidget::keyPressEvent(event);
316 event->accept();
317 }
318
keyReleaseEvent(QKeyEvent * event)319 void ControlDialog::keyReleaseEvent(QKeyEvent* event)
320 {
321 m_pMainWindow->commonKeyReleaseEvent(event);
322 QWidget::keyReleaseEvent(event);
323 event->accept();
324 }
325