diff -r ee5758ddb6d2 -r 8e1fe64ce4e3 src/main.cpp --- a/src/main.cpp Sat Jun 11 15:20:24 2022 +0300 +++ b/src/main.cpp Sun Jun 12 20:47:04 2022 +0300 @@ -3,15 +3,34 @@ #include #include #include +#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "version.h" +#include "ui/canvas.h" #include "document.h" #include "settingseditor/settingseditor.h" #include "widgets/colorselectdialog.h" static const QDir LOCALE_DIR {":/locale"}; +class ModelSubWindow : public QMdiSubWindow +{ + Q_OBJECT +public: + const ModelId modelId; + ModelSubWindow(ModelId modelId, QWidget* widget) : + QMdiSubWindow{widget}, + modelId{modelId} + { + } +protected: + void closeEvent(QCloseEvent* event) override + { + event->ignore(); + } +}; + static void doQtRegistrations() { QCoreApplication::setApplicationName(::appName); @@ -32,6 +51,18 @@ } }; +class ModelData : public QObject +{ + Q_OBJECT +public: + ModelData(QObject* parent) : QObject {parent} {} + std::unique_ptr canvas; + std::unique_ptr itemSelectionModel; + std::unique_ptr tools; + Model* model; +}; +#include "main.moc" + static constexpr MemberData renderStyleButtons[] = { { offsetof(Ui_MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal }, { offsetof(Ui_MainWindow, actionRenderStyleBfc), gl::RenderStyle::BfcRedGreen }, @@ -107,52 +138,41 @@ } } -/* -void MainWindow::handleDocumentSplitterChange() +ModelData* findModelData(DocumentManager* documents, ModelId modelId) +{ + return documents->findPayload(modelId); +} + +static ModelSubWindow* currentModelSubWindow(Ui_MainWindow* ui) { - EditorTabWidget* currentDocument = this->currentDocument(); - if (currentDocument != nullptr) - { - this->documentSplitterState = currentDocument->saveSplitterState(); - for (int i = 0; i < this->ui->tabs->count(); i += 1) - { - EditorTabWidget* document = qobject_cast(this->ui->tabs->widget(i)); - if (document != nullptr and document != currentDocument) - { - document->restoreSplitterState(this->documentSplitterState); - } - } - this->settings.setMainSplitterState(this->documentSplitterState); - } + return qobject_cast(ui->mdiArea->activeSubWindow()); } -*/ -static EditorTabWidget* currentTabWidget(Ui_MainWindow* ui) +static ModelData* currentModelData(Ui_MainWindow* ui, DocumentManager* documents) { - QMdiSubWindow* activeSubWindow = ui->mdiArea->activeSubWindow(); - if (activeSubWindow == nullptr) { - return nullptr; + if (auto* const activeSubWindow = currentModelSubWindow(ui)) { + return findModelData(documents, activeSubWindow->modelId); } else { - return qobject_cast(activeSubWindow->widget()); - } -}; - - -static void closeDocument(DocumentManager* documents, EditorTabWidget *document) -{ - std::optional modelId = documents->findIdForModel(document->model); - if (modelId.has_value()) { - documents->closeDocument(modelId.value()); - delete document; + return nullptr; } } -static std::optional findCurrentModelId(Ui_MainWindow* ui, DocumentManager* documents) +static Model* currentModelBody(Ui_MainWindow* ui, DocumentManager* documents) { - const EditorTabWidget* tab = currentTabWidget(ui); - if (tab != nullptr) { - return documents->findIdForModel(tab->model); + if (auto* const activeSubWindow = currentModelSubWindow(ui)) { + return documents->getModelById(activeSubWindow->modelId); + } + else { + return nullptr; + } +} + +static std::optional findCurrentModelId(Ui_MainWindow* ui) +{ + ModelSubWindow* activeSubWindow = qobject_cast(ui->mdiArea->activeSubWindow()); + if (activeSubWindow != nullptr) { + return activeSubWindow->modelId; } else { return {}; @@ -196,16 +216,28 @@ } } +template +static void forModel(const DocumentManager* documents, Fn&& fn) +{ + forValueInMap(*documents, [&fn](const DocumentManager::ModelInfo& info) + { + ModelData* modelSpecificData = qobject_cast(info.payload); + if (modelSpecificData != nullptr) { + fn(&info, modelSpecificData); + } + }); +} + static void updateRenderPreferences( Ui_MainWindow* ui, - const gl::RenderPreferences* renderPreferences) + const gl::RenderPreferences* renderPreferences, + const DocumentManager* documents) { - for (QMdiSubWindow* subWindow : ui->mdiArea->subWindowList()) { - EditorTabWidget* tab = qobject_cast(subWindow->widget()); - if (tab != nullptr) { - tab->canvas->setRenderPreferences(*renderPreferences); + forModel(documents, [&renderPreferences](const void*, const ModelData* data){ + if (data->canvas != nullptr) { + data->canvas->setRenderPreferences(*renderPreferences); } - } + }); for (auto data : ::renderStyleButtons) { QAction* action = data.memberInstance(ui); action->setChecked(renderPreferences->style == data.payload); @@ -295,7 +327,6 @@ QStringList recentlyOpenedFiles; ColorTable colorTable; gl::RenderPreferences renderPreferences; - QMap itemSelectionModels; ui.setupUi(&mainWindow); const uiutilities::KeySequenceMap defaultKeyboardShortcuts = uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); @@ -340,7 +371,7 @@ libraries.restoreFromSettings(&settings); updateRecentlyOpenedDocumentsMenu(); colorTable = loadColors(&libraries); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); ui.mdiArea->setViewMode(static_cast(settings.viewMode())); ui.retranslateUi(&mainWindow); }; @@ -357,36 +388,45 @@ }; const auto openModelForEditing = [&](const ModelId modelId){ Model* model = documents.getModelById(modelId); - EditorTabWidget* document = new EditorTabWidget{model, &documents, colorTable}; - QObject::connect( - document, - &EditorTabWidget::modelAction, - std::bind(executeAction, model, std::placeholders::_1)); - QItemSelectionModel* selectionModel = new QItemSelectionModel{model}; - itemSelectionModels[model] = selectionModel; - QObject::connect(selectionModel, &QItemSelectionModel::selectionChanged, - [model, document](const QItemSelection& selected, const QItemSelection& deselected) - { - auto resolveIndex = [&model](const QModelIndex& index){ - return model->idAt(index.row()); - }; - auto resolve = [&resolveIndex](const QItemSelection& selection) + if (model != nullptr) { + ModelData* data = new ModelData(&documents); + data->tools = std::make_unique(model, colorTable); + data->canvas = std::make_unique(model, data->tools.get(), &documents, colorTable); + data->itemSelectionModel = std::make_unique(model); + data->model = model; + QObject::connect( + data->tools.get(), + &EditTools::modelAction, + std::bind(executeAction, model, std::placeholders::_1)); + QObject::connect(data->itemSelectionModel.get(), &QItemSelectionModel::selectionChanged, + [modelId, &documents]( + const QItemSelection& selected, + const QItemSelection& deselected) { - return fn::map>(selection.indexes(), resolveIndex); - }; - document->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); - }); - document->canvas->setRenderPreferences(renderPreferences); - QObject::connect( - document, - &EditorTabWidget::newStatusText, - [&](const QString& newStatusText) { - mainWindow.statusBar()->showMessage(newStatusText); + ModelData* data = findModelData(&documents, modelId); + if (data != nullptr) { + auto resolveIndex = [&data](const QModelIndex& index){ + return data->model->idAt(index.row()); + }; + auto resolve = [&resolveIndex](const QItemSelection& selection) + { + return fn::map>(selection.indexes(), resolveIndex); + }; + data->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); + } }); - const QFileInfo fileInfo{*documents.modelPath(modelId)}; - QMdiSubWindow* subWindow = ui.mdiArea->addSubWindow(document); - subWindow->setWindowTitle(tabName(fileInfo)); - subWindow->show(); + data->canvas->setRenderPreferences(renderPreferences); + QObject::connect( + data->tools.get(), + &EditTools::newStatusText, + [&](const QString& newStatusText) { + mainWindow.statusBar()->showMessage(newStatusText); + }); + const QFileInfo fileInfo{*documents.modelPath(modelId)}; + QMdiSubWindow* subWindow = ui.mdiArea->addSubWindow(data->canvas.get()); + subWindow->setWindowTitle(tabName(fileInfo)); + subWindow->show(); + } }; QObject::connect(ui.actionNew, &QAction::triggered, [&]{ openModelForEditing(documents.newModel()); @@ -411,18 +451,14 @@ } }); QObject::connect(ui.actionQuit, &QAction::triggered, &mainWindow, &QMainWindow::close); - QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&ui]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) - { - adjustGridToView(tab->canvas); + QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&]{ + if (ModelData* data = currentModelData(&ui, &documents)) { + adjustGridToView(data->canvas.get()); } }); QObject::connect(ui.actionClose, &QAction::triggered, [&ui, &documents]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) - { - closeDocument(&documents, tab); + if (ModelData* data = currentModelData(&ui, &documents)) { + // TODO } }); const auto save = [&](ModelId modelId){ @@ -442,7 +478,7 @@ } }; const auto actionSaveAs = [&]{ - const std::optional modelId = findCurrentModelId(&ui, &documents); + const std::optional modelId = findCurrentModelId(&ui); if (modelId.has_value()) { const QString* pathPtr = documents.modelPath(*modelId); @@ -467,40 +503,37 @@ }; QObject::connect(ui.actionSaveAs, &QAction::triggered, actionSaveAs); QObject::connect(ui.actionSave, &QAction::triggered, [&]{ - if (currentTabWidget(&ui) != nullptr) { - const std::optional modelId = findCurrentModelId(&ui, &documents); - if (modelId.has_value()) { - const QString* path = documents.modelPath(*modelId); - if (path == nullptr or path->isEmpty()) { - actionSaveAs(); - } - else { - save(*modelId); - } + const std::optional modelId = findCurrentModelId(&ui); + if (modelId.has_value()) { + const QString* path = documents.modelPath(*modelId); + if (path == nullptr or path->isEmpty()) { + actionSaveAs(); + } + else { + save(*modelId); } } }); QObject::connect(ui.actionDelete, &QAction::triggered, [&]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) { + if (Model* model = currentModelBody(&ui, &documents)) { std::vector selectedRows = rows(ui.modelListView->selectionModel()->selectedRows()); std::sort(selectedRows.begin(), selectedRows.end(), std::greater{}); for (int row : selectedRows) { - executeAction(tab->model, DeleteFromModel{.position = row}); + executeAction(model, DeleteFromModel{.position = row}); } } }); QObject::connect(ui.actionDrawAxes, &QAction::triggered, [&](bool drawAxes){ renderPreferences.drawAxes = drawAxes; saveSettings(); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); }); for (auto data : ::renderStyleButtons) { QAction* action = data.memberInstance(&ui); QObject::connect(action, &QAction::triggered, [&, data]{ renderPreferences.style = data.payload; saveSettings(); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); }); } const auto checkEditingModeAction = [&ui](EditingMode mode) { @@ -511,24 +544,22 @@ initializeTools(&ui, &mainWindow); for (QAction* action : ui.editingModesToolBar->actions()) { QObject::connect(action, &QAction::triggered, [&, action]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) { + if (ModelData* data = currentModelData(&ui, &documents)) { const EditingMode mode = action->data().value(); - tab->setEditMode(mode); + data->tools->setEditMode(mode); checkEditingModeAction(mode); } }); } QObject::connect(ui.mdiArea, &QMdiArea::subWindowActivated, [&](QMdiSubWindow* subWindow) { - if (subWindow != nullptr) { - EditorTabWidget* tab = qobject_cast(subWindow->widget()); - if (tab != nullptr) { - checkEditingModeAction(tab->currentEditingMode()); - QItemSelectionModel* selectionModel = itemSelectionModels.value(tab->model); - if (selectionModel != nullptr) { - ui.modelListView->setModel(tab->model); - ui.modelListView->setSelectionModel(selectionModel); + ModelSubWindow* modelSubWindow = qobject_cast(subWindow); + if (modelSubWindow != nullptr) { + if (ModelData* data = documents.findPayload(modelSubWindow->modelId)) { + checkEditingModeAction(data->tools->currentEditingMode()); + if (data->itemSelectionModel != nullptr) { + ui.modelListView->setModel(data->model); + ui.modelListView->setSelectionModel(data->itemSelectionModel.get()); } } } @@ -536,7 +567,7 @@ mainWindow.setWindowTitle(title()); mainWindow.restoreGeometry(settings.mainWindowGeometry()); restoreSettings(); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); mainWindow.show(); const int result = app.exec(); saveSettings();