1 #include "lc_global.h"
2 #include "lc_mainwindow.h"
3 #include <QPrintDialog>
4 #include <QPrintPreviewDialog>
5 #include "lc_partselectionwidget.h"
6 #include "lc_timelinewidget.h"
7 #include "lc_viewwidget.h"
8 #include "lc_qcolorlist.h"
9 #include "lc_qpropertiestree.h"
10 #include "lc_qutils.h"
11 #include "lc_qupdatedialog.h"
12 #include "lc_qaboutdialog.h"
13 #include "lc_setsdatabasedialog.h"
14 #include "lc_qhtmldialog.h"
15 #include "lc_renderdialog.h"
16 #include "lc_instructionsdialog.h"
17 #include "lc_profile.h"
18 #include "lc_view.h"
19 #include "project.h"
20 #include "piece.h"
21 #include "camera.h"
22 #include "group.h"
23 #include "pieceinf.h"
24 #include "lc_library.h"
25 #include "lc_colors.h"
26 #include "lc_previewwidget.h"
27
28 #if LC_ENABLE_GAMEPAD
29 #include <QtGamepad/QGamepad>
30 #endif
31
32 lcMainWindow* gMainWindow;
33 #define LC_TAB_LAYOUT_VERSION 0x0001
34
mousePressEvent(QMouseEvent * Event)35 void lcTabBar::mousePressEvent(QMouseEvent* Event)
36 {
37 if (Event->button() == Qt::MiddleButton)
38 mMousePressTab = tabAt(Event->pos());
39 else
40 QTabBar::mousePressEvent(Event);
41 }
42
mouseReleaseEvent(QMouseEvent * Event)43 void lcTabBar::mouseReleaseEvent(QMouseEvent* Event)
44 {
45 if (Event->button() == Qt::MiddleButton && tabAt(Event->pos()) == mMousePressTab)
46 tabCloseRequested(mMousePressTab);
47 else
48 QTabBar::mouseReleaseEvent(Event);
49 }
50
lcMainWindow()51 lcMainWindow::lcMainWindow()
52 {
53 memset(mActions, 0, sizeof(mActions));
54
55 mTransformType = lcTransformType::RelativeTranslation;
56
57 mColorIndex = lcGetColorIndex(7);
58 mTool = lcTool::Select;
59 mAddKeys = false;
60 mMoveSnapEnabled = true;
61 mAngleSnapEnabled = true;
62 mMoveXYSnapIndex = 4;
63 mMoveZSnapIndex = 3;
64 mAngleSnapIndex = 5;
65 mRelativeTransform = true;
66 mLocalTransform = false;
67 mCurrentPieceInfo = nullptr;
68 mSelectionMode = lcSelectionMode::Single;
69 mModelTabWidget = nullptr;
70 mPreviewToolBar = nullptr;
71 mPreviewWidget = nullptr;
72
73 for (int FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++)
74 mRecentFiles[FileIdx] = lcGetProfileString((LC_PROFILE_KEY)(LC_PROFILE_RECENT_FILE1 + FileIdx));
75
76 #if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
77 connect(&mGamepadTimer, &QTimer::timeout, this, &lcMainWindow::UpdateGamepads);
78 mLastGamepadUpdate = QDateTime::currentDateTime();
79 mGamepadTimer.start(33);
80 #endif
81
82 gMainWindow = this;
83 }
84
~lcMainWindow()85 lcMainWindow::~lcMainWindow()
86 {
87 if (mCurrentPieceInfo)
88 {
89 lcPiecesLibrary* Library = lcGetPiecesLibrary();
90 Library->ReleasePieceInfo(mCurrentPieceInfo);
91 mCurrentPieceInfo = nullptr;
92 }
93
94 for (int FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++)
95 lcSetProfileString((LC_PROFILE_KEY)(LC_PROFILE_RECENT_FILE1 + FileIdx), mRecentFiles[FileIdx]);
96
97 gMainWindow = nullptr;
98 }
99
CreateWidgets()100 void lcMainWindow::CreateWidgets()
101 {
102 setAcceptDrops(true);
103 setWindowIcon(QIcon(":/resources/leocad.png"));
104 setWindowFilePath(QString());
105
106 CreateActions();
107 CreateToolBars();
108 CreateMenus();
109 CreateStatusBar();
110
111 mModelTabWidget = new QTabWidget();
112 mModelTabWidget->tabBar()->setMovable(true);
113 mModelTabWidget->tabBar()->setTabsClosable(true);
114 mModelTabWidget->tabBar()->setContextMenuPolicy(Qt::CustomContextMenu);
115 setCentralWidget(mModelTabWidget);
116
117 connect(mModelTabWidget->tabBar(), SIGNAL(tabCloseRequested(int)), this, SLOT(ModelTabClosed(int)));
118 connect(mModelTabWidget->tabBar(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ModelTabContextMenuRequested(const QPoint&)));
119 connect(mModelTabWidget, SIGNAL(currentChanged(int)), this, SLOT(ModelTabChanged(int)));
120
121 connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(ClipboardChanged()));
122 ClipboardChanged();
123
124 QSettings Settings;
125 Settings.beginGroup("MainWindow");
126 resize(QSize(800, 600));
127 move(QPoint(200, 200));
128 restoreGeometry(Settings.value("Geometry").toByteArray());
129 restoreState(Settings.value("State").toByteArray());
130 mPartSelectionWidget->LoadState(Settings);
131 Settings.endGroup();
132 }
133
CreateActions()134 void lcMainWindow::CreateActions()
135 {
136 for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++)
137 {
138 QAction* Action = new QAction(qApp->translate("Menu", gCommands[CommandIdx].MenuName), this);
139 Action->setStatusTip(qApp->translate("Status", gCommands[CommandIdx].StatusText));
140 connect(Action, SIGNAL(triggered()), this, SLOT(ActionTriggered()));
141 addAction(Action);
142 mActions[CommandIdx] = Action;
143 }
144
145 mActions[LC_FILE_NEW]->setToolTip(tr("New Model"));
146 mActions[LC_FILE_OPEN]->setToolTip(tr("Open Model"));
147 mActions[LC_FILE_SAVE]->setToolTip(tr("Save Model"));
148
149 QIcon FileNewIcon;
150 FileNewIcon.addFile(":/resources/file_new.png");
151 FileNewIcon.addFile(":/resources/file_new_16.png");
152 mActions[LC_FILE_NEW]->setIcon(FileNewIcon);
153
154 QIcon FileSaveIcon;
155 FileSaveIcon.addFile(":/resources/file_save.png");
156 FileSaveIcon.addFile(":/resources/file_save_16.png");
157 mActions[LC_FILE_SAVE]->setIcon(FileSaveIcon);
158
159 QIcon FileOpenIcon;
160 FileOpenIcon.addFile(":/resources/file_open.png");
161 FileOpenIcon.addFile(":/resources/file_open_16.png");
162 mActions[LC_FILE_OPEN]->setIcon(FileOpenIcon);
163
164 QIcon FilePrintIcon;
165 FilePrintIcon.addFile(":/resources/file_print.png");
166 FilePrintIcon.addFile(":/resources/file_print_16.png");
167 mActions[LC_FILE_PRINT]->setIcon(FilePrintIcon);
168
169 QIcon FilePrintPreviewIcon;
170 FilePrintPreviewIcon.addFile(":/resources/file_print_preview.png");
171 FilePrintPreviewIcon.addFile(":/resources/file_print_preview_16.png");
172 mActions[LC_FILE_PRINT_PREVIEW]->setIcon(FilePrintPreviewIcon);
173
174 QIcon EditUndoIcon;
175 EditUndoIcon.addFile(":/resources/edit_undo.png");
176 EditUndoIcon.addFile(":/resources/edit_undo_16.png");
177 mActions[LC_EDIT_UNDO]->setIcon(EditUndoIcon);
178
179 QIcon EditRedoIcon;
180 EditRedoIcon.addFile(":/resources/edit_redo.png");
181 EditRedoIcon.addFile(":/resources/edit_redo_16.png");
182 mActions[LC_EDIT_REDO]->setIcon(EditRedoIcon);
183
184 QIcon EditCutIcon;
185 EditCutIcon.addFile(":/resources/edit_cut.png");
186 EditCutIcon.addFile(":/resources/edit_cut_16.png");
187 mActions[LC_EDIT_CUT]->setIcon(EditCutIcon);
188
189 QIcon EditCopyIcon;
190 EditCopyIcon.addFile(":/resources/edit_copy.png");
191 EditCopyIcon.addFile(":/resources/edit_copy_16.png");
192 mActions[LC_EDIT_COPY]->setIcon(EditCopyIcon);
193
194 QIcon EditPasteIcon;
195 EditPasteIcon.addFile(":/resources/edit_paste.png");
196 EditPasteIcon.addFile(":/resources/edit_paste_16.png");
197 mActions[LC_EDIT_PASTE]->setIcon(EditPasteIcon);
198
199 QIcon EditActionInsertIcon;
200 EditActionInsertIcon.addFile(":/resources/action_insert.png");
201 EditActionInsertIcon.addFile(":/resources/action_insert_16.png");
202 mActions[LC_EDIT_ACTION_INSERT]->setIcon(EditActionInsertIcon);
203
204 QIcon EditActionLightIcon;
205 EditActionLightIcon.addFile(":/resources/action_light.png");
206 EditActionLightIcon.addFile(":/resources/action_light_16.png");
207 mActions[LC_EDIT_ACTION_LIGHT]->setIcon(EditActionLightIcon);
208
209 QIcon EditActionSpotLightIcon;
210 EditActionSpotLightIcon.addFile(":/resources/action_spotlight.png");
211 EditActionSpotLightIcon.addFile(":/resources/action_spotlight_16.png");
212 mActions[LC_EDIT_ACTION_SPOTLIGHT]->setIcon(EditActionSpotLightIcon);
213
214 QIcon EditActionSelectIcon;
215 EditActionSelectIcon.addFile(":/resources/action_select.png");
216 EditActionSelectIcon.addFile(":/resources/action_select_16.png");
217 mActions[LC_EDIT_ACTION_SELECT]->setIcon(EditActionSelectIcon);
218
219 QIcon EditActionMoveIcon;
220 EditActionMoveIcon.addFile(":/resources/action_move.png");
221 EditActionMoveIcon.addFile(":/resources/action_move_16.png");
222 mActions[LC_EDIT_ACTION_MOVE]->setIcon(EditActionMoveIcon);
223
224 QIcon EditActionRotateIcon;
225 EditActionRotateIcon.addFile(":/resources/action_rotate.png");
226 EditActionRotateIcon.addFile(":/resources/action_rotate_16.png");
227 mActions[LC_EDIT_ACTION_ROTATE]->setIcon(EditActionRotateIcon);
228
229 QIcon EditActionDeleteIcon;
230 EditActionDeleteIcon.addFile(":/resources/action_delete.png");
231 EditActionDeleteIcon.addFile(":/resources/action_delete_16.png");
232 mActions[LC_EDIT_ACTION_DELETE]->setIcon(EditActionDeleteIcon);
233
234 QIcon EditActionPaintIcon;
235 EditActionPaintIcon.addFile(":/resources/action_paint.png");
236 EditActionPaintIcon.addFile(":/resources/action_paint_16.png");
237 mActions[LC_EDIT_ACTION_PAINT]->setIcon(EditActionPaintIcon);
238
239 QIcon EditActionColorPickerIcon;
240 EditActionColorPickerIcon.addFile(":/resources/action_color_picker.png");
241 EditActionColorPickerIcon.addFile(":/resources/action_color_picker_16.png");
242 mActions[LC_EDIT_ACTION_COLOR_PICKER]->setIcon(EditActionColorPickerIcon);
243
244 QIcon EditActionZoomIcon;
245 EditActionZoomIcon.addFile(":/resources/action_zoom.png");
246 EditActionZoomIcon.addFile(":/resources/action_zoom_16.png");
247 mActions[LC_EDIT_ACTION_ZOOM]->setIcon(EditActionZoomIcon);
248
249 QIcon EditActionPanIcon;
250 EditActionPanIcon.addFile(":/resources/action_pan.png");
251 EditActionPanIcon.addFile(":/resources/action_pan_16.png");
252 mActions[LC_EDIT_ACTION_PAN]->setIcon(EditActionPanIcon);
253
254 mActions[LC_EDIT_ACTION_CAMERA]->setIcon(QIcon(":/resources/action_camera.png"));
255 mActions[LC_EDIT_ACTION_ROTATE_VIEW]->setIcon(QIcon(":/resources/action_rotate_view.png"));
256 mActions[LC_EDIT_ACTION_ROLL]->setIcon(QIcon(":/resources/action_roll.png"));
257 mActions[LC_EDIT_ACTION_ZOOM_REGION]->setIcon(QIcon(":/resources/action_zoom_region.png"));
258 mActions[LC_EDIT_FIND]->setIcon(QIcon(":/resources/edit_find.png"));
259 mActions[LC_EDIT_FIND_NEXT]->setIcon(QIcon(":/resources/edit_find_next.png"));
260 mActions[LC_EDIT_FIND_PREVIOUS]->setIcon(QIcon(":/resources/edit_find_previous.png"));
261 mActions[LC_EDIT_FIND_ALL]->setIcon(QIcon(":/resources/edit_find_all.png"));
262 mActions[LC_EDIT_REPLACE_NEXT]->setIcon(QIcon(":/resources/edit_replace_next.png"));
263 mActions[LC_EDIT_REPLACE_ALL]->setIcon(QIcon(":/resources/edit_replace_all.png"));
264 mActions[LC_PIECE_SHOW_EARLIER]->setIcon(QIcon(":/resources/piece_show_earlier.png"));
265 mActions[LC_PIECE_SHOW_LATER]->setIcon(QIcon(":/resources/piece_show_later.png"));
266 mActions[LC_VIEW_SPLIT_HORIZONTAL]->setIcon(QIcon(":/resources/view_split_horizontal.png"));
267 mActions[LC_VIEW_SPLIT_VERTICAL]->setIcon(QIcon(":/resources/view_split_vertical.png"));
268 mActions[LC_VIEW_ZOOM_IN]->setIcon(QIcon(":/resources/view_zoomin.png"));
269 mActions[LC_VIEW_ZOOM_OUT]->setIcon(QIcon(":/resources/view_zoomout.png"));
270 mActions[LC_VIEW_ZOOM_EXTENTS]->setIcon(QIcon(":/resources/view_zoomextents.png"));
271 mActions[LC_VIEW_TIME_FIRST]->setIcon(QIcon(":/resources/time_first.png"));
272 mActions[LC_VIEW_TIME_PREVIOUS]->setIcon(QIcon(":/resources/time_previous.png"));
273 mActions[LC_VIEW_TIME_NEXT]->setIcon(QIcon(":/resources/time_next.png"));
274 mActions[LC_VIEW_TIME_LAST]->setIcon(QIcon(":/resources/time_last.png"));
275 mActions[LC_VIEW_TIME_ADD_KEYS]->setIcon(QIcon(":/resources/time_add_keys.png"));
276 mActions[LC_HELP_HOMEPAGE]->setIcon(QIcon(":/resources/help_homepage.png"));
277
278 mActions[LC_EDIT_SNAP_MOVE_TOGGLE]->setCheckable(true);
279 mActions[LC_EDIT_SNAP_ANGLE_TOGGLE]->setCheckable(true);
280 mActions[LC_VIEW_CAMERA_NONE]->setCheckable(true);
281 mActions[LC_VIEW_TIME_ADD_KEYS]->setCheckable(true);
282
283 for (int ActionIndex = LC_VIEW_TOOLBAR_FIRST; ActionIndex <= LC_VIEW_TOOLBAR_LAST; ActionIndex++)
284 mActions[ActionIndex]->setCheckable(true);
285
286 QActionGroup* ActionRelativeGroup = new QActionGroup(this);
287 for (int ActionIdx = LC_EDIT_TRANSFORM_RELATIVE; ActionIdx <= LC_EDIT_TRANSFORM_ABSOLUTE; ActionIdx++)
288 {
289 mActions[ActionIdx]->setCheckable(true);
290 ActionRelativeGroup->addAction(mActions[ActionIdx]);
291 }
292
293 QActionGroup* ActionSeparateGroup = new QActionGroup(this);
294 for (int ActionIdx = LC_EDIT_TRANSFORM_SEPARATELY; ActionIdx <= LC_EDIT_TRANSFORM_TOGETHER; ActionIdx++)
295 {
296 mActions[ActionIdx]->setCheckable(true);
297 ActionSeparateGroup->addAction(mActions[ActionIdx]);
298 }
299
300 QActionGroup* ActionSnapXYGroup = new QActionGroup(this);
301 for (int ActionIdx = LC_EDIT_SNAP_MOVE_XY0; ActionIdx <= LC_EDIT_SNAP_MOVE_XY9; ActionIdx++)
302 {
303 mActions[ActionIdx]->setCheckable(true);
304 ActionSnapXYGroup->addAction(mActions[ActionIdx]);
305 }
306
307 QActionGroup* ActionSnapZGroup = new QActionGroup(this);
308 for (int ActionIdx = LC_EDIT_SNAP_MOVE_Z0; ActionIdx <= LC_EDIT_SNAP_MOVE_Z9; ActionIdx++)
309 {
310 mActions[ActionIdx]->setCheckable(true);
311 ActionSnapZGroup->addAction(mActions[ActionIdx]);
312 }
313
314 QActionGroup* ActionSnapAngleGroup = new QActionGroup(this);
315 for (int ActionIdx = LC_EDIT_SNAP_ANGLE0; ActionIdx <= LC_EDIT_SNAP_ANGLE9; ActionIdx++)
316 {
317 mActions[ActionIdx]->setCheckable(true);
318 ActionSnapAngleGroup->addAction(mActions[ActionIdx]);
319 }
320
321 QActionGroup* ActionTransformTypeGroup = new QActionGroup(this);
322 for (int ActionIdx = LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION; ActionIdx <= LC_EDIT_TRANSFORM_RELATIVE_ROTATION; ActionIdx++)
323 {
324 mActions[ActionIdx]->setCheckable(true);
325 ActionTransformTypeGroup->addAction(mActions[ActionIdx]);
326 }
327
328 QActionGroup* ActionToolGroup = new QActionGroup(this);
329 for (int ActionIdx = LC_EDIT_ACTION_FIRST; ActionIdx <= LC_EDIT_ACTION_LAST; ActionIdx++)
330 {
331 mActions[ActionIdx]->setCheckable(true);
332 ActionToolGroup->addAction(mActions[ActionIdx]);
333 }
334
335 QActionGroup* ActionCameraGroup = new QActionGroup(this);
336 ActionCameraGroup->addAction(mActions[LC_VIEW_CAMERA_NONE]);
337 for (int ActionIdx = LC_VIEW_CAMERA_FIRST; ActionIdx <= LC_VIEW_CAMERA_LAST; ActionIdx++)
338 {
339 mActions[ActionIdx]->setCheckable(true);
340 ActionCameraGroup->addAction(mActions[ActionIdx]);
341 }
342
343 QActionGroup* ActionPerspectiveGroup = new QActionGroup(this);
344 for (int ActionIdx = LC_VIEW_PROJECTION_FIRST; ActionIdx <= LC_VIEW_PROJECTION_LAST; ActionIdx++)
345 {
346 mActions[ActionIdx]->setCheckable(true);
347 ActionPerspectiveGroup->addAction(mActions[ActionIdx]);
348 }
349
350 QActionGroup* ActionShadingGroup = new QActionGroup(this);
351 for (int ActionIdx = LC_VIEW_SHADING_FIRST; ActionIdx <= LC_VIEW_SHADING_LAST; ActionIdx++)
352 {
353 mActions[ActionIdx]->setCheckable(true);
354 ActionShadingGroup->addAction(mActions[ActionIdx]);
355 }
356
357 QActionGroup* SelectionModeGroup = new QActionGroup(this);
358 for (int ActionIdx = LC_EDIT_SELECTION_MODE_FIRST; ActionIdx <= LC_EDIT_SELECTION_MODE_LAST; ActionIdx++)
359 {
360 mActions[ActionIdx]->setCheckable(true);
361 SelectionModeGroup->addAction(mActions[ActionIdx]);
362 }
363
364 QActionGroup* ModelGroup = new QActionGroup(this);
365 for (int ActionIdx = LC_MODEL_FIRST; ActionIdx <= LC_MODEL_LAST; ActionIdx++)
366 {
367 mActions[ActionIdx]->setCheckable(true);
368 ModelGroup->addAction(mActions[ActionIdx]);
369 }
370
371 UpdateShortcuts();
372 }
373
CreateMenus()374 void lcMainWindow::CreateMenus()
375 {
376 QMenu* TransformMenu = new QMenu(tr("Transform"), this);
377 TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION]);
378 TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION]);
379 TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_RELATIVE_ROTATION]);
380 TransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION]);
381 mActions[LC_EDIT_TRANSFORM]->setMenu(TransformMenu);
382
383 mCameraMenu = new QMenu(tr("C&ameras"), this);
384 mCameraMenu->addAction(mActions[LC_VIEW_CAMERA_NONE]);
385
386 for (int actionIdx = LC_VIEW_CAMERA_FIRST; actionIdx <= LC_VIEW_CAMERA_LAST; actionIdx++)
387 mCameraMenu->addAction(mActions[actionIdx]);
388
389 mViewpointMenu = new QMenu(tr("&Viewpoints"), this);
390 mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_FRONT]);
391 mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_BACK]);
392 mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_LEFT]);
393 mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_RIGHT]);
394 mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_TOP]);
395 mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_BOTTOM]);
396 mViewpointMenu->addAction(mActions[LC_VIEW_VIEWPOINT_HOME]);
397
398 mProjectionMenu = new QMenu(tr("Projection"), this);
399 mProjectionMenu->addAction(mActions[LC_VIEW_PROJECTION_PERSPECTIVE]);
400 mProjectionMenu->addAction(mActions[LC_VIEW_PROJECTION_ORTHO]);
401
402 mShadingMenu = new QMenu(tr("Sh&ading"), this);
403 mShadingMenu->addAction(mActions[LC_VIEW_SHADING_WIREFRAME]);
404 mShadingMenu->addAction(mActions[LC_VIEW_SHADING_FLAT]);
405 mShadingMenu->addAction(mActions[LC_VIEW_SHADING_DEFAULT_LIGHTS]);
406
407 mToolsMenu = new QMenu(tr("Tools"), this);
408 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_INSERT]);
409 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_LIGHT]);
410 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]);
411 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
412 mToolsMenu->addSeparator();
413 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SELECT]);
414 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_MOVE]);
415 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ROTATE]);
416 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_DELETE]);
417 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_PAINT]);
418 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_COLOR_PICKER]);
419 mToolsMenu->addSeparator();
420 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ZOOM]);
421 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_PAN]);
422 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ROTATE_VIEW]);
423 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ROLL]);
424 mToolsMenu->addAction(mActions[LC_EDIT_ACTION_ZOOM_REGION]);
425
426 QMenu* FileMenu = menuBar()->addMenu(tr("&File"));
427 FileMenu->addAction(mActions[LC_FILE_NEW]);
428 FileMenu->addAction(mActions[LC_FILE_OPEN]);
429 FileMenu->addAction(mActions[LC_FILE_MERGE]);
430 FileMenu->addSeparator();
431 FileMenu->addAction(mActions[LC_FILE_SAVE]);
432 FileMenu->addAction(mActions[LC_FILE_SAVEAS]);
433 FileMenu->addAction(mActions[LC_FILE_SAVE_IMAGE]);
434 QMenu* ImportMenu = FileMenu->addMenu(tr("&Import"));
435 ImportMenu->addAction(mActions[LC_FILE_IMPORT_LDD]);
436 ImportMenu->addAction(mActions[LC_FILE_IMPORT_INVENTORY]);
437 QMenu* ExportMenu = FileMenu->addMenu(tr("&Export"));
438 ExportMenu->addAction(mActions[LC_FILE_EXPORT_3DS]);
439 ExportMenu->addAction(mActions[LC_FILE_EXPORT_BRICKLINK]);
440 ExportMenu->addAction(mActions[LC_FILE_EXPORT_COLLADA]);
441 ExportMenu->addAction(mActions[LC_FILE_EXPORT_CSV]);
442 ExportMenu->addAction(mActions[LC_FILE_EXPORT_HTML]);
443 ExportMenu->addAction(mActions[LC_FILE_EXPORT_POVRAY]);
444 ExportMenu->addAction(mActions[LC_FILE_EXPORT_WAVEFRONT]);
445 FileMenu->addSeparator();
446 FileMenu->addAction(mActions[LC_FILE_RENDER]);
447 FileMenu->addAction(mActions[LC_FILE_INSTRUCTIONS]);
448 FileMenu->addAction(mActions[LC_FILE_PRINT]);
449 FileMenu->addAction(mActions[LC_FILE_PRINT_PREVIEW]);
450 FileMenu->addSeparator();
451 FileMenu->addAction(mActions[LC_FILE_RECENT1]);
452 FileMenu->addAction(mActions[LC_FILE_RECENT2]);
453 FileMenu->addAction(mActions[LC_FILE_RECENT3]);
454 FileMenu->addAction(mActions[LC_FILE_RECENT4]);
455 mActionFileRecentSeparator = FileMenu->addSeparator();
456 FileMenu->addAction(mActions[LC_FILE_EXIT]);
457
458 QMenu* EditMenu = menuBar()->addMenu(tr("&Edit"));
459 EditMenu->addAction(mActions[LC_EDIT_UNDO]);
460 EditMenu->addAction(mActions[LC_EDIT_REDO]);
461 EditMenu->addSeparator();
462 EditMenu->addAction(mActions[LC_EDIT_CUT]);
463 EditMenu->addAction(mActions[LC_EDIT_COPY]);
464 EditMenu->addAction(mActions[LC_EDIT_PASTE]);
465 EditMenu->addAction(mActions[LC_EDIT_PASTE_STEPS]);
466 EditMenu->addSeparator();
467 EditMenu->addAction(mActions[LC_EDIT_FIND]);
468 EditMenu->addAction(mActions[LC_EDIT_FIND_NEXT]);
469 EditMenu->addAction(mActions[LC_EDIT_FIND_PREVIOUS]);
470 EditMenu->addAction(mActions[LC_EDIT_REPLACE]);
471 EditMenu->addAction(mActions[LC_EDIT_REPLACE_NEXT]);
472 EditMenu->addSeparator();
473 EditMenu->addAction(mActions[LC_EDIT_SELECT_ALL]);
474 EditMenu->addAction(mActions[LC_EDIT_SELECT_NONE]);
475 EditMenu->addAction(mActions[LC_EDIT_SELECT_INVERT]);
476 EditMenu->addAction(mActions[LC_EDIT_SELECT_BY_NAME]);
477 EditMenu->addMenu(mSelectionModeMenu);
478 EditMenu->addSeparator();
479 EditMenu->addMenu(mTransformMenu);
480 EditMenu->addMenu(mToolsMenu);
481
482 QMenu* ViewMenu = menuBar()->addMenu(tr("&View"));
483 ViewMenu->addAction(mActions[LC_VIEW_PREFERENCES]);
484 ViewMenu->addSeparator();
485 ViewMenu->addAction(mActions[LC_VIEW_ZOOM_EXTENTS]);
486 ViewMenu->addAction(mActions[LC_VIEW_LOOK_AT]);
487 ViewMenu->addMenu(mViewpointMenu);
488 ViewMenu->addMenu(mCameraMenu);
489 ViewMenu->addMenu(mProjectionMenu);
490 ViewMenu->addMenu(mShadingMenu);
491 QMenu* StepMenu = ViewMenu->addMenu(tr("Ste&p"));
492 StepMenu->addAction(mActions[LC_VIEW_TIME_FIRST]);
493 StepMenu->addAction(mActions[LC_VIEW_TIME_PREVIOUS]);
494 StepMenu->addAction(mActions[LC_VIEW_TIME_NEXT]);
495 StepMenu->addAction(mActions[LC_VIEW_TIME_LAST]);
496 StepMenu->addSeparator();
497 StepMenu->addAction(mActions[LC_VIEW_TIME_INSERT_BEFORE]);
498 StepMenu->addAction(mActions[LC_VIEW_TIME_INSERT_AFTER]);
499 StepMenu->addAction(mActions[LC_VIEW_TIME_DELETE]);
500 ViewMenu->addSeparator();
501 ViewMenu->addAction(mActions[LC_VIEW_SPLIT_HORIZONTAL]);
502 ViewMenu->addAction(mActions[LC_VIEW_SPLIT_VERTICAL]);
503 ViewMenu->addAction(mActions[LC_VIEW_REMOVE_VIEW]);
504 ViewMenu->addAction(mActions[LC_VIEW_RESET_VIEWS]);
505 ViewMenu->addSeparator();
506 QMenu* ToolBarsMenu = ViewMenu->addMenu(tr("T&oolbars"));
507 connect(ToolBarsMenu, SIGNAL(aboutToShow()), this, SLOT(UpdateDockWidgetActions()));
508 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_PARTS]);
509 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_COLORS]);
510 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_PROPERTIES]);
511 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_TIMELINE]);
512 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_PREVIEW]);
513 ToolBarsMenu->addSeparator();
514 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_STANDARD]);
515 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_TOOLS]);
516 ToolBarsMenu->addAction(mActions[LC_VIEW_TOOLBAR_TIME]);
517 ViewMenu->addAction(mActions[LC_VIEW_FULLSCREEN]);
518
519 QMenu* PieceMenu = menuBar()->addMenu(tr("&Piece"));
520 PieceMenu->addAction(mActions[LC_PIECE_INSERT]);
521 PieceMenu->addAction(mActions[LC_PIECE_DELETE]);
522 PieceMenu->addAction(mActions[LC_PIECE_DUPLICATE]);
523 PieceMenu->addAction(mActions[LC_PIECE_PAINT_SELECTED]);
524 PieceMenu->addAction(mActions[LC_PIECE_ARRAY]);
525 PieceMenu->addAction(mActions[LC_PIECE_MINIFIG_WIZARD]);
526 PieceMenu->addAction(mActions[LC_PIECE_RESET_PIVOT_POINT]);
527 PieceMenu->addAction(mActions[LC_PIECE_REMOVE_KEY_FRAMES]);
528 PieceMenu->addSeparator();
529 PieceMenu->addAction(mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]);
530 PieceMenu->addAction(mActions[LC_PIECE_EDIT_END_SUBMODEL]);
531 PieceMenu->addAction(mActions[LC_PIECE_VIEW_SELECTED_MODEL]);
532 PieceMenu->addAction(mActions[LC_PIECE_INLINE_SELECTED_MODELS]);
533 PieceMenu->addAction(mActions[LC_PIECE_MOVE_SELECTION_TO_MODEL]);
534 PieceMenu->addSeparator();
535 PieceMenu->addAction(mActions[LC_PIECE_GROUP]);
536 PieceMenu->addAction(mActions[LC_PIECE_UNGROUP]);
537 PieceMenu->addAction(mActions[LC_PIECE_GROUP_REMOVE]);
538 PieceMenu->addAction(mActions[LC_PIECE_GROUP_ADD]);
539 PieceMenu->addAction(mActions[LC_PIECE_GROUP_EDIT]);
540 PieceMenu->addSeparator();
541 PieceMenu->addAction(mActions[LC_PIECE_HIDE_SELECTED]);
542 PieceMenu->addAction(mActions[LC_PIECE_HIDE_UNSELECTED]);
543 PieceMenu->addAction(mActions[LC_PIECE_UNHIDE_SELECTED]);
544 PieceMenu->addAction(mActions[LC_PIECE_UNHIDE_ALL]);
545
546 QMenu* ModelMenu = menuBar()->addMenu(tr("Sub&model"));
547 ModelMenu->addAction(mActions[LC_MODEL_PROPERTIES]);
548 ModelMenu->addAction(mActions[LC_MODEL_NEW]);
549 ModelMenu->addAction(mActions[LC_MODEL_LIST]);
550 ModelMenu->addSeparator();
551 for (int ModelIdx = LC_MODEL_FIRST; ModelIdx <= LC_MODEL_LAST; ModelIdx++)
552 ModelMenu->addAction(mActions[ModelIdx]);
553
554 QMenu* HelpMenu = menuBar()->addMenu(tr("&Help"));
555 HelpMenu->addAction(mActions[LC_HELP_HOMEPAGE]);
556 HelpMenu->addAction(mActions[LC_HELP_BUG_REPORT]);
557 #if !LC_DISABLE_UPDATE_CHECK
558 HelpMenu->addAction(mActions[LC_HELP_UPDATES]);
559 #endif
560 #ifndef Q_OS_MACOS
561 HelpMenu->addSeparator();
562 #endif
563 HelpMenu->addAction(mActions[LC_HELP_ABOUT]);
564 }
565
CreateToolBars()566 void lcMainWindow::CreateToolBars()
567 {
568 mSelectionModeMenu = new QMenu(tr("Selection Mode"), this);
569 for (int ModeIdx = LC_EDIT_SELECTION_MODE_FIRST; ModeIdx <= LC_EDIT_SELECTION_MODE_LAST; ModeIdx++)
570 mSelectionModeMenu->addAction(mActions[ModeIdx]);
571
572 QAction* SelectionModeAction = new QAction(tr("Selection Mode"), this);
573 SelectionModeAction->setStatusTip(tr("Change selection mode"));
574 SelectionModeAction->setIcon(QIcon(":/resources/action_select.png"));
575 SelectionModeAction->setMenu(mSelectionModeMenu);
576
577 mTransformMenu = new QMenu(tr("Transform"), this);
578 mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_RELATIVE]);
579 mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_ABSOLUTE]);
580 mTransformMenu->addSeparator();
581 mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_TOGETHER]);
582 mTransformMenu->addAction(mActions[LC_EDIT_TRANSFORM_SEPARATELY]);
583
584 QAction* TransformAction = new QAction(tr("Transform"), this);
585 TransformAction->setStatusTip(tr("Transform Options"));
586 TransformAction->setIcon(QIcon(":/resources/edit_transform_relative.png"));
587 TransformAction->setMenu(mTransformMenu);
588
589 QMenu* SnapXYMenu = new QMenu(tr("Snap XY"), this);
590 for (int actionIdx = LC_EDIT_SNAP_MOVE_XY0; actionIdx <= LC_EDIT_SNAP_MOVE_XY9; actionIdx++)
591 SnapXYMenu->addAction(mActions[actionIdx]);
592
593 QMenu* SnapZMenu = new QMenu(tr("Snap Z"), this);
594 for (int actionIdx = LC_EDIT_SNAP_MOVE_Z0; actionIdx <= LC_EDIT_SNAP_MOVE_Z9; actionIdx++)
595 SnapZMenu->addAction(mActions[actionIdx]);
596
597 QMenu* SnapMenu = new QMenu(tr("Snap Menu"), this);
598 SnapMenu->addAction(mActions[LC_EDIT_SNAP_MOVE_TOGGLE]);
599 SnapMenu->addSeparator();
600 SnapMenu->addMenu(SnapXYMenu);
601 SnapMenu->addMenu(SnapZMenu);
602
603 QAction* MoveAction = new QAction(tr("Movement Snap"), this);
604 MoveAction->setStatusTip(tr("Snap translations to fixed intervals"));
605 MoveAction->setIcon(QIcon(":/resources/edit_snap_move.png"));
606 MoveAction->setMenu(SnapMenu);
607
608 QMenu* SnapAngleMenu = new QMenu(tr("Snap Angle Menu"), this);
609 SnapAngleMenu->addAction(mActions[LC_EDIT_SNAP_ANGLE_TOGGLE]);
610 SnapAngleMenu->addSeparator();
611 for (int actionIdx = LC_EDIT_SNAP_ANGLE0; actionIdx <= LC_EDIT_SNAP_ANGLE9; actionIdx++)
612 SnapAngleMenu->addAction(mActions[actionIdx]);
613
614 QAction* AngleAction = new QAction(tr("Rotation Snap"), this);
615 AngleAction->setStatusTip(tr("Snap rotations to fixed intervals"));
616 AngleAction->setIcon(QIcon(":/resources/edit_snap_angle.png"));
617 AngleAction->setMenu(SnapAngleMenu);
618
619 mStandardToolBar = addToolBar(tr("Standard"));
620 mStandardToolBar->setObjectName("StandardToolbar");
621 mStandardToolBar->addAction(mActions[LC_FILE_NEW]);
622 mStandardToolBar->addAction(mActions[LC_FILE_OPEN]);
623 mStandardToolBar->addAction(mActions[LC_FILE_SAVE]);
624 mStandardToolBar->addSeparator();
625 mStandardToolBar->addAction(mActions[LC_EDIT_UNDO]);
626 mStandardToolBar->addAction(mActions[LC_EDIT_REDO]);
627 mStandardToolBar->addSeparator();
628 mStandardToolBar->addAction(SelectionModeAction);
629 mStandardToolBar->addAction(TransformAction);
630 mStandardToolBar->addAction(MoveAction);
631 mStandardToolBar->addAction(AngleAction);
632 ((QToolButton*)mStandardToolBar->widgetForAction(SelectionModeAction))->setPopupMode(QToolButton::InstantPopup);
633 ((QToolButton*)mStandardToolBar->widgetForAction(TransformAction))->setPopupMode(QToolButton::InstantPopup);
634 ((QToolButton*)mStandardToolBar->widgetForAction(MoveAction))->setPopupMode(QToolButton::InstantPopup);
635 ((QToolButton*)mStandardToolBar->widgetForAction(AngleAction))->setPopupMode(QToolButton::InstantPopup);
636
637 mTimeToolBar = addToolBar(tr("Time"));
638 mTimeToolBar->setObjectName("TimeToolbar");
639 mTimeToolBar->addAction(mActions[LC_VIEW_TIME_FIRST]);
640 mTimeToolBar->addAction(mActions[LC_VIEW_TIME_PREVIOUS]);
641 mTimeToolBar->addAction(mActions[LC_VIEW_TIME_NEXT]);
642 mTimeToolBar->addAction(mActions[LC_VIEW_TIME_LAST]);
643 mTimeToolBar->addAction(mActions[LC_VIEW_TIME_ADD_KEYS]);
644
645 mToolsToolBar = addToolBar(tr("Tools"));
646 mToolsToolBar->setObjectName("ToolsToolbar");
647 insertToolBarBreak(mToolsToolBar);
648 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_INSERT]);
649 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_LIGHT]);
650 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]);
651 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
652 mToolsToolBar->addSeparator();
653 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SELECT]);
654 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_MOVE]);
655 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ROTATE]);
656 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_DELETE]);
657 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_PAINT]);
658 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_COLOR_PICKER]);
659 mToolsToolBar->addSeparator();
660 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ZOOM]);
661 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_PAN]);
662 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ROTATE_VIEW]);
663 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ROLL]);
664 mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_ZOOM_REGION]);
665 mToolsToolBar->hide();
666
667 mPartsToolBar = new QDockWidget(tr("Parts"), this);
668 mPartsToolBar->setObjectName("PartsToolbar");
669 mPartSelectionWidget = new lcPartSelectionWidget(mPartsToolBar);
670 mPartsToolBar->setWidget(mPartSelectionWidget);
671 addDockWidget(Qt::RightDockWidgetArea, mPartsToolBar);
672
673 mColorsToolBar = new QDockWidget(tr("Colors"), this);
674 mColorsToolBar->setObjectName("ColorsToolbar");
675 mColorsToolBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
676
677 mColorList = new lcQColorList();
678 connect(mColorList, SIGNAL(colorChanged(int)), this, SLOT(ColorChanged(int)));
679
680 QWidget* ColorWidget = new QWidget(mColorsToolBar);
681
682 QVBoxLayout* ColorLayout = new QVBoxLayout(ColorWidget);
683 ColorLayout->setContentsMargins(0, 0, 0, 0);
684
685 QHBoxLayout* ColorButtonLayout = new QHBoxLayout();
686 ColorButtonLayout->setContentsMargins(0, 0, 0, 0);
687 ColorLayout->addLayout(ColorButtonLayout);
688
689 mColorButton = new QToolButton(ColorWidget);
690 mColorButton->setAutoRaise(true);
691 mColorButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
692 mColorButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
693 ColorButtonLayout->addWidget(mColorButton);
694
695 connect(mColorButton, SIGNAL(clicked()), this, SLOT(ColorButtonClicked()));
696
697 ColorLayout->addWidget(mColorList);
698
699 mColorsToolBar->setWidget(ColorWidget);
700 addDockWidget(Qt::RightDockWidgetArea, mColorsToolBar);
701
702 mPropertiesToolBar = new QDockWidget(tr("Properties"), this);
703 mPropertiesToolBar->setObjectName("PropertiesToolbar");
704
705 QWidget* PropertiesWidget = new QWidget(mPropertiesToolBar);
706 QVBoxLayout* PropertiesLayout = new QVBoxLayout(PropertiesWidget);
707 PropertiesLayout->setContentsMargins(0, 0, 0, 0);
708
709 mPropertiesWidget = new lcQPropertiesTree(PropertiesWidget);
710 PropertiesLayout->addWidget(mPropertiesWidget);
711
712 QHBoxLayout* TransformLayout = new QHBoxLayout;
713 QWidget* TransformWidget = new QWidget();
714 TransformWidget->setLayout(TransformLayout);
715
716 QToolButton* TransformButton = new QToolButton(TransformWidget);
717 TransformButton->setDefaultAction(mActions[LC_EDIT_TRANSFORM]);
718 TransformButton->setPopupMode(QToolButton::InstantPopup);
719 TransformLayout->addWidget(TransformButton);
720
721 mTransformXEdit = new lcTransformLineEdit();
722 TransformLayout->addWidget(mTransformXEdit);
723 mTransformYEdit = new lcTransformLineEdit();
724 TransformLayout->addWidget(mTransformYEdit);
725 mTransformZEdit = new lcTransformLineEdit();
726 TransformLayout->addWidget(mTransformZEdit);
727
728 PropertiesLayout->addWidget(TransformWidget);
729
730 connect(mTransformXEdit, SIGNAL(returnPressed()), mActions[LC_EDIT_TRANSFORM], SIGNAL(triggered()));
731 connect(mTransformYEdit, SIGNAL(returnPressed()), mActions[LC_EDIT_TRANSFORM], SIGNAL(triggered()));
732 connect(mTransformZEdit, SIGNAL(returnPressed()), mActions[LC_EDIT_TRANSFORM], SIGNAL(triggered()));
733
734 mPropertiesToolBar->setWidget(PropertiesWidget);
735 addDockWidget(Qt::RightDockWidgetArea, mPropertiesToolBar);
736
737 mTimelineToolBar = new QDockWidget(tr("Timeline"), this);
738 mTimelineToolBar->setObjectName("TimelineToolbar");
739 mTimelineToolBar->setAcceptDrops(true);
740
741 mTimelineWidget = new lcTimelineWidget(mTimelineToolBar);
742
743 mTimelineToolBar->setWidget(mTimelineWidget);
744 addDockWidget(Qt::RightDockWidgetArea, mTimelineToolBar);
745
746 CreatePreviewWidget();
747
748 tabifyDockWidget(mPartsToolBar, mPropertiesToolBar);
749 tabifyDockWidget(mPropertiesToolBar, mTimelineToolBar);
750 tabifyDockWidget(mTimelineToolBar, mPreviewToolBar);
751
752 connect(mPropertiesToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool)));
753 connect(mTimelineToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool)));
754 connect(mPartsToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool)));
755 connect(mColorsToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool)));
756
757 mPartsToolBar->raise();
758 }
759
CreateView(lcModel * Model)760 lcView* lcMainWindow::CreateView(lcModel* Model)
761 {
762 lcView* NewView = new lcView(lcViewType::View, Model);
763
764 connect(NewView, SIGNAL(CameraChanged()), this, SLOT(ViewCameraChanged()));
765 connect(NewView, SIGNAL(FocusReceived()), this, SLOT(ViewFocusReceived()));
766
767 AddView(NewView);
768
769 return NewView;
770 }
771
PreviewPiece(const QString & PartId,int ColorCode,bool ShowPreview)772 void lcMainWindow::PreviewPiece(const QString& PartId, int ColorCode, bool ShowPreview)
773 {
774 if (ShowPreview)
775 mPreviewToolBar->show();
776
777 mPreviewWidget->SetCurrentPiece(PartId, ColorCode);
778 }
779
CreatePreviewWidget()780 void lcMainWindow::CreatePreviewWidget()
781 {
782 mPreviewWidget = new lcPreviewDockWidget();
783
784 mPreviewToolBar = new QDockWidget(tr("Preview"), this);
785 mPreviewToolBar->setWindowTitle(tr("Preview"));
786 mPreviewToolBar->setObjectName("PreviewToolBar");
787 mPreviewToolBar->setWidget(mPreviewWidget);
788 addDockWidget(Qt::RightDockWidgetArea, mPreviewToolBar);
789
790 connect(mPreviewToolBar, SIGNAL(topLevelChanged(bool)), this, SLOT(EnableWindowFlags(bool)));
791 }
792
TogglePreviewWidget(bool Visible)793 void lcMainWindow::TogglePreviewWidget(bool Visible)
794 {
795 if (mPreviewToolBar)
796 {
797 if (Visible)
798 mPreviewToolBar->show();
799 else
800 mPreviewToolBar->hide();
801 }
802 else if (Visible)
803 {
804 CreatePreviewWidget();
805 }
806 }
807
EnableWindowFlags(bool Detached)808 void lcMainWindow::EnableWindowFlags(bool Detached)
809 {
810 if (Detached)
811 {
812 QDockWidget* DockWidget = qobject_cast<QDockWidget*>(sender());
813
814 DockWidget->setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
815
816 if (isVisible())
817 DockWidget->show();
818 }
819 }
820
821 class lcElidedLabel : public QFrame
822 {
823 public:
lcElidedLabel(QWidget * Parent=nullptr)824 explicit lcElidedLabel(QWidget* Parent = nullptr)
825 : QFrame(Parent)
826 {
827 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
828 }
829
setText(const QString & Text)830 void setText(const QString& Text)
831 {
832 mText = Text;
833 update();
834 }
835
836 protected:
837 void paintEvent(QPaintEvent* event) override;
838
839 QString mText;
840 };
841
paintEvent(QPaintEvent * event)842 void lcElidedLabel::paintEvent(QPaintEvent* event)
843 {
844 QFrame::paintEvent(event);
845
846 QPainter Painter(this);
847 QFontMetrics FontMetrics = Painter.fontMetrics();
848
849 int LineSpacing = FontMetrics.lineSpacing();
850 int y = 0;
851
852 QTextLayout TextLayout(mText, Painter.font());
853 TextLayout.beginLayout();
854
855 for (;;)
856 {
857 QTextLine Line = TextLayout.createLine();
858
859 if (!Line.isValid())
860 break;
861
862 Line.setLineWidth(width());
863 int NextLineY = y + LineSpacing;
864
865 if (height() >= NextLineY + LineSpacing)
866 {
867 Line.draw(&Painter, QPoint(0, y));
868 y = NextLineY;
869 }
870 else
871 {
872 QString LastLine = mText.mid(Line.textStart());
873 QString ElidedLastLine = FontMetrics.elidedText(LastLine, Qt::ElideRight, width());
874 Painter.drawText(QPoint(0, y + FontMetrics.ascent()), ElidedLastLine);
875 Line = TextLayout.createLine();
876 break;
877 }
878 }
879
880 TextLayout.endLayout();
881 }
882
CreateStatusBar()883 void lcMainWindow::CreateStatusBar()
884 {
885 QStatusBar* StatusBar = new QStatusBar(this);
886 setStatusBar(StatusBar);
887
888 mStatusBarLabel = new lcElidedLabel();
889 StatusBar->addWidget(mStatusBarLabel, 1);
890
891 mStatusPositionLabel = new QLabel();
892 StatusBar->addPermanentWidget(mStatusPositionLabel);
893
894 mStatusSnapLabel = new QLabel();
895 StatusBar->addPermanentWidget(mStatusSnapLabel);
896
897 mStatusTimeLabel = new QLabel();
898 StatusBar->addPermanentWidget(mStatusTimeLabel);
899 }
900
closeEvent(QCloseEvent * Event)901 void lcMainWindow::closeEvent(QCloseEvent* Event)
902 {
903 if (SaveProjectIfModified())
904 {
905 Event->accept();
906
907 QSettings Settings;
908 Settings.beginGroup("MainWindow");
909 Settings.setValue("Geometry", saveGeometry());
910 Settings.setValue("State", saveState());
911 mPartSelectionWidget->SaveState(Settings);
912 Settings.endGroup();
913
914 gApplication->SaveTabLayout();
915 }
916 else
917 Event->ignore();
918 }
919
dragEnterEvent(QDragEnterEvent * Event)920 void lcMainWindow::dragEnterEvent(QDragEnterEvent* Event)
921 {
922 if (Event->mimeData()->hasUrls())
923 Event->acceptProposedAction();
924 }
925
dropEvent(QDropEvent * Event)926 void lcMainWindow::dropEvent(QDropEvent* Event)
927 {
928 const QMimeData* MimeData = Event->mimeData();
929 const QList<QUrl> Urls = MimeData->urls();
930 for (const QUrl& Url : Urls)
931 if (OpenProject(Url.toLocalFile()))
932 break;
933 }
934
createPopupMenu()935 QMenu* lcMainWindow::createPopupMenu()
936 {
937 QMenu* Menu = new QMenu(this);
938
939 UpdateDockWidgetActions();
940
941 Menu->addAction(mActions[LC_VIEW_TOOLBAR_PARTS]);
942 Menu->addAction(mActions[LC_VIEW_TOOLBAR_COLORS]);
943 Menu->addAction(mActions[LC_VIEW_TOOLBAR_PROPERTIES]);
944 Menu->addAction(mActions[LC_VIEW_TOOLBAR_TIMELINE]);
945 Menu->addAction(mActions[LC_VIEW_TOOLBAR_PREVIEW]);
946 Menu->addSeparator();
947 Menu->addAction(mActions[LC_VIEW_TOOLBAR_STANDARD]);
948 Menu->addAction(mActions[LC_VIEW_TOOLBAR_TOOLS]);
949 Menu->addAction(mActions[LC_VIEW_TOOLBAR_TIME]);
950
951 return Menu;
952 }
953
UpdateDockWidgetActions()954 void lcMainWindow::UpdateDockWidgetActions()
955 {
956 mActions[LC_VIEW_TOOLBAR_PARTS]->setChecked(mPartsToolBar->isVisible());
957 mActions[LC_VIEW_TOOLBAR_COLORS]->setChecked(mColorsToolBar->isVisible());
958 mActions[LC_VIEW_TOOLBAR_PROPERTIES]->setChecked(mPropertiesToolBar->isVisible());
959 mActions[LC_VIEW_TOOLBAR_TIMELINE]->setChecked(mTimelineToolBar->isVisible());
960 mActions[LC_VIEW_TOOLBAR_STANDARD]->setChecked(mStandardToolBar->isVisible());
961 mActions[LC_VIEW_TOOLBAR_TOOLS]->setChecked(mToolsToolBar->isVisible());
962 mActions[LC_VIEW_TOOLBAR_TIME]->setChecked(mTimeToolBar->isVisible());
963 mActions[LC_VIEW_TOOLBAR_PREVIEW]->setChecked(mPreviewToolBar->isVisible());
964 }
965
UpdateGamepads()966 void lcMainWindow::UpdateGamepads()
967 {
968 #if LC_ENABLE_GAMEPAD
969 QDateTime Now = QDateTime::currentDateTime();
970 quint64 Elapsed = mLastGamepadUpdate.msecsTo(Now);
971 mLastGamepadUpdate = Now;
972
973 if (!gMainWindow)
974 return;
975
976 lcView* ActiveView = GetActiveView();
977 if (!ActiveView)
978 return;
979
980 const QList<int> Gamepads = QGamepadManager::instance()->connectedGamepads();
981 if (Gamepads.isEmpty())
982 return;
983
984 QGamepad Gamepad(Gamepads[0]);
985
986 float Scale = (float)Elapsed / 20.0f;
987 lcVector3 Distance(Scale * Gamepad.axisLeftX(), 0.0f, -Scale * Gamepad.axisLeftY());
988
989 if (fabsf(Distance.LengthSquared()) > 0.01f)
990 ActiveView->MoveCamera(Distance);
991 #endif
992 }
993
ModelTabContextMenuRequested(const QPoint & Point)994 void lcMainWindow::ModelTabContextMenuRequested(const QPoint& Point)
995 {
996 QMenu* Menu = new QMenu;
997
998 mModelTabWidgetContextMenuIndex = mModelTabWidget->tabBar()->tabAt(Point);
999
1000 if (mModelTabWidget->count() > 1)
1001 Menu->addAction(tr("Close Other Tabs"), this, SLOT(ModelTabCloseOtherTabs()));
1002 if (mModelTabWidgetContextMenuIndex == mModelTabWidget->currentIndex())
1003 Menu->addAction(mActions[LC_VIEW_RESET_VIEWS]);
1004
1005 Menu->exec(QCursor::pos());
1006 delete Menu;
1007 }
1008
ModelTabCloseOtherTabs()1009 void lcMainWindow::ModelTabCloseOtherTabs()
1010 {
1011 if (mModelTabWidgetContextMenuIndex == -1)
1012 return;
1013
1014 while (mModelTabWidget->count() - 1 > mModelTabWidgetContextMenuIndex)
1015 delete mModelTabWidget->widget(mModelTabWidgetContextMenuIndex + 1);
1016
1017 while (mModelTabWidget->count() > 1)
1018 delete mModelTabWidget->widget(0);
1019 }
1020
ModelTabClosed(int Index)1021 void lcMainWindow::ModelTabClosed(int Index)
1022 {
1023 if (mModelTabWidget->count() != 1)
1024 delete mModelTabWidget->widget(Index);
1025 else
1026 NewProject();
1027 }
1028
ModelTabChanged(int Index)1029 void lcMainWindow::ModelTabChanged(int Index)
1030 {
1031 Project* Project = lcGetActiveProject();
1032 lcModelTabWidget* CurrentTab = (lcModelTabWidget*)mModelTabWidget->widget(Index);
1033
1034 Project->SetActiveModel(Project->GetModels().FindIndex(CurrentTab ? CurrentTab->GetModel() : nullptr));
1035 }
1036
ClipboardChanged()1037 void lcMainWindow::ClipboardChanged()
1038 {
1039 const QString MimeType = QLatin1String("application/vnd.leocad-clipboard");
1040 const QMimeData* MimeData = QApplication::clipboard()->mimeData();
1041 QByteArray ClipboardData;
1042
1043 if (MimeData && MimeData->hasFormat(MimeType))
1044 ClipboardData = MimeData->data(MimeType);
1045
1046 gApplication->SetClipboard(ClipboardData);
1047 }
1048
ActionTriggered()1049 void lcMainWindow::ActionTriggered()
1050 {
1051 QObject* Action = sender();
1052
1053 for (int CommandIdx = 0; CommandIdx < LC_NUM_COMMANDS; CommandIdx++)
1054 {
1055 if (Action == mActions[CommandIdx])
1056 {
1057 HandleCommand((lcCommandId)CommandIdx);
1058 break;
1059 }
1060 }
1061 }
1062
ColorChanged(int ColorIndex)1063 void lcMainWindow::ColorChanged(int ColorIndex)
1064 {
1065 SetColorIndex(ColorIndex);
1066 }
1067
ColorButtonClicked()1068 void lcMainWindow::ColorButtonClicked()
1069 {
1070 lcModel* ActiveModel = GetActiveModel();
1071
1072 if (ActiveModel)
1073 ActiveModel->PaintSelectedPieces();
1074 }
1075
ProjectFileChanged(const QString & Path)1076 void lcMainWindow::ProjectFileChanged(const QString& Path)
1077 {
1078 static bool Ignore;
1079
1080 if (Ignore)
1081 return;
1082
1083 QString Text = tr("The file '%1' has been modified by another application, do you want to reload it?").arg(QDir::toNativeSeparators(Path));
1084
1085 Project* CurrentProject = lcGetActiveProject();
1086
1087 Ignore = true;
1088
1089 if (QMessageBox::question(this, tr("File Changed"), Text, QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1090 {
1091 Ignore = false;
1092 CurrentProject->MarkAsModified();
1093 UpdateTitle();
1094 return;
1095 }
1096
1097 Ignore = false;
1098
1099 QFileInfo FileInfo(Path);
1100
1101 if (FileInfo == QFileInfo(CurrentProject->GetFileName()))
1102 {
1103 Project* NewProject = new Project;
1104
1105 if (NewProject->Load(Path, true))
1106 {
1107 QByteArray TabLayout = GetTabLayout();
1108 gApplication->SetProject(NewProject);
1109 RestoreTabLayout(TabLayout);
1110 lcView::UpdateAllViews();
1111 }
1112 }
1113 else
1114 {
1115 PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(FileInfo.fileName().toLatin1(), CurrentProject, false, true);
1116
1117 if (Info && Info->IsProject())
1118 Info->GetProject()->Load(Path, true);
1119 }
1120 }
1121
Print(QPrinter * Printer)1122 void lcMainWindow::Print(QPrinter* Printer)
1123 {
1124 #ifndef QT_NO_PRINTER
1125 int DocCopies;
1126 int PageCopies;
1127
1128 lcInstructions* Instructions = lcGetActiveProject()->GetInstructions();
1129 const int PageCount = static_cast<int>(Instructions->mPages.size());
1130
1131 if (Printer->collateCopies())
1132 {
1133 DocCopies = 1;
1134 PageCopies = Printer->supportsMultipleCopies() ? 1 : Printer->copyCount();
1135 }
1136 else
1137 {
1138 DocCopies = Printer->supportsMultipleCopies() ? 1 : Printer->copyCount();
1139 PageCopies = 1;
1140 }
1141
1142 int FromPage = Printer->fromPage();
1143 int ToPage = Printer->toPage();
1144 bool Ascending = true;
1145
1146 if (FromPage == 0 && ToPage == 0)
1147 {
1148 FromPage = 1;
1149 ToPage = PageCount;
1150 }
1151
1152 FromPage = qMax(1, FromPage);
1153 ToPage = qMin(PageCount, ToPage);
1154
1155 if (ToPage < FromPage)
1156 return;
1157
1158 if (Printer->pageOrder() == QPrinter::LastPageFirst)
1159 {
1160 int Tmp = FromPage;
1161 FromPage = ToPage;
1162 ToPage = Tmp;
1163 Ascending = false;
1164 }
1165
1166 QRect PageRect = Printer->pageLayout().paintRectPixels(Printer->resolution());
1167 const int Resolution = Printer->resolution();
1168 const int Margin = Resolution / 2; // todo: user setting
1169 QRect MarginRect = QRect(PageRect.left() + Margin, PageRect.top() + Margin, PageRect.width() - Margin * 2, PageRect.height() - Margin * 2);
1170
1171 QPainter Painter(Printer);
1172 bool FirstPage = true;
1173 // TODO: option to print background
1174
1175 for (int DocCopy = 0; DocCopy < DocCopies; DocCopy++)
1176 {
1177 int Page = FromPage;
1178
1179 for (;;)
1180 {
1181 for (int PageCopy = 0; PageCopy < PageCopies; PageCopy++)
1182 {
1183 if (Printer->printerState() == QPrinter::Aborted || Printer->printerState() == QPrinter::Error)
1184 return;
1185
1186 if (!FirstPage)
1187 Printer->newPage();
1188 else
1189 FirstPage = false;
1190
1191 int StepWidth = MarginRect.width();
1192 int StepHeight = MarginRect.height();
1193
1194 const lcInstructionsPage& PageLayout = Instructions->mPages[Page - 1];
1195 lcModel* Model = PageLayout.Steps[0].Model;
1196 lcStep Step = PageLayout.Steps[0].Step;
1197 QImage Image = Model->GetStepImage(false, StepWidth, StepHeight, Step);
1198
1199 Painter.drawImage(MarginRect.left(), MarginRect.top(), Image);
1200
1201 // TODO: add print options somewhere but Qt doesn't allow changes to the page setup dialog
1202 // DWORD dwPrint = theApp.GetProfileInt("Settings","Print", PRINT_NUMBERS|PRINT_BORDER);
1203
1204 // if (print text)
1205 {
1206 QFont Font("Helvetica", 96);
1207 Painter.setFont(Font);
1208
1209 QFontMetrics FontMetrics(Font);
1210
1211 int TextMargin = Resolution / 2;
1212 QRect TextRect = QRect(MarginRect.left() + TextMargin, MarginRect.top() + TextMargin, MarginRect.width() - TextMargin * 2, MarginRect.height() - TextMargin * 2);
1213
1214 Painter.drawText(TextRect, Qt::AlignTop | Qt::AlignLeft, QString::number(Step));
1215 }
1216 /*
1217 // if (print border)
1218 {
1219 QPen BlackPen(Qt::black, 2);
1220 Painter.setPen(BlackPen);
1221
1222 Painter.drawLine(MarginRect.left(), MarginRect.top(), MarginRect.right(), MarginRect.top());
1223 Painter.drawLine(MarginRect.left(), MarginRect.bottom(), MarginRect.right(), MarginRect.bottom());
1224 Painter.drawLine(MarginRect.left(), MarginRect.top(), MarginRect.left(), MarginRect.bottom());
1225 Painter.drawLine(MarginRect.right(), MarginRect.top(), MarginRect.right(), MarginRect.bottom());
1226 }
1227 */
1228 // TODO: print header and footer
1229 }
1230
1231 if (Page == ToPage)
1232 break;
1233
1234 if (Ascending)
1235 Page++;
1236 else
1237 Page--;
1238 }
1239 }
1240 #endif
1241 }
1242
ShowUpdatesDialog()1243 void lcMainWindow::ShowUpdatesDialog()
1244 {
1245 lcQUpdateDialog Dialog(this, false);
1246 Dialog.exec();
1247 }
1248
ShowAboutDialog()1249 void lcMainWindow::ShowAboutDialog()
1250 {
1251 lcQAboutDialog Dialog(this);
1252 Dialog.exec();
1253 }
1254
ShowHTMLDialog()1255 void lcMainWindow::ShowHTMLDialog()
1256 {
1257 lcHTMLExportOptions Options(lcGetActiveProject());
1258
1259 lcQHTMLDialog Dialog(this, &Options);
1260 if (Dialog.exec() != QDialog::Accepted)
1261 return;
1262
1263 Options.SaveDefaults();
1264 lcGetActiveProject()->ExportHTML(Options);
1265 }
1266
ShowRenderDialog()1267 void lcMainWindow::ShowRenderDialog()
1268 {
1269 lcRenderDialog Dialog(this);
1270 Dialog.exec();
1271 }
1272
ShowInstructionsDialog()1273 void lcMainWindow::ShowInstructionsDialog()
1274 {
1275 lcInstructionsDialog* Dialog = new lcInstructionsDialog(this, lcGetActiveProject());
1276 Dialog->setWindowModality(Qt::ApplicationModal);
1277 Dialog->setAttribute(Qt::WA_DeleteOnClose);
1278 Dialog->show();
1279 }
1280
ShowPrintDialog()1281 void lcMainWindow::ShowPrintDialog()
1282 {
1283 #ifndef QT_NO_PRINTER
1284 int PageCount = static_cast<int>(lcGetActiveProject()->GetInstructions()->mPages.size());
1285
1286 QPrinter Printer(QPrinter::HighResolution);
1287 Printer.setFromTo(1, PageCount + 1);
1288
1289 QPrintDialog PrintDialog(&Printer, this);
1290
1291 if (PrintDialog.exec() == QDialog::Accepted)
1292 Print(&Printer);
1293 #endif
1294 }
1295
SetShadingMode(lcShadingMode ShadingMode)1296 void lcMainWindow::SetShadingMode(lcShadingMode ShadingMode)
1297 {
1298 lcGetPreferences().mShadingMode = ShadingMode;
1299
1300 UpdateShadingMode();
1301
1302 lcView::UpdateAllViews();
1303
1304 if (mPartSelectionWidget)
1305 mPartSelectionWidget->Redraw();
1306 }
1307
SetSelectionMode(lcSelectionMode SelectionMode)1308 void lcMainWindow::SetSelectionMode(lcSelectionMode SelectionMode)
1309 {
1310 mSelectionMode = SelectionMode;
1311
1312 UpdateSelectionMode();
1313 }
1314
ToggleViewSphere()1315 void lcMainWindow::ToggleViewSphere()
1316 {
1317 lcGetPreferences().mViewSphereEnabled = !lcGetPreferences().mViewSphereEnabled;
1318
1319 lcView::UpdateAllViews();
1320 }
1321
ToggleAxisIcon()1322 void lcMainWindow::ToggleAxisIcon()
1323 {
1324 lcGetPreferences().mDrawAxes = !lcGetPreferences().mDrawAxes;
1325
1326 lcView::UpdateAllViews();
1327 }
1328
ToggleGrid()1329 void lcMainWindow::ToggleGrid()
1330 {
1331 lcGetPreferences().mGridEnabled = !lcGetPreferences().mGridEnabled;
1332
1333 lcView::UpdateAllViews();
1334 }
1335
ToggleFadePreviousSteps()1336 void lcMainWindow::ToggleFadePreviousSteps()
1337 {
1338 lcGetPreferences().mFadeSteps = !lcGetPreferences().mFadeSteps;
1339
1340 lcView::UpdateAllViews();
1341 }
1342
GetTabLayout()1343 QByteArray lcMainWindow::GetTabLayout()
1344 {
1345 QByteArray TabLayoutData;
1346 QDataStream DataStream(&TabLayoutData, QIODevice::WriteOnly);
1347
1348 DataStream << (quint32)LC_TAB_LAYOUT_VERSION;
1349 qint32 NumTabs = mModelTabWidget->count();
1350 DataStream << NumTabs;
1351 DataStream << ((lcModelTabWidget*)mModelTabWidget->currentWidget())->GetModel()->GetProperties().mFileName;
1352
1353 for (int TabIdx = 0; TabIdx < NumTabs; TabIdx++)
1354 {
1355 lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(TabIdx);
1356
1357 DataStream << TabWidget->GetModel()->GetProperties().mFileName;
1358
1359 std::function<void (QWidget*)> SaveWidget = [&DataStream, &SaveWidget, &TabWidget](QWidget* Widget)
1360 {
1361 if (Widget->metaObject() == &lcViewWidget::staticMetaObject)
1362 {
1363 lcView* CurrentView = ((lcViewWidget*)Widget)->GetView();
1364
1365 DataStream << (qint32)0;
1366 DataStream << (qint32)(TabWidget->GetActiveView() == CurrentView ? 1 : 0);
1367
1368 const lcCamera* Camera = CurrentView->GetCamera();
1369
1370 if (Camera->IsSimple())
1371 {
1372 DataStream << (qint32)0;
1373 DataStream << Camera->m_fovy;
1374 DataStream << Camera->m_zNear;
1375 DataStream << Camera->m_zFar;
1376 DataStream << Camera->mPosition;
1377 DataStream << Camera->mTargetPosition;
1378 DataStream << Camera->mUpVector;
1379 }
1380 else
1381 {
1382 DataStream << (qint32)1;
1383 DataStream << Camera->GetName();
1384 }
1385 }
1386 else
1387 {
1388 QSplitter* Splitter = (QSplitter*)Widget;
1389
1390 DataStream << (qint32)(Splitter->orientation() == Qt::Horizontal ? 1 : 2);
1391 DataStream << Splitter->sizes();
1392
1393 SaveWidget(Splitter->widget(0));
1394 SaveWidget(Splitter->widget(1));
1395 }
1396 };
1397
1398 QLayout* TabLayout = TabWidget->layout();
1399 SaveWidget(TabLayout->itemAt(0)->widget());
1400 }
1401
1402 return TabLayoutData;
1403 }
1404
RestoreTabLayout(const QByteArray & TabLayout)1405 void lcMainWindow::RestoreTabLayout(const QByteArray& TabLayout)
1406 {
1407 if (TabLayout.isEmpty())
1408 return;
1409
1410 QDataStream DataStream(TabLayout);
1411
1412 quint32 Version;
1413 DataStream >> Version;
1414
1415 if (Version != LC_TAB_LAYOUT_VERSION)
1416 return;
1417
1418 qint32 NumTabs;
1419 DataStream >> NumTabs;
1420 QString CurrentTabName;
1421 DataStream >> CurrentTabName;
1422
1423 RemoveAllModelTabs();
1424
1425 for (int TabIdx = 0; TabIdx < NumTabs; TabIdx++)
1426 {
1427 QString ModelName;
1428 DataStream >> ModelName;
1429
1430 lcModel* Model = lcGetActiveProject()->GetModel(ModelName);
1431 lcModelTabWidget* TabWidget = nullptr;
1432
1433 if (Model)
1434 {
1435 SetCurrentModelTab(Model);
1436 TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(mModelTabWidget->count() - 1);
1437 }
1438
1439 QWidget* ActiveWidget = nullptr;
1440
1441 std::function<void(QWidget*)> LoadWidget = [&DataStream, &LoadWidget, &ActiveWidget, this](QWidget* ParentWidget)
1442 {
1443 qint32 WidgetType;
1444 DataStream >> WidgetType;
1445
1446 if (WidgetType == 0)
1447 {
1448 qint32 IsActive;
1449 DataStream >> IsActive;
1450
1451 if (IsActive)
1452 ActiveWidget = ParentWidget;
1453
1454 qint32 CameraType;
1455 DataStream >> CameraType;
1456
1457 lcView* CurrentView = nullptr;
1458
1459 if (ParentWidget)
1460 CurrentView = ((lcViewWidget*)ParentWidget)->GetView();
1461
1462 if (CameraType == 0)
1463 {
1464 float FoV, ZNear, ZFar;
1465 lcVector3 Position, TargetPosition, UpVector;
1466
1467 DataStream >> FoV;
1468 DataStream >> ZNear;
1469 DataStream >> ZFar;
1470 DataStream >> Position;
1471 DataStream >> TargetPosition;
1472 DataStream >> UpVector;
1473
1474 if (CurrentView)
1475 {
1476 lcCamera* Camera = CurrentView->GetCamera();
1477 if (!std::isnan(FoV))
1478 Camera->m_fovy = FoV;
1479 if (!std::isnan(ZNear))
1480 Camera->m_zNear = ZNear;
1481 if (!std::isnan(ZFar))
1482 Camera->m_zFar = ZFar;
1483 if (!Position.IsNan() && !TargetPosition.IsNan() && !UpVector.IsNan())
1484 {
1485 Camera->mPosition = Position;
1486 Camera->mTargetPosition = TargetPosition;
1487 Camera->mUpVector = UpVector;
1488 }
1489 Camera->UpdatePosition(1);
1490 }
1491 }
1492 else
1493 {
1494 QByteArray CameraName;
1495 DataStream >> CameraName;
1496
1497 if (CurrentView)
1498 CurrentView->SetCamera(CameraName);
1499 }
1500 }
1501 else
1502 {
1503 QList<int> Sizes;
1504 DataStream >> Sizes;
1505
1506 if (ParentWidget)
1507 {
1508 ParentWidget->setFocus();
1509
1510 if (WidgetType == 1)
1511 SplitVertical();
1512 else
1513 SplitHorizontal();
1514
1515 QSplitter* Splitter = (QSplitter*)ParentWidget->parentWidget();
1516 Splitter->setSizes(Sizes);
1517
1518 LoadWidget(Splitter->widget(0));
1519 LoadWidget(Splitter->widget(1));
1520 }
1521 else
1522 {
1523 LoadWidget(nullptr);
1524 LoadWidget(nullptr);
1525 }
1526 }
1527 };
1528
1529 LoadWidget(TabWidget ? TabWidget->layout()->itemAt(0)->widget() : nullptr);
1530
1531 if (ActiveWidget && TabWidget)
1532 ActiveWidget->setFocus();
1533 }
1534
1535 if (!mModelTabWidget->count())
1536 lcGetActiveProject()->SetActiveModel(0);
1537 else
1538 lcGetActiveProject()->SetActiveModel(CurrentTabName);
1539 }
1540
RemoveAllModelTabs()1541 void lcMainWindow::RemoveAllModelTabs()
1542 {
1543 while (mModelTabWidget->count())
1544 delete mModelTabWidget->widget(0);
1545 }
1546
CloseCurrentModelTab()1547 void lcMainWindow::CloseCurrentModelTab()
1548 {
1549 if (mModelTabWidget->count() > 1)
1550 delete mModelTabWidget->currentWidget();
1551 else
1552 NewProject();
1553 }
1554
SetCurrentModelTab(lcModel * Model)1555 void lcMainWindow::SetCurrentModelTab(lcModel* Model)
1556 {
1557 for (int TabIdx = 0; TabIdx < mModelTabWidget->count(); TabIdx++)
1558 {
1559 lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(TabIdx);
1560
1561 if (TabWidget->GetModel() == Model)
1562 {
1563 mModelTabWidget->setCurrentIndex(TabIdx);
1564 return;
1565 }
1566 }
1567
1568 lcModelTabWidget* TabWidget = new lcModelTabWidget(Model);
1569 mModelTabWidget->addTab(TabWidget, Model->GetProperties().mFileName);
1570
1571 QVBoxLayout* CentralLayout = new QVBoxLayout(TabWidget);
1572 CentralLayout->setContentsMargins(0, 0, 0, 0);
1573
1574 lcView* NewView = CreateView(Model);
1575 lcViewWidget* ViewWidget = new lcViewWidget(TabWidget, NewView);
1576 CentralLayout->addWidget(ViewWidget);
1577
1578 mModelTabWidget->setCurrentWidget(TabWidget);
1579
1580 ViewWidget->show();
1581 ViewWidget->setFocus();
1582 NewView->ZoomExtents();
1583 }
1584
AddView(lcView * View)1585 void lcMainWindow::AddView(lcView* View)
1586 {
1587 lcModelTabWidget* TabWidget = GetTabWidgetForModel(View->GetModel());
1588
1589 if (!TabWidget)
1590 return;
1591
1592 if (!TabWidget->GetActiveView())
1593 {
1594 TabWidget->SetActiveView(View);
1595 UpdatePerspective();
1596 }
1597 }
1598
RemoveView(lcView * View)1599 void lcMainWindow::RemoveView(lcView* View)
1600 {
1601 lcModelTabWidget* TabWidget = GetTabForView(View);
1602
1603 if (TabWidget)
1604 TabWidget->RemoveView(View);
1605 }
1606
SetActiveView(lcView * ActiveView)1607 void lcMainWindow::SetActiveView(lcView* ActiveView)
1608 {
1609 lcModelTabWidget* TabWidget = GetTabForView(ActiveView);
1610
1611 if (!TabWidget)
1612 return;
1613
1614 lcView* CurrentActiveView = TabWidget->GetActiveView();
1615
1616 if (CurrentActiveView == ActiveView)
1617 return;
1618
1619 if (CurrentActiveView)
1620 CurrentActiveView->SetTopSubmodelActive();
1621
1622 TabWidget->SetActiveView(ActiveView);
1623
1624 UpdateCameraMenu();
1625 UpdatePerspective();
1626 }
1627
SetTool(lcTool Tool)1628 void lcMainWindow::SetTool(lcTool Tool)
1629 {
1630 mTool = Tool;
1631
1632 QAction* Action = mActions[LC_EDIT_ACTION_FIRST + static_cast<int>(mTool)];
1633
1634 if (Action)
1635 Action->setChecked(true);
1636
1637 lcView::UpdateAllViews();
1638 }
1639
SetColorIndex(int ColorIndex)1640 void lcMainWindow::SetColorIndex(int ColorIndex)
1641 {
1642 mColorIndex = ColorIndex;
1643
1644 if (mPartSelectionWidget)
1645 mPartSelectionWidget->SetColorIndex(ColorIndex);
1646
1647 UpdateColor();
1648 }
1649
SetMoveSnapEnabled(bool Enabled)1650 void lcMainWindow::SetMoveSnapEnabled(bool Enabled)
1651 {
1652 mMoveSnapEnabled = Enabled;
1653 UpdateSnap();
1654 }
1655
SetAngleSnapEnabled(bool Enabled)1656 void lcMainWindow::SetAngleSnapEnabled(bool Enabled)
1657 {
1658 mAngleSnapEnabled = Enabled;
1659 UpdateSnap();
1660 }
1661
SetMoveXYSnapIndex(int Index)1662 void lcMainWindow::SetMoveXYSnapIndex(int Index)
1663 {
1664 mMoveXYSnapIndex = Index;
1665 UpdateSnap();
1666 }
1667
SetMoveZSnapIndex(int Index)1668 void lcMainWindow::SetMoveZSnapIndex(int Index)
1669 {
1670 mMoveZSnapIndex = Index;
1671 UpdateSnap();
1672 }
1673
SetAngleSnapIndex(int Index)1674 void lcMainWindow::SetAngleSnapIndex(int Index)
1675 {
1676 mAngleSnapIndex = Index;
1677 UpdateSnap();
1678 }
1679
SetRelativeTransform(bool RelativeTransform)1680 void lcMainWindow::SetRelativeTransform(bool RelativeTransform)
1681 {
1682 mRelativeTransform = RelativeTransform;
1683
1684 UpdateLockSnap();
1685 lcView::UpdateAllViews();
1686 }
1687
SetSeparateTransform(bool SelectionTransform)1688 void lcMainWindow::SetSeparateTransform(bool SelectionTransform)
1689 {
1690 mLocalTransform = SelectionTransform;
1691
1692 UpdateLockSnap();
1693 }
1694
SetTransformType(lcTransformType TransformType)1695 void lcMainWindow::SetTransformType(lcTransformType TransformType)
1696 {
1697 if (TransformType < lcTransformType::First || TransformType >= lcTransformType::Count)
1698 return;
1699
1700 mTransformType = TransformType;
1701
1702 constexpr const char* IconNames[] =
1703 {
1704 ":/resources/edit_transform_absolute_translation.png",
1705 ":/resources/edit_transform_relative_translation.png",
1706 ":/resources/edit_transform_absolute_rotation.png",
1707 ":/resources/edit_transform_relative_rotation.png"
1708 };
1709
1710 LC_ARRAY_SIZE_CHECK(IconNames, lcTransformType::Count);
1711
1712 int TransformIndex = static_cast<int>(TransformType);
1713 mActions[LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION + TransformIndex]->setChecked(true);
1714 mActions[LC_EDIT_TRANSFORM]->setIcon(QIcon(IconNames[TransformIndex]));
1715 }
1716
SetCurrentPieceInfo(PieceInfo * Info)1717 void lcMainWindow::SetCurrentPieceInfo(PieceInfo* Info)
1718 {
1719 lcPiecesLibrary* Library = lcGetPiecesLibrary();
1720
1721 if (mCurrentPieceInfo)
1722 Library->ReleasePieceInfo(mCurrentPieceInfo);
1723
1724 mCurrentPieceInfo = Info;
1725
1726 if (mCurrentPieceInfo)
1727 Library->LoadPieceInfo(mCurrentPieceInfo, true, true);
1728 }
1729
GetTransformAmount()1730 lcVector3 lcMainWindow::GetTransformAmount()
1731 {
1732 lcVector3 Transform;
1733
1734 Transform.x = lcParseValueLocalized(mTransformXEdit->text());
1735 Transform.y = lcParseValueLocalized(mTransformYEdit->text());
1736 Transform.z = lcParseValueLocalized(mTransformZEdit->text());
1737
1738 return Transform;
1739 }
1740
SplitView(Qt::Orientation Orientation)1741 void lcMainWindow::SplitView(Qt::Orientation Orientation)
1742 {
1743 QWidget* Focus = focusWidget();
1744
1745 if (Focus->metaObject() != &lcViewWidget::staticMetaObject)
1746 return;
1747
1748 QWidget* Parent = Focus->parentWidget();
1749 QSplitter* Splitter;
1750 QList<int> Sizes;
1751
1752 if (Parent->metaObject() == &lcModelTabWidget::staticMetaObject)
1753 {
1754 Splitter = new QSplitter(Orientation, Parent);
1755 Parent->layout()->addWidget(Splitter);
1756 Splitter->addWidget(Focus);
1757 Splitter->addWidget(new lcViewWidget(mModelTabWidget->currentWidget(), CreateView(GetCurrentTabModel())));
1758 }
1759 else
1760 {
1761 QSplitter* ParentSplitter = (QSplitter*)Parent;
1762 Sizes = ParentSplitter->sizes();
1763 int FocusIndex = ParentSplitter->indexOf(Focus);
1764
1765 Splitter = new QSplitter(Orientation, Parent);
1766 ParentSplitter->insertWidget(FocusIndex, Splitter);
1767 Splitter->addWidget(Focus);
1768 Splitter->addWidget(new lcViewWidget(mModelTabWidget->currentWidget(), CreateView(GetCurrentTabModel())));
1769
1770 ParentSplitter->setSizes(Sizes);
1771 }
1772
1773 Sizes.clear();
1774 Sizes.append(10);
1775 Sizes.append(10);
1776 Splitter->setSizes(Sizes);
1777 Focus->setFocus();
1778 }
1779
SplitHorizontal()1780 void lcMainWindow::SplitHorizontal()
1781 {
1782 SplitView(Qt::Vertical);
1783 }
1784
SplitVertical()1785 void lcMainWindow::SplitVertical()
1786 {
1787 SplitView(Qt::Horizontal);
1788 }
1789
RemoveActiveView()1790 void lcMainWindow::RemoveActiveView()
1791 {
1792 QWidget* Focus = focusWidget();
1793
1794 if (Focus->metaObject() != &lcViewWidget::staticMetaObject)
1795 return;
1796
1797 QWidget* Parent = Focus->parentWidget();
1798
1799 if (Parent->metaObject() == &lcModelTabWidget::staticMetaObject)
1800 return;
1801
1802 QWidget* ParentParentWidget = Parent->parentWidget();
1803 QSplitter* ParentSplitter = (QSplitter*)Parent;
1804 int FocusIndex = ParentSplitter->indexOf(Focus);
1805 QWidget* OtherWidget = ParentSplitter->widget(!FocusIndex);
1806
1807 if (ParentParentWidget->metaObject() == &lcModelTabWidget::staticMetaObject)
1808 {
1809 QLayout* CentralLayout = ParentParentWidget->layout();
1810
1811 CentralLayout->addWidget(OtherWidget);
1812 CentralLayout->removeWidget(Parent);
1813 }
1814 else
1815 {
1816 QSplitter* ParentParentSplitter = (QSplitter*)ParentParentWidget;
1817 QList<int> Sizes = ParentParentSplitter->sizes();
1818
1819 int ParentIndex = ParentParentSplitter->indexOf(Parent);
1820 Parent->setParent(nullptr);
1821 ParentParentSplitter->insertWidget(ParentIndex, OtherWidget);
1822
1823 ParentParentSplitter->setSizes(Sizes);
1824 }
1825
1826 Parent->deleteLater();
1827
1828 if (OtherWidget->metaObject() != &lcViewWidget::staticMetaObject)
1829 {
1830 lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->currentWidget();
1831
1832 if (TabWidget)
1833 OtherWidget = TabWidget->GetAnyViewWidget();
1834 }
1835
1836 OtherWidget->setFocus();
1837 }
1838
ResetViews()1839 void lcMainWindow::ResetViews()
1840 {
1841 lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->currentWidget();
1842
1843 if (!TabWidget)
1844 return;
1845
1846 QLayout* TabLayout = TabWidget->layout();
1847 QWidget* TopWidget = TabLayout->itemAt(0)->widget();
1848 TopWidget->deleteLater();
1849
1850 lcView* NewView = CreateView(TabWidget->GetModel());
1851 lcViewWidget* ViewWidget = new lcViewWidget(TabWidget, NewView);
1852 TabLayout->addWidget(ViewWidget);
1853
1854 ViewWidget->show();
1855 ViewWidget->setFocus();
1856 NewView->ZoomExtents();
1857 }
1858
ToggleDockWidget(QWidget * DockWidget)1859 void lcMainWindow::ToggleDockWidget(QWidget* DockWidget)
1860 {
1861 if (DockWidget->isHidden())
1862 DockWidget->show();
1863 else
1864 DockWidget->hide();
1865 }
1866
TogglePrintPreview()1867 void lcMainWindow::TogglePrintPreview()
1868 {
1869 #ifndef QT_NO_PRINTER
1870 // todo: print preview inside main window
1871
1872 int PageCount = static_cast<int>(lcGetActiveProject()->GetInstructions()->mPages.size());
1873
1874 QPrinter Printer(QPrinter::ScreenResolution);
1875 Printer.setFromTo(1, PageCount + 1);
1876
1877 QPrintPreviewDialog Preview(&Printer, this);
1878 connect(&Preview, SIGNAL(paintRequested(QPrinter*)), SLOT(Print(QPrinter*)));
1879 Preview.exec();
1880 #endif
1881 }
1882
ToggleFullScreen()1883 void lcMainWindow::ToggleFullScreen()
1884 {
1885 // todo: hide toolbars and menu
1886 // todo: create fullscreen toolbar or support esc key to go back
1887 if (isFullScreen())
1888 showNormal();
1889 else
1890 showFullScreen();
1891 }
1892
AddRecentFile(const QString & FileName)1893 void lcMainWindow::AddRecentFile(const QString& FileName)
1894 {
1895 QString SavedName = FileName;
1896 int FileIdx;
1897
1898 QFileInfo FileInfo(FileName);
1899
1900 for (FileIdx = 0; FileIdx < LC_MAX_RECENT_FILES; FileIdx++)
1901 if (QFileInfo(mRecentFiles[FileIdx]) == FileInfo)
1902 break;
1903
1904 for (FileIdx = lcMin(FileIdx, LC_MAX_RECENT_FILES - 1); FileIdx > 0; FileIdx--)
1905 mRecentFiles[FileIdx] = mRecentFiles[FileIdx - 1];
1906
1907 mRecentFiles[0] = SavedName;
1908
1909 UpdateRecentFiles();
1910 }
1911
RemoveRecentFile(int FileIndex)1912 void lcMainWindow::RemoveRecentFile(int FileIndex)
1913 {
1914 for (int FileIdx = FileIndex; FileIdx < LC_MAX_RECENT_FILES - 1; FileIdx++)
1915 mRecentFiles[FileIdx] = mRecentFiles[FileIdx + 1];
1916
1917 mRecentFiles[LC_MAX_RECENT_FILES - 1].clear();
1918
1919 UpdateRecentFiles();
1920 }
1921
UpdateSelectedObjects(bool SelectionChanged)1922 void lcMainWindow::UpdateSelectedObjects(bool SelectionChanged)
1923 {
1924 int Flags = 0;
1925 lcArray<lcObject*> Selection;
1926 lcObject* Focus = nullptr;
1927
1928 lcModel* ActiveModel = GetActiveModel();
1929 if (ActiveModel)
1930 ActiveModel->GetSelectionInformation(&Flags, Selection, &Focus);
1931
1932 if (SelectionChanged)
1933 {
1934 mTimelineWidget->UpdateSelection();
1935
1936 mActions[LC_EDIT_CUT]->setEnabled(Flags & LC_SEL_SELECTED);
1937 mActions[LC_EDIT_COPY]->setEnabled(Flags & LC_SEL_SELECTED);
1938 mActions[LC_EDIT_FIND]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1939 mActions[LC_EDIT_FIND_NEXT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1940 mActions[LC_EDIT_FIND_PREVIOUS]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1941 mActions[LC_EDIT_FIND_ALL]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1942 mActions[LC_EDIT_REPLACE]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1943 mActions[LC_EDIT_REPLACE_NEXT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1944 mActions[LC_EDIT_REPLACE_ALL]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1945 mActions[LC_EDIT_SELECT_INVERT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1946 mActions[LC_EDIT_SELECT_BY_NAME]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1947 mActions[LC_EDIT_SELECT_NONE]->setEnabled(Flags & LC_SEL_SELECTED);
1948 mActions[LC_EDIT_SELECT_ALL]->setEnabled(Flags & LC_SEL_UNSELECTED);
1949
1950 mActions[LC_PIECE_DELETE]->setEnabled(Flags & LC_SEL_SELECTED);
1951 mActions[LC_PIECE_DUPLICATE]->setEnabled(Flags & LC_SEL_SELECTED);
1952 mActions[LC_PIECE_PAINT_SELECTED]->setEnabled(Flags & LC_SEL_PIECE);
1953 mActions[LC_PIECE_RESET_PIVOT_POINT]->setEnabled(Flags & LC_SEL_SELECTED);
1954 mActions[LC_PIECE_REMOVE_KEY_FRAMES]->setEnabled(Flags & LC_SEL_SELECTED);
1955 mActions[LC_PIECE_ARRAY]->setEnabled(Flags & LC_SEL_PIECE);
1956 mActions[LC_PIECE_CONTROL_POINT_INSERT]->setEnabled(Flags & LC_SEL_CAN_ADD_CONTROL_POINT);
1957 mActions[LC_PIECE_CONTROL_POINT_REMOVE]->setEnabled(Flags & LC_SEL_CAN_REMOVE_CONTROL_POINT);
1958 mActions[LC_PIECE_HIDE_SELECTED]->setEnabled(Flags & LC_SEL_VISIBLE_SELECTED);
1959 mActions[LC_PIECE_HIDE_UNSELECTED]->setEnabled(Flags & LC_SEL_UNSELECTED);
1960 mActions[LC_PIECE_UNHIDE_SELECTED]->setEnabled(Flags & LC_SEL_HIDDEN_SELECTED);
1961 mActions[LC_PIECE_UNHIDE_ALL]->setEnabled(Flags & LC_SEL_HIDDEN);
1962 mActions[LC_PIECE_VIEW_SELECTED_MODEL]->setEnabled(Flags & LC_SEL_MODEL_SELECTED);
1963 mActions[LC_PIECE_MOVE_SELECTION_TO_MODEL]->setEnabled(Flags & LC_SEL_PIECE);
1964 mActions[LC_PIECE_INLINE_SELECTED_MODELS]->setEnabled(Flags & LC_SEL_MODEL_SELECTED);
1965 mActions[LC_PIECE_EDIT_SELECTED_SUBMODEL]->setEnabled(Flags & LC_SEL_MODEL_SELECTED);
1966 mActions[LC_PIECE_GROUP]->setEnabled(Flags & LC_SEL_CAN_GROUP);
1967 mActions[LC_PIECE_UNGROUP]->setEnabled(Flags & LC_SEL_GROUPED);
1968 mActions[LC_PIECE_GROUP_ADD]->setEnabled((Flags & (LC_SEL_GROUPED | LC_SEL_FOCUS_GROUPED)) == LC_SEL_GROUPED);
1969 mActions[LC_PIECE_GROUP_REMOVE]->setEnabled(Flags & LC_SEL_FOCUS_GROUPED);
1970 mActions[LC_PIECE_GROUP_EDIT]->setEnabled((Flags & LC_SEL_NO_PIECES) == 0);
1971 mActions[LC_PIECE_SHOW_EARLIER]->setEnabled(Flags & LC_SEL_PIECE); // FIXME: disable if current step is 1
1972 mActions[LC_PIECE_SHOW_LATER]->setEnabled(Flags & LC_SEL_PIECE);
1973 mActions[LC_TIMELINE_MOVE_SELECTION]->setEnabled(Flags & LC_SEL_PIECE);
1974
1975 mActions[LC_PIECE_EDIT_END_SUBMODEL]->setEnabled(GetCurrentTabModel() != ActiveModel);
1976 }
1977
1978 mPropertiesWidget->Update(Selection, Focus);
1979
1980 QString Message;
1981
1982 if ((Selection.GetSize() == 1) && Focus)
1983 {
1984 if (Focus->IsPiece())
1985 Message = tr("%1 (ID: %2)").arg(Focus->GetName(), ((lcPiece*)Focus)->GetID());
1986 else
1987 Message = Focus->GetName();
1988 }
1989 else if (Selection.GetSize() > 0)
1990 {
1991 Message = tr("%n Object(s) selected", "", Selection.GetSize());
1992
1993 if (Focus && Focus->IsPiece())
1994 {
1995 Message.append(tr(" - %1 (ID: %2)").arg(Focus->GetName(), ((lcPiece*)Focus)->GetID()));
1996
1997 const lcGroup* Group = ((lcPiece*)Focus)->GetGroup();
1998 if (Group && !Group->mName.isEmpty())
1999 Message.append(tr(" in group '%1'").arg(Group->mName));
2000 }
2001 }
2002
2003 mStatusBarLabel->setText(Message);
2004 lcVector3 Position;
2005 lcGetActiveModel()->GetFocusPosition(Position);
2006
2007 QString Label("X: %1 Y: %2 Z: %3");
2008 Label = Label.arg(QLocale::system().toString(Position[0], 'f', 2), QLocale::system().toString(Position[1], 'f', 2), QLocale::system().toString(Position[2], 'f', 2));
2009 mStatusPositionLabel->setText(Label);
2010 }
2011
UpdateTimeline(bool Clear,bool UpdateItems)2012 void lcMainWindow::UpdateTimeline(bool Clear, bool UpdateItems)
2013 {
2014 mTimelineWidget->Update(Clear, UpdateItems);
2015 }
2016
UpdatePaste(bool Enabled)2017 void lcMainWindow::UpdatePaste(bool Enabled)
2018 {
2019 if (mActions[LC_EDIT_PASTE])
2020 mActions[LC_EDIT_PASTE]->setEnabled(Enabled);
2021
2022 if (mActions[LC_EDIT_PASTE_STEPS])
2023 mActions[LC_EDIT_PASTE_STEPS]->setEnabled(Enabled);
2024 }
2025
UpdateCurrentStep()2026 void lcMainWindow::UpdateCurrentStep()
2027 {
2028 lcModel* Model = lcGetActiveModel();
2029 lcStep CurrentStep = Model->GetCurrentStep();
2030 lcStep LastStep = Model->GetLastStep();
2031
2032 mActions[LC_VIEW_TIME_FIRST]->setEnabled(CurrentStep != 1);
2033 mActions[LC_VIEW_TIME_PREVIOUS]->setEnabled(CurrentStep > 1);
2034 mActions[LC_VIEW_TIME_NEXT]->setEnabled(CurrentStep < LC_STEP_MAX);
2035 mActions[LC_VIEW_TIME_LAST]->setEnabled(CurrentStep != LastStep);
2036
2037 mStatusTimeLabel->setText(QString(tr("Step %1")).arg(QString::number(CurrentStep)));
2038 }
2039
SetAddKeys(bool AddKeys)2040 void lcMainWindow::SetAddKeys(bool AddKeys)
2041 {
2042 QAction* Action = mActions[LC_VIEW_TIME_ADD_KEYS];
2043
2044 if (Action)
2045 Action->setChecked(AddKeys);
2046
2047 mAddKeys = AddKeys;
2048 }
2049
UpdateLockSnap()2050 void lcMainWindow::UpdateLockSnap()
2051 {
2052 if (GetRelativeTransform())
2053 mActions[LC_EDIT_TRANSFORM_RELATIVE]->setChecked(true);
2054 else
2055 mActions[LC_EDIT_TRANSFORM_ABSOLUTE]->setChecked(true);
2056
2057 if (GetSeparateTransform())
2058 mActions[LC_EDIT_TRANSFORM_SEPARATELY]->setChecked(true);
2059 else
2060 mActions[LC_EDIT_TRANSFORM_TOGETHER]->setChecked(true);
2061
2062 UpdateSnap();
2063 }
2064
UpdateSnap()2065 void lcMainWindow::UpdateSnap()
2066 {
2067 mActions[LC_EDIT_SNAP_MOVE_TOGGLE]->setChecked(mMoveSnapEnabled);
2068 mActions[LC_EDIT_SNAP_ANGLE_TOGGLE]->setChecked(mAngleSnapEnabled);
2069 mActions[LC_EDIT_SNAP_MOVE_XY0 + mMoveXYSnapIndex]->setChecked(true);
2070 mActions[LC_EDIT_SNAP_MOVE_Z0 + mMoveZSnapIndex]->setChecked(true);
2071 mActions[LC_EDIT_SNAP_ANGLE0 + mAngleSnapIndex]->setChecked(true);
2072
2073 QString Relative = mRelativeTransform ? tr("Rel") : tr("Abs");
2074 mStatusSnapLabel->setText(QString(tr(" M: %1 %2 R: %3 %4 ")).arg(GetMoveXYSnapText(), GetMoveZSnapText(), GetAngleSnapText(), Relative));
2075 }
2076
UpdateColor()2077 void lcMainWindow::UpdateColor()
2078 {
2079 QPixmap Pixmap(14, 14);
2080 Pixmap.fill(QColor::fromRgbF(gColorList[mColorIndex].Value[0], gColorList[mColorIndex].Value[1], gColorList[mColorIndex].Value[2]));
2081
2082 mColorButton->setIcon(Pixmap);
2083 mColorButton->setText(QString(" ") + gColorList[mColorIndex].Name);
2084 mColorList->setCurrentColor(mColorIndex);
2085 }
2086
UpdateUndoRedo(const QString & UndoText,const QString & RedoText)2087 void lcMainWindow::UpdateUndoRedo(const QString& UndoText, const QString& RedoText)
2088 {
2089 QAction* UndoAction = mActions[LC_EDIT_UNDO];
2090 QAction* RedoAction = mActions[LC_EDIT_REDO];
2091
2092 if (!UndoText.isEmpty())
2093 {
2094 UndoAction->setEnabled(true);
2095 UndoAction->setText(QString(tr("&Undo %1")).arg(UndoText));
2096 }
2097 else
2098 {
2099 UndoAction->setEnabled(false);
2100 UndoAction->setText(tr("&Undo"));
2101 }
2102
2103 if (!RedoText.isEmpty())
2104 {
2105 RedoAction->setEnabled(true);
2106 RedoAction->setText(QString(tr("&Redo %1")).arg(RedoText));
2107 }
2108 else
2109 {
2110 RedoAction->setEnabled(false);
2111 RedoAction->setText(tr("&Redo"));
2112 }
2113 }
2114
ViewFocusReceived()2115 void lcMainWindow::ViewFocusReceived()
2116 {
2117 SetActiveView(qobject_cast<lcView*>(sender()));
2118 }
2119
ViewCameraChanged()2120 void lcMainWindow::ViewCameraChanged()
2121 {
2122 lcView* View = qobject_cast<lcView*>(sender());
2123
2124 if (!View || !View->IsLastFocused())
2125 return;
2126
2127 UpdateCameraMenu();
2128 }
2129
UpdateCameraMenu()2130 void lcMainWindow::UpdateCameraMenu()
2131 {
2132 const lcArray<lcCamera*>& Cameras = lcGetActiveModel()->GetCameras();
2133 lcView* ActiveView = GetActiveView();
2134 const lcCamera* CurrentCamera = ActiveView ? ActiveView->GetCamera() : nullptr;
2135 bool CurrentSet = false;
2136
2137 for (int ActionIdx = LC_VIEW_CAMERA_FIRST; ActionIdx <= LC_VIEW_CAMERA_LAST; ActionIdx++)
2138 {
2139 QAction* Action = mActions[ActionIdx];
2140 int CameraIdx = ActionIdx - LC_VIEW_CAMERA_FIRST;
2141
2142 if (CameraIdx < Cameras.GetSize())
2143 {
2144 if (CurrentCamera == Cameras[CameraIdx])
2145 {
2146 Action->setChecked(true);
2147 CurrentSet = true;
2148 }
2149
2150 Action->setText(Cameras[CameraIdx]->GetName());
2151 Action->setVisible(true);
2152 }
2153 else
2154 Action->setVisible(false);
2155 }
2156
2157 if (!CurrentSet)
2158 mActions[LC_VIEW_CAMERA_NONE]->setChecked(true);
2159
2160 UpdatePerspective();
2161 }
2162
UpdatePerspective()2163 void lcMainWindow::UpdatePerspective()
2164 {
2165 lcView* ActiveView = GetActiveView();
2166
2167 if (ActiveView)
2168 {
2169 if (ActiveView->GetCamera()->IsOrtho())
2170 mActions[LC_VIEW_PROJECTION_ORTHO]->setChecked(true);
2171 else
2172 mActions[LC_VIEW_PROJECTION_PERSPECTIVE]->setChecked(true);
2173 }
2174 }
2175
UpdateShadingMode()2176 void lcMainWindow::UpdateShadingMode()
2177 {
2178 mActions[LC_VIEW_SHADING_FIRST + static_cast<int>(lcGetPreferences().mShadingMode)]->setChecked(true);
2179 }
2180
UpdateSelectionMode()2181 void lcMainWindow::UpdateSelectionMode()
2182 {
2183 switch (mSelectionMode)
2184 {
2185 case lcSelectionMode::Single:
2186 mActions[LC_EDIT_SELECTION_SINGLE]->setChecked(true);
2187 break;
2188
2189 case lcSelectionMode::Piece:
2190 mActions[LC_EDIT_SELECTION_PIECE]->setChecked(true);
2191 break;
2192
2193 case lcSelectionMode::Color:
2194 mActions[LC_EDIT_SELECTION_COLOR]->setChecked(true);
2195 break;
2196
2197 case lcSelectionMode::PieceColor:
2198 mActions[LC_EDIT_SELECTION_PIECE_COLOR]->setChecked(true);
2199 break;
2200 }
2201 }
2202
UpdateModels()2203 void lcMainWindow::UpdateModels()
2204 {
2205 const lcArray<lcModel*>& Models = lcGetActiveProject()->GetModels();
2206 lcModel* CurrentModel = lcGetActiveModel();
2207
2208 for (int ActionIdx = LC_MODEL_FIRST; ActionIdx <= LC_MODEL_LAST; ActionIdx++)
2209 {
2210 QAction* Action = mActions[ActionIdx];
2211 int ModelIdx = ActionIdx - LC_MODEL_FIRST;
2212
2213 if (ModelIdx < Models.GetSize())
2214 {
2215 Action->setChecked(CurrentModel == Models[ModelIdx]);
2216 Action->setText(QString::fromLatin1("%1%2 %3").arg(ModelIdx < 9 ? QString("&") : QString(), QString::number(ModelIdx + 1), Models[ModelIdx]->GetProperties().mFileName));
2217 Action->setVisible(true);
2218 }
2219 else
2220 Action->setVisible(false);
2221 }
2222
2223 for (int TabIdx = 0; TabIdx < mModelTabWidget->count(); )
2224 {
2225 lcModelTabWidget* TabWidget = (lcModelTabWidget*)mModelTabWidget->widget(TabIdx);
2226 lcModel* Model = TabWidget->GetModel();
2227
2228 if (!Model)
2229 TabIdx++;
2230 else if (Models.FindIndex(Model) != -1)
2231 {
2232 mModelTabWidget->setTabText(TabIdx, Model->GetProperties().mFileName);
2233 TabIdx++;
2234 }
2235 else
2236 delete TabWidget;
2237 }
2238
2239 mPartSelectionWidget->UpdateModels();
2240
2241 if (mCurrentPieceInfo && mCurrentPieceInfo->IsModel())
2242 if (Models.FindIndex(mCurrentPieceInfo->GetModel()) == -1)
2243 SetCurrentPieceInfo(nullptr);
2244 }
2245
UpdateCategories()2246 void lcMainWindow::UpdateCategories()
2247 {
2248 mPartSelectionWidget->UpdateCategories();
2249 }
2250
UpdateTitle()2251 void lcMainWindow::UpdateTitle()
2252 {
2253 setWindowModified(lcGetActiveProject()->IsModified());
2254 setWindowFilePath(lcGetActiveProject()->GetTitle());
2255 }
2256
UpdateModified(bool Modified)2257 void lcMainWindow::UpdateModified(bool Modified)
2258 {
2259 setWindowModified(Modified);
2260 }
2261
UpdateRecentFiles()2262 void lcMainWindow::UpdateRecentFiles()
2263 {
2264 for (int ActionIdx = LC_FILE_RECENT_FIRST; ActionIdx <= LC_FILE_RECENT_LAST; ActionIdx++)
2265 {
2266 int FileIdx = ActionIdx - LC_FILE_RECENT_FIRST;
2267 QAction* Action = mActions[ActionIdx];
2268
2269 if (!mRecentFiles[FileIdx].isEmpty())
2270 {
2271 Action->setText(QString("&%1 %2").arg(QString::number(FileIdx + 1), QDir::toNativeSeparators(mRecentFiles[FileIdx])));
2272 Action->setVisible(true);
2273 }
2274 else
2275 Action->setVisible(false);
2276 }
2277
2278 mActionFileRecentSeparator->setVisible(!mRecentFiles[0].isEmpty());
2279 }
2280
UpdateShortcuts()2281 void lcMainWindow::UpdateShortcuts()
2282 {
2283 for (int ActionIdx = 0; ActionIdx < LC_NUM_COMMANDS; ActionIdx++)
2284 mActions[ActionIdx]->setShortcut(QKeySequence(gKeyboardShortcuts.mShortcuts[ActionIdx]));
2285 }
2286
NewProject()2287 void lcMainWindow::NewProject()
2288 {
2289 if (!SaveProjectIfModified())
2290 return;
2291
2292 Project* NewProject = new Project();
2293 gApplication->SetProject(NewProject);
2294 lcGetPiecesLibrary()->UnloadUnusedParts();
2295 }
2296
OpenProject(const QString & FileName)2297 bool lcMainWindow::OpenProject(const QString& FileName)
2298 {
2299 if (!SaveProjectIfModified())
2300 return false;
2301
2302 QString LoadFileName = FileName;
2303
2304 if (LoadFileName.isEmpty())
2305 {
2306 LoadFileName = lcGetActiveProject()->GetFileName();
2307
2308 if (LoadFileName.isEmpty())
2309 LoadFileName = lcGetProfileString(LC_PROFILE_PROJECTS_PATH);
2310
2311 LoadFileName = QFileDialog::getOpenFileName(this, tr("Open Model"), LoadFileName, tr("Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*)"));
2312
2313 if (LoadFileName.isEmpty())
2314 return false;
2315
2316 lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(LoadFileName).absolutePath());
2317 }
2318
2319 return OpenProjectFile(LoadFileName);
2320 }
2321
OpenRecentProject(int RecentFileIndex)2322 void lcMainWindow::OpenRecentProject(int RecentFileIndex)
2323 {
2324 if (!SaveProjectIfModified())
2325 return;
2326
2327 if (!OpenProjectFile(mRecentFiles[RecentFileIndex]))
2328 RemoveRecentFile(RecentFileIndex);
2329 }
2330
OpenProjectFile(const QString & FileName)2331 bool lcMainWindow::OpenProjectFile(const QString& FileName)
2332 {
2333 Project* NewProject = new Project();
2334
2335 if (NewProject->Load(FileName, true))
2336 {
2337 gApplication->SetProject(NewProject);
2338 AddRecentFile(FileName);
2339 lcView::UpdateProjectViews(NewProject);
2340
2341 return true;
2342 }
2343
2344 delete NewProject;
2345 return false;
2346 }
2347
MergeProject()2348 void lcMainWindow::MergeProject()
2349 {
2350 QString LoadFileName = lcGetActiveProject()->GetFileName();
2351
2352 if (LoadFileName.isEmpty())
2353 LoadFileName = lcGetProfileString(LC_PROFILE_PROJECTS_PATH);
2354
2355 LoadFileName = QFileDialog::getOpenFileName(this, tr("Merge Model"), LoadFileName, tr("Supported Files (*.lcd *.ldr *.dat *.mpd);;All Files (*.*)"));
2356
2357 if (LoadFileName.isEmpty())
2358 return;
2359
2360 lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(LoadFileName).absolutePath());
2361
2362 Project* NewProject = new Project();
2363
2364 if (NewProject->Load(LoadFileName, true))
2365 {
2366 int NumModels = NewProject->GetModels().GetSize();
2367
2368 lcGetActiveProject()->Merge(NewProject);
2369
2370 if (NumModels == 1)
2371 QMessageBox::information(this, tr("LeoCAD"), tr("Merged 1 submodel."));
2372 else
2373 QMessageBox::information(this, tr("LeoCAD"), tr("Merged %1 submodels.").arg(NumModels));
2374
2375 UpdateModels();
2376 }
2377
2378 delete NewProject;
2379 }
2380
ImportLDD()2381 void lcMainWindow::ImportLDD()
2382 {
2383 if (!SaveProjectIfModified())
2384 return;
2385
2386 QString LoadFileName = QFileDialog::getOpenFileName(this, tr("Import"), QString(), tr("LEGO Diginal Designer Files (*.lxf);;All Files (*.*)"));
2387 if (LoadFileName.isEmpty())
2388 return;
2389
2390 Project* NewProject = new Project();
2391
2392 if (NewProject->ImportLDD(LoadFileName))
2393 {
2394 gApplication->SetProject(NewProject);
2395 lcView::UpdateProjectViews(NewProject);
2396 }
2397 else
2398 delete NewProject;
2399 }
2400
ImportInventory()2401 void lcMainWindow::ImportInventory()
2402 {
2403 if (!SaveProjectIfModified())
2404 return;
2405
2406 lcSetsDatabaseDialog Dialog(this);
2407 if (Dialog.exec() != QDialog::Accepted)
2408 return;
2409
2410 Project* NewProject = new Project();
2411
2412 if (NewProject->ImportInventory(Dialog.GetSetInventory(), Dialog.GetSetName(), Dialog.GetSetDescription()))
2413 {
2414 gApplication->SetProject(NewProject);
2415 lcView::UpdateProjectViews(NewProject);
2416 }
2417 else
2418 delete NewProject;
2419 }
SaveProject(const QString & FileName)2420 bool lcMainWindow::SaveProject(const QString& FileName)
2421 {
2422 QString SaveFileName = FileName;
2423 Project* Project = lcGetActiveProject();
2424
2425 if (SaveFileName.isEmpty())
2426 {
2427 SaveFileName = Project->GetFileName();
2428
2429 if (SaveFileName.isEmpty())
2430 SaveFileName = QFileInfo(QDir(lcGetProfileString(LC_PROFILE_PROJECTS_PATH)), Project->GetTitle()).absoluteFilePath();
2431
2432 QString Filter = (Project->GetModels().GetSize() > 1) ? tr("Supported Files (*.mpd);;All Files (*.*)") : tr("Supported Files (*.ldr *.dat *.mpd);;All Files (*.*)");
2433
2434 SaveFileName = QFileDialog::getSaveFileName(this, tr("Save Model"), SaveFileName, Filter);
2435
2436 if (SaveFileName.isEmpty())
2437 return false;
2438
2439 lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(SaveFileName).absolutePath());
2440 }
2441
2442 if (QFileInfo(SaveFileName).suffix().toLower() == QLatin1String("lcd"))
2443 {
2444 QMessageBox::warning(this, tr("Error"), tr("Saving files in LCD format is no longer supported, please use the LDR or MPD formats instead."));
2445 return false;
2446 }
2447
2448 if (!Project->Save(SaveFileName))
2449 return false;
2450
2451 AddRecentFile(SaveFileName);
2452 UpdateTitle();
2453
2454 return true;
2455 }
2456
SaveProjectIfModified()2457 bool lcMainWindow::SaveProjectIfModified()
2458 {
2459 Project* Project = lcGetActiveProject();
2460 if (!Project->IsModified())
2461 return true;
2462
2463 switch (QMessageBox::question(this, tr("Save Model"), tr("Save changes to '%1'?").arg(Project->GetTitle()), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel))
2464 {
2465 default:
2466 case QMessageBox::Cancel:
2467 return false;
2468
2469 case QMessageBox::Yes:
2470 if (!SaveProject(Project->GetFileName()))
2471 return false;
2472 break;
2473
2474 case QMessageBox::No:
2475 break;
2476 }
2477
2478 return true;
2479 }
2480
SetModelFromFocus()2481 bool lcMainWindow::SetModelFromFocus()
2482 {
2483 lcObject* FocusObject = GetActiveModel()->GetFocusObject();
2484
2485 if (!FocusObject || !FocusObject->IsPiece())
2486 return false;
2487
2488 lcModel* Model = ((lcPiece*)FocusObject)->mPieceInfo->GetModel();
2489
2490 if (Model)
2491 {
2492 Project* Project = lcGetActiveProject();
2493 Project->SetActiveModel(Project->GetModels().FindIndex(Model));
2494 return true;
2495 }
2496
2497 return false;
2498 }
2499
SetModelFromSelection()2500 void lcMainWindow::SetModelFromSelection()
2501 {
2502 if (SetModelFromFocus())
2503 return;
2504
2505 lcModel* Model = GetActiveModel()->GetFirstSelectedSubmodel();
2506
2507 if (Model)
2508 {
2509 Project* Project = lcGetActiveProject();
2510 Project->SetActiveModel(Project->GetModels().FindIndex(Model));
2511 }
2512 }
2513
GetActiveModel() const2514 lcModel* lcMainWindow::GetActiveModel() const
2515 {
2516 lcView* ActiveView = GetActiveView();
2517 return ActiveView ? ActiveView->GetActiveModel() : nullptr;
2518 }
2519
GetTabForView(lcView * View) const2520 lcModelTabWidget* lcMainWindow::GetTabForView(lcView* View) const
2521 {
2522 QWidget* Widget = View->GetWidget();
2523
2524 while (Widget)
2525 {
2526 lcModelTabWidget* TabWidget = qobject_cast<lcModelTabWidget*>(Widget);
2527
2528 if (TabWidget)
2529 return TabWidget;
2530 else
2531 Widget = Widget->parentWidget();
2532 }
2533
2534 return nullptr;
2535 }
2536
HandleCommand(lcCommandId CommandId)2537 void lcMainWindow::HandleCommand(lcCommandId CommandId)
2538 {
2539 lcView* ActiveView = GetActiveView();
2540 lcModel* ActiveModel = ActiveView ? ActiveView->GetActiveModel() : nullptr;
2541
2542 switch (CommandId)
2543 {
2544 case LC_FILE_NEW:
2545 NewProject();
2546 break;
2547
2548 case LC_FILE_OPEN:
2549 OpenProject(QString());
2550 break;
2551
2552 case LC_FILE_MERGE:
2553 MergeProject();
2554 break;
2555
2556 case LC_FILE_SAVE:
2557 SaveProject(lcGetActiveProject()->GetFileName());
2558 break;
2559
2560 case LC_FILE_SAVEAS:
2561 SaveProject(QString());
2562 break;
2563
2564 case LC_FILE_SAVE_IMAGE:
2565 lcGetActiveProject()->SaveImage();
2566 break;
2567
2568 case LC_FILE_IMPORT_LDD:
2569 ImportLDD();
2570 break;
2571
2572 case LC_FILE_IMPORT_INVENTORY:
2573 ImportInventory();
2574 break;
2575
2576 case LC_FILE_EXPORT_3DS:
2577 lcGetActiveProject()->Export3DStudio(QString());
2578 break;
2579
2580 case LC_FILE_EXPORT_COLLADA:
2581 lcGetActiveProject()->ExportCOLLADA(QString());
2582 break;
2583
2584 case LC_FILE_EXPORT_HTML:
2585 ShowHTMLDialog();
2586 break;
2587
2588 case LC_FILE_EXPORT_BRICKLINK:
2589 lcGetActiveProject()->ExportBrickLink();
2590 break;
2591
2592 case LC_FILE_EXPORT_CSV:
2593 lcGetActiveProject()->ExportCSV();
2594 break;
2595
2596 case LC_FILE_EXPORT_POVRAY:
2597 lcGetActiveProject()->ExportPOVRay(QString());
2598 break;
2599
2600 case LC_FILE_EXPORT_WAVEFRONT:
2601 lcGetActiveProject()->ExportWavefront(QString());
2602 break;
2603
2604 case LC_FILE_RENDER:
2605 ShowRenderDialog();
2606 break;
2607
2608 case LC_FILE_INSTRUCTIONS:
2609 ShowInstructionsDialog();
2610 break;
2611
2612 case LC_FILE_PRINT_PREVIEW:
2613 TogglePrintPreview();
2614 break;
2615
2616 case LC_FILE_PRINT:
2617 ShowPrintDialog();
2618 break;
2619
2620 case LC_FILE_RECENT1:
2621 case LC_FILE_RECENT2:
2622 case LC_FILE_RECENT3:
2623 case LC_FILE_RECENT4:
2624 OpenRecentProject(CommandId - LC_FILE_RECENT1);
2625 break;
2626
2627 case LC_FILE_EXIT:
2628 close();
2629 break;
2630
2631 case LC_EDIT_UNDO:
2632 if (ActiveModel)
2633 ActiveModel->UndoAction();
2634 break;
2635
2636 case LC_EDIT_REDO:
2637 if (ActiveModel)
2638 ActiveModel->RedoAction();
2639 break;
2640
2641 case LC_EDIT_CUT:
2642 if (ActiveModel)
2643 ActiveModel->Cut();
2644 break;
2645
2646 case LC_EDIT_COPY:
2647 if (ActiveModel)
2648 ActiveModel->Copy();
2649 break;
2650
2651 case LC_EDIT_PASTE:
2652 if (ActiveModel)
2653 ActiveModel->Paste(true);
2654 break;
2655
2656 case LC_EDIT_PASTE_STEPS:
2657 if (ActiveModel)
2658 ActiveModel->Paste(false);
2659 break;
2660
2661 case LC_EDIT_FIND:
2662 if (ActiveView)
2663 ActiveView->ShowFindReplaceWidget(false);
2664 break;
2665
2666 case LC_EDIT_FIND_NEXT:
2667 if (ActiveModel)
2668 ActiveModel->FindReplacePiece(true, false);
2669 break;
2670
2671 case LC_EDIT_FIND_PREVIOUS:
2672 if (ActiveModel)
2673 ActiveModel->FindReplacePiece(false, false);
2674 break;
2675
2676 case LC_EDIT_FIND_ALL:
2677 if (ActiveModel)
2678 ActiveModel->FindReplacePiece(true, true);
2679 break;
2680
2681 case LC_EDIT_REPLACE:
2682 if (ActiveView)
2683 ActiveView->ShowFindReplaceWidget(true);
2684 break;
2685
2686 case LC_EDIT_REPLACE_ALL:
2687 if (ActiveModel)
2688 ActiveModel->FindReplacePiece(true, true);
2689 break;
2690
2691 case LC_EDIT_REPLACE_NEXT:
2692 if (ActiveModel)
2693 ActiveModel->FindReplacePiece(true, false);
2694 break;
2695
2696 case LC_EDIT_SELECT_ALL:
2697 if (ActiveModel)
2698 ActiveModel->SelectAllPieces();
2699 break;
2700
2701 case LC_EDIT_SELECT_NONE:
2702 if (ActiveModel)
2703 ActiveModel->ClearSelection(true);
2704 break;
2705
2706 case LC_EDIT_SELECT_INVERT:
2707 if (ActiveModel)
2708 ActiveModel->InvertSelection();
2709 break;
2710
2711 case LC_EDIT_SELECT_BY_NAME:
2712 if (ActiveModel)
2713 ActiveModel->ShowSelectByNameDialog();
2714 break;
2715
2716 case LC_EDIT_SELECTION_SINGLE:
2717 SetSelectionMode(lcSelectionMode::Single);
2718 break;
2719
2720 case LC_EDIT_SELECTION_PIECE:
2721 SetSelectionMode(lcSelectionMode::Piece);
2722 break;
2723
2724 case LC_EDIT_SELECTION_COLOR:
2725 SetSelectionMode(lcSelectionMode::Color);
2726 break;
2727
2728 case LC_EDIT_SELECTION_PIECE_COLOR:
2729 SetSelectionMode(lcSelectionMode::PieceColor);
2730 break;
2731
2732 case LC_VIEW_SPLIT_HORIZONTAL:
2733 SplitHorizontal();
2734 break;
2735
2736 case LC_VIEW_SPLIT_VERTICAL:
2737 SplitVertical();
2738 break;
2739
2740 case LC_VIEW_REMOVE_VIEW:
2741 RemoveActiveView();
2742 break;
2743
2744 case LC_VIEW_RESET_VIEWS:
2745 ResetViews();
2746 break;
2747
2748 case LC_VIEW_TOOLBAR_STANDARD:
2749 ToggleDockWidget(mStandardToolBar);
2750 break;
2751
2752 case LC_VIEW_TOOLBAR_TOOLS:
2753 ToggleDockWidget(mToolsToolBar);
2754 break;
2755
2756 case LC_VIEW_TOOLBAR_TIME:
2757 ToggleDockWidget(mTimeToolBar);
2758 break;
2759
2760 case LC_VIEW_TOOLBAR_PARTS:
2761 ToggleDockWidget(mPartsToolBar);
2762 break;
2763
2764 case LC_VIEW_TOOLBAR_COLORS:
2765 ToggleDockWidget(mColorsToolBar);
2766 break;
2767
2768 case LC_VIEW_TOOLBAR_PROPERTIES:
2769 ToggleDockWidget(mPropertiesToolBar);
2770 break;
2771
2772 case LC_VIEW_TOOLBAR_TIMELINE:
2773 ToggleDockWidget(mTimelineToolBar);
2774 break;
2775
2776 case LC_VIEW_TOOLBAR_PREVIEW:
2777 ToggleDockWidget(mPreviewToolBar);
2778 break;
2779
2780 case LC_VIEW_FULLSCREEN:
2781 ToggleFullScreen();
2782 break;
2783
2784 case LC_VIEW_CLOSE_CURRENT_TAB:
2785 CloseCurrentModelTab();
2786 break;
2787
2788 case LC_VIEW_SHADING_WIREFRAME:
2789 SetShadingMode(lcShadingMode::Wireframe);
2790 break;
2791
2792 case LC_VIEW_SHADING_FLAT:
2793 SetShadingMode(lcShadingMode::Flat);
2794 break;
2795
2796 case LC_VIEW_SHADING_DEFAULT_LIGHTS:
2797 SetShadingMode(lcShadingMode::DefaultLights);
2798 break;
2799
2800 case LC_VIEW_PROJECTION_PERSPECTIVE:
2801 if (ActiveView)
2802 ActiveView->SetProjection(false);
2803 break;
2804
2805 case LC_VIEW_PROJECTION_ORTHO:
2806 if (ActiveView)
2807 ActiveView->SetProjection(true);
2808 break;
2809
2810 case LC_VIEW_TOGGLE_VIEW_SPHERE:
2811 ToggleViewSphere();
2812 break;
2813
2814 case LC_VIEW_TOGGLE_AXIS_ICON:
2815 ToggleAxisIcon();
2816 break;
2817
2818 case LC_VIEW_TOGGLE_GRID:
2819 ToggleGrid();
2820 break;
2821
2822 case LC_VIEW_FADE_PREVIOUS_STEPS:
2823 ToggleFadePreviousSteps();
2824 break;
2825
2826 case LC_PIECE_INSERT:
2827 if (ActiveModel)
2828 ActiveModel->AddPiece();
2829 break;
2830
2831 case LC_PIECE_DELETE:
2832 if (ActiveModel)
2833 ActiveModel->DeleteSelectedObjects();
2834 break;
2835
2836 case LC_PIECE_DUPLICATE:
2837 if (ActiveModel)
2838 ActiveModel->DuplicateSelectedPieces();
2839 break;
2840
2841 case LC_PIECE_PAINT_SELECTED:
2842 if (ActiveModel)
2843 ActiveModel->PaintSelectedPieces();
2844 break;
2845
2846 case LC_PIECE_RESET_PIVOT_POINT:
2847 if (ActiveModel)
2848 ActiveModel->ResetSelectedPiecesPivotPoint();
2849 break;
2850
2851 case LC_PIECE_REMOVE_KEY_FRAMES:
2852 if (ActiveModel)
2853 ActiveModel->RemoveSelectedPiecesKeyFrames();
2854 break;
2855
2856 case LC_PIECE_CONTROL_POINT_INSERT:
2857 if (ActiveModel)
2858 ActiveModel->InsertControlPoint();
2859 break;
2860
2861 case LC_PIECE_CONTROL_POINT_REMOVE:
2862 if (ActiveModel)
2863 ActiveModel->RemoveFocusedControlPoint();
2864 break;
2865
2866 case LC_PIECE_MOVE_PLUSX:
2867 if (ActiveModel)
2868 ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true);
2869 break;
2870
2871 case LC_PIECE_MOVE_MINUSX:
2872 if (ActiveModel)
2873 ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(-lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true);
2874 break;
2875
2876 case LC_PIECE_MOVE_PLUSY:
2877 if (ActiveModel)
2878 ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true);
2879 break;
2880
2881 case LC_PIECE_MOVE_MINUSY:
2882 if (ActiveModel)
2883 ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true);
2884 break;
2885
2886 case LC_PIECE_MOVE_PLUSZ:
2887 if (ActiveModel)
2888 ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true);
2889 break;
2890
2891 case LC_PIECE_MOVE_MINUSZ:
2892 if (ActiveModel)
2893 ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true);
2894 break;
2895
2896 case LC_PIECE_ROTATE_PLUSX:
2897 if (ActiveModel)
2898 ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
2899 break;
2900
2901 case LC_PIECE_ROTATE_MINUSX:
2902 if (ActiveModel)
2903 ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(-lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
2904 break;
2905
2906 case LC_PIECE_ROTATE_PLUSY:
2907 if (ActiveModel)
2908 ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
2909 break;
2910
2911 case LC_PIECE_ROTATE_MINUSY:
2912 if (ActiveModel)
2913 ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
2914 break;
2915
2916 case LC_PIECE_ROTATE_PLUSZ:
2917 if (ActiveModel)
2918 ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
2919 break;
2920
2921 case LC_PIECE_ROTATE_MINUSZ:
2922 if (ActiveModel)
2923 ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
2924 break;
2925
2926 case LC_PIECE_MINIFIG_WIZARD:
2927 if (ActiveModel)
2928 ActiveModel->ShowMinifigDialog();
2929 break;
2930
2931 case LC_PIECE_ARRAY:
2932 if (ActiveModel)
2933 ActiveModel->ShowArrayDialog();
2934 break;
2935
2936 case LC_PIECE_VIEW_SELECTED_MODEL:
2937 SetModelFromSelection();
2938 break;
2939
2940 case LC_PIECE_MOVE_SELECTION_TO_MODEL:
2941 if (ActiveModel)
2942 ActiveModel->MoveSelectionToModel(lcGetActiveProject()->CreateNewModel(false));
2943 break;
2944
2945 case LC_PIECE_INLINE_SELECTED_MODELS:
2946 if (ActiveModel)
2947 ActiveModel->InlineSelectedModels();
2948 break;
2949
2950 case LC_PIECE_EDIT_END_SUBMODEL:
2951 if (ActiveView)
2952 {
2953 ActiveView->SetTopSubmodelActive();
2954 if (ActiveModel)
2955 {
2956 std::vector<lcModel*> UpdatedModels;
2957 ActiveModel->UpdatePieceInfo(UpdatedModels);
2958 }
2959 }
2960 break;
2961
2962 case LC_PIECE_EDIT_SELECTED_SUBMODEL:
2963 if (ActiveView)
2964 ActiveView->SetSelectedSubmodelActive();
2965 break;
2966
2967 case LC_PIECE_GROUP:
2968 if (ActiveModel)
2969 ActiveModel->GroupSelection();
2970 break;
2971
2972 case LC_PIECE_UNGROUP:
2973 if (ActiveModel)
2974 ActiveModel->UngroupSelection();
2975 break;
2976
2977 case LC_PIECE_GROUP_ADD:
2978 if (ActiveModel)
2979 ActiveModel->AddSelectedPiecesToGroup();
2980 break;
2981
2982 case LC_PIECE_GROUP_REMOVE:
2983 if (ActiveModel)
2984 ActiveModel->RemoveFocusPieceFromGroup();
2985 break;
2986
2987 case LC_PIECE_GROUP_EDIT:
2988 if (ActiveModel)
2989 ActiveModel->ShowEditGroupsDialog();
2990 break;
2991
2992 case LC_PIECE_HIDE_SELECTED:
2993 if (ActiveModel)
2994 ActiveModel->HideSelectedPieces();
2995 break;
2996
2997 case LC_PIECE_HIDE_UNSELECTED:
2998 if (ActiveModel)
2999 ActiveModel->HideUnselectedPieces();
3000 break;
3001
3002 case LC_PIECE_UNHIDE_SELECTED:
3003 if (ActiveModel)
3004 ActiveModel->UnhideSelectedPieces();
3005 break;
3006
3007 case LC_PIECE_UNHIDE_ALL:
3008 if (ActiveModel)
3009 ActiveModel->UnhideAllPieces();
3010 break;
3011
3012 case LC_PIECE_SHOW_EARLIER:
3013 if (ActiveModel)
3014 ActiveModel->ShowSelectedPiecesEarlier();
3015 break;
3016
3017 case LC_PIECE_SHOW_LATER:
3018 if (ActiveModel)
3019 ActiveModel->ShowSelectedPiecesLater();
3020 break;
3021
3022 case LC_VIEW_PREFERENCES:
3023 gApplication->ShowPreferencesDialog();
3024 break;
3025
3026 case LC_VIEW_ZOOM_IN:
3027 if (ActiveView)
3028 ActiveView->Zoom(10.0f);
3029 break;
3030
3031 case LC_VIEW_ZOOM_OUT:
3032 if (ActiveView)
3033 ActiveView->Zoom(-10.0f);
3034 break;
3035
3036 case LC_VIEW_ZOOM_EXTENTS:
3037 if (ActiveView)
3038 ActiveView->ZoomExtents();
3039 break;
3040
3041 case LC_VIEW_LOOK_AT:
3042 if (ActiveView)
3043 ActiveView->LookAt();
3044 break;
3045
3046 case LC_VIEW_MOVE_FORWARD:
3047 if (ActiveView)
3048 ActiveView->MoveCamera(lcVector3(0.0f, 0.0f, -1.0f));
3049 break;
3050
3051 case LC_VIEW_MOVE_BACKWARD:
3052 if (ActiveView)
3053 ActiveView->MoveCamera(lcVector3(0.0f, 0.0f, 1.0f));
3054 break;
3055
3056 case LC_VIEW_MOVE_LEFT:
3057 if (ActiveView)
3058 ActiveView->MoveCamera(lcVector3(-1.0f, 0.0f, 0.0f));
3059 break;
3060
3061 case LC_VIEW_MOVE_RIGHT:
3062 if (ActiveView)
3063 ActiveView->MoveCamera(lcVector3(1.0f, 0.0f, 0.0f));
3064 break;
3065
3066 case LC_VIEW_MOVE_UP:
3067 if (ActiveView)
3068 ActiveView->MoveCamera(lcVector3(0.0f, 1.0f, 0.0f));
3069 break;
3070
3071 case LC_VIEW_MOVE_DOWN:
3072 if (ActiveView)
3073 ActiveView->MoveCamera(lcVector3(0.0f, -1.0f, 0.0f));
3074 break;
3075
3076 case LC_VIEW_TIME_NEXT:
3077 if (ActiveModel)
3078 ActiveModel->ShowNextStep();
3079 break;
3080
3081 case LC_VIEW_TIME_PREVIOUS:
3082 if (ActiveModel)
3083 ActiveModel->ShowPreviousStep();
3084 break;
3085
3086 case LC_VIEW_TIME_FIRST:
3087 if (ActiveModel)
3088 ActiveModel->ShowFirstStep();
3089 break;
3090
3091 case LC_VIEW_TIME_LAST:
3092 if (ActiveModel)
3093 ActiveModel->ShowLastStep();
3094 break;
3095
3096 case LC_VIEW_TIME_INSERT_BEFORE:
3097 lcGetActiveModel()->InsertStep(lcGetActiveModel()->GetCurrentStep());
3098 break;
3099
3100 case LC_VIEW_TIME_INSERT_AFTER:
3101 lcGetActiveModel()->InsertStep(lcGetActiveModel()->GetCurrentStep() + 1);
3102 break;
3103
3104 case LC_VIEW_TIME_DELETE:
3105 lcGetActiveModel()->RemoveStep(lcGetActiveModel()->GetCurrentStep());
3106 break;
3107
3108 case LC_VIEW_VIEWPOINT_FRONT:
3109 if (ActiveView)
3110 ActiveView->SetViewpoint(lcViewpoint::Front);
3111 break;
3112
3113 case LC_VIEW_VIEWPOINT_BACK:
3114 if (ActiveView)
3115 ActiveView->SetViewpoint(lcViewpoint::Back);
3116 break;
3117
3118 case LC_VIEW_VIEWPOINT_TOP:
3119 if (ActiveView)
3120 ActiveView->SetViewpoint(lcViewpoint::Top);
3121 break;
3122
3123 case LC_VIEW_VIEWPOINT_BOTTOM:
3124 if (ActiveView)
3125 ActiveView->SetViewpoint(lcViewpoint::Bottom);
3126 break;
3127
3128 case LC_VIEW_VIEWPOINT_LEFT:
3129 if (ActiveView)
3130 ActiveView->SetViewpoint(lcViewpoint::Left);
3131 break;
3132
3133 case LC_VIEW_VIEWPOINT_RIGHT:
3134 if (ActiveView)
3135 ActiveView->SetViewpoint(lcViewpoint::Right);
3136 break;
3137
3138 case LC_VIEW_VIEWPOINT_HOME:
3139 if (ActiveView)
3140 ActiveView->SetViewpoint(lcViewpoint::Home);
3141 break;
3142
3143 case LC_VIEW_CAMERA_NONE:
3144 if (ActiveView)
3145 ActiveView->RemoveCamera();
3146 break;
3147
3148 case LC_VIEW_CAMERA1:
3149 case LC_VIEW_CAMERA2:
3150 case LC_VIEW_CAMERA3:
3151 case LC_VIEW_CAMERA4:
3152 case LC_VIEW_CAMERA5:
3153 case LC_VIEW_CAMERA6:
3154 case LC_VIEW_CAMERA7:
3155 case LC_VIEW_CAMERA8:
3156 case LC_VIEW_CAMERA9:
3157 case LC_VIEW_CAMERA10:
3158 case LC_VIEW_CAMERA11:
3159 case LC_VIEW_CAMERA12:
3160 case LC_VIEW_CAMERA13:
3161 case LC_VIEW_CAMERA14:
3162 case LC_VIEW_CAMERA15:
3163 case LC_VIEW_CAMERA16:
3164 if (ActiveView)
3165 ActiveView->SetCameraIndex(CommandId - LC_VIEW_CAMERA1);
3166 break;
3167
3168 case LC_MODEL_NEW:
3169 lcGetActiveProject()->CreateNewModel(true);
3170 break;
3171
3172 case LC_MODEL_PROPERTIES:
3173 lcGetActiveModel()->ShowPropertiesDialog();
3174 break;
3175
3176 case LC_MODEL_LIST:
3177 lcGetActiveProject()->ShowModelListDialog();
3178 break;
3179
3180 case LC_MODEL_01:
3181 case LC_MODEL_02:
3182 case LC_MODEL_03:
3183 case LC_MODEL_04:
3184 case LC_MODEL_05:
3185 case LC_MODEL_06:
3186 case LC_MODEL_07:
3187 case LC_MODEL_08:
3188 case LC_MODEL_09:
3189 case LC_MODEL_10:
3190 case LC_MODEL_11:
3191 case LC_MODEL_12:
3192 case LC_MODEL_13:
3193 case LC_MODEL_14:
3194 case LC_MODEL_15:
3195 case LC_MODEL_16:
3196 case LC_MODEL_17:
3197 case LC_MODEL_18:
3198 case LC_MODEL_19:
3199 case LC_MODEL_20:
3200 case LC_MODEL_21:
3201 case LC_MODEL_22:
3202 case LC_MODEL_23:
3203 case LC_MODEL_24:
3204 case LC_MODEL_25:
3205 case LC_MODEL_26:
3206 case LC_MODEL_27:
3207 case LC_MODEL_28:
3208 case LC_MODEL_29:
3209 case LC_MODEL_30:
3210 case LC_MODEL_31:
3211 case LC_MODEL_32:
3212 case LC_MODEL_33:
3213 case LC_MODEL_34:
3214 case LC_MODEL_35:
3215 case LC_MODEL_36:
3216 case LC_MODEL_37:
3217 case LC_MODEL_38:
3218 case LC_MODEL_39:
3219 case LC_MODEL_40:
3220 lcGetActiveProject()->SetActiveModel(CommandId - LC_MODEL_01);
3221 break;
3222
3223 case LC_HELP_HOMEPAGE:
3224 QDesktopServices::openUrl(QUrl("https://www.leocad.org/"));
3225 break;
3226
3227 case LC_HELP_BUG_REPORT:
3228 QDesktopServices::openUrl(QUrl("https://github.com/leozide/leocad/issues"));
3229 break;
3230
3231 case LC_HELP_UPDATES:
3232 ShowUpdatesDialog();
3233 break;
3234
3235 case LC_HELP_ABOUT:
3236 ShowAboutDialog();
3237 break;
3238
3239 case LC_VIEW_TIME_ADD_KEYS:
3240 SetAddKeys(!GetAddKeys());
3241 break;
3242
3243 case LC_EDIT_TRANSFORM_RELATIVE:
3244 SetRelativeTransform(true);
3245 break;
3246
3247 case LC_EDIT_TRANSFORM_ABSOLUTE:
3248 SetRelativeTransform(false);
3249 break;
3250
3251 case LC_EDIT_TRANSFORM_TOGGLE_RELATIVE:
3252 SetRelativeTransform(!GetRelativeTransform());
3253 break;
3254
3255 case LC_EDIT_TRANSFORM_SEPARATELY:
3256 SetSeparateTransform(true);
3257 break;
3258
3259 case LC_EDIT_TRANSFORM_TOGETHER:
3260 SetSeparateTransform(false);
3261 break;
3262
3263 case LC_EDIT_TRANSFORM_TOGGLE_SEPARATE:
3264 SetSeparateTransform(!GetSeparateTransform());
3265 break;
3266
3267 case LC_EDIT_SNAP_MOVE_TOGGLE:
3268 SetMoveSnapEnabled(!mMoveSnapEnabled);
3269 break;
3270
3271 case LC_EDIT_SNAP_MOVE_XY0:
3272 case LC_EDIT_SNAP_MOVE_XY1:
3273 case LC_EDIT_SNAP_MOVE_XY2:
3274 case LC_EDIT_SNAP_MOVE_XY3:
3275 case LC_EDIT_SNAP_MOVE_XY4:
3276 case LC_EDIT_SNAP_MOVE_XY5:
3277 case LC_EDIT_SNAP_MOVE_XY6:
3278 case LC_EDIT_SNAP_MOVE_XY7:
3279 case LC_EDIT_SNAP_MOVE_XY8:
3280 case LC_EDIT_SNAP_MOVE_XY9:
3281 SetMoveXYSnapIndex(CommandId - LC_EDIT_SNAP_MOVE_XY0);
3282 break;
3283
3284 case LC_EDIT_SNAP_MOVE_Z0:
3285 case LC_EDIT_SNAP_MOVE_Z1:
3286 case LC_EDIT_SNAP_MOVE_Z2:
3287 case LC_EDIT_SNAP_MOVE_Z3:
3288 case LC_EDIT_SNAP_MOVE_Z4:
3289 case LC_EDIT_SNAP_MOVE_Z5:
3290 case LC_EDIT_SNAP_MOVE_Z6:
3291 case LC_EDIT_SNAP_MOVE_Z7:
3292 case LC_EDIT_SNAP_MOVE_Z8:
3293 case LC_EDIT_SNAP_MOVE_Z9:
3294 SetMoveZSnapIndex(CommandId - LC_EDIT_SNAP_MOVE_Z0);
3295 break;
3296
3297 case LC_EDIT_SNAP_ANGLE_TOGGLE:
3298 SetAngleSnapEnabled(!mAngleSnapEnabled);
3299 break;
3300
3301 case LC_EDIT_SNAP_ANGLE0:
3302 case LC_EDIT_SNAP_ANGLE1:
3303 case LC_EDIT_SNAP_ANGLE2:
3304 case LC_EDIT_SNAP_ANGLE3:
3305 case LC_EDIT_SNAP_ANGLE4:
3306 case LC_EDIT_SNAP_ANGLE5:
3307 case LC_EDIT_SNAP_ANGLE6:
3308 case LC_EDIT_SNAP_ANGLE7:
3309 case LC_EDIT_SNAP_ANGLE8:
3310 case LC_EDIT_SNAP_ANGLE9:
3311 SetAngleSnapIndex(CommandId - LC_EDIT_SNAP_ANGLE0);
3312 break;
3313
3314 case LC_EDIT_TRANSFORM:
3315 if (ActiveModel)
3316 ActiveModel->TransformSelectedObjects(GetTransformType(), GetTransformAmount());
3317 break;
3318
3319 case LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION:
3320 SetTransformType(lcTransformType::AbsoluteTranslation);
3321 break;
3322
3323 case LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION:
3324 SetTransformType(lcTransformType::RelativeTranslation);
3325 break;
3326
3327 case LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION:
3328 SetTransformType(lcTransformType::AbsoluteRotation);
3329 break;
3330
3331 case LC_EDIT_TRANSFORM_RELATIVE_ROTATION:
3332 SetTransformType(lcTransformType::RelativeRotation);
3333 break;
3334
3335 case LC_EDIT_ACTION_SELECT:
3336 SetTool(lcTool::Select);
3337 break;
3338
3339 case LC_EDIT_ACTION_INSERT:
3340 SetTool(lcTool::Insert);
3341 break;
3342
3343 case LC_EDIT_ACTION_LIGHT:
3344 SetTool(lcTool::Light);
3345 break;
3346
3347 case LC_EDIT_ACTION_SPOTLIGHT:
3348 SetTool(lcTool::SpotLight);
3349 break;
3350
3351 case LC_EDIT_ACTION_CAMERA:
3352 SetTool(lcTool::Camera);
3353 break;
3354
3355 case LC_EDIT_ACTION_MOVE:
3356 SetTool(lcTool::Move);
3357 break;
3358
3359 case LC_EDIT_ACTION_ROTATE:
3360 SetTool(lcTool::Rotate);
3361 break;
3362
3363 case LC_EDIT_ACTION_DELETE:
3364 SetTool(lcTool::Eraser);
3365 break;
3366
3367 case LC_EDIT_ACTION_PAINT:
3368 SetTool(lcTool::Paint);
3369 break;
3370
3371 case LC_EDIT_ACTION_COLOR_PICKER:
3372 SetTool(lcTool::ColorPicker);
3373 break;
3374
3375 case LC_EDIT_ACTION_ZOOM:
3376 SetTool(lcTool::Zoom);
3377 break;
3378
3379 case LC_EDIT_ACTION_ZOOM_REGION:
3380 SetTool(lcTool::ZoomRegion);
3381 break;
3382
3383 case LC_EDIT_ACTION_PAN:
3384 SetTool(lcTool::Pan);
3385 break;
3386
3387 case LC_EDIT_ACTION_ROTATE_VIEW:
3388 SetTool(lcTool::RotateView);
3389 break;
3390
3391 case LC_EDIT_ACTION_ROLL:
3392 SetTool(lcTool::Roll);
3393 break;
3394
3395 case LC_EDIT_CANCEL:
3396 if (ActiveView && !ActiveView->CloseFindReplaceDialog())
3397 ActiveView->CancelTrackingOrClearSelection();
3398 break;
3399
3400 case LC_TIMELINE_INSERT_BEFORE:
3401 mTimelineWidget->InsertStepBefore();
3402 break;
3403
3404 case LC_TIMELINE_INSERT_AFTER:
3405 mTimelineWidget->InsertStepAfter();
3406 break;
3407
3408 case LC_TIMELINE_DELETE:
3409 mTimelineWidget->RemoveStep();
3410 break;
3411
3412 case LC_TIMELINE_MOVE_SELECTION:
3413 mTimelineWidget->MoveSelection();
3414 break;
3415
3416 case LC_TIMELINE_SET_CURRENT:
3417 mTimelineWidget->SetCurrentStep();
3418 break;
3419
3420 case LC_NUM_COMMANDS:
3421 break;
3422 }
3423 }
3424