1 #include <QApplication> |
1 #include <QApplication> |
2 #include <QFileDialog> |
2 #include <QFileDialog> |
3 #include <QMessageBox> |
3 #include <QMessageBox> |
4 #include <QMdiSubWindow> |
4 #include <QMdiSubWindow> |
|
5 #include <QStackedWidget> |
5 #include "mainwindow.h" |
6 #include "mainwindow.h" |
6 #include "ui_mainwindow.h" |
7 #include "ui_mainwindow.h" |
7 #include "version.h" |
8 #include "version.h" |
8 #include "document.h" |
9 #include "document.h" |
9 #include "settingseditor/settingseditor.h" |
10 #include "settingseditor/settingseditor.h" |
144 documents->closeDocument(modelId.value()); |
145 documents->closeDocument(modelId.value()); |
145 delete document; |
146 delete document; |
146 } |
147 } |
147 } |
148 } |
148 |
149 |
149 static void handleTabCloseButton(Ui_MainWindow* ui, DocumentManager* documents, int tabIndex) |
|
150 { |
|
151 /* |
|
152 if (tabIndex >= 0 and tabIndex < ui->tabs->count()) { |
|
153 EditorTabWidget* tab = qobject_cast<EditorTabWidget*>(ui->tabs->widget(tabIndex)); |
|
154 if (tab != nullptr) { |
|
155 closeDocument(documents, tab); |
|
156 } |
|
157 } |
|
158 */ |
|
159 } |
|
160 |
|
161 static std::optional<ModelId> findCurrentModelId(Ui_MainWindow* ui, DocumentManager* documents) |
150 static std::optional<ModelId> findCurrentModelId(Ui_MainWindow* ui, DocumentManager* documents) |
162 { |
151 { |
163 const EditorTabWidget* tab = currentTabWidget(ui); |
152 const EditorTabWidget* tab = currentTabWidget(ui); |
164 if (tab != nullptr) { |
153 if (tab != nullptr) { |
165 return documents->findIdForModel(tab->model); |
154 return documents->findIdForModel(tab->model); |
232 .selectedColor = settings->selectedColor(), |
221 .selectedColor = settings->selectedColor(), |
233 .lineThickness = settings->lineThickness(), |
222 .lineThickness = settings->lineThickness(), |
234 .lineAntiAliasing = settings->lineAntiAliasing(), |
223 .lineAntiAliasing = settings->lineAntiAliasing(), |
235 .drawAxes = settings->drawAxes(), |
224 .drawAxes = settings->drawAxes(), |
236 }; |
225 }; |
|
226 } |
|
227 |
|
228 void initializeTools(Ui_MainWindow* ui, QWidget* parent) |
|
229 { |
|
230 const struct |
|
231 { |
|
232 QString name, tooltip; |
|
233 QPixmap icon; |
|
234 QWidget* widget; |
|
235 } editingModesInfo[] = { |
|
236 { |
|
237 .name = QObject::tr("Select"), |
|
238 .tooltip = QObject::tr("Select elements from the model."), |
|
239 .icon = {":/icons/navigate-outline.png"}, |
|
240 //.widget = this->objectEditor, |
|
241 }, |
|
242 { |
|
243 .name = QObject::tr("Draw"), |
|
244 .tooltip = QObject::tr("Draw new elements into the model."), |
|
245 .icon = {":/icons/pencil-outline.png"}, |
|
246 .widget = nullptr, |
|
247 }, |
|
248 }; |
|
249 for (int i = 0; i < countof(editingModesInfo); ++i) { |
|
250 const auto& editingModeInfo = editingModesInfo[i]; |
|
251 QAction* action = new QAction{editingModeInfo.name, parent}; |
|
252 action->setCheckable(true); |
|
253 action->setChecked(i == 0); |
|
254 action->setData(static_cast<EditingMode>(i)); |
|
255 action->setToolTip(editingModeInfo.tooltip); |
|
256 action->setIcon(QPixmap{editingModeInfo.icon}); |
|
257 ui->editingModesToolBar->addAction(action); |
|
258 QWidget* widget = editingModeInfo.widget; |
|
259 if (widget == nullptr) { |
|
260 widget = new QWidget{parent}; |
|
261 } |
|
262 ui->toolWidgetStack->addWidget(widget); |
|
263 } |
237 } |
264 } |
238 |
265 |
239 int main(int argc, char *argv[]) |
266 int main(int argc, char *argv[]) |
240 { |
267 { |
241 doQtRegistrations(); |
268 doQtRegistrations(); |
249 LibraryManager libraries{&mainWindow}; |
276 LibraryManager libraries{&mainWindow}; |
250 QByteArray documentSplitterState; |
277 QByteArray documentSplitterState; |
251 QStringList recentlyOpenedFiles; |
278 QStringList recentlyOpenedFiles; |
252 ldraw::ColorTable colorTable; |
279 ldraw::ColorTable colorTable; |
253 gl::RenderPreferences renderPreferences; |
280 gl::RenderPreferences renderPreferences; |
|
281 QMap<Model*, QItemSelectionModel*> itemSelectionModels; |
254 ui.setupUi(&mainWindow); |
282 ui.setupUi(&mainWindow); |
255 const uiutilities::KeySequenceMap defaultKeyboardShortcuts = |
283 const uiutilities::KeySequenceMap defaultKeyboardShortcuts = |
256 uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); |
284 uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); |
257 const auto saveSettings = [&]{ |
285 const auto saveSettings = [&]{ |
258 settings.setMainWindowGeometry(mainWindow.saveGeometry()); |
286 settings.setMainWindowGeometry(mainWindow.saveGeometry()); |
297 } |
325 } |
298 saveSettings(); |
326 saveSettings(); |
299 updateRecentlyOpenedDocumentsMenu(); |
327 updateRecentlyOpenedDocumentsMenu(); |
300 }; |
328 }; |
301 const auto openModelForEditing = [&](const ModelId modelId){ |
329 const auto openModelForEditing = [&](const ModelId modelId){ |
302 EditorTabWidget* document = new EditorTabWidget{ |
330 Model* model = documents.getModelById(modelId); |
303 documents.getModelById(modelId), |
331 EditorTabWidget* document = new EditorTabWidget{model, &documents, colorTable}; |
304 &documents, |
332 QItemSelectionModel* selectionModel = new QItemSelectionModel{model}; |
305 colorTable, |
333 itemSelectionModels[model] = selectionModel; |
306 }; |
334 QObject::connect(selectionModel, &QItemSelectionModel::selectionChanged, |
|
335 [model, document](const QItemSelection& selected, const QItemSelection& deselected) |
|
336 { |
|
337 auto resolveIndex = [&model](const QModelIndex& index){ |
|
338 return model->idAt(index.row()); |
|
339 }; |
|
340 auto resolve = [&resolveIndex](const QItemSelection& selection) |
|
341 { |
|
342 return fn::map<QSet<ModelId>>(selection.indexes(), resolveIndex); |
|
343 }; |
|
344 document->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); |
|
345 }); |
307 document->canvas->setRenderPreferences(renderPreferences); |
346 document->canvas->setRenderPreferences(renderPreferences); |
308 QObject::connect( |
347 QObject::connect( |
309 document, |
348 document, |
310 &EditorTabWidget::newStatusText, |
349 &EditorTabWidget::newStatusText, |
311 [&](const QString& newStatusText) { |
350 [&](const QString& newStatusText) { |
313 }); |
352 }); |
314 const QFileInfo fileInfo{*documents.modelPath(modelId)}; |
353 const QFileInfo fileInfo{*documents.modelPath(modelId)}; |
315 QMdiSubWindow* subWindow = ui.mdiArea->addSubWindow(document); |
354 QMdiSubWindow* subWindow = ui.mdiArea->addSubWindow(document); |
316 subWindow->setWindowTitle(tabName(fileInfo)); |
355 subWindow->setWindowTitle(tabName(fileInfo)); |
317 subWindow->show(); |
356 subWindow->show(); |
318 document->restoreSplitterState(documentSplitterState); |
|
319 }; |
357 }; |
320 QObject::connect(ui.actionNew, &QAction::triggered, [&]{ |
358 QObject::connect(ui.actionNew, &QAction::triggered, [&]{ |
321 openModelForEditing(documents.newModel()); |
359 openModelForEditing(documents.newModel()); |
322 }); |
360 }); |
323 QObject::connect(ui.actionOpen, &QAction::triggered, [&]{ |
361 QObject::connect(ui.actionOpen, &QAction::triggered, [&]{ |
407 save(*modelId); |
445 save(*modelId); |
408 } |
446 } |
409 } |
447 } |
410 } |
448 } |
411 }); |
449 }); |
412 /* |
|
413 QObject::connect(ui.mdiArea, &QTabWidget::tabCloseRequested, [&](int index){ |
|
414 handleTabCloseButton(&ui, &documents, index); |
|
415 }); |
|
416 */ |
|
417 QObject::connect(ui.actionDrawAxes, &QAction::triggered, [&](bool drawAxes){ |
450 QObject::connect(ui.actionDrawAxes, &QAction::triggered, [&](bool drawAxes){ |
418 renderPreferences.drawAxes = drawAxes; |
451 renderPreferences.drawAxes = drawAxes; |
419 saveSettings(); |
452 saveSettings(); |
420 updateRenderPreferences(&ui, &renderPreferences); |
453 updateRenderPreferences(&ui, &renderPreferences); |
421 }); |
454 }); |
425 renderPreferences.style = data.payload; |
458 renderPreferences.style = data.payload; |
426 saveSettings(); |
459 saveSettings(); |
427 updateRenderPreferences(&ui, &renderPreferences); |
460 updateRenderPreferences(&ui, &renderPreferences); |
428 }); |
461 }); |
429 } |
462 } |
|
463 const auto checkEditingModeAction = [&ui](EditingMode mode) { |
|
464 for (QAction* action : ui.editingModesToolBar->actions()) { |
|
465 action->setChecked(action->data().value<EditingMode>() == mode); |
|
466 } |
|
467 }; |
|
468 initializeTools(&ui, &mainWindow); |
|
469 for (QAction* action : ui.editingModesToolBar->actions()) { |
|
470 QObject::connect(action, &QAction::triggered, [&, action]{ |
|
471 EditorTabWidget* tab = currentTabWidget(&ui); |
|
472 if (tab != nullptr) { |
|
473 const EditingMode mode = action->data().value<EditingMode>(); |
|
474 tab->setEditMode(mode); |
|
475 checkEditingModeAction(mode); |
|
476 } |
|
477 }); |
|
478 } |
|
479 QObject::connect(ui.mdiArea, &QMdiArea::subWindowActivated, |
|
480 [&](QMdiSubWindow* subWindow){ |
|
481 EditorTabWidget* tab = qobject_cast<EditorTabWidget*>(subWindow->widget()); |
|
482 if (tab != nullptr) { |
|
483 checkEditingModeAction(tab->currentEditingMode()); |
|
484 QItemSelectionModel* selectionModel = itemSelectionModels.value(tab->model); |
|
485 if (selectionModel != nullptr) { |
|
486 ui.modelListView->setModel(tab->model); |
|
487 ui.modelListView->setSelectionModel(selectionModel); |
|
488 } |
|
489 } |
|
490 }); |
430 mainWindow.setWindowTitle(title()); |
491 mainWindow.setWindowTitle(title()); |
431 mainWindow.restoreGeometry(settings.mainWindowGeometry()); |
492 mainWindow.restoreGeometry(settings.mainWindowGeometry()); |
432 restoreSettings(); |
493 restoreSettings(); |
433 updateRenderPreferences(&ui, &renderPreferences); |
494 updateRenderPreferences(&ui, &renderPreferences); |
434 mainWindow.show(); |
495 mainWindow.show(); |