73 coordCount = 12; |
73 coordCount = 12; |
74 } break; |
74 } break; |
75 |
75 |
76 case OBJ_Bfc: |
76 case OBJ_Bfc: |
77 { |
77 { |
78 rb_bfcType = new RadioGroup ("Statement", {}, 0, Qt::Vertical); |
78 rb_bfcType = new RadioGroup("Statement", {}, 0, Qt::Vertical); |
79 |
79 |
80 for_enum (BfcStatement, i) |
80 for_enum(BfcStatement, i) |
81 { |
81 { |
82 // Separate these in two columns |
82 // Separate these in two columns |
83 if (int (i) == int (BfcStatement::NumValues) / 2) |
83 if (int(i) == int(BfcStatement::NumValues) / 2) |
84 rb_bfcType->rowBreak(); |
84 rb_bfcType->rowBreak(); |
85 |
85 |
86 rb_bfcType->addButton (LDBfc::statementToString (i)); |
86 rb_bfcType->addButton(LDBfc::statementToString(i)); |
87 } |
87 } |
88 |
88 |
89 if (obj) |
89 if (obj) |
90 rb_bfcType->setValue ((int) static_cast<LDBfc*> (obj)->statement()); |
90 rb_bfcType->setValue((int) static_cast<LDBfc*>(obj)->statement()); |
91 } break; |
91 } break; |
92 |
92 |
93 case OBJ_SubfileReference: |
93 case OBJ_SubfileReference: |
94 { |
94 { |
95 coordCount = 3; |
95 coordCount = 3; |
96 tw_subfileList = new QTreeWidget(); |
96 tw_subfileList = new QTreeWidget(); |
97 tw_subfileList->setHeaderLabel (tr ("Primitives")); |
97 tw_subfileList->setHeaderLabel(tr("Primitives")); |
98 populatePrimitivesTree (tw_subfileList, (obj ? static_cast<LDSubfileReference*> (obj)->fileInfo()->name() : "")); |
98 populatePrimitivesTree(tw_subfileList,(obj ? static_cast<LDSubfileReference*>(obj)->fileInfo()->name() : "")); |
99 |
99 |
100 connect (tw_subfileList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_subfileTypeChanged())); |
100 connect(tw_subfileList, SIGNAL(itemSelectionChanged()), this, SLOT(slot_subfileTypeChanged())); |
101 lb_subfileName = new QLabel ("File:"); |
101 lb_subfileName = new QLabel("File:"); |
102 le_subfileName = new QLineEdit; |
102 le_subfileName = new QLineEdit; |
103 le_subfileName->setFocus(); |
103 le_subfileName->setFocus(); |
104 |
104 |
105 if (obj) |
105 if (obj) |
106 { |
106 { |
107 LDSubfileReference* ref = static_cast<LDSubfileReference*> (obj); |
107 LDSubfileReference* ref = static_cast<LDSubfileReference*>(obj); |
108 le_subfileName->setText (ref->fileInfo()->name()); |
108 le_subfileName->setText(ref->fileInfo()->name()); |
109 } |
109 } |
110 } break; |
110 } break; |
111 |
111 |
112 default: |
112 default: |
113 { |
113 { |
114 Critical (format ("Unhandled LDObject type %1 (%2) in AddObjectDialog", (int) type, typeName)); |
114 Critical(format("Unhandled LDObject type %1(%2) in AddObjectDialog",(int) type, typeName)); |
115 } return; |
115 } return; |
116 } |
116 } |
117 |
117 |
118 QPixmap icon = GetIcon (format ("add-%1", typeName)); |
118 QPixmap icon = GetIcon(format("add-%1", typeName)); |
119 LDObject* defaults = LDObject::getDefault (type); |
119 LDObject* defaults = LDObject::getDefault(type); |
120 |
120 |
121 lb_typeIcon = new QLabel; |
121 lb_typeIcon = new QLabel; |
122 lb_typeIcon->setPixmap (icon); |
122 lb_typeIcon->setPixmap(icon); |
123 |
123 |
124 // Show a color edit dialog for the types that actually use the color |
124 // Show a color edit dialog for the types that actually use the color |
125 if (defaults->isColored()) |
125 if (defaults->isColored()) |
126 { |
126 { |
127 if (obj) |
127 if (obj) |
128 m_color = obj->color(); |
128 m_color = obj->color(); |
129 else |
129 else |
130 m_color = (type == OBJ_CondLine or type == OBJ_Line) ? EdgeColor : MainColor; |
130 m_color = (type == OBJ_CondLine or type == OBJ_Line) ? EdgeColor : MainColor; |
131 |
131 |
132 pb_color = new QPushButton; |
132 pb_color = new QPushButton; |
133 setButtonBackground (pb_color, m_color); |
133 setButtonBackground(pb_color, m_color); |
134 connect (pb_color, SIGNAL (clicked()), this, SLOT (slot_colorButtonClicked())); |
134 connect(pb_color, SIGNAL(clicked()), this, SLOT(slot_colorButtonClicked())); |
135 } |
135 } |
136 |
136 |
137 for (int i = 0; i < coordCount; ++i) |
137 for (int i = 0; i < coordCount; ++i) |
138 { |
138 { |
139 dsb_coords[i] = new QDoubleSpinBox; |
139 dsb_coords[i] = new QDoubleSpinBox; |
140 dsb_coords[i]->setDecimals (5); |
140 dsb_coords[i]->setDecimals(5); |
141 dsb_coords[i]->setMinimum (-10000.0); |
141 dsb_coords[i]->setMinimum(-10000.0); |
142 dsb_coords[i]->setMaximum (10000.0); |
142 dsb_coords[i]->setMaximum(10000.0); |
143 } |
143 } |
144 |
144 |
145 QGridLayout* const layout = new QGridLayout; |
145 QGridLayout* const layout = new QGridLayout; |
146 layout->addWidget (lb_typeIcon, 0, 0); |
146 layout->addWidget(lb_typeIcon, 0, 0); |
147 |
147 |
148 switch (type) |
148 switch(type) |
149 { |
149 { |
150 case OBJ_Line: |
150 case OBJ_Line: |
151 case OBJ_CondLine: |
151 case OBJ_CondLine: |
152 case OBJ_Triangle: |
152 case OBJ_Triangle: |
153 case OBJ_Quad: |
153 case OBJ_Quad: |
154 // Apply coordinates |
154 // Apply coordinates |
155 if (obj) |
155 if (obj) |
156 { |
156 { |
157 for (int i = 0; i < coordCount / 3; ++i) |
157 for (int i = 0; i < coordCount / 3; ++i) |
158 { |
158 { |
159 obj->vertex (i).apply ([&](Axis ax, double value) |
159 obj->vertex(i).apply([&](Axis ax, double value) |
160 { |
160 { |
161 dsb_coords[(i * 3) + ax]->setValue (value); |
161 dsb_coords[(i * 3) + ax]->setValue(value); |
162 }); |
162 }); |
163 } |
163 } |
164 } |
164 } |
165 break; |
165 break; |
166 |
166 |
167 case OBJ_Comment: |
167 case OBJ_Comment: |
168 layout->addWidget (le_comment, 0, 1); |
168 layout->addWidget(le_comment, 0, 1); |
169 break; |
169 break; |
170 |
170 |
171 case OBJ_Bfc: |
171 case OBJ_Bfc: |
172 layout->addWidget (rb_bfcType, 0, 1); |
172 layout->addWidget(rb_bfcType, 0, 1); |
173 break; |
173 break; |
174 |
174 |
175 case OBJ_SubfileReference: |
175 case OBJ_SubfileReference: |
176 layout->addWidget (tw_subfileList, 1, 1, 1, 2); |
176 layout->addWidget(tw_subfileList, 1, 1, 1, 2); |
177 layout->addWidget (lb_subfileName, 2, 1); |
177 layout->addWidget(lb_subfileName, 2, 1); |
178 layout->addWidget (le_subfileName, 2, 2); |
178 layout->addWidget(le_subfileName, 2, 2); |
179 break; |
179 break; |
180 |
180 |
181 default: |
181 default: |
182 break; |
182 break; |
183 } |
183 } |
184 |
184 |
185 if (defaults->hasMatrix()) |
185 if (defaults->hasMatrix()) |
186 { |
186 { |
187 LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj); |
187 LDMatrixObject* mo = dynamic_cast<LDMatrixObject*>(obj); |
188 QLabel* lb_matrix = new QLabel ("Matrix:"); |
188 QLabel* lb_matrix = new QLabel("Matrix:"); |
189 le_matrix = new QLineEdit; |
189 le_matrix = new QLineEdit; |
190 // le_matrix->setValidator (new QDoubleValidator); |
190 // le_matrix->setValidator(new QDoubleValidator); |
191 Matrix defaultMatrix = IdentityMatrix; |
191 Matrix defaultMatrix = IdentityMatrix; |
192 |
192 |
193 if (mo) |
193 if (mo) |
194 { |
194 { |
195 mo->position().apply ([&](Axis ax, double value) |
195 mo->position().apply([&](Axis ax, double value) |
196 { |
196 { |
197 dsb_coords[ax]->setValue (value); |
197 dsb_coords[ax]->setValue(value); |
198 }); |
198 }); |
199 |
199 |
200 defaultMatrix = mo->transform(); |
200 defaultMatrix = mo->transform(); |
201 } |
201 } |
202 |
202 |
203 le_matrix->setText (defaultMatrix.toString()); |
203 le_matrix->setText(defaultMatrix.toString()); |
204 layout->addWidget (lb_matrix, 4, 1); |
204 layout->addWidget(lb_matrix, 4, 1); |
205 layout->addWidget (le_matrix, 4, 2, 1, 3); |
205 layout->addWidget(le_matrix, 4, 2, 1, 3); |
206 } |
206 } |
207 |
207 |
208 if (defaults->isColored()) |
208 if (defaults->isColored()) |
209 layout->addWidget (pb_color, 1, 0); |
209 layout->addWidget(pb_color, 1, 0); |
210 |
210 |
211 if (coordCount > 0) |
211 if (coordCount > 0) |
212 { |
212 { |
213 QGridLayout* const qCoordLayout = new QGridLayout; |
213 QGridLayout* const qCoordLayout = new QGridLayout; |
214 |
214 |
215 for (int i = 0; i < coordCount; ++i) |
215 for (int i = 0; i < coordCount; ++i) |
216 qCoordLayout->addWidget (dsb_coords[i], (i / 3), (i % 3)); |
216 qCoordLayout->addWidget(dsb_coords[i],(i / 3),(i % 3)); |
217 |
217 |
218 layout->addLayout (qCoordLayout, 0, 1, (coordCount / 3), 3); |
218 layout->addLayout(qCoordLayout, 0, 1,(coordCount / 3), 3); |
219 } |
219 } |
220 |
220 |
221 QDialogButtonBox* bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |
221 QDialogButtonBox* bbx_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |
222 QWidget::connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); |
222 QWidget::connect(bbx_buttons, SIGNAL(accepted()), this, SLOT(accept())); |
223 QWidget::connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); |
223 QWidget::connect(bbx_buttons, SIGNAL(rejected()), this, SLOT(reject())); |
224 layout->addWidget (bbx_buttons, 5, 0, 1, 4); |
224 layout->addWidget(bbx_buttons, 5, 0, 1, 4); |
225 setLayout (layout); |
225 setLayout(layout); |
226 setWindowTitle (format (tr ("Edit %1"), typeName)); |
226 setWindowTitle(format(tr("Edit %1"), typeName)); |
227 setWindowIcon (icon); |
227 setWindowIcon(icon); |
228 } |
228 } |
229 |
229 |
230 // ============================================================================= |
230 // ============================================================================= |
231 // ============================================================================= |
231 // ============================================================================= |
232 void AddObjectDialog::setButtonBackground (QPushButton* button, LDColor color) |
232 void AddObjectDialog::setButtonBackground(QPushButton* button, LDColor color) |
233 { |
233 { |
234 button->setIcon (GetIcon ("palette")); |
234 button->setIcon(GetIcon("palette")); |
235 button->setAutoFillBackground (true); |
235 button->setAutoFillBackground(true); |
236 |
236 |
237 if (color.isValid()) |
237 if (color.isValid()) |
238 button->setStyleSheet (format ("background-color: %1", color.hexcode())); |
238 button->setStyleSheet(format("background-color: %1", color.hexcode())); |
239 } |
239 } |
240 |
240 |
241 // ============================================================================= |
241 // ============================================================================= |
242 // ============================================================================= |
242 // ============================================================================= |
243 QString AddObjectDialog::currentSubfileName() |
243 QString AddObjectDialog::currentSubfileName() |
244 { |
244 { |
245 PrimitiveTreeItem* item = static_cast<PrimitiveTreeItem*> (tw_subfileList->currentItem()); |
245 PrimitiveTreeItem* item = static_cast<PrimitiveTreeItem*>(tw_subfileList->currentItem()); |
246 |
246 |
247 if (item->primitive() == nullptr) |
247 if (item->primitive() == nullptr) |
248 return ""; // selected a heading |
248 return ""; // selected a heading |
249 |
249 |
250 return item->primitive()->name; |
250 return item->primitive()->name; |
252 |
252 |
253 // ============================================================================= |
253 // ============================================================================= |
254 // ============================================================================= |
254 // ============================================================================= |
255 void AddObjectDialog::slot_colorButtonClicked() |
255 void AddObjectDialog::slot_colorButtonClicked() |
256 { |
256 { |
257 ColorSelector::selectColor (this, m_color, m_color); |
257 ColorSelector::selectColor(this, m_color, m_color); |
258 setButtonBackground (pb_color, m_color); |
258 setButtonBackground(pb_color, m_color); |
259 } |
259 } |
260 |
260 |
261 // ============================================================================= |
261 // ============================================================================= |
262 // ============================================================================= |
262 // ============================================================================= |
263 void AddObjectDialog::slot_subfileTypeChanged() |
263 void AddObjectDialog::slot_subfileTypeChanged() |
264 { |
264 { |
265 QString name = currentSubfileName(); |
265 QString name = currentSubfileName(); |
266 |
266 |
267 if (name.length() > 0) |
267 if (name.length() > 0) |
268 le_subfileName->setText (name); |
268 le_subfileName->setText(name); |
269 } |
269 } |
270 |
270 |
271 // ============================================================================= |
271 // ============================================================================= |
272 // ============================================================================= |
272 // ============================================================================= |
273 template<typename T> |
273 template<typename T> |
274 static T* InitObject (LDObject*& obj) |
274 static T* InitObject(LDObject*& obj) |
275 { |
275 { |
276 if (obj == nullptr) |
276 if (obj == nullptr) |
277 obj = new T; |
277 obj = new T; |
278 |
278 |
279 return static_cast<T*> (obj); |
279 return static_cast<T*>(obj); |
280 } |
280 } |
281 |
281 |
282 // ============================================================================= |
282 // ============================================================================= |
283 // ============================================================================= |
283 // ============================================================================= |
284 #include "documentmanager.h" |
284 #include "documentmanager.h" |
285 void AddObjectDialog::staticDialog (const LDObjectType type, LDObject* obj) |
285 void AddObjectDialog::staticDialog(const LDObjectType type, LDObject* obj) |
286 { |
286 { |
287 setlocale (LC_ALL, "C"); |
287 setlocale(LC_ALL, "C"); |
288 |
288 |
289 // FIXME: Redirect to Edit Raw |
289 // FIXME: Redirect to Edit Raw |
290 if (obj and obj->type() == OBJ_Error) |
290 if (obj and obj->type() == OBJ_Error) |
291 return; |
291 return; |
292 |
292 |
293 if (type == OBJ_Empty) |
293 if (type == OBJ_Empty) |
294 return; // Nothing to edit with empties |
294 return; // Nothing to edit with empties |
295 |
295 |
296 const bool newObject = (obj == nullptr); |
296 const bool newObject = (obj == nullptr); |
297 Matrix transform = IdentityMatrix; |
297 Matrix transform = IdentityMatrix; |
298 AddObjectDialog dlg (type, obj); |
298 AddObjectDialog dlg(type, obj); |
299 |
299 |
300 if (obj and obj->type() != type) |
300 if (obj and obj->type() != type) |
301 return; |
301 return; |
302 |
302 |
303 if (dlg.exec() == QDialog::Rejected) |
303 if (dlg.exec() == QDialog::Rejected) |
304 return; |
304 return; |
305 |
305 |
306 if (type == OBJ_SubfileReference) |
306 if (type == OBJ_SubfileReference) |
307 { |
307 { |
308 QStringList matrixstrvals = dlg.le_matrix->text().split (" ", QString::SkipEmptyParts); |
308 QStringList matrixstrvals = dlg.le_matrix->text().split(" ", QString::SkipEmptyParts); |
309 |
309 |
310 if (matrixstrvals.size() == 9) |
310 if (matrixstrvals.size() == 9) |
311 { |
311 { |
312 double matrixvals[9]; |
312 double matrixvals[9]; |
313 int i = 0; |
313 int i = 0; |
314 |
314 |
315 for (QString val : matrixstrvals) |
315 for (QString val : matrixstrvals) |
316 matrixvals[i++] = val.toFloat(); |
316 matrixvals[i++] = val.toFloat(); |
317 |
317 |
318 transform = Matrix (matrixvals); |
318 transform = Matrix(matrixvals); |
319 } |
319 } |
320 } |
320 } |
321 |
321 |
322 switch (type) |
322 switch(type) |
323 { |
323 { |
324 case OBJ_Comment: |
324 case OBJ_Comment: |
325 { |
325 { |
326 LDComment* comm = InitObject<LDComment> (obj); |
326 LDComment* comm = InitObject<LDComment>(obj); |
327 comm->setText (dlg.le_comment->text()); |
327 comm->setText(dlg.le_comment->text()); |
328 } |
328 } |
329 break; |
329 break; |
330 |
330 |
331 case OBJ_Line: |
331 case OBJ_Line: |
332 case OBJ_Triangle: |
332 case OBJ_Triangle: |
333 case OBJ_Quad: |
333 case OBJ_Quad: |
334 case OBJ_CondLine: |
334 case OBJ_CondLine: |
335 { |
335 { |
336 if (not obj) |
336 if (not obj) |
337 obj = LDObject::getDefault (type); |
337 obj = LDObject::getDefault(type); |
338 |
338 |
339 for (int i = 0; i < obj->numVertices(); ++i) |
339 for (int i = 0; i < obj->numVertices(); ++i) |
340 { |
340 { |
341 Vertex v; |
341 Vertex v; |
342 |
342 |
343 v.apply ([&](Axis ax, double& value) |
343 v.apply([&](Axis ax, double& value) |
344 { |
344 { |
345 value = dlg.dsb_coords[(i * 3) + ax]->value(); |
345 value = dlg.dsb_coords[(i * 3) + ax]->value(); |
346 }); |
346 }); |
347 |
347 |
348 obj->setVertex (i, v); |
348 obj->setVertex(i, v); |
349 } |
349 } |
350 } break; |
350 } break; |
351 |
351 |
352 case OBJ_Bfc: |
352 case OBJ_Bfc: |
353 { |
353 { |
354 LDBfc* bfc = InitObject<LDBfc> (obj); |
354 LDBfc* bfc = InitObject<LDBfc>(obj); |
355 int value = dlg.rb_bfcType->value(); |
355 int value = dlg.rb_bfcType->value(); |
356 if (value == qBound (0, value, int (BfcStatement::NumValues) - 1)) |
356 if (value == qBound(0, value, int(BfcStatement::NumValues) - 1)) |
357 bfc->setStatement (BfcStatement (dlg.rb_bfcType->value())); |
357 bfc->setStatement(BfcStatement(dlg.rb_bfcType->value())); |
358 } break; |
358 } break; |
359 |
359 |
360 case OBJ_SubfileReference: |
360 case OBJ_SubfileReference: |
361 { |
361 { |
362 QString name = dlg.le_subfileName->text(); |
362 QString name = dlg.le_subfileName->text(); |
363 |
363 |
364 if (name.length() == 0) |
364 if (name.length() == 0) |
365 return; // no subfile filename |
365 return; // no subfile filename |
366 |
366 |
367 LDDocument* document = g_win->documents()->getDocumentByName (name); |
367 LDDocument* document = g_win->documents()->getDocumentByName(name); |
368 |
368 |
369 if (not document) |
369 if (not document) |
370 { |
370 { |
371 Critical (format ("Couldn't open `%1': %2", name, strerror (errno))); |
371 Critical(format("Couldn't open `%1': %2", name, strerror(errno))); |
372 return; |
372 return; |
373 } |
373 } |
374 |
374 |
375 LDSubfileReference* ref = InitObject<LDSubfileReference> (obj); |
375 LDSubfileReference* ref = InitObject<LDSubfileReference>(obj); |
376 |
376 |
377 for_axes (ax) |
377 for_axes(ax) |
378 ref->setCoordinate (ax, dlg.dsb_coords[ax]->value()); |
378 ref->setCoordinate(ax, dlg.dsb_coords[ax]->value()); |
379 |
379 |
380 ref->setTransform (transform); |
380 ref->setTransform(transform); |
381 ref->setFileInfo (document); |
381 ref->setFileInfo(document); |
382 } break; |
382 } break; |
383 |
383 |
384 default: |
384 default: |
385 break; |
385 break; |
386 } |
386 } |
387 |
387 |
388 if (obj->isColored()) |
388 if (obj->isColored()) |
389 obj->setColor (dlg.m_color); |
389 obj->setColor(dlg.m_color); |
390 |
390 |
391 if (newObject) |
391 if (newObject) |
392 { |
392 { |
393 int idx = g_win->suggestInsertPoint(); |
393 int idx = g_win->suggestInsertPoint(); |
394 g_win->currentDocument()->insertObj (idx, obj); |
394 g_win->currentDocument()->insertObj(idx, obj); |
395 } |
395 } |
396 |
396 |
397 g_win->refresh(); |
397 g_win->refresh(); |
398 } |
398 } |