src/gui_actions.cpp

changeset 557
04e140bdeb0b
parent 556
5f4395ec5db0
child 558
5f6e30e0450c
equal deleted inserted replaced
556:5f4395ec5db0 557:04e140bdeb0b
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 Santeri 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 <QFileDialog>
20 #include <QMessageBox>
21 #include <QTextEdit>
22 #include <QBoxLayout>
23 #include <QDialogButtonBox>
24 #include <QPushButton>
25 #include <QInputDialog>
26
27 #include "gui.h"
28 #include "document.h"
29 #include "history.h"
30 #include "configDialog.h"
31 #include "addObjectDialog.h"
32 #include "misc.h"
33 #include "gldraw.h"
34 #include "dialogs.h"
35 #include "primitives.h"
36 #include "ui_newpart.h"
37 #include "widgets.h"
38
39 extern_cfg (Bool, gl_wireframe);
40 extern_cfg (Bool, gl_colorbfc);
41 extern_cfg (String, ld_defaultname);
42 extern_cfg (String, ld_defaultuser);
43 extern_cfg (Int, ld_defaultlicense);
44
45 // =============================================================================
46 // -----------------------------------------------------------------------------
47 DEFINE_ACTION (New, CTRL_SHIFT (N))
48 { QDialog* dlg = new QDialog (g_win);
49 Ui::NewPartUI ui;
50 ui.setupUi (dlg);
51
52 str authortext = ld_defaultname;
53
54 if (!ld_defaultuser.value.isEmpty())
55 authortext.append (fmt (" [%1]", ld_defaultuser));
56
57 ui.le_author->setText (authortext);
58
59 switch (ld_defaultlicense)
60 { case 0:
61 ui.rb_license_ca->setChecked (true);
62 break;
63
64 case 1:
65 ui.rb_license_nonca->setChecked (true);
66 break;
67
68 case 2:
69 ui.rb_license_none->setChecked (true);
70 break;
71
72 default:
73 QMessageBox::warning (null, "Warning",
74 fmt ("Unknown ld_defaultlicense value %1!", ld_defaultlicense));
75 break;
76 }
77
78 if (dlg->exec() == false)
79 return;
80
81 newFile();
82
83 const LDBFC::Type BFCType =
84 ui.rb_bfc_ccw->isChecked() ? LDBFC::CertifyCCW :
85 ui.rb_bfc_cw->isChecked() ? LDBFC::CertifyCW : LDBFC::NoCertify;
86
87 const str license =
88 ui.rb_license_ca->isChecked() ? CALicense :
89 ui.rb_license_nonca->isChecked() ? NonCALicense : "";
90
91 getCurrentDocument()->addObjects (
92 { new LDComment (ui.le_title->text()),
93 new LDComment ("Name: <untitled>.dat"),
94 new LDComment (fmt ("Author: %1", ui.le_author->text())),
95 new LDComment (fmt ("!LDRAW_ORG Unofficial_Part")),
96 (license != "" ? new LDComment (license) : null),
97 new LDEmpty,
98 new LDBFC (BFCType),
99 new LDEmpty,
100 });
101
102 g_win->doFullRefresh();
103 }
104
105 // =============================================================================
106 // -----------------------------------------------------------------------------
107 DEFINE_ACTION (NewFile, CTRL (N))
108 { newFile();
109 }
110
111 // =============================================================================
112 // -----------------------------------------------------------------------------
113 DEFINE_ACTION (Open, CTRL (O))
114 { str name = QFileDialog::getOpenFileName (g_win, "Open File", "", "LDraw files (*.dat *.ldr)");
115
116 if (name.length() == 0)
117 return;
118
119 openMainFile (name);
120 }
121
122 // =============================================================================
123 // -----------------------------------------------------------------------------
124 DEFINE_ACTION (Save, CTRL (S))
125 { g_win->save (getCurrentDocument(), false);
126 }
127
128 // =============================================================================
129 // -----------------------------------------------------------------------------
130 DEFINE_ACTION (SaveAs, CTRL_SHIFT (S))
131 { g_win->save (getCurrentDocument(), true);
132 }
133
134 // =============================================================================
135 // -----------------------------------------------------------------------------
136 DEFINE_ACTION (SaveAll, CTRL (L))
137 { for (LDDocument* file : g_loadedFiles)
138 { if (file->isImplicit())
139 continue;
140
141 g_win->save (file, false);
142 }
143 }
144
145 // =============================================================================
146 // -----------------------------------------------------------------------------
147 DEFINE_ACTION (Close, CTRL (W))
148 { if (!getCurrentDocument()->isSafeToClose())
149 return;
150
151 delete getCurrentDocument();
152 }
153
154 // =============================================================================
155 // -----------------------------------------------------------------------------
156 DEFINE_ACTION (CloseAll, 0)
157 { if (!safeToCloseAll())
158 return;
159
160 closeAll();
161 }
162
163 // =============================================================================
164 // -----------------------------------------------------------------------------
165 DEFINE_ACTION (Settings, 0)
166 { (new ConfigDialog)->exec();
167 }
168
169 // =============================================================================
170 // -----------------------------------------------------------------------------
171 DEFINE_ACTION (SetLDrawPath, 0)
172 { (new LDrawPathDialog (true))->exec();
173 }
174
175 // =============================================================================
176 // -----------------------------------------------------------------------------
177 DEFINE_ACTION (Exit, CTRL (Q))
178 { exit (0);
179 }
180
181 // =============================================================================
182 // -----------------------------------------------------------------------------
183 DEFINE_ACTION (NewSubfile, 0)
184 { AddObjectDialog::staticDialog (LDObject::Subfile, null);
185 }
186
187 // =============================================================================
188 // -----------------------------------------------------------------------------
189 DEFINE_ACTION (NewLine, 0)
190 { AddObjectDialog::staticDialog (LDObject::Line, null);
191 }
192
193 // =============================================================================
194 // -----------------------------------------------------------------------------
195 DEFINE_ACTION (NewTriangle, 0)
196 { AddObjectDialog::staticDialog (LDObject::Triangle, null);
197 }
198
199 // =============================================================================
200 // -----------------------------------------------------------------------------
201 DEFINE_ACTION (NewQuad, 0)
202 { AddObjectDialog::staticDialog (LDObject::Quad, null);
203 }
204
205 // =============================================================================
206 // -----------------------------------------------------------------------------
207 DEFINE_ACTION (NewCLine, 0)
208 { AddObjectDialog::staticDialog (LDObject::CondLine, null);
209 }
210
211 // =============================================================================
212 // -----------------------------------------------------------------------------
213 DEFINE_ACTION (NewComment, 0)
214 { AddObjectDialog::staticDialog (LDObject::Comment, null);
215 }
216
217 // =============================================================================
218 // -----------------------------------------------------------------------------
219 DEFINE_ACTION (NewBFC, 0)
220 { AddObjectDialog::staticDialog (LDObject::BFC, null);
221 }
222
223 // =============================================================================
224 // -----------------------------------------------------------------------------
225 DEFINE_ACTION (NewVertex, 0)
226 { AddObjectDialog::staticDialog (LDObject::Vertex, null);
227 }
228
229 // =============================================================================
230 // -----------------------------------------------------------------------------
231 DEFINE_ACTION (Edit, 0)
232 { if (selection().size() != 1)
233 return;
234
235 LDObject* obj = selection() [0];
236 AddObjectDialog::staticDialog (obj->getType(), obj);
237 }
238
239 // =============================================================================
240 // -----------------------------------------------------------------------------
241 DEFINE_ACTION (Help, KEY (F1))
242 {
243 }
244
245 // =============================================================================
246 // -----------------------------------------------------------------------------
247 DEFINE_ACTION (About, 0)
248 { AboutDialog().exec();
249 }
250
251 // =============================================================================
252 // -----------------------------------------------------------------------------
253 DEFINE_ACTION (AboutQt, 0)
254 { QMessageBox::aboutQt (g_win);
255 }
256
257 // =============================================================================
258 // -----------------------------------------------------------------------------
259 DEFINE_ACTION (SelectAll, CTRL (A))
260 { for (LDObject* obj : getCurrentDocument()->getObjects())
261 obj->select();
262
263 g_win->updateSelection();
264 }
265
266 // =============================================================================
267 // -----------------------------------------------------------------------------
268 DEFINE_ACTION (SelectByColor, CTRL_SHIFT (A))
269 { int colnum = g_win->getSelectedColor();
270
271 if (colnum == -1)
272 return; // no consensus on color
273
274 getCurrentDocument()->clearSelection();
275
276 for (LDObject* obj : getCurrentDocument()->getObjects())
277 if (obj->getColor() == colnum)
278 obj->select();
279
280 g_win->updateSelection();
281 }
282
283 // =============================================================================
284 // -----------------------------------------------------------------------------
285 DEFINE_ACTION (SelectByType, 0)
286 { if (selection().isEmpty())
287 return;
288
289 LDObject::Type type = g_win->getUniformSelectedType();
290
291 if (type == LDObject::Unidentified)
292 return;
293
294 // If we're selecting subfile references, the reference filename must also
295 // be uniform.
296 str refName;
297
298 if (type == LDObject::Subfile)
299 { refName = static_cast<LDSubfile*> (selection()[0])->getFileInfo()->getName();
300
301 for (LDObject* obj : selection())
302 if (static_cast<LDSubfile*> (obj)->getFileInfo()->getName() != refName)
303 return;
304 }
305
306 getCurrentDocument()->clearSelection();
307
308 for (LDObject* obj : getCurrentDocument()->getObjects())
309 { if (obj->getType() != type)
310 continue;
311
312 if (type == LDObject::Subfile && static_cast<LDSubfile*> (obj)->getFileInfo()->getName() != refName)
313 continue;
314
315 obj->select();
316 }
317
318 g_win->updateSelection();
319 }
320
321 // =============================================================================
322 // -----------------------------------------------------------------------------
323 DEFINE_ACTION (GridCoarse, 0)
324 { grid = Grid::Coarse;
325 g_win->updateGridToolBar();
326 }
327
328 DEFINE_ACTION (GridMedium, 0)
329 { grid = Grid::Medium;
330 g_win->updateGridToolBar();
331 }
332
333 DEFINE_ACTION (GridFine, 0)
334 { grid = Grid::Fine;
335 g_win->updateGridToolBar();
336 }
337
338 // =============================================================================
339 // -----------------------------------------------------------------------------
340 DEFINE_ACTION (ResetView, CTRL (0))
341 { g_win->R()->resetAngles();
342 g_win->R()->update();
343 }
344
345 // =============================================================================
346 // -----------------------------------------------------------------------------
347 DEFINE_ACTION (InsertFrom, 0)
348 { str fname = QFileDialog::getOpenFileName();
349 int idx = g_win->getInsertionPoint();
350
351 if (!fname.length())
352 return;
353
354 File f (fname, File::Read);
355
356 if (!f)
357 { critical (fmt ("Couldn't open %1 (%2)", fname, strerror (errno)));
358 return;
359 }
360
361 QList<LDObject*> objs = loadFileContents (&f, null);
362
363 getCurrentDocument()->clearSelection();
364
365 for (LDObject* obj : objs)
366 { getCurrentDocument()->insertObj (idx, obj);
367 obj->select();
368 g_win->R()->compileObject (obj);
369
370 idx++;
371 }
372
373 g_win->refresh();
374 g_win->scrollToSelection();
375 }
376
377 // =============================================================================
378 // -----------------------------------------------------------------------------
379 DEFINE_ACTION (ExportTo, 0)
380 { if (selection().isEmpty())
381 return;
382
383 str fname = QFileDialog::getSaveFileName();
384
385 if (fname.length() == 0)
386 return;
387
388 QFile file (fname);
389
390 if (!file.open (QIODevice::WriteOnly | QIODevice::Text))
391 { critical (fmt ("Unable to open %1 for writing (%2)", fname, strerror (errno)));
392 return;
393 }
394
395 for (LDObject* obj : selection())
396 { str contents = obj->raw();
397 QByteArray data = contents.toUtf8();
398 file.write (data, data.size());
399 file.write ("\r\n", 2);
400 }
401 }
402
403 // =============================================================================
404 // -----------------------------------------------------------------------------
405 DEFINE_ACTION (InsertRaw, 0)
406 { int idx = g_win->getInsertionPoint();
407
408 QDialog* const dlg = new QDialog;
409 QVBoxLayout* const layout = new QVBoxLayout;
410 QTextEdit* const te_edit = new QTextEdit;
411 QDialogButtonBox* const bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
412
413 layout->addWidget (te_edit);
414 layout->addWidget (bbx_buttons);
415 dlg->setLayout (layout);
416 dlg->setWindowTitle (APPNAME ": Insert Raw");
417 dlg->connect (bbx_buttons, SIGNAL (accepted()), dlg, SLOT (accept()));
418 dlg->connect (bbx_buttons, SIGNAL (rejected()), dlg, SLOT (reject()));
419
420 if (dlg->exec() == false)
421 return;
422
423 getCurrentDocument()->clearSelection();
424
425 for (str line : str (te_edit->toPlainText()).split ("\n"))
426 { LDObject* obj = parseLine (line);
427
428 getCurrentDocument()->insertObj (idx, obj);
429 obj->select();
430 g_win->R()->compileObject (obj);
431 idx++;
432 }
433
434 g_win->refresh();
435 g_win->scrollToSelection();
436 }
437
438 // =============================================================================
439 // -----------------------------------------------------------------------------
440 DEFINE_ACTION (Screenshot, 0)
441 { setlocale (LC_ALL, "C");
442
443 int w, h;
444 uchar* imgdata = g_win->R()->getScreencap (w, h);
445 QImage img = imageFromScreencap (imgdata, w, h);
446
447 str root = basename (getCurrentDocument()->getName());
448
449 if (root.right (4) == ".dat")
450 root.chop (4);
451
452 str defaultname = (root.length() > 0) ? fmt ("%1.png", root) : "";
453 str fname = QFileDialog::getSaveFileName (g_win, "Save Screencap", defaultname,
454 "PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;All Files (*.*)");
455
456 if (fname.length() > 0 && !img.save (fname))
457 critical (fmt ("Couldn't open %1 for writing to save screencap: %2", fname, strerror (errno)));
458
459 delete[] imgdata;
460 }
461
462 // =============================================================================
463 // -----------------------------------------------------------------------------
464 extern_cfg (Bool, gl_axes);
465 DEFINE_ACTION (Axes, 0)
466 { gl_axes = !gl_axes;
467 g_win->updateActions();
468 g_win->R()->update();
469 }
470
471 // =============================================================================
472 // -----------------------------------------------------------------------------
473 DEFINE_ACTION (VisibilityToggle, 0)
474 { for (LDObject* obj : selection())
475 obj->toggleHidden();
476
477 g_win->refresh();
478 }
479
480 // =============================================================================
481 // -----------------------------------------------------------------------------
482 DEFINE_ACTION (VisibilityHide, 0)
483 { for (LDObject* obj : selection())
484 obj->setHidden (true);
485
486 g_win->refresh();
487 }
488
489 // =============================================================================
490 // -----------------------------------------------------------------------------
491 DEFINE_ACTION (VisibilityReveal, 0)
492 { for (LDObject* obj : selection())
493 obj->setHidden (false);
494
495 g_win->refresh();
496 }
497
498 // =============================================================================
499 // -----------------------------------------------------------------------------
500 DEFINE_ACTION (Wireframe, 0)
501 { gl_wireframe = !gl_wireframe;
502 g_win->R()->refresh();
503 }
504
505 // =============================================================================
506 // -----------------------------------------------------------------------------
507 DEFINE_ACTION (SetOverlay, 0)
508 { OverlayDialog dlg;
509
510 if (!dlg.exec())
511 return;
512
513 g_win->R()->setupOverlay ((GL::EFixedCamera) dlg.camera(), dlg.fpath(), dlg.ofsx(),
514 dlg.ofsy(), dlg.lwidth(), dlg.lheight());
515 }
516
517 // =============================================================================
518 // -----------------------------------------------------------------------------
519 DEFINE_ACTION (ClearOverlay, 0)
520 { g_win->R()->clearOverlay();
521 }
522
523 // =============================================================================
524 // -----------------------------------------------------------------------------
525 DEFINE_ACTION (ModeSelect, CTRL (1))
526 { g_win->R()->setEditMode (ESelectMode);
527 }
528
529 // =============================================================================
530 // -----------------------------------------------------------------------------
531 DEFINE_ACTION (ModeDraw, CTRL (2))
532 { g_win->R()->setEditMode (EDrawMode);
533 }
534
535 // =============================================================================
536 // -----------------------------------------------------------------------------
537 DEFINE_ACTION (ModeCircle, CTRL (3))
538 { g_win->R()->setEditMode (ECircleMode);
539 }
540
541 // =============================================================================
542 // -----------------------------------------------------------------------------
543 DEFINE_ACTION (SetDrawDepth, 0)
544 { if (g_win->R()->camera() == GL::EFreeCamera)
545 return;
546
547 bool ok;
548 double depth = QInputDialog::getDouble (g_win, "Set Draw Depth",
549 fmt ("Depth value for %1 Camera:", g_win->R()->getCameraName()),
550 g_win->R()->getDepthValue(), -10000.0f, 10000.0f, 3, &ok);
551
552 if (ok)
553 g_win->R()->setDepthValue (depth);
554 }
555
556 #if 0
557 // This is a test to draw a dummy axle. Meant to be used as a primitive gallery,
558 // but I can't figure how to generate these pictures properly. Multi-threading
559 // these is an immense pain.
560 DEFINE_ACTION (testpic, "Test picture", "", "", (0))
561 { LDDocument* file = getFile ("axle.dat");
562 setlocale (LC_ALL, "C");
563
564 if (!file)
565 { critical ("couldn't load axle.dat");
566 return;
567 }
568
569 int w, h;
570
571 GLRenderer* rend = new GLRenderer;
572 rend->resize (64, 64);
573 rend->setAttribute (Qt::WA_DontShowOnScreen);
574 rend->show();
575 rend->setFile (file);
576 rend->setDrawOnly (true);
577 rend->compileAllObjects();
578 rend->initGLData();
579 rend->drawGLScene();
580
581 uchar* imgdata = rend->screencap (w, h);
582 QImage img = imageFromScreencap (imgdata, w, h);
583
584 if (img.isNull())
585 { critical ("Failed to create the image!\n");
586 }
587 else
588 { QLabel* label = new QLabel;
589 QDialog* dlg = new QDialog;
590 label->setPixmap (QPixmap::fromImage (img));
591 QVBoxLayout* layout = new QVBoxLayout (dlg);
592 layout->addWidget (label);
593 dlg->exec();
594 }
595
596 delete[] imgdata;
597 rend->deleteLater();
598 }
599 #endif
600
601 // =============================================================================
602 // -----------------------------------------------------------------------------
603 DEFINE_ACTION (ScanPrimitives, 0)
604 { PrimitiveLister::start();
605 }
606
607 // =============================================================================
608 // -----------------------------------------------------------------------------
609 DEFINE_ACTION (BFCView, SHIFT (B))
610 { gl_colorbfc = !gl_colorbfc;
611 g_win->updateActions();
612 g_win->R()->refresh();
613 }
614
615 // =============================================================================
616 // -----------------------------------------------------------------------------
617 DEFINE_ACTION (JumpTo, CTRL (G))
618 { bool ok;
619 int defval = 0;
620 LDObject* obj;
621
622 if (selection().size() == 1)
623 defval = selection()[0]->getIndex();
624
625 int idx = QInputDialog::getInt (null, "Go to line", "Go to line:", defval,
626 1, getCurrentDocument()->getObjectCount(), 1, &ok);
627
628 if (!ok || (obj = getCurrentDocument()->getObject (idx - 1)) == null)
629 return;
630
631 getCurrentDocument()->clearSelection();
632 obj->select();
633 g_win->updateSelection();
634 }

mercurial