src/main.cpp

changeset 354
91053052bb28
parent 353
c229d38f04c6
child 355
e81f4ad53efd
equal deleted inserted replaced
353:c229d38f04c6 354:91053052bb28
6 #include <QMessageBox> 6 #include <QMessageBox>
7 #include <QScrollBar> 7 #include <QScrollBar>
8 #include <QStackedWidget> 8 #include <QStackedWidget>
9 #include <QTranslator> 9 #include <QTranslator>
10 #include <ui_about.h> 10 #include <ui_about.h>
11 #include <ui_mainwindow.h>
12 #include "src/gl/partrenderer.h" 11 #include "src/gl/partrenderer.h"
13 #include "src/layers/axeslayer.h" 12 #include "src/layers/axeslayer.h"
14 #include "src/layers/edittools.h" 13 #include "src/layers/edittools.h"
15 #include "src/layers/gridlayer.h" 14 #include "src/layers/gridlayer.h"
16 #include "src/ldrawalgorithm.h" 15 #include "src/ldrawalgorithm.h"
16 #include "src/mainwindow.h"
17 #include "src/messagelog.h" 17 #include "src/messagelog.h"
18 #include "src/settings.h" 18 #include "src/settings.h"
19 #include "src/settingseditor/settingseditor.h" 19 #include "src/settingseditor/settingseditor.h"
20 #include "src/ui/circletooloptionswidget.h" 20 #include "src/ui/circletooloptionswidget.h"
21 #include "src/version.h" 21 #include "src/version.h"
88 qRegisterMetaTypeStreamOperators<QMdiArea::ViewMode>(); 88 qRegisterMetaTypeStreamOperators<QMdiArea::ViewMode>();
89 qRegisterMetaTypeStreamOperators<Qt::ToolButtonStyle>(); 89 qRegisterMetaTypeStreamOperators<Qt::ToolButtonStyle>();
90 #endif 90 #endif
91 } 91 }
92 92
93 template<typename BaseType, typename MemberType, typename DataType>
94 struct MemberData
95 {
96 std::size_t member;
97 DataType payload;
98 constexpr MemberType memberInstance(BaseType* instance) const
99 {
100 return *reinterpret_cast<MemberType*>(reinterpret_cast<char*>(instance) + this->member);
101 }
102 };
103
104 static constexpr MemberData<Ui_MainWindow, QAction*, gl::RenderStyle> renderStyleButtons[] = {
105 { offsetof(Ui_MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal },
106 { offsetof(Ui_MainWindow, actionRenderStyleBfc), gl::RenderStyle::BfcRedGreen },
107 { offsetof(Ui_MainWindow, actionRenderStyleRandom), gl::RenderStyle::RandomColors },
108 { offsetof(Ui_MainWindow, actionRenderStylePickScene), gl::RenderStyle::PickScene },
109 };
110
111 static std::optional<ModelId> openModelFromPath( 93 static std::optional<ModelId> openModelFromPath(
112 const QString& path, 94 const QString& path,
113 const LibrariesModel* libraries, 95 const LibrariesModel* libraries,
114 DocumentManager* documents, 96 DocumentManager* documents,
115 QWidget* parent) 97 QWidget* parent)
151 static ModelData* findModelData(const DocumentManager* documents, ModelId modelId) 133 static ModelData* findModelData(const DocumentManager* documents, ModelId modelId)
152 { 134 {
153 return documents->findPayload<ModelData>(modelId); 135 return documents->findPayload<ModelData>(modelId);
154 } 136 }
155 137
156 static ModelSubWindow* currentModelSubWindow(Ui_MainWindow* ui) 138 static ModelSubWindow* currentModelSubWindow(MainWindow* ui)
157 { 139 {
158 auto* w = ui->mdiArea->activeSubWindow(); 140 auto* w = ui->mdiArea->activeSubWindow();
159 return qobject_cast<ModelSubWindow*>(w); 141 return qobject_cast<ModelSubWindow*>(w);
160 } 142 }
161 143
162 static ModelData* currentModelData(Ui_MainWindow* ui, const DocumentManager* documents) 144 static ModelData* currentModelData(MainWindow* ui, const DocumentManager* documents)
163 { 145 {
164 if (auto* const activeSubWindow = currentModelSubWindow(ui)) { 146 if (auto* const activeSubWindow = currentModelSubWindow(ui)) {
165 return findModelData(documents, activeSubWindow->modelId); 147 return findModelData(documents, activeSubWindow->modelId);
166 } 148 }
167 else { 149 else {
168 return nullptr; 150 return nullptr;
169 } 151 }
170 } 152 }
171 153
172 static std::optional<ModelId> findCurrentModelId(Ui_MainWindow* ui) 154 static std::optional<ModelId> findCurrentModelId(MainWindow* ui)
173 { 155 {
174 ModelSubWindow* activeSubWindow = qobject_cast<ModelSubWindow*>(ui->mdiArea->activeSubWindow()); 156 ModelSubWindow* activeSubWindow = qobject_cast<ModelSubWindow*>(ui->mdiArea->activeSubWindow());
175 if (activeSubWindow != nullptr) { 157 if (activeSubWindow != nullptr) {
176 return activeSubWindow->modelId; 158 return activeSubWindow->modelId;
177 } 159 }
178 else { 160 else {
179 return {}; 161 return {};
180 } 162 }
181 } 163 }
182 164
183 static QString title(Ui_MainWindow* ui) 165 static QString title(MainWindow* ui)
184 { 166 {
185 QMdiSubWindow* subWindow = ui->mdiArea->activeSubWindow(); 167 QMdiSubWindow* subWindow = ui->mdiArea->activeSubWindow();
186 QString titlestring; 168 QString titlestring;
187 const QString versionString = fullVersionString(QLocale::ShortFormat); 169 const QString versionString = fullVersionString(QLocale::ShortFormat);
188 if (subWindow != nullptr) { 170 if (subWindow != nullptr) {
236 } 218 }
237 }); 219 });
238 } 220 }
239 221
240 static void updateRenderPreferences( 222 static void updateRenderPreferences(
241 Ui_MainWindow* ui, 223 MainWindow* ui,
242 const gl::RenderPreferences* renderPreferences, 224 const gl::RenderPreferences* renderPreferences,
243 const DocumentManager* documents) 225 const DocumentManager* documents)
244 { 226 {
245 forEachModel(documents, [&renderPreferences](const void*, const ModelData* data){ 227 forEachModel(documents, [&renderPreferences](const void*, const ModelData* data){
246 if (data->canvas != nullptr) { 228 if (data->canvas != nullptr) {
247 data->canvas->setRenderPreferences(*renderPreferences); 229 data->canvas->setRenderPreferences(*renderPreferences);
248 data->canvas->setLayerEnabled(data->axesLayer.get(), renderPreferences->drawAxes); 230 data->canvas->setLayerEnabled(data->axesLayer.get(), renderPreferences->drawAxes);
249 } 231 }
250 }); 232 });
251 for (auto data : ::renderStyleButtons) { 233 ui->setRenderStyle(renderPreferences->style);
252 QAction* action = data.memberInstance(ui);
253 action->setChecked(renderPreferences->style == data.payload);
254 }
255 ui->actionDrawAxes->setChecked(renderPreferences->drawAxes); 234 ui->actionDrawAxes->setChecked(renderPreferences->drawAxes);
256 ui->actionWireframe->setChecked(renderPreferences->wireframe); 235 ui->actionWireframe->setChecked(renderPreferences->wireframe);
257 } 236 }
258 237
259 static gl::RenderPreferences loadRenderPreferences() 238 static gl::RenderPreferences loadRenderPreferences()
273 struct ToolWidgets 252 struct ToolWidgets
274 { 253 {
275 CircleToolOptionsWidget* circleToolOptions; 254 CircleToolOptionsWidget* circleToolOptions;
276 }; 255 };
277 256
278 static void initializeTools(Ui_MainWindow* ui, ToolWidgets* toolWidgets, QWidget* parent) 257 static void initializeTools(MainWindow* ui, ToolWidgets* toolWidgets, QWidget* parent)
279 { 258 {
280 const struct 259 const struct
281 { 260 {
282 QString name, tooltip; 261 QString name, tooltip;
283 QPixmap icon; 262 QPixmap icon;
403 int main(int argc, char *argv[]) 382 int main(int argc, char *argv[])
404 { 383 {
405 doQtRegistrations(); 384 doQtRegistrations();
406 QApplication app{argc, argv}; 385 QApplication app{argc, argv};
407 QApplication::setWindowIcon(QIcon{":/icons/appicon.png"}); 386 QApplication::setWindowIcon(QIcon{":/icons/appicon.png"});
408 QMainWindow mainWindow; 387 MainWindow mainWindow;
409 Ui_MainWindow ui;
410 DocumentManager documents; 388 DocumentManager documents;
411 QString currentLanguage = "en"; 389 QString currentLanguage = "en";
412 QTranslator translator{&mainWindow}; 390 QTranslator translator{&mainWindow};
413 LibrariesModel libraries{&mainWindow}; 391 LibrariesModel libraries{&mainWindow};
414 QStringList recentlyOpenedFiles; 392 QStringList recentlyOpenedFiles;
415 ColorTable colorTable; 393 ColorTable colorTable;
416 gl::RenderPreferences renderPreferences; 394 gl::RenderPreferences renderPreferences;
417 MessageLog messageLog; 395 MessageLog messageLog;
418 Signal settingsChanged; 396 Signal settingsChanged;
419 ui.setupUi(&mainWindow);
420 ToolWidgets toolWidgets{ 397 ToolWidgets toolWidgets{
421 .circleToolOptions = new CircleToolOptionsWidget{&mainWindow}, 398 .circleToolOptions = new CircleToolOptionsWidget{&mainWindow},
422 }; 399 };
423 const auto updateTitle = [&ui, &mainWindow]{ 400 const auto updateTitle = [&mainWindow]{
424 mainWindow.setWindowTitle(title(&ui)); 401 mainWindow.setWindowTitle(title(&mainWindow));
425 }; 402 };
426 const uiutilities::KeySequenceMap defaultKeyboardShortcuts = 403 const uiutilities::KeySequenceMap defaultKeyboardShortcuts =
427 uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); 404 uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow));
428 const auto saveSettings = [ 405 const auto saveSettings = [
429 &libraries, 406 &libraries,
445 &colorTable, 422 &colorTable,
446 &documents, 423 &documents,
447 &mainWindow, 424 &mainWindow,
448 &messageLog, 425 &messageLog,
449 &renderPreferences, 426 &renderPreferences,
450 &settingsChanged, 427 &settingsChanged]
451 &ui]
452 (const ModelId modelId) 428 (const ModelId modelId)
453 { 429 {
454 QTextDocument* model = documents.getModelById(modelId); 430 QTextDocument* model = documents.getModelById(modelId);
455 if (model != nullptr) { 431 if (model != nullptr) {
456 ModelData* data = new ModelData(&documents); 432 ModelData* data = new ModelData(&documents);
512 &EditTools::suggestCursor, 488 &EditTools::suggestCursor,
513 data->canvas.get(), 489 data->canvas.get(),
514 &QWidget::setCursor); 490 &QWidget::setCursor);
515 data->tools->setEditMode(SelectMode); 491 data->tools->setEditMode(SelectMode);
516 const QFileInfo fileInfo{*documents.modelPath(modelId)}; 492 const QFileInfo fileInfo{*documents.modelPath(modelId)};
517 auto* const subWindow = createSubWindow<ModelSubWindow>(ui.mdiArea, modelId); 493 auto* const subWindow = createSubWindow<ModelSubWindow>(mainWindow.mdiArea, modelId);
518 subWindow->setMinimumSize({96, 96}); 494 subWindow->setMinimumSize({96, 96});
519 subWindow->resize({320, 200}); 495 subWindow->resize({320, 200});
520 subWindow->setWidget(data->canvas.get()); 496 subWindow->setWidget(data->canvas.get());
521 subWindow->setWindowTitle(tabName(fileInfo)); 497 subWindow->setWindowTitle(tabName(fileInfo));
522 subWindow->show(); 498 subWindow->show();
525 const auto updateRecentlyOpenedDocumentsMenu = [ 501 const auto updateRecentlyOpenedDocumentsMenu = [
526 &documents, 502 &documents,
527 &libraries, 503 &libraries,
528 &mainWindow, 504 &mainWindow,
529 &openModelForEditing, 505 &openModelForEditing,
530 &recentlyOpenedFiles, 506 &recentlyOpenedFiles]
531 &ui] 507 {
532 { 508 rebuildRecentFilesMenu(mainWindow.menuRecentFiles, recentlyOpenedFiles, &mainWindow);
533 rebuildRecentFilesMenu(ui.menuRecentFiles, recentlyOpenedFiles, &mainWindow); 509 for (QAction* action : mainWindow.menuRecentFiles->actions()) {
534 for (QAction* action : ui.menuRecentFiles->actions()) {
535 QString path = action->data().toString(); 510 QString path = action->data().toString();
536 QObject::connect( 511 QObject::connect(
537 action, 512 action,
538 &QAction::triggered, 513 &QAction::triggered,
539 [path, &libraries, &documents, &mainWindow, &openModelForEditing]() { 514 [path, &libraries, &documents, &mainWindow, &openModelForEditing]() {
552 &libraries, 527 &libraries,
553 &mainWindow, 528 &mainWindow,
554 &recentlyOpenedFiles, 529 &recentlyOpenedFiles,
555 &renderPreferences, 530 &renderPreferences,
556 &settingsChanged, 531 &settingsChanged,
557 &ui,
558 &updateRecentlyOpenedDocumentsMenu] 532 &updateRecentlyOpenedDocumentsMenu]
559 { 533 {
560 recentlyOpenedFiles = setting<Setting::RecentFiles>(); 534 recentlyOpenedFiles = setting<Setting::RecentFiles>();
561 renderPreferences = loadRenderPreferences(); 535 renderPreferences = loadRenderPreferences();
562 libraries.restoreFromSettings(); 536 libraries.restoreFromSettings();
563 updateRecentlyOpenedDocumentsMenu(); 537 updateRecentlyOpenedDocumentsMenu();
564 colorTable = loadColors(&libraries); 538 colorTable = loadColors(&libraries);
565 updateRenderPreferences(&ui, &renderPreferences, &documents); 539 updateRenderPreferences(&mainWindow, &renderPreferences, &documents);
566 ui.mdiArea->setViewMode(setting<Setting::ViewMode>()); 540 mainWindow.mdiArea->setViewMode(setting<Setting::ViewMode>());
567 ui.retranslateUi(&mainWindow); 541 mainWindow.retranslateUi(&mainWindow);
568 mainWindow.setToolButtonStyle(setting<Setting::ToolButtonStyle>()); 542 mainWindow.setToolButtonStyle(setting<Setting::ToolButtonStyle>());
569 settingsChanged.emit(); 543 settingsChanged.emit();
570 }; 544 };
571 const auto addRecentlyOpenedFile = [ 545 const auto addRecentlyOpenedFile = [
572 &recentlyOpenedFiles, 546 &recentlyOpenedFiles,
582 recentlyOpenedFiles.removeLast(); 556 recentlyOpenedFiles.removeLast();
583 } 557 }
584 saveSettings(); 558 saveSettings();
585 updateRecentlyOpenedDocumentsMenu(); 559 updateRecentlyOpenedDocumentsMenu();
586 }; 560 };
587 QObject::connect(ui.actionNew, &QAction::triggered, 561 QObject::connect(mainWindow.actionNew, &QAction::triggered,
588 [&documents, &openModelForEditing]{ 562 [&documents, &openModelForEditing]{
589 openModelForEditing(documents.newModel()); 563 openModelForEditing(documents.newModel());
590 } 564 }
591 ); 565 );
592 QObject::connect(ui.actionOpen, &QAction::triggered, 566 QObject::connect(mainWindow.actionOpen, &QAction::triggered,
593 [&addRecentlyOpenedFile, &documents, &libraries, &mainWindow, &openModelForEditing] 567 [&addRecentlyOpenedFile, &documents, &libraries, &mainWindow, &openModelForEditing]
594 { 568 {
595 const QString path = getOpenModelPath(&mainWindow); 569 const QString path = getOpenModelPath(&mainWindow);
596 if (not path.isEmpty()) 570 if (not path.isEmpty())
597 { 571 {
601 addRecentlyOpenedFile(path); 575 addRecentlyOpenedFile(path);
602 } 576 }
603 } 577 }
604 } 578 }
605 ); 579 );
606 QObject::connect(ui.actionSettingsEditor, &QAction::triggered, [&defaultKeyboardShortcuts, &restoreSettings, &settingsChanged, &ui]{ 580 QObject::connect(mainWindow.actionSettingsEditor, &QAction::triggered, [&defaultKeyboardShortcuts, &restoreSettings, &settingsChanged, &mainWindow]{
607 if (ui.mdiArea->findChildren<SettingsEditor*>().isEmpty()) { 581 if (mainWindow.mdiArea->findChildren<SettingsEditor*>().isEmpty()) {
608 auto* const settingsEditor = createSubWindow<SettingsEditor>(ui.mdiArea, defaultKeyboardShortcuts); 582 auto* const settingsEditor = createSubWindow<SettingsEditor>(mainWindow.mdiArea, defaultKeyboardShortcuts);
609 QObject::connect(&settingsChanged, &Signal::triggered, settingsEditor, &SettingsEditor::loadSettings); 583 QObject::connect(&settingsChanged, &Signal::triggered, settingsEditor, &SettingsEditor::loadSettings);
610 QObject::connect(settingsEditor, &SettingsEditor::settingsChanged, restoreSettings); 584 QObject::connect(settingsEditor, &SettingsEditor::settingsChanged, restoreSettings);
611 settingsEditor->setAttribute(Qt::WA_DeleteOnClose); 585 settingsEditor->setAttribute(Qt::WA_DeleteOnClose);
612 settingsEditor->show(); 586 settingsEditor->show();
613 } 587 }
614 }); 588 });
615 QObject::connect(ui.actionQuit, &QAction::triggered, &mainWindow, &QMainWindow::close); 589 QObject::connect(mainWindow.actionQuit, &QAction::triggered, &mainWindow, &QMainWindow::close);
616 #if 0 590 #if 0
617 QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&]{ 591 QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&]{
618 if (ModelData* data = currentModelData(&ui, &documents)) { 592 if (ModelData* data = currentModelData(&ui, &documents)) {
619 adjustGridToView(data->canvas.get()); 593 adjustGridToView(data->canvas.get());
620 } 594 }
621 }); 595 });
622 #endif 596 #endif
623 QObject::connect(ui.actionClose, &QAction::triggered, [&ui, &documents]{ 597 QObject::connect(mainWindow.actionClose, &QAction::triggered, [&mainWindow, &documents]{
624 if (ModelData* data = currentModelData(&ui, &documents)) { 598 if (ModelData* data = currentModelData(&mainWindow, &documents)) {
625 // TODO 599 // TODO
626 } 600 }
627 }); 601 });
628 const auto save = [&addRecentlyOpenedFile, &documents, &mainWindow](ModelId modelId){ 602 const auto save = [&addRecentlyOpenedFile, &mainWindow](DocumentManager* documents, ModelId modelId){
629 QString error; 603 QString error;
630 QTextStream errorStream{&error}; 604 QTextStream errorStream{&error};
631 const bool succeeded = documents.saveModel(modelId, errorStream); 605 const bool succeeded = documents->saveModel(modelId, errorStream);
632 if (not succeeded) 606 if (not succeeded)
633 { 607 {
634 QMessageBox::critical(&mainWindow, QObject::tr("Save error"), error); 608 QMessageBox::critical(&mainWindow, QObject::tr("Save error"), error);
635 } 609 }
636 else 610 else
637 { 611 {
638 const QString* pathPtr = documents.modelPath(modelId); 612 const QString* pathPtr = documents->modelPath(modelId);
639 if (pathPtr != nullptr) { 613 if (pathPtr != nullptr) {
640 addRecentlyOpenedFile(*pathPtr); 614 addRecentlyOpenedFile(*pathPtr);
641 } 615 }
642 } 616 }
643 };; 617 };
644 const auto actionSaveAs = [&documents, &libraries, &mainWindow, &save, &ui]{ 618 const auto actionSaveAs = [&documents, &libraries, &mainWindow, &save]{
645 const std::optional<ModelId> modelId = findCurrentModelId(&ui); 619 const std::optional<ModelId> modelId = findCurrentModelId(&mainWindow);
646 if (modelId.has_value()) 620 if (modelId.has_value())
647 { 621 {
648 const QString* pathPtr = documents.modelPath(*modelId); 622 const QString* pathPtr = documents.modelPath(*modelId);
649 QString defaultPath = (pathPtr != nullptr) ? *pathPtr : ""; 623 QString defaultPath = (pathPtr != nullptr) ? *pathPtr : "";
650 const QString newPath = QFileDialog::getSaveFileName( 624 const QString newPath = QFileDialog::getSaveFileName(
655 ); 629 );
656 if (not newPath.isEmpty()) { 630 if (not newPath.isEmpty()) {
657 QString error; 631 QString error;
658 QTextStream errorStream{&error}; 632 QTextStream errorStream{&error};
659 documents.setModelPath(*modelId, newPath, libraries, errorStream); 633 documents.setModelPath(*modelId, newPath, libraries, errorStream);
660 QMdiSubWindow* const subWindow = ui.mdiArea->currentSubWindow(); 634 QMdiSubWindow* const subWindow = mainWindow.mdiArea->currentSubWindow();
661 if (subWindow != nullptr) { 635 if (subWindow != nullptr) {
662 subWindow->setWindowTitle(tabName(QFileInfo{newPath})); 636 subWindow->setWindowTitle(tabName(QFileInfo{newPath}));
663 } 637 }
664 save(*modelId); 638 save(&documents, *modelId);
665 } 639 }
666 } 640 }
667 }; 641 };
668 QObject::connect(ui.actionSaveAs, &QAction::triggered, actionSaveAs); 642 QObject::connect(mainWindow.actionSaveAs, &QAction::triggered, actionSaveAs);
669 QObject::connect(ui.actionSave, &QAction::triggered, [ 643 QObject::connect(mainWindow.actionSave, &QAction::triggered, [
670 &actionSaveAs, 644 &actionSaveAs,
671 &documents, 645 &documents,
672 &save, 646 &save,
673 &ui] 647 &mainWindow]
674 { 648 {
675 const std::optional<ModelId> modelId = findCurrentModelId(&ui); 649 const std::optional<ModelId> modelId = findCurrentModelId(&mainWindow);
676 if (modelId.has_value()) { 650 if (modelId.has_value()) {
677 const QString* path = documents.modelPath(*modelId); 651 const QString* path = documents.modelPath(*modelId);
678 if (path == nullptr or path->isEmpty()) { 652 if (path == nullptr or path->isEmpty()) {
679 actionSaveAs(); 653 actionSaveAs();
680 } 654 }
681 else { 655 else {
682 save(*modelId); 656 save(&documents, *modelId);
683 } 657 }
684 } 658 }
685 }); 659 });
686 QObject::connect(ui.actionDrawAxes, &QAction::triggered, [ 660 QObject::connect(mainWindow.actionDrawAxes, &QAction::triggered, [
687 &documents, 661 &documents,
688 &renderPreferences, 662 &renderPreferences,
689 &saveSettings, 663 &saveSettings,
690 &ui] 664 &mainWindow]
691 (bool drawAxes) 665 (bool drawAxes)
692 { 666 {
693 renderPreferences.drawAxes = drawAxes; 667 renderPreferences.drawAxes = drawAxes;
694 saveSettings(); 668 saveSettings();
695 updateRenderPreferences(&ui, &renderPreferences, &documents); 669 updateRenderPreferences(&mainWindow, &renderPreferences, &documents);
696 }); 670 });
697 QObject::connect(ui.actionWireframe, &QAction::triggered, [ 671 QObject::connect(mainWindow.actionWireframe, &QAction::triggered, [
698 &documents, 672 &documents,
699 &renderPreferences, 673 &renderPreferences,
700 &saveSettings, 674 &saveSettings,
701 &ui] 675 &mainWindow]
702 (bool enabled) 676 (bool enabled)
703 { 677 {
704 renderPreferences.wireframe = enabled; 678 renderPreferences.wireframe = enabled;
705 saveSettings(); 679 saveSettings();
706 updateRenderPreferences(&ui, &renderPreferences, &documents); 680 updateRenderPreferences(&mainWindow, &renderPreferences, &documents);
707 }); 681 });
708 for (auto data : ::renderStyleButtons) { 682 QObject::connect(&mainWindow, &MainWindow::renderStyleSelected, [
709 QAction* action = data.memberInstance(&ui); 683 &documents,
710 QObject::connect(action, &QAction::triggered, [&, data]{ 684 &mainWindow,
711 renderPreferences.style = data.payload; 685 &renderPreferences,
712 saveSettings(); 686 &saveSettings]
713 updateRenderPreferences(&ui, &renderPreferences, &documents); 687 (gl::RenderStyle newStyle)
714 }); 688 {
715 } 689 renderPreferences.style = newStyle;
716 const auto checkEditingModeAction = [&ui, &documents](EditingMode mode) { 690 saveSettings();
717 const bool hasDocument = currentModelData(&ui, &documents) != nullptr; 691 updateRenderPreferences(&mainWindow, &renderPreferences, &documents);
718 for (QAction* action : ui.editingModesToolBar->actions()) { 692 });
693 const auto checkEditingModeAction = [&mainWindow, &documents](EditingMode mode) {
694 const bool hasDocument = currentModelData(&mainWindow, &documents) != nullptr;
695 for (QAction* action : mainWindow.editingModesToolBar->actions()) {
719 action->setEnabled(hasDocument); 696 action->setEnabled(hasDocument);
720 action->setChecked(hasDocument and action->data().value<EditingMode>() == mode); 697 action->setChecked(hasDocument and action->data().value<EditingMode>() == mode);
721 } 698 }
722 }; 699 };
723 initializeTools(&ui, &toolWidgets, &mainWindow); 700 initializeTools(&mainWindow, &toolWidgets, &mainWindow);
724 for (QAction* action : ui.editingModesToolBar->actions()) { 701 for (QAction* action : mainWindow.editingModesToolBar->actions()) {
725 QObject::connect(action, &QAction::triggered, [ 702 QObject::connect(action, &QAction::triggered, [
726 action, 703 action,
727 &checkEditingModeAction, 704 &checkEditingModeAction,
728 &documents, 705 &documents,
729 &ui] 706 &mainWindow]
730 { 707 {
731 if (ModelData* data = currentModelData(&ui, &documents)) { 708 if (ModelData* data = currentModelData(&mainWindow, &documents)) {
732 const EditingMode mode = action->data().value<EditingMode>(); 709 const EditingMode mode = action->data().value<EditingMode>();
733 data->tools->setEditMode(mode); 710 data->tools->setEditMode(mode);
734 checkEditingModeAction(mode); 711 checkEditingModeAction(mode);
735 } 712 }
736 }); 713 });
737 } 714 }
738 QObject::connect(ui.mdiArea, &QMdiArea::subWindowActivated, [ 715 QObject::connect(mainWindow.mdiArea, &QMdiArea::subWindowActivated, [
739 &checkEditingModeAction, 716 &checkEditingModeAction,
740 &documents, 717 &documents,
741 &ui, 718 &mainWindow,
742 &updateTitle] 719 &updateTitle]
743 (QMdiSubWindow* subWindow) 720 (QMdiSubWindow* subWindow)
744 { 721 {
745 ModelSubWindow* modelSubWindow = qobject_cast<ModelSubWindow*>(subWindow); 722 ModelSubWindow* modelSubWindow = qobject_cast<ModelSubWindow*>(subWindow);
746 if (modelSubWindow != nullptr) { 723 if (modelSubWindow != nullptr) {
747 if (ModelData* data = documents.findPayload<ModelData>(modelSubWindow->modelId)) { 724 if (ModelData* data = documents.findPayload<ModelData>(modelSubWindow->modelId)) {
748 checkEditingModeAction(data->tools->currentEditingMode()); 725 checkEditingModeAction(data->tools->currentEditingMode());
749 ui.modelEdit->setDocument(data->model); 726 mainWindow.modelEdit->setDocument(data->model);
750 ui.modelEdit->setTextCursor(*data->textcursor); 727 mainWindow.modelEdit->setTextCursor(*data->textcursor);
751 } 728 }
752 } 729 }
753 else { 730 else {
754 checkEditingModeAction(EditingMode::SelectMode); 731 checkEditingModeAction(EditingMode::SelectMode);
755 } 732 }
756 ui.modelEdit->setEnabled(modelSubWindow != nullptr); 733 mainWindow.modelEdit->setEnabled(modelSubWindow != nullptr);
757 updateTitle(); 734 updateTitle();
758 }); 735 });
759 ui.messageLog->setModel(&messageLog); 736 mainWindow.messageLog->setModel(&messageLog);
760 QObject::connect(ui.actionAboutQt, &QAction::triggered, &app, &QApplication::aboutQt); 737 QObject::connect(mainWindow.actionAboutQt, &QAction::triggered, &app, &QApplication::aboutQt);
761 QObject::connect(&documents, &DocumentManager::message, &messageLog, &MessageLog::addMessage); 738 QObject::connect(&documents, &DocumentManager::message, &messageLog, &MessageLog::addMessage);
762 QObject::connect(&messageLog, &MessageLog::rowsAboutToBeInserted, [&ui]{ 739 QObject::connect(&messageLog, &MessageLog::rowsAboutToBeInserted, [&mainWindow]{
763 const auto bar = ui.messageLog->verticalScrollBar(); 740 const auto bar = mainWindow.messageLog->verticalScrollBar();
764 ui.messageLog->setProperty("shouldAutoScroll", bar->value() == bar->maximum()); 741 mainWindow.messageLog->setProperty("shouldAutoScroll", bar->value() == bar->maximum());
765 }); 742 });
766 QObject::connect(&messageLog, &MessageLog::rowsInserted, [&ui]{ 743 QObject::connect(&messageLog, &MessageLog::rowsInserted, [&mainWindow]{
767 ui.messageLog->resizeRowsToContents(); 744 mainWindow.messageLog->resizeRowsToContents();
768 if (ui.messageLog->property("shouldAutoScroll").toBool()) { 745 if (mainWindow.messageLog->property("shouldAutoScroll").toBool()) {
769 ui.messageLog->scrollToBottom(); 746 mainWindow.messageLog->scrollToBottom();
770 } 747 }
771 }); 748 });
772 QObject::connect( 749 QObject::connect(
773 toolWidgets.circleToolOptions, 750 toolWidgets.circleToolOptions,
774 &CircleToolOptionsWidget::optionsChanged, 751 &CircleToolOptionsWidget::optionsChanged,
775 [&ui, &documents](const CircleToolOptions& options) { 752 [&mainWindow, &documents](const CircleToolOptions& options) {
776 if (ModelData* data = currentModelData(&ui, &documents)) { 753 if (ModelData* data = currentModelData(&mainWindow, &documents)) {
777 data->tools->setCircleToolOptions(options); 754 data->tools->setCircleToolOptions(options);
778 } 755 }
779 }); 756 });
780 QObject::connect( 757 QObject::connect(
781 ui.actionMakeUnofficial, 758 mainWindow.actionMakeUnofficial,
782 &QAction::triggered, 759 &QAction::triggered,
783 [&documents, &ui]{ 760 [&documents, &mainWindow]{
784 if (ModelData* data = currentModelData(&ui, &documents)) { 761 if (ModelData* data = currentModelData(&mainWindow, &documents)) {
785 QTextDocument* const model = data->model; 762 QTextDocument* const model = data->model;
786 for (const ModelAction& action : ldraw::makeUnofficial(model)) { 763 for (const ModelAction& action : ldraw::makeUnofficial(model)) {
787 executeAction(model, action); 764 executeAction(model, action);
788 } 765 }
789 } 766 }
790 }); 767 });
791 QObject::connect( 768 QObject::connect(
792 ui.actionAbout, 769 mainWindow.actionAbout,
793 &QAction::triggered, 770 &QAction::triggered,
794 [&mainWindow, &ui]{ 771 [&mainWindow]{
795 // Make sure that there's an OpenGL context active, otherwise 772 // Make sure that there's an OpenGL context active, otherwise
796 // we cannot obtain OpenGL information 773 // we cannot obtain OpenGL information
797 if (ui.mdiArea->findChildren<ModelSubWindow*>().empty()) { 774 if (mainWindow.mdiArea->findChildren<ModelSubWindow*>().empty()) {
798 ui.actionNew->trigger(); 775 mainWindow.actionNew->trigger();
799 } 776 }
800 about(&mainWindow); 777 about(&mainWindow);
801 } 778 }
802 ); 779 );
803 QObject::connect( 780 QObject::connect(
804 ui.modelEdit, 781 mainWindow.modelEdit,
805 &QPlainTextEdit::textChanged, 782 &QPlainTextEdit::textChanged,
806 [&documents, &libraries, &ui]{ 783 [&documents, &libraries, &mainWindow]{
807 if (ModelData* data = currentModelData(&ui, &documents)) { 784 if (ModelData* data = currentModelData(&mainWindow, &documents)) {
808 documents.loadDependenciesForAllModels(libraries); 785 documents.loadDependenciesForAllModels(libraries);
809 data->canvas->update(); 786 data->canvas->update();
810 } 787 }
811 }); 788 });
812 mainWindow.tabifyDockWidget(ui.messageLogDock, ui.toolOptionsDock); 789 mainWindow.tabifyDockWidget(mainWindow.messageLogDock, mainWindow.toolOptionsDock);
813 mainWindow.restoreGeometry(setting<Setting::MainWindowGeometry>()); 790 mainWindow.restoreGeometry(setting<Setting::MainWindowGeometry>());
814 mainWindow.restoreState(setting<Setting::MainWindowState>()); 791 mainWindow.restoreState(setting<Setting::MainWindowState>());
815 // If a dock is made floating and the app is closed, the dock becomes invisible 792 // If a dock is made floating and the app is closed, the dock becomes invisible
816 // after the restoreState call. So we make them visible again here. 793 // after the restoreState call. So we make them visible again here.
817 for (QDockWidget* dock : mainWindow.findChildren<QDockWidget*>()) { 794 for (QDockWidget* dock : mainWindow.findChildren<QDockWidget*>()) {
818 dock->setVisible(true); 795 dock->setVisible(true);
819 } 796 }
820 restoreSettings(); 797 restoreSettings();
821 updateRenderPreferences(&ui, &renderPreferences, &documents); 798 updateRenderPreferences(&mainWindow, &renderPreferences, &documents);
822 ui.actionAbout->setText(ui.actionAbout->text().arg(CMAKE_PROJECT_NAME)); 799 mainWindow.actionAbout->setText(mainWindow.actionAbout->text().arg(CMAKE_PROJECT_NAME));
823 updateTitle(); 800 updateTitle();
824 mainWindow.show(); 801 mainWindow.show();
825 const int result = app.exec(); 802 const int result = app.exec();
826 saveSettings(); 803 saveSettings();
827 return result; 804 return result;

mercurial