src/addObjectDialog.cpp

changeset 1075
711c5fff384d
parent 1074
a62f810ca26f
child 1076
55cfa9e42d70
equal deleted inserted replaced
1074:a62f810ca26f 1075:711c5fff384d
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 - 2017 Teemu Piippo
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <QGridLayout>
20 #include <QCheckBox>
21 #include <QDialogButtonBox>
22 #include <QSpinBox>
23 #include <QLabel>
24 #include <QListWidget>
25 #include <QTreeWidget>
26 #include <QLineEdit>
27 #include <QPushButton>
28 #include "mainwindow.h"
29 #include "addObjectDialog.h"
30 #include "ldDocument.h"
31 #include "colors.h"
32 #include "dialogs/colorselector.h"
33 #include "editHistory.h"
34 #include "radioGroup.h"
35 #include "matrixinput.h"
36 #include "miscallenous.h"
37 #include "primitives.h"
38
39 // =============================================================================
40 //
41 AddObjectDialog::AddObjectDialog (const LDObjectType type, LDObject* obj, QWidget* parent) :
42 QDialog (parent)
43 {
44 setlocale (LC_ALL, "C");
45
46 int coordCount = 0;
47 QString typeName = LDObject::typeName (type);
48
49 switch (type)
50 {
51 case OBJ_Comment:
52 {
53 le_comment = new QLineEdit;
54
55 if (obj)
56 le_comment->setText (static_cast<LDComment*> (obj)->text());
57
58 le_comment->setMinimumWidth (384);
59 } break;
60
61 case OBJ_Line:
62 {
63 coordCount = 6;
64 } break;
65
66 case OBJ_Triangle:
67 {
68 coordCount = 9;
69 } break;
70
71 case OBJ_Quad:
72 case OBJ_CondLine:
73 {
74 coordCount = 12;
75 } break;
76
77 case OBJ_Bfc:
78 {
79 rb_bfcType = new RadioGroup ("Statement", {}, 0, Qt::Vertical);
80
81 for (BfcStatement statement : iterateEnum<BfcStatement>())
82 {
83 // Separate these in two columns
84 if (int(statement) == EnumLimits<BfcStatement>::Count / 2)
85 rb_bfcType->rowBreak();
86
87 rb_bfcType->addButton (LDBfc::statementToString(statement));
88 }
89
90 if (obj)
91 rb_bfcType->setValue ((int) static_cast<LDBfc*> (obj)->statement());
92 } break;
93
94 case OBJ_SubfileReference:
95 {
96 coordCount = 3;
97 tw_subfileList = new QTreeWidget();
98 tw_subfileList->setHeaderLabel (tr ("Primitives"));
99
100 QString defaultname;
101
102 if (obj)
103 defaultname = static_cast<LDSubfileReference*> (obj)->fileInfo()->name();
104
105 g_win->primitives()->populateTreeWidget(tw_subfileList, defaultname);
106 connect (tw_subfileList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_subfileTypeChanged()));
107 lb_subfileName = new QLabel ("File:");
108 le_subfileName = new QLineEdit;
109 le_subfileName->setFocus();
110
111 if (obj)
112 {
113 LDSubfileReference* ref = static_cast<LDSubfileReference*> (obj);
114 le_subfileName->setText (ref->fileInfo()->name());
115 }
116 } break;
117
118 default:
119 {
120 Critical (format ("Unhandled LDObject type %1 (%2) in AddObjectDialog", (int) type, typeName));
121 } return;
122 }
123
124 QPixmap icon = GetIcon (format ("add-%1", typeName));
125 LDObject* defaults = LDObject::getDefault (type);
126
127 lb_typeIcon = new QLabel;
128 lb_typeIcon->setPixmap (icon);
129
130 // Show a color edit dialog for the types that actually use the color
131 if (defaults->isColored())
132 {
133 if (obj)
134 m_color = obj->color();
135 else
136 m_color = (type == OBJ_CondLine or type == OBJ_Line) ? EdgeColor : MainColor;
137
138 pb_color = new QPushButton;
139 setButtonBackground (pb_color, m_color);
140 connect (pb_color, SIGNAL (clicked()), this, SLOT (slot_colorButtonClicked()));
141 }
142
143 for (int i = 0; i < coordCount; ++i)
144 {
145 dsb_coords[i] = new QDoubleSpinBox;
146 dsb_coords[i]->setDecimals (5);
147 dsb_coords[i]->setMinimum (-10000.0);
148 dsb_coords[i]->setMaximum (10000.0);
149 }
150
151 QGridLayout* const layout = new QGridLayout;
152 layout->addWidget (lb_typeIcon, 0, 0);
153
154 switch (type)
155 {
156 case OBJ_Line:
157 case OBJ_CondLine:
158 case OBJ_Triangle:
159 case OBJ_Quad:
160 // Apply coordinates
161 if (obj)
162 {
163 for (int i = 0; i < coordCount / 3; ++i)
164 {
165 obj->vertex (i).apply ([&](Axis ax, double value)
166 {
167 dsb_coords[(i * 3) + ax]->setValue (value);
168 });
169 }
170 }
171 break;
172
173 case OBJ_Comment:
174 layout->addWidget (le_comment, 0, 1);
175 break;
176
177 case OBJ_Bfc:
178 layout->addWidget (rb_bfcType, 0, 1);
179 break;
180
181 case OBJ_SubfileReference:
182 layout->addWidget (tw_subfileList, 1, 1, 1, 2);
183 layout->addWidget (lb_subfileName, 2, 1);
184 layout->addWidget (le_subfileName, 2, 2);
185 break;
186
187 default:
188 break;
189 }
190
191 if (defaults->hasMatrix())
192 {
193 LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj);
194 QLabel* lb_matrix = new QLabel ("Matrix:");
195 matrix = new MatrixInput;
196
197 if (mo)
198 {
199 mo->position().apply ([&](Axis ax, double value)
200 {
201 dsb_coords[ax]->setValue (value);
202 });
203 matrix->setValue(mo->transformationMatrix());
204 }
205 else
206 matrix->setValue(Matrix::identity);
207
208 layout->addWidget (lb_matrix, 4, 1);
209 layout->addWidget (matrix, 4, 2, 1, 3);
210 }
211
212 if (defaults->isColored())
213 layout->addWidget (pb_color, 1, 0);
214
215 if (coordCount > 0)
216 {
217 QGridLayout* const qCoordLayout = new QGridLayout;
218
219 for (int i = 0; i < coordCount; ++i)
220 qCoordLayout->addWidget (dsb_coords[i], (i / 3), (i % 3));
221
222 layout->addLayout (qCoordLayout, 0, 1, (coordCount / 3), 3);
223 }
224
225 QDialogButtonBox* bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
226 QWidget::connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept()));
227 QWidget::connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject()));
228 layout->addWidget (bbx_buttons, 5, 0, 1, 4);
229 setLayout (layout);
230 setWindowTitle (format (tr ("Edit %1"), typeName));
231 setWindowIcon (icon);
232 }
233
234 // =============================================================================
235 // =============================================================================
236 void AddObjectDialog::setButtonBackground (QPushButton* button, LDColor color)
237 {
238 button->setIcon (GetIcon ("palette"));
239 button->setAutoFillBackground (true);
240
241 if (color.isValid())
242 button->setStyleSheet (format ("background-color: %1", color.hexcode()));
243 }
244
245 // =============================================================================
246 // =============================================================================
247 QString AddObjectDialog::currentSubfileName()
248 {
249 PrimitiveTreeItem* item = static_cast<PrimitiveTreeItem*> (tw_subfileList->currentItem());
250
251 if (item->primitive() == nullptr)
252 return ""; // selected a heading
253
254 return item->primitive()->name;
255 }
256
257 // =============================================================================
258 // =============================================================================
259 void AddObjectDialog::slot_colorButtonClicked()
260 {
261 ColorSelector::selectColor (this, m_color, m_color);
262 setButtonBackground (pb_color, m_color);
263 }
264
265 // =============================================================================
266 // =============================================================================
267 void AddObjectDialog::slot_subfileTypeChanged()
268 {
269 QString name = currentSubfileName();
270
271 if (not name.isEmpty())
272 le_subfileName->setText (name);
273 }
274
275 // =============================================================================
276 // =============================================================================
277 template<typename T>
278 static T* InitObject (LDObject*& obj)
279 {
280 if (obj == nullptr)
281 obj = new T;
282
283 return static_cast<T*> (obj);
284 }
285
286 // =============================================================================
287 // =============================================================================
288 #include "documentmanager.h"
289 void AddObjectDialog::staticDialog (const LDObjectType type, LDObject* obj)
290 {
291 setlocale (LC_ALL, "C");
292
293 // FIXME: Redirect to Edit Raw
294 if (obj and obj->type() == OBJ_Error)
295 return;
296
297 if (type == OBJ_Empty)
298 return; // Nothing to edit with empties
299
300 const bool newObject = (obj == nullptr);
301 Matrix transform = Matrix::identity;
302 AddObjectDialog dlg (type, obj);
303
304 if (obj and obj->type() != type)
305 return;
306
307 if (dlg.exec() == QDialog::Rejected)
308 return;
309
310 if (type == OBJ_SubfileReference)
311 transform = dlg.matrix->value();
312
313 switch (type)
314 {
315 case OBJ_Comment:
316 {
317 LDComment* comm = InitObject<LDComment> (obj);
318 comm->setText (dlg.le_comment->text());
319 }
320 break;
321
322 case OBJ_Line:
323 case OBJ_Triangle:
324 case OBJ_Quad:
325 case OBJ_CondLine:
326 {
327 if (not obj)
328 obj = LDObject::getDefault (type);
329
330 for (int i = 0; i < obj->numVertices(); ++i)
331 {
332 Vertex v;
333
334 v.apply ([&](Axis ax, double& value)
335 {
336 value = dlg.dsb_coords[(i * 3) + ax]->value();
337 });
338
339 obj->setVertex (i, v);
340 }
341 } break;
342
343 case OBJ_Bfc:
344 {
345 LDBfc* bfc = InitObject<LDBfc> (obj);
346 int value = dlg.rb_bfcType->value();
347 if (valueInEnum<BfcStatement>(value))
348 bfc->setStatement(BfcStatement(value));
349 } break;
350
351 case OBJ_SubfileReference:
352 {
353 QString name = dlg.le_subfileName->text();
354
355 if (name.isEmpty())
356 return; // no subfile filename
357
358 LDDocument* document = g_win->documents()->getDocumentByName (name);
359
360 if (not document)
361 {
362 Critical (format ("Couldn't open `%1': %2", name, strerror (errno)));
363 return;
364 }
365
366 LDSubfileReference* ref = InitObject<LDSubfileReference> (obj);
367
368 for_axes (ax)
369 ref->setCoordinate (ax, dlg.dsb_coords[ax]->value());
370
371 ref->setTransformationMatrix (transform);
372 ref->setFileInfo (document);
373 } break;
374
375 default:
376 break;
377 }
378
379 if (obj->isColored())
380 obj->setColor (dlg.m_color);
381
382 if (newObject)
383 {
384 int idx = g_win->suggestInsertPoint();
385 g_win->currentDocument()->insertObject (idx, obj);
386 }
387
388 g_win->refresh();
389 }

mercurial