src/gui_editactions.cpp

changeset 493
16766ac1bbd9
parent 484
5b5c77c7f3dd
child 498
791c831c8020
equal deleted inserted replaced
492:e964085e6913 493:16766ac1bbd9
38 cfg (Bool, edit_schemanticinline, false); 38 cfg (Bool, edit_schemanticinline, false);
39 extern_cfg (String, ld_defaultuser); 39 extern_cfg (String, ld_defaultuser);
40 40
41 // ============================================================================= 41 // =============================================================================
42 // ----------------------------------------------------------------------------- 42 // -----------------------------------------------------------------------------
43 static int copyToClipboard() { 43 static int copyToClipboard()
44 List<LDObject*> objs = g_win->sel(); 44 { List<LDObject*> objs = g_win->sel();
45 int num = 0; 45 int num = 0;
46 46
47 // Clear the clipboard first. 47 // Clear the clipboard first.
48 qApp->clipboard()->clear(); 48 qApp->clipboard()->clear();
49 49
50 // Now, copy the contents into the clipboard. 50 // Now, copy the contents into the clipboard.
51 str data; 51 str data;
52 52
53 for (LDObject* obj : objs) { 53 for (LDObject* obj : objs)
54 if (data.length() > 0) 54 { if (data.length() > 0)
55 data += "\n"; 55 data += "\n";
56 56
57 data += obj->raw(); 57 data += obj->raw();
58 ++num; 58 ++num;
59 } 59 }
60 60
61 qApp->clipboard()->setText (data); 61 qApp->clipboard()->setText (data);
62 return num; 62 return num;
63 } 63 }
64 64
65 // ============================================================================= 65 // =============================================================================
66 // ----------------------------------------------------------------------------- 66 // -----------------------------------------------------------------------------
67 DEFINE_ACTION (Cut, CTRL (X)) { 67 DEFINE_ACTION (Cut, CTRL (X))
68 int num = copyToClipboard(); 68 { int num = copyToClipboard();
69 g_win->deleteSelection(); 69 g_win->deleteSelection();
70 log (ForgeWindow::tr ("%1 objects cut"), num); 70 log (ForgeWindow::tr ("%1 objects cut"), num);
71 } 71 }
72 72
73 // ============================================================================= 73 // =============================================================================
74 // ----------------------------------------------------------------------------- 74 // -----------------------------------------------------------------------------
75 DEFINE_ACTION (Copy, CTRL (C)) { 75 DEFINE_ACTION (Copy, CTRL (C))
76 int num = copyToClipboard(); 76 { int num = copyToClipboard();
77 log (ForgeWindow::tr ("%1 objects copied"), num); 77 log (ForgeWindow::tr ("%1 objects copied"), num);
78 } 78 }
79 79
80 // ============================================================================= 80 // =============================================================================
81 // ----------------------------------------------------------------------------- 81 // -----------------------------------------------------------------------------
82 DEFINE_ACTION (Paste, CTRL (V)) { 82 DEFINE_ACTION (Paste, CTRL (V))
83 const str clipboardText = qApp->clipboard()->text(); 83 { const str clipboardText = qApp->clipboard()->text();
84 ulong idx = g_win->getInsertionPoint(); 84 ulong idx = g_win->getInsertionPoint();
85 g_win->sel().clear(); 85 g_win->sel().clear();
86 int num = 0; 86 int num = 0;
87 87
88 for (str line : clipboardText.split ("\n")) { 88 for (str line : clipboardText.split ("\n"))
89 LDObject* pasted = parseLine (line); 89 { LDObject* pasted = parseLine (line);
90 LDFile::current()->insertObj (idx++, pasted); 90 LDFile::current()->insertObj (idx++, pasted);
91 g_win->sel() << pasted; 91 g_win->sel() << pasted;
92 g_win->R()->compileObject (pasted); 92 g_win->R()->compileObject (pasted);
93 ++num; 93 ++num;
94 } 94 }
95 95
96 log (ForgeWindow::tr ("%1 objects pasted"), num); 96 log (ForgeWindow::tr ("%1 objects pasted"), num);
97 g_win->refresh(); 97 g_win->refresh();
98 g_win->scrollToSelection(); 98 g_win->scrollToSelection();
99 } 99 }
100 100
101 // ============================================================================= 101 // =============================================================================
102 // ----------------------------------------------------------------------------- 102 // -----------------------------------------------------------------------------
103 DEFINE_ACTION (Delete, KEY (Delete)) { 103 DEFINE_ACTION (Delete, KEY (Delete))
104 int num = g_win->deleteSelection(); 104 { int num = g_win->deleteSelection();
105 log (ForgeWindow::tr ("%1 objects deleted"), num); 105 log (ForgeWindow::tr ("%1 objects deleted"), num);
106 } 106 }
107 107
108 // ============================================================================= 108 // =============================================================================
109 // ----------------------------------------------------------------------------- 109 // -----------------------------------------------------------------------------
110 static void doInline (bool deep) { 110 static void doInline (bool deep)
111 List<LDObject*> sel = g_win->sel(); 111 { List<LDObject*> sel = g_win->sel();
112 112
113 for (LDObject* obj : sel) { 113 for (LDObject* obj : sel)
114 // Get the index of the subfile so we know where to insert the 114 { // Get the index of the subfile so we know where to insert the
115 // inlined contents. 115 // inlined contents.
116 long idx = obj->getIndex(); 116 long idx = obj->getIndex();
117 117
118 if (idx == -1) 118 if (idx == -1)
119 continue; 119 continue;
120 120
121 List<LDObject*> objs; 121 List<LDObject*> objs;
122 122
123 if (obj->getType() == LDObject::Subfile) 123 if (obj->getType() == LDObject::Subfile)
124 objs = static_cast<LDSubfile*> (obj)->inlineContents ( 124 objs = static_cast<LDSubfile*> (obj)->inlineContents (
125 (LDSubfile::InlineFlags) 125 (LDSubfile::InlineFlags)
126 ((deep) ? LDSubfile::DeepInline : 0) | 126 ( (deep) ? LDSubfile::DeepInline : 0) |
127 LDSubfile::CacheInline 127 LDSubfile::CacheInline
128 ); 128 );
129 else 129 else
130 continue; 130 continue;
131 131
132 // Merge in the inlined objects 132 // Merge in the inlined objects
133 for (LDObject* inlineobj : objs) { 133 for (LDObject * inlineobj : objs)
134 str line = inlineobj->raw(); 134 { str line = inlineobj->raw();
135 delete inlineobj; 135 delete inlineobj;
136 136
137 LDObject* newobj = parseLine (line); 137 LDObject* newobj = parseLine (line);
138 LDFile::current()->insertObj (idx++, newobj); 138 LDFile::current()->insertObj (idx++, newobj);
139 g_win->sel() << newobj; 139 g_win->sel() << newobj;
140 g_win->R()->compileObject (newobj); 140 g_win->R()->compileObject (newobj);
141 } 141 }
142 142
143 // Delete the subfile now as it's been inlined. 143 // Delete the subfile now as it's been inlined.
144 LDFile::current()->forgetObject (obj); 144 LDFile::current()->forgetObject (obj);
145 delete obj; 145 delete obj;
146 } 146 }
147 147
148 g_win->refresh(); 148 g_win->refresh();
149 } 149 }
150 150
151 DEFINE_ACTION (Inline, CTRL (I)) { 151 DEFINE_ACTION (Inline, CTRL (I))
152 doInline (false); 152 { doInline (false);
153 } 153 }
154 154
155 DEFINE_ACTION (InlineDeep, CTRL_SHIFT (I)) { 155 DEFINE_ACTION (InlineDeep, CTRL_SHIFT (I))
156 doInline (true); 156 { doInline (true);
157 } 157 }
158 158
159 // ============================================================================= 159 // =============================================================================
160 // ----------------------------------------------------------------------------- 160 // -----------------------------------------------------------------------------
161 DEFINE_ACTION (SplitQuads, 0) { 161 DEFINE_ACTION (SplitQuads, 0)
162 List<LDObject*> objs = g_win->sel(); 162 { List<LDObject*> objs = g_win->sel();
163 int num = 0; 163 int num = 0;
164 164
165 for (LDObject* obj : objs) { 165 for (LDObject* obj : objs)
166 if (obj->getType() != LDObject::Quad) 166 { if (obj->getType() != LDObject::Quad)
167 continue; 167 continue;
168 168
169 // Find the index of this quad 169 // Find the index of this quad
170 long index = obj->getIndex(); 170 long index = obj->getIndex();
171 171
172 if (index == -1) 172 if (index == -1)
173 return; 173 return;
174 174
175 List<LDTriangle*> triangles = static_cast<LDQuad*> (obj)->splitToTriangles(); 175 List<LDTriangle*> triangles = static_cast<LDQuad*> (obj)->splitToTriangles();
176 176
177 // Replace the quad with the first triangle and add the second triangle 177 // Replace the quad with the first triangle and add the second triangle
178 // after the first one. 178 // after the first one.
179 LDFile::current()->setObject (index, triangles[0]); 179 LDFile::current()->setObject (index, triangles[0]);
180 LDFile::current()->insertObj (index + 1, triangles[1]); 180 LDFile::current()->insertObj (index + 1, triangles[1]);
181 181
182 for (LDTriangle * t : triangles) 182 for (LDTriangle* t : triangles)
183 g_win->R()->compileObject (t); 183 g_win->R()->compileObject (t);
184 184
185 // Delete this quad now, it has been split. 185 // Delete this quad now, it has been split.
186 delete obj; 186 delete obj;
187 187
188 num++; 188 num++;
189 } 189 }
190 190
191 log ("%1 quadrilaterals split", num); 191 log ("%1 quadrilaterals split", num);
192 g_win->refresh(); 192 g_win->refresh();
193 } 193 }
194 194
195 // ============================================================================= 195 // =============================================================================
196 // ----------------------------------------------------------------------------- 196 // -----------------------------------------------------------------------------
197 DEFINE_ACTION (EditRaw, KEY (F9)) { 197 DEFINE_ACTION (EditRaw, KEY (F9))
198 if (g_win->sel().size() != 1) 198 { if (g_win->sel().size() != 1)
199 return; 199 return;
200 200
201 LDObject* obj = g_win->sel() [0]; 201 LDObject* obj = g_win->sel() [0];
202 QDialog* dlg = new QDialog; 202 QDialog* dlg = new QDialog;
203 Ui::EditRawUI ui; 203 Ui::EditRawUI ui;
204 204
205 ui.setupUi (dlg); 205 ui.setupUi (dlg);
206 ui.code->setText (obj->raw()); 206 ui.code->setText (obj->raw());
207 207
208 if (obj->getType() == LDObject::Error) 208 if (obj->getType() == LDObject::Error)
209 ui.errorDescription->setText (static_cast<LDError*> (obj)->reason); 209 ui.errorDescription->setText (static_cast<LDError*> (obj)->reason);
210 else { 210 else
211 ui.errorDescription->hide(); 211 { ui.errorDescription->hide();
212 ui.errorIcon->hide(); 212 ui.errorIcon->hide();
213 } 213 }
214 214
215 if (!dlg->exec()) 215 if (!dlg->exec())
216 return; 216 return;
217 217
218 LDObject* oldobj = obj; 218 LDObject* oldobj = obj;
219 219
220 // Reinterpret it from the text of the input field 220 // Reinterpret it from the text of the input field
221 obj = parseLine (ui.code->text()); 221 obj = parseLine (ui.code->text());
222 oldobj->replace (obj); 222 oldobj->replace (obj);
223 223
224 // Refresh 224 // Refresh
225 g_win->R()->compileObject (obj); 225 g_win->R()->compileObject (obj);
226 g_win->refresh(); 226 g_win->refresh();
227 } 227 }
228 228
229 // ============================================================================= 229 // =============================================================================
230 // ----------------------------------------------------------------------------- 230 // -----------------------------------------------------------------------------
231 DEFINE_ACTION (SetColor, KEY (C)) { 231 DEFINE_ACTION (SetColor, KEY (C))
232 if (g_win->sel().size() <= 0) 232 { if (g_win->sel().size() <= 0)
233 return; 233 return;
234 234
235 short colnum; 235 short colnum;
236 short defcol = -1; 236 short defcol = -1;
237 237
238 List<LDObject*> objs = g_win->sel(); 238 List<LDObject*> objs = g_win->sel();
239 239
240 // If all selected objects have the same color, said color is our default 240 // If all selected objects have the same color, said color is our default
241 // value to the color selection dialog. 241 // value to the color selection dialog.
242 defcol = g_win->getSelectedColor(); 242 defcol = g_win->getSelectedColor();
243 243
244 // Show the dialog to the user now and ask for a color. 244 // Show the dialog to the user now and ask for a color.
245 if (ColorSelector::getColor (colnum, defcol, g_win)) { 245 if (ColorSelector::getColor (colnum, defcol, g_win))
246 for (LDObject* obj : objs) { 246 { for (LDObject* obj : objs)
247 if (obj->isColored() == false) 247 { if (obj->isColored() == false)
248 continue; 248 continue;
249 249
250 obj->setColor (colnum); 250 obj->setColor (colnum);
251 g_win->R()->compileObject (obj); 251 g_win->R()->compileObject (obj);
252 } 252 }
253 253
254 g_win->refresh(); 254 g_win->refresh();
255 } 255 }
256 } 256 }
257 257
258 // ============================================================================= 258 // =============================================================================
259 // ----------------------------------------------------------------------------- 259 // -----------------------------------------------------------------------------
260 DEFINE_ACTION (Borders, CTRL_SHIFT (B)) { 260 DEFINE_ACTION (Borders, CTRL_SHIFT (B))
261 List<LDObject*> objs = g_win->sel(); 261 { List<LDObject*> objs = g_win->sel();
262 int num = 0; 262 int num = 0;
263 263
264 for (LDObject* obj : objs) { 264 for (LDObject* obj : objs)
265 if (obj->getType() != LDObject::Quad && obj->getType() != LDObject::Triangle) 265 { if (obj->getType() != LDObject::Quad && obj->getType() != LDObject::Triangle)
266 continue; 266 continue;
267 267
268 short numLines; 268 short numLines;
269 LDLine* lines[4]; 269 LDLine* lines[4];
270 270
271 if (obj->getType() == LDObject::Quad) { 271 if (obj->getType() == LDObject::Quad)
272 numLines = 4; 272 { numLines = 4;
273 273
274 LDQuad* quad = static_cast<LDQuad*> (obj); 274 LDQuad* quad = static_cast<LDQuad*> (obj);
275 lines[0] = new LDLine (quad->getVertex (0), quad->getVertex (1)); 275 lines[0] = new LDLine (quad->getVertex (0), quad->getVertex (1));
276 lines[1] = new LDLine (quad->getVertex (1), quad->getVertex (2)); 276 lines[1] = new LDLine (quad->getVertex (1), quad->getVertex (2));
277 lines[2] = new LDLine (quad->getVertex (2), quad->getVertex (3)); 277 lines[2] = new LDLine (quad->getVertex (2), quad->getVertex (3));
278 lines[3] = new LDLine (quad->getVertex (3), quad->getVertex (0)); 278 lines[3] = new LDLine (quad->getVertex (3), quad->getVertex (0));
279 } else { 279 }
280 numLines = 3; 280 else
281 281 { numLines = 3;
282
282 LDTriangle* tri = static_cast<LDTriangle*> (obj); 283 LDTriangle* tri = static_cast<LDTriangle*> (obj);
283 lines[0] = new LDLine (tri->getVertex (0), tri->getVertex (1)); 284 lines[0] = new LDLine (tri->getVertex (0), tri->getVertex (1));
284 lines[1] = new LDLine (tri->getVertex (1), tri->getVertex (2)); 285 lines[1] = new LDLine (tri->getVertex (1), tri->getVertex (2));
285 lines[2] = new LDLine (tri->getVertex (2), tri->getVertex (0)); 286 lines[2] = new LDLine (tri->getVertex (2), tri->getVertex (0));
286 } 287 }
287 288
288 for (short i = 0; i < numLines; ++i) { 289 for (short i = 0; i < numLines; ++i)
289 ulong idx = obj->getIndex() + i + 1; 290 { long idx = obj->getIndex() + i + 1;
290 291
291 lines[i]->setColor (edgecolor); 292 lines[i]->setColor (edgecolor);
292 LDFile::current()->insertObj (idx, lines[i]); 293 LDFile::current()->insertObj (idx, lines[i]);
293 g_win->R()->compileObject (lines[i]); 294 g_win->R()->compileObject (lines[i]);
294 } 295 }
295 296
296 num += numLines; 297 num += numLines;
297 } 298 }
298 299
299 log (ForgeWindow::tr ("Added %1 border lines"), num); 300 log (ForgeWindow::tr ("Added %1 border lines"), num);
300 g_win->refresh(); 301 g_win->refresh();
301 } 302 }
302 303
303 // ============================================================================= 304 // =============================================================================
304 // ----------------------------------------------------------------------------- 305 // -----------------------------------------------------------------------------
305 DEFINE_ACTION (CornerVerts, 0) { 306 DEFINE_ACTION (CornerVerts, 0)
306 int num = 0; 307 { int num = 0;
307 308
308 for (LDObject* obj : g_win->sel()) { 309 for (LDObject* obj : g_win->sel())
309 if (obj->vertices() < 2) 310 { if (obj->vertices() < 2)
310 continue; 311 continue;
311 312
312 ulong idx = obj->getIndex(); 313 ulong idx = obj->getIndex();
313 314
314 for (short i = 0; i < obj->vertices(); ++i) { 315 for (short i = 0; i < obj->vertices(); ++i)
315 LDVertex* vert = new LDVertex; 316 { LDVertex* vert = new LDVertex;
316 vert->pos = obj->getVertex (i); 317 vert->pos = obj->getVertex (i);
317 vert->setColor (obj->color()); 318 vert->setColor (obj->color());
318 319
319 LDFile::current()->insertObj (++idx, vert); 320 LDFile::current()->insertObj (++idx, vert);
320 g_win->R()->compileObject (vert); 321 g_win->R()->compileObject (vert);
321 ++num; 322 ++num;
322 } 323 }
323 } 324 }
324 325
325 log (ForgeWindow::tr ("Added %1 vertices"), num); 326 log (ForgeWindow::tr ("Added %1 vertices"), num);
326 g_win->refresh(); 327 g_win->refresh();
327 } 328 }
328 329
329 // ============================================================================= 330 // =============================================================================
330 // ----------------------------------------------------------------------------- 331 // -----------------------------------------------------------------------------
331 static void doMoveSelection (const bool up) { 332 static void doMoveSelection (const bool up)
332 List<LDObject*> objs = g_win->sel(); 333 { List<LDObject*> objs = g_win->sel();
333 LDObject::moveObjects (objs, up); 334 LDObject::moveObjects (objs, up);
334 g_win->buildObjList(); 335 g_win->buildObjList();
335 } 336 }
336 337
337 // ============================================================================= 338 // =============================================================================
338 // ----------------------------------------------------------------------------- 339 // -----------------------------------------------------------------------------
339 DEFINE_ACTION (MoveUp, KEY (PageUp)) { 340 DEFINE_ACTION (MoveUp, KEY (PageUp))
340 doMoveSelection (true); 341 { doMoveSelection (true);
341 } 342 }
342 343
343 DEFINE_ACTION (MoveDown, KEY (PageDown)) { 344 DEFINE_ACTION (MoveDown, KEY (PageDown))
344 doMoveSelection (false); 345 { doMoveSelection (false);
345 } 346 }
346 347
347 // ============================================================================= 348 // =============================================================================
348 // ----------------------------------------------------------------------------- 349 // -----------------------------------------------------------------------------
349 DEFINE_ACTION (Undo, CTRL (Z)) { 350 DEFINE_ACTION (Undo, CTRL (Z))
350 LDFile::current()->undo(); 351 { LDFile::current()->undo();
351 } 352 }
352 353
353 DEFINE_ACTION (Redo, CTRL_SHIFT (Z)) { 354 DEFINE_ACTION (Redo, CTRL_SHIFT (Z))
354 LDFile::current()->redo(); 355 { LDFile::current()->redo();
355 } 356 }
356 357
357 // ============================================================================= 358 // =============================================================================
358 // ----------------------------------------------------------------------------- 359 // -----------------------------------------------------------------------------
359 void doMoveObjects (vertex vect) { 360 void doMoveObjects (vertex vect)
360 // Apply the grid values 361 { // Apply the grid values
361 vect[X] *= currentGrid().confs[Grid::X]->value; 362 vect[X] *= currentGrid().confs[Grid::X]->value;
362 vect[Y] *= currentGrid().confs[Grid::Y]->value; 363 vect[Y] *= currentGrid().confs[Grid::Y]->value;
363 vect[Z] *= currentGrid().confs[Grid::Z]->value; 364 vect[Z] *= currentGrid().confs[Grid::Z]->value;
364 365
365 for (LDObject* obj : g_win->sel()) { 366 for (LDObject* obj : g_win->sel())
366 obj->move (vect); 367 { obj->move (vect);
367 g_win->R()->compileObject (obj); 368 g_win->R()->compileObject (obj);
368 } 369 }
369 370
370 g_win->refresh(); 371 g_win->refresh();
371 } 372 }
372 373
373 // ============================================================================= 374 // =============================================================================
374 // ----------------------------------------------------------------------------- 375 // -----------------------------------------------------------------------------
375 DEFINE_ACTION (MoveXNeg, KEY (Left)) { 376 DEFINE_ACTION (MoveXNeg, KEY (Left))
376 doMoveObjects ({-1, 0, 0}); 377 { doMoveObjects ( { -1, 0, 0});
377 } 378 }
378 379
379 DEFINE_ACTION (MoveYNeg, KEY (Home)) { 380 DEFINE_ACTION (MoveYNeg, KEY (Home))
380 doMoveObjects ({0, -1, 0}); 381 { doMoveObjects ( {0, -1, 0});
381 } 382 }
382 383
383 DEFINE_ACTION (MoveZNeg, KEY (Down)) { 384 DEFINE_ACTION (MoveZNeg, KEY (Down))
384 doMoveObjects ({0, 0, -1}); 385 { doMoveObjects ( {0, 0, -1});
385 } 386 }
386 387
387 DEFINE_ACTION (MoveXPos, KEY (Right)) { 388 DEFINE_ACTION (MoveXPos, KEY (Right))
388 doMoveObjects ({1, 0, 0}); 389 { doMoveObjects ( {1, 0, 0});
389 } 390 }
390 391
391 DEFINE_ACTION (MoveYPos, KEY (End)) { 392 DEFINE_ACTION (MoveYPos, KEY (End))
392 doMoveObjects ({0, 1, 0}); 393 { doMoveObjects ( {0, 1, 0});
393 } 394 }
394 395
395 DEFINE_ACTION (MoveZPos, KEY (Up)) { 396 DEFINE_ACTION (MoveZPos, KEY (Up))
396 doMoveObjects ({0, 0, 1}); 397 { doMoveObjects ( {0, 0, 1});
397 } 398 }
398 399
399 // ============================================================================= 400 // =============================================================================
400 // ----------------------------------------------------------------------------- 401 // -----------------------------------------------------------------------------
401 DEFINE_ACTION (Invert, CTRL_SHIFT (W)) { 402 DEFINE_ACTION (Invert, CTRL_SHIFT (W))
402 List<LDObject*> sel = g_win->sel(); 403 { List<LDObject*> sel = g_win->sel();
403 404
404 for (LDObject* obj : sel) { 405 for (LDObject* obj : sel)
405 obj->invert(); 406 { obj->invert();
406 g_win->R()->compileObject (obj); 407 g_win->R()->compileObject (obj);
407 } 408 }
408 409
409 g_win->refresh(); 410 g_win->refresh();
410 } 411 }
411 412
412 // ============================================================================= 413 // =============================================================================
413 // ----------------------------------------------------------------------------- 414 // -----------------------------------------------------------------------------
414 static void rotateVertex (vertex& v, const vertex& rotpoint, const matrix& transform) { 415 static void rotateVertex (vertex& v, const vertex& rotpoint, const matrix& transform)
415 v.move (-rotpoint); 416 { v.move (-rotpoint);
416 v.transform (transform, g_origin); 417 v.transform (transform, g_origin);
417 v.move (rotpoint); 418 v.move (rotpoint);
418 } 419 }
419 420
420 // ============================================================================= 421 // =============================================================================
421 // ----------------------------------------------------------------------------- 422 // -----------------------------------------------------------------------------
422 static void doRotate (const short l, const short m, const short n) { 423 static void doRotate (const short l, const short m, const short n)
423 List<LDObject*> sel = g_win->sel(); 424 { List<LDObject*> sel = g_win->sel();
424 List<vertex*> queue; 425 List<vertex*> queue;
425 const vertex rotpoint = rotPoint (sel); 426 const vertex rotpoint = rotPoint (sel);
426 const double angle = (pi * currentGrid().confs[Grid::Angle]->value) / 180, 427 const double angle = (pi * currentGrid().confs[Grid::Angle]->value) / 180,
427 cosangle = cos (angle), 428 cosangle = cos (angle),
428 sinangle = sin (angle); 429 sinangle = sin (angle);
429 430
430 // ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2 431 // ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2
431 matrix transform ({ 432 matrix transform (
432 (l * l * (1 - cosangle)) + cosangle, 433 { (l* l * (1 - cosangle)) + cosangle,
433 (m * l * (1 - cosangle)) - (n * sinangle), 434 (m* l * (1 - cosangle)) - (n* sinangle),
434 (n * l * (1 - cosangle)) + (m * sinangle), 435 (n* l * (1 - cosangle)) + (m* sinangle),
435 436
436 (l * m * (1 - cosangle)) + (n * sinangle), 437 (l* m * (1 - cosangle)) + (n* sinangle),
437 (m * m * (1 - cosangle)) + cosangle, 438 (m* m * (1 - cosangle)) + cosangle,
438 (n * m * (1 - cosangle)) - (l * sinangle), 439 (n* m * (1 - cosangle)) - (l* sinangle),
439 440
440 (l * n * (1 - cosangle)) - (m * sinangle), 441 (l* n * (1 - cosangle)) - (m* sinangle),
441 (m * n * (1 - cosangle)) + (l * sinangle), 442 (m* n * (1 - cosangle)) + (l* sinangle),
442 (n * n * (1 - cosangle)) + cosangle 443 (n* n * (1 - cosangle)) + cosangle
443 }); 444 });
444 445
445 // Apply the above matrix to everything 446 // Apply the above matrix to everything
446 for (LDObject* obj : sel) { 447 for (LDObject* obj : sel)
447 if (obj->vertices()) { 448 { if (obj->vertices())
448 for (short i = 0; i < obj->vertices(); ++i) { 449 { for (short i = 0; i < obj->vertices(); ++i)
449 vertex v = obj->getVertex (i); 450 { vertex v = obj->getVertex (i);
450 rotateVertex (v, rotpoint, transform); 451 rotateVertex (v, rotpoint, transform);
451 obj->setVertex (i, v); 452 obj->setVertex (i, v);
452 } 453 }
453 } elif (obj->hasMatrix()) { 454 } elif (obj->hasMatrix())
454 LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj); 455
455 456 { LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj);
457
456 // Transform the position 458 // Transform the position
457 vertex v = mo->position(); 459 vertex v = mo->position();
458 rotateVertex (v, rotpoint, transform); 460 rotateVertex (v, rotpoint, transform);
459 mo->setPosition (v); 461 mo->setPosition (v);
460 462
461 // Transform the matrix 463 // Transform the matrix
462 mo->setTransform (mo->transform() * transform); 464 mo->setTransform (mo->transform() * transform);
463 } elif (obj->getType() == LDObject::Vertex) { 465 } elif (obj->getType() == LDObject::Vertex)
464 LDVertex* vert = static_cast<LDVertex*> (obj); 466 { LDVertex* vert = static_cast<LDVertex*> (obj);
465 vertex v = vert->pos; 467 vertex v = vert->pos;
466 rotateVertex (v, rotpoint, transform); 468 rotateVertex (v, rotpoint, transform);
467 vert->pos = v; 469 vert->pos = v;
468 } 470 }
469 471
470 g_win->R()->compileObject (obj); 472 g_win->R()->compileObject (obj);
471 } 473 }
472 474
473 g_win->refresh(); 475 g_win->refresh();
474 } 476 }
475 477
476 // ============================================================================= 478 // =============================================================================
477 // ----------------------------------------------------------------------------- 479 // -----------------------------------------------------------------------------
478 DEFINE_ACTION (RotateXPos, CTRL (Right)) { doRotate (1, 0, 0); } 480 DEFINE_ACTION (RotateXPos, CTRL (Right))
479 DEFINE_ACTION (RotateYPos, CTRL (End)) { doRotate (0, 1, 0); } 481 { doRotate (1, 0, 0);
480 DEFINE_ACTION (RotateZPos, CTRL (Up)) { doRotate (0, 0, 1); } 482 }
481 DEFINE_ACTION (RotateXNeg, CTRL (Left)) { doRotate (-1, 0, 0); } 483 DEFINE_ACTION (RotateYPos, CTRL (End))
482 DEFINE_ACTION (RotateYNeg, CTRL (Home)) { doRotate (0, -1, 0); } 484 { doRotate (0, 1, 0);
483 DEFINE_ACTION (RotateZNeg, CTRL (Down)) { doRotate (0, 0, -1); } 485 }
484 486 DEFINE_ACTION (RotateZPos, CTRL (Up))
485 DEFINE_ACTION (RotationPoint, (0)) { 487 { doRotate (0, 0, 1);
486 configRotationPoint(); 488 }
487 } 489 DEFINE_ACTION (RotateXNeg, CTRL (Left))
488 490 { doRotate (-1, 0, 0);
489 // ============================================================================= 491 }
490 // ----------------------------------------------------------------------------- 492 DEFINE_ACTION (RotateYNeg, CTRL (Home))
491 DEFINE_ACTION (RoundCoordinates, 0) { 493 { doRotate (0, -1, 0);
492 setlocale (LC_ALL, "C"); 494 }
495 DEFINE_ACTION (RotateZNeg, CTRL (Down))
496 { doRotate (0, 0, -1);
497 }
498
499 DEFINE_ACTION (RotationPoint, (0))
500 { configRotationPoint();
501 }
502
503 // =============================================================================
504 // -----------------------------------------------------------------------------
505 DEFINE_ACTION (RoundCoordinates, 0)
506 { setlocale (LC_ALL, "C");
493 int num = 0; 507 int num = 0;
494 508
495 for (LDObject* obj : g_win->sel()) 509 for (LDObject* obj : g_win->sel())
496 for (short i = 0; i < obj->vertices(); ++i) { 510 for (short i = 0; i < obj->vertices(); ++i)
497 vertex v = obj->getVertex (i); 511 { vertex v = obj->getVertex (i);
498 512
499 for (const Axis ax : g_Axes) { 513 for (const Axis ax : g_Axes)
500 // HACK: .. should find a better way to do this 514 { // HACK: .. should find a better way to do this
501 char valstr[64]; 515 char valstr[64];
502 sprintf (valstr, "%.3f", v[ax]); 516 sprintf (valstr, "%.3f", v[ax]);
503 v[ax] = atof (valstr); 517 v[ax] = atof (valstr);
504 } 518 }
505 519
506 obj->setVertex (i, v); 520 obj->setVertex (i, v);
507 g_win->R()->compileObject (obj); 521 g_win->R()->compileObject (obj);
508 num += 3; 522 num += 3;
509 } 523 }
510 524
511 log (ForgeWindow::tr ("Rounded %1 coordinates"), num); 525 log (ForgeWindow::tr ("Rounded %1 coordinates"), num);
512 g_win->refresh(); 526 g_win->refresh();
513 } 527 }
514 528
515 // ============================================================================= 529 // =============================================================================
516 // ----------------------------------------------------------------------------- 530 // -----------------------------------------------------------------------------
517 DEFINE_ACTION (Uncolorize, 0) { 531 DEFINE_ACTION (Uncolorize, 0)
518 int num = 0; 532 { int num = 0;
519 533
520 for (LDObject* obj : g_win->sel()) { 534 for (LDObject* obj : g_win->sel())
521 if (obj->isColored() == false) 535 { if (obj->isColored() == false)
522 continue; 536 continue;
523 537
524 int col = maincolor; 538 int col = maincolor;
525 539
526 if (obj->getType() == LDObject::Line || obj->getType() == LDObject::CndLine) 540 if (obj->getType() == LDObject::Line || obj->getType() == LDObject::CndLine)
527 col = edgecolor; 541 col = edgecolor;
528 542
529 obj->setColor (col); 543 obj->setColor (col);
530 g_win->R()->compileObject (obj); 544 g_win->R()->compileObject (obj);
531 num++; 545 num++;
532 } 546 }
533 547
534 log (ForgeWindow::tr ("%1 objects uncolored"), num); 548 log (ForgeWindow::tr ("%1 objects uncolored"), num);
535 g_win->refresh(); 549 g_win->refresh();
536 } 550 }
537 551
538 // ============================================================================= 552 // =============================================================================
539 // ----------------------------------------------------------------------------- 553 // -----------------------------------------------------------------------------
540 DEFINE_ACTION (ReplaceCoords, CTRL (R)) { 554 DEFINE_ACTION (ReplaceCoords, CTRL (R))
541 QDialog* dlg = new QDialog (g_win); 555 { QDialog* dlg = new QDialog (g_win);
542 Ui::ReplaceCoordsUI ui; 556 Ui::ReplaceCoordsUI ui;
543 ui.setupUi (dlg); 557 ui.setupUi (dlg);
544 558
545 if (!dlg->exec()) 559 if (!dlg->exec())
546 return; 560 return;
547 561
548 const double search = ui.search->value(), 562 const double search = ui.search->value(),
549 replacement = ui.replacement->value(); 563 replacement = ui.replacement->value();
550 const bool any = ui.any->isChecked(), 564 const bool any = ui.any->isChecked(),
551 rel = ui.relative->isChecked(); 565 rel = ui.relative->isChecked();
552 566
553 List<Axis> sel; 567 List<Axis> sel;
554 int num = 0; 568 int num = 0;
555 569
570 if (ui.x->isChecked()) sel << X;
571
572 if (ui.y->isChecked()) sel << Y;
573
574 if (ui.z->isChecked()) sel << Z;
575
576 for (LDObject* obj : g_win->sel())
577 for (short i = 0; i < obj->vertices(); ++i)
578 { vertex v = obj->getVertex (i);
579
580 for (Axis ax : sel)
581 { double& coord = v[ax];
582
583 if (any || coord == search)
584 { if (!rel)
585 coord = 0;
586
587 coord += replacement;
588 num++;
589 }
590 }
591
592 obj->setVertex (i, v);
593 g_win->R()->compileObject (obj);
594 }
595
596 log (ForgeWindow::tr ("Altered %1 values"), num);
597 g_win->refresh();
598 }
599
600 // =============================================================================
601 // -----------------------------------------------------------------------------
602 DEFINE_ACTION (Flip, CTRL_SHIFT (F))
603 { QDialog* dlg = new QDialog;
604 Ui::FlipUI ui;
605 ui.setupUi (dlg);
606
607 if (!dlg->exec())
608 return;
609
610 List<Axis> sel;
611
556 if (ui.x->isChecked()) sel << X; 612 if (ui.x->isChecked()) sel << X;
557 if (ui.y->isChecked()) sel << Y; 613 if (ui.y->isChecked()) sel << Y;
558 if (ui.z->isChecked()) sel << Z; 614 if (ui.z->isChecked()) sel << Z;
559 615
560 for (LDObject* obj : g_win->sel()) 616 for (LDObject* obj : g_win->sel())
561 for (short i = 0; i < obj->vertices(); ++i) { 617 for (short i = 0; i < obj->vertices(); ++i)
562 vertex v = obj->getVertex (i); 618 { vertex v = obj->getVertex (i);
563 619
564 for (Axis ax : sel) {
565 double& coord = v[ax];
566
567 if (any || coord == search) {
568 if (!rel)
569 coord = 0;
570
571 coord += replacement;
572 num++;
573 }
574 }
575
576 obj->setVertex (i, v);
577 g_win->R()->compileObject (obj);
578 }
579
580 log (ForgeWindow::tr ("Altered %1 values"), num);
581 g_win->refresh();
582 }
583
584 // =============================================================================
585 // -----------------------------------------------------------------------------
586 DEFINE_ACTION (Flip, CTRL_SHIFT (F)) {
587 QDialog* dlg = new QDialog;
588 Ui::FlipUI ui;
589 ui.setupUi (dlg);
590
591 if (!dlg->exec())
592 return;
593
594 List<Axis> sel;
595 if (ui.x->isChecked()) sel << X;
596 if (ui.y->isChecked()) sel << Y;
597 if (ui.z->isChecked()) sel << Z;
598
599 for (LDObject* obj : g_win->sel())
600 for (short i = 0; i < obj->vertices(); ++i) {
601 vertex v = obj->getVertex (i);
602
603 for (Axis ax : sel) 620 for (Axis ax : sel)
604 v[ax] *= -1; 621 v[ax] *= -1;
605 622
606 obj->setVertex (i, v); 623 obj->setVertex (i, v);
607 g_win->R()->compileObject (obj); 624 g_win->R()->compileObject (obj);
608 } 625 }
609 626
610 g_win->refresh(); 627 g_win->refresh();
611 } 628 }
612 629
613 // ============================================================================= 630 // =============================================================================
614 // ----------------------------------------------------------------------------- 631 // -----------------------------------------------------------------------------
615 DEFINE_ACTION (Demote, 0) { 632 DEFINE_ACTION (Demote, 0)
616 List<LDObject*> sel = g_win->sel(); 633 { List<LDObject*> sel = g_win->sel();
617 int num = 0; 634 int num = 0;
618 635
619 for (LDObject* obj : sel) { 636 for (LDObject* obj : sel)
620 if (obj->getType() != LDObject::CndLine) 637 { if (obj->getType() != LDObject::CndLine)
621 continue; 638 continue;
622 639
623 LDLine* repl = static_cast<LDCndLine*> (obj)->demote(); 640 LDLine* repl = static_cast<LDCndLine*> (obj)->demote();
624 g_win->R()->compileObject (repl); 641 g_win->R()->compileObject (repl);
625 ++num; 642 ++num;
626 } 643 }
627 644
628 log (ForgeWindow::tr ("Demoted %1 conditional lines"), num); 645 log (ForgeWindow::tr ("Demoted %1 conditional lines"), num);
629 g_win->refresh(); 646 g_win->refresh();
630 } 647 }
631 648
632 // ============================================================================= 649 // =============================================================================
633 // ----------------------------------------------------------------------------- 650 // -----------------------------------------------------------------------------
634 static bool isColorUsed (short colnum) { 651 static bool isColorUsed (short colnum)
635 for (LDObject* obj : LDFile::current()->objects()) 652 { for (LDObject* obj : LDFile::current()->objects())
636 if (obj->isColored() && obj->color() == colnum) 653 if (obj->isColored() && obj->color() == colnum)
637 return true; 654 return true;
638 655
639 return false; 656 return false;
640 } 657 }
641 658
642 // ============================================================================= 659 // =============================================================================
643 // ----------------------------------------------------------------------------- 660 // -----------------------------------------------------------------------------
644 DEFINE_ACTION (Autocolor, 0) { 661 DEFINE_ACTION (Autocolor, 0)
645 short colnum = 0; 662 { short colnum = 0;
646 663
647 while (colnum < MAX_COLORS && (getColor (colnum) == null || isColorUsed (colnum))) 664 while (colnum < MAX_COLORS && (getColor (colnum) == null || isColorUsed (colnum)))
648 colnum++; 665 colnum++;
649 666
650 if (colnum >= MAX_COLORS) { 667 if (colnum >= MAX_COLORS)
651 log (ForgeWindow::tr ("Cannot auto-color: all colors are in use!")); 668 { log (ForgeWindow::tr ("Cannot auto-color: all colors are in use!"));
652 return; 669 return;
653 } 670 }
654 671
655 for (LDObject* obj : g_win->sel()) { 672 for (LDObject* obj : g_win->sel())
656 if (obj->isColored() == false) 673 { if (obj->isColored() == false)
657 continue; 674 continue;
658 675
659 obj->setColor (colnum); 676 obj->setColor (colnum);
660 g_win->R()->compileObject (obj); 677 g_win->R()->compileObject (obj);
661 } 678 }
662 679
663 log (ForgeWindow::tr ("Auto-colored: new color is [%1] %2"), colnum, getColor (colnum)->name); 680 log (ForgeWindow::tr ("Auto-colored: new color is [%1] %2"), colnum, getColor (colnum)->name);
664 g_win->refresh(); 681 g_win->refresh();
665 } 682 }
666 683
667 // ============================================================================= 684 // =============================================================================
668 // ----------------------------------------------------------------------------- 685 // -----------------------------------------------------------------------------
669 DEFINE_ACTION (AddHistoryLine, 0) { 686 DEFINE_ACTION (AddHistoryLine, 0)
670 LDObject* obj; 687 { LDObject* obj;
671 bool ishistory = false, 688 bool ishistory = false,
672 prevIsHistory = false; 689 prevIsHistory = false;
673 690
674 QDialog* dlg = new QDialog; 691 QDialog* dlg = new QDialog;
675 Ui_AddHistoryLine* ui = new Ui_AddHistoryLine; 692 Ui_AddHistoryLine* ui = new Ui_AddHistoryLine;
676 ui->setupUi (dlg); 693 ui->setupUi (dlg);
677 ui->m_username->setText (ld_defaultuser); 694 ui->m_username->setText (ld_defaultuser);
678 ui->m_date->setDate (QDate::currentDate()); 695 ui->m_date->setDate (QDate::currentDate());
679 ui->m_comment->setFocus(); 696 ui->m_comment->setFocus();
680 697
681 if (!dlg->exec()) 698 if (!dlg->exec())
682 return; 699 return;
683 700
684 // Create the comment object based on input 701 // Create the comment object based on input
685 str commentText = fmt ("!HISTORY %1 [%2] %3", 702 str commentText = fmt ("!HISTORY %1 [%2] %3",
686 ui->m_date->date().toString("yyyy-MM-dd"), 703 ui->m_date->date().toString ("yyyy-MM-dd"),
687 ui->m_username->text(), 704 ui->m_username->text(),
688 ui->m_comment->text()); 705 ui->m_comment->text());
689 706
690 LDComment* comm = new LDComment (commentText); 707 LDComment* comm = new LDComment (commentText);
691 708
692 // Find a spot to place the new comment 709 // Find a spot to place the new comment
693 for ( 710 for (
694 obj = LDFile::current()->object (0); 711 obj = LDFile::current()->object (0);
695 obj && obj->next() && !obj->next()->isScemantic(); 712 obj && obj->next() && !obj->next()->isScemantic();
696 obj = obj->next() 713 obj = obj->next()
697 ) { 714 )
698 LDComment* comm = dynamic_cast<LDComment*> (obj); 715 { LDComment* comm = dynamic_cast<LDComment*> (obj);
716
699 if (comm && comm->text.startsWith ("!HISTORY ")) 717 if (comm && comm->text.startsWith ("!HISTORY "))
700 ishistory = true; 718 ishistory = true;
701 719
702 if (prevIsHistory && !ishistory) { 720 if (prevIsHistory && !ishistory)
703 // Last line was history, this isn't, thus insert the new history 721 { // Last line was history, this isn't, thus insert the new history
704 // line here. 722 // line here.
705 break; 723 break;
706 } 724 }
707 725
708 prevIsHistory = ishistory; 726 prevIsHistory = ishistory;
709 } 727 }
710 728
711 int idx = obj ? obj->getIndex() : 0; 729 int idx = obj ? obj->getIndex() : 0;
712 LDFile::current()->insertObj (idx++, comm); 730 LDFile::current()->insertObj (idx++, comm);
713 731
714 // If we're adding a history line right before a scemantic object, pad it 732 // If we're adding a history line right before a scemantic object, pad it
715 // an empty line 733 // an empty line
716 if (obj && obj->next() && obj->next()->isScemantic()) 734 if (obj && obj->next() && obj->next()->isScemantic())
717 LDFile::current()->insertObj (idx, new LDEmpty); 735 LDFile::current()->insertObj (idx, new LDEmpty);
718 736
719 g_win->buildObjList(); 737 g_win->buildObjList();
720 delete ui; 738 delete ui;
721 } 739 }

mercurial