# HG changeset patch # User Teemu Piippo # Date 1681045148 -10800 # Node ID e1d646a4cbd86b6379a99dc74e081483ad968af7 # Parent c5e8b68e34f88c22709ca93e1d631272f3da4167 Extracted the state of the program into a MainState structure, and extracted local functions of main() into static functions. I was planning to make the core logic and state of the program into a Main class, which would be a QObject that would have lots of signals and slots, but it looks like this works even without it diff -r c5e8b68e34f8 -r e1d646a4cbd8 CMakeLists.txt --- a/CMakeLists.txt Sun Apr 09 13:28:36 2023 +0300 +++ b/CMakeLists.txt Sun Apr 09 15:59:08 2023 +0300 @@ -106,6 +106,7 @@ src/ldrawalgorithm.h src/ldrawsyntaxhighlighter.h src/libraries.h + src/main.h src/mainwindow.h src/messagelog.h src/model.h diff -r c5e8b68e34f8 -r e1d646a4cbd8 src/basics.h --- a/src/basics.h Sun Apr 09 13:28:36 2023 +0300 +++ b/src/basics.h Sun Apr 09 15:59:08 2023 +0300 @@ -356,3 +356,5 @@ return *reinterpret_cast(reinterpret_cast(instance) + this->member); } }; + +constexpr glm::mat4 DEFAULT_GRID_MATRIX = {{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}; diff -r c5e8b68e34f8 -r e1d646a4cbd8 src/main.cpp --- a/src/main.cpp Sun Apr 09 13:28:36 2023 +0300 +++ b/src/main.cpp Sun Apr 09 15:59:08 2023 +0300 @@ -23,6 +23,7 @@ #include "src/parser.h" #include "src/ldrawsyntaxhighlighter.h" #include +#include "src/main.h" static const QDir LOCALE_DIR {":/locale"}; @@ -145,26 +146,6 @@ } } -static QString title(MainWindow* ui) -{ - QMdiSubWindow* subWindow = ui->mdiArea->activeSubWindow(); - QString titlestring; - const QString versionString = fullVersionString(QLocale::ShortFormat); - if (subWindow != nullptr) { - titlestring = QObject::tr("%1 - %2").arg(subWindow->windowTitle(), versionString); - } - else { - titlestring = versionString; - } - if (/* DISABLES CODE */ (true) - and std::strcmp(CMAKE_BUILD_TYPE, "Release") != 0 - and std::strcmp(CMAKE_BUILD_TYPE, "MinSizeRel") != 0 - ) { - titlestring += QObject::tr(" [%1]").arg(CMAKE_BUILD_TYPE); - } - return titlestring; -} - static ColorTable loadColors(const LibrariesModel* libraries) { QTextStream errors; @@ -328,13 +309,8 @@ return font; } -constexpr glm::mat4 DEFAULT_GRID_MATRIX = {{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}; - -int main(int argc, char *argv[]) +struct MainState { - doQtRegistrations(); - QApplication app{argc, argv}; - QApplication::setWindowIcon(QIcon{":/icons/appicon.png"}); MainWindow mainWindow; DocumentManager documents; QString currentLanguage = "en"; @@ -344,194 +320,234 @@ ColorTable colorTable; gl::RenderPreferences renderPreferences; MessageLog messageLog; - Signal settingsChanged; ToolWidgets toolWidgets{ .circleToolOptions = new CircleToolOptionsWidget{&mainWindow}, }; - const auto updateTitle = [&mainWindow]{ - mainWindow.setWindowTitle(title(&mainWindow)); - }; - const uiutilities::KeySequenceMap defaultKeyboardShortcuts = - uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); - const auto saveSettings = [ - &libraries, - &mainWindow, - &recentlyOpenedFiles, - &renderPreferences, - &settingsChanged] - { - setSetting(mainWindow.saveGeometry()); - setSetting(mainWindow.saveState()); - setSetting(recentlyOpenedFiles); - setSetting(renderPreferences.style); - setSetting(renderPreferences.drawAxes); - setSetting(renderPreferences.wireframe); - libraries.storeToSettings(); - settingsChanged.emit(); - }; - const auto openModelForEditing = [ - &colorTable, - &documents, - &mainWindow, - &messageLog, - &renderPreferences, - &settingsChanged] - (const ModelId modelId) - { - QTextDocument* model = documents.getModelById(modelId); - if (model != nullptr) { - ModelData* data = new ModelData(&documents); - data->tools = std::make_unique(); - data->canvas = std::make_unique(model, &documents, colorTable); - data->axesLayer = std::make_unique(); - data->gridLayer = std::make_unique(); - data->gridLayer->setGridMatrix(DEFAULT_GRID_MATRIX); - data->tools->setGridMatrix(DEFAULT_GRID_MATRIX); - data->model = model; - data->canvas->addRenderLayer(data->axesLayer.get()); - data->canvas->setLayerEnabled(data->axesLayer.get(), setting()); - data->canvas->addRenderLayer(data->gridLayer.get()); - data->canvas->addRenderLayer(data->tools.get()); - new LDrawSyntaxHighlighter{model}; - data->textcursor = std::make_unique(model); - documents.setModelPayload(modelId, data); - QObject::connect( - data->tools.get(), - &EditTools::modelAction, - std::bind(executeAction, model, std::placeholders::_1)); - data->canvas->setRenderPreferences(renderPreferences); - QObject::connect( - data->tools.get(), - &EditTools::newStatusText, - [&mainWindow](const QString& newStatusText) { - mainWindow.statusBar()->showMessage(newStatusText); - }); +}; + +static void openModelForEditing(MainState* state, const ModelId modelId) +{ + QTextDocument* model = state->documents.getModelById(modelId); + if (model != nullptr) { + ModelData* data = new ModelData(&state->documents); + data->tools = std::make_unique(); + data->canvas = std::make_unique(model, &state->documents, state->colorTable); + data->axesLayer = std::make_unique(); + data->gridLayer = std::make_unique(); + data->gridLayer->setGridMatrix(DEFAULT_GRID_MATRIX); + data->tools->setGridMatrix(DEFAULT_GRID_MATRIX); + data->model = model; + data->canvas->addRenderLayer(data->axesLayer.get()); + data->canvas->setLayerEnabled(data->axesLayer.get(), setting()); + data->canvas->addRenderLayer(data->gridLayer.get()); + data->canvas->addRenderLayer(data->tools.get()); + new LDrawSyntaxHighlighter{model}; + data->textcursor = std::make_unique(model); + state->documents.setModelPayload(modelId, data); + QObject::connect( + data->tools.get(), + &EditTools::modelAction, + std::bind(executeAction, model, std::placeholders::_1)); + data->canvas->setRenderPreferences(state->renderPreferences); + QObject::connect( + data->tools.get(), + &EditTools::newStatusText, + [&state](const QString& newStatusText) { + state->mainWindow.statusBar()->showMessage(newStatusText); + }); #if 0 - QObject::connect( - data->tools.get(), - &EditTools::select, - [modelId, &documents](const QSet& indices, bool retain) { - ModelData* data = findModelData(&documents, modelId); - if (data != nullptr) { - if (not retain) { - data->textcursor->clearSelection(); - } - for (const ElementId id : indices) { - opt index = data->model->find(id); - if (index.has_value()) { - const QModelIndex qindex = data->model->index(*index); - data->itemSelectionModel->select(qindex, QItemSelectionModel::Select); - } + QObject::connect( + data->tools.get(), + &EditTools::select, + [modelId, &documents](const QSet& indices, bool retain) { + ModelData* data = findModelData(&documents, modelId); + if (data != nullptr) { + if (not retain) { + data->textcursor->clearSelection(); + } + for (const ElementId id : indices) { + opt index = data->model->find(id); + if (index.has_value()) { + const QModelIndex qindex = data->model->index(*index); + data->itemSelectionModel->select(qindex, QItemSelectionModel::Select); } } - }); -#endif - QObject::connect(&settingsChanged, &Signal::triggered, [modelId, &documents]{ - ModelData* data = findModelData(&documents, modelId); - if (data != nullptr) { - data->gridLayer->settingsChanged(); } }); - QObject::connect(data->canvas.get(), &PartRenderer::message, &messageLog, &MessageLog::addMessage); - QObject::connect( - data->tools.get(), - &EditTools::suggestCursor, - data->canvas.get(), - &QWidget::setCursor); - data->tools->setEditMode(SelectMode); - const QFileInfo fileInfo{*documents.modelPath(modelId)}; - auto* const subWindow = createSubWindow(mainWindow.mdiArea, modelId); - subWindow->setMinimumSize({96, 96}); - subWindow->resize({320, 200}); - subWindow->setWidget(data->canvas.get()); - subWindow->setWindowTitle(tabName(fileInfo)); - subWindow->show(); - } - }; - const auto updateRecentlyOpenedDocumentsMenu = [ - &mainWindow, - &recentlyOpenedFiles] - { - mainWindow.rebuildRecentFilesMenu(recentlyOpenedFiles); - }; - const auto restoreSettings = [ - &colorTable, - &documents, - &libraries, - &mainWindow, - &recentlyOpenedFiles, - &renderPreferences, - &settingsChanged, - &updateRecentlyOpenedDocumentsMenu] +#endif +#if 0 + QObject::connect(this, &Main::settingsChanged, [modelId, this]{ + ModelData* data = findModelData(&state.documents, modelId); + if (data != nullptr) { + data->gridLayer->settingsChanged(); + } + }); +#endif + QObject::connect(data->canvas.get(), &PartRenderer::message, &state->messageLog, &MessageLog::addMessage); + QObject::connect( + data->tools.get(), + &EditTools::suggestCursor, + data->canvas.get(), + &QWidget::setCursor); + data->tools->setEditMode(SelectMode); + const QFileInfo fileInfo{*state->documents.modelPath(modelId)}; + auto* const subWindow = createSubWindow(state->mainWindow.mdiArea, modelId); + subWindow->setMinimumSize({96, 96}); + subWindow->resize({320, 200}); + subWindow->setWidget(data->canvas.get()); + subWindow->setWindowTitle(tabName(fileInfo)); + subWindow->show(); + } +} + +static void updateRecentlyOpenedDocumentsMenu(MainState* state) +{ + state->mainWindow.rebuildRecentFilesMenu(state->recentlyOpenedFiles); +} + +static void restoreSettings(MainState* state) +{ + state->recentlyOpenedFiles = setting(); + state->renderPreferences = loadRenderPreferences(); + state->libraries.restoreFromSettings(); + updateRecentlyOpenedDocumentsMenu(state); + state->colorTable = loadColors(&state->libraries); + updateRenderPreferences(&state->mainWindow, &state->renderPreferences, &state->documents); + state->mainWindow.mdiArea->setViewMode(setting()); + state->mainWindow.retranslateUi(&state->mainWindow); + state->mainWindow.setToolButtonStyle(setting()); +} + +static void saveSettings(MainState* state) +{ + setSetting(state->mainWindow.saveGeometry()); + setSetting(state->mainWindow.saveState()); + setSetting(state->recentlyOpenedFiles); + setSetting(state->renderPreferences.style); + setSetting(state->renderPreferences.drawAxes); + setSetting(state->renderPreferences.wireframe); + state->libraries.storeToSettings(); +} + +static void addRecentlyOpenedFile(MainState* state, const QString& path) +{ + constexpr int maxRecentlyOpenedFiles = 10; + state->recentlyOpenedFiles.removeAll(path); + state->recentlyOpenedFiles.insert(0, path); + while (state->recentlyOpenedFiles.size() > maxRecentlyOpenedFiles) { - recentlyOpenedFiles = setting(); - renderPreferences = loadRenderPreferences(); - libraries.restoreFromSettings(); - updateRecentlyOpenedDocumentsMenu(); - colorTable = loadColors(&libraries); - updateRenderPreferences(&mainWindow, &renderPreferences, &documents); - mainWindow.mdiArea->setViewMode(setting()); - mainWindow.retranslateUi(&mainWindow); - mainWindow.setToolButtonStyle(setting()); - settingsChanged.emit(); - }; - const auto addRecentlyOpenedFile = [ - &recentlyOpenedFiles, - &saveSettings, - &updateRecentlyOpenedDocumentsMenu] - (const QString& path) + state->recentlyOpenedFiles.removeLast(); + } + saveSettings(state); + updateRecentlyOpenedDocumentsMenu(state); +} + +static void saveCurrentModel(MainState* state, ModelId modelId) +{ + QString error; + QTextStream errorStream{&error}; + const bool succeeded = state->documents.saveModel(modelId, errorStream); + if (not succeeded) + { + QMessageBox::critical(&state->mainWindow, QObject::tr("Save error"), error); + } + else + { + const QString* pathPtr = state->documents.modelPath(modelId); + if (pathPtr != nullptr) { + addRecentlyOpenedFile(state, *pathPtr); + } + } +} + +static void saveCurrentModelAs(MainState* state) +{ + const std::optional modelId = findCurrentModelId(&state->mainWindow); + if (modelId.has_value()) { - constexpr int maxRecentlyOpenedFiles = 10; - recentlyOpenedFiles.removeAll(path); - recentlyOpenedFiles.insert(0, path); - while (recentlyOpenedFiles.size() > maxRecentlyOpenedFiles) - { - recentlyOpenedFiles.removeLast(); + const QString* pathPtr = state->documents.modelPath(*modelId); + QString defaultPath = (pathPtr != nullptr) ? *pathPtr : ""; + const QString newPath = QFileDialog::getSaveFileName( + &state->mainWindow, + QObject::tr("Save as…"), + QFileInfo{defaultPath}.absoluteDir().path(), + QObject::tr("LDraw files (*.ldr *dat);;All files (*)") + ); + if (not newPath.isEmpty()) { + QString error; + QTextStream errorStream{&error}; + state->documents.setModelPath(*modelId, newPath, state->libraries, errorStream); + QMdiSubWindow* const subWindow = state->mainWindow.mdiArea->currentSubWindow(); + if (subWindow != nullptr) { + subWindow->setWindowTitle(tabName(QFileInfo{newPath})); + } + saveCurrentModel(state, *modelId); } - saveSettings(); - updateRecentlyOpenedDocumentsMenu(); - }; + } +} + +static void checkEditingModeAction(MainState* state, const EditingMode mode) +{ + const bool hasDocument = currentModelData(&state->mainWindow, &state->documents) != nullptr; + for (QAction* action : state->mainWindow.editingModesToolBar->actions()) + { + action->setEnabled(hasDocument); + action->setChecked(hasDocument and action->data().value() == mode); + } +} + +int main(int argc, char *argv[]) +{ + doQtRegistrations(); + QApplication app{argc, argv}; + QApplication::setWindowIcon(QIcon{":/icons/appicon.png"}); + MainState state; QObject::connect( - &mainWindow, + &state.mainWindow, &MainWindow::recentFileSelected, - [&libraries, &documents, &mainWindow, &openModelForEditing, &addRecentlyOpenedFile](const QString& path) { - const auto id = openModelFromPath(path, &libraries, &documents, &mainWindow); + [&state](const QString& path) { + const auto id = openModelFromPath(path, &state.libraries, &state.documents, &state.mainWindow); if (id.has_value()) { - openModelForEditing(id.value()); - addRecentlyOpenedFile(path); + openModelForEditing(&state, id.value()); + addRecentlyOpenedFile(&state, path); } } ); - QObject::connect(mainWindow.actionNew, &QAction::triggered, - [&documents, &openModelForEditing]{ - openModelForEditing(documents.newModel()); + QObject::connect(state.mainWindow.actionNew, &QAction::triggered, + [&state]{ + openModelForEditing(&state, state.documents.newModel()); } ); - QObject::connect(mainWindow.actionOpen, &QAction::triggered, - [&addRecentlyOpenedFile, &documents, &libraries, &mainWindow, &openModelForEditing] + QObject::connect(state.mainWindow.actionOpen, &QAction::triggered, + [&state] { - const QString path = getOpenModelPath(&mainWindow); + const QString path = getOpenModelPath(&state.mainWindow); if (not path.isEmpty()) { - const std::optional id = openModelFromPath(path, &libraries, &documents, &mainWindow); + const std::optional id = openModelFromPath(path, &state.libraries, &state.documents, &state.mainWindow); if (id.has_value()) { - openModelForEditing(id.value()); - addRecentlyOpenedFile(path); + openModelForEditing(&state, id.value()); + addRecentlyOpenedFile(&state, path); } } } ); - QObject::connect(mainWindow.actionSettingsEditor, &QAction::triggered, [&defaultKeyboardShortcuts, &restoreSettings, &settingsChanged, &mainWindow]{ - if (mainWindow.mdiArea->findChildren().isEmpty()) { - auto* const settingsEditor = createSubWindow(mainWindow.mdiArea, defaultKeyboardShortcuts); - QObject::connect(&settingsChanged, &Signal::triggered, settingsEditor, &SettingsEditor::loadSettings); - QObject::connect(settingsEditor, &SettingsEditor::settingsChanged, restoreSettings); + QObject::connect(state.mainWindow.actionSettingsEditor, &QAction::triggered, [ + &state, + defaultKeyboardShortcuts = uiutilities::makeKeySequenceMap(uiutilities::collectActions(&state.mainWindow))] + { + if (state.mainWindow.mdiArea->findChildren().isEmpty()) + { + auto* const settingsEditor = createSubWindow(state.mainWindow.mdiArea, defaultKeyboardShortcuts); + QObject::connect(settingsEditor, &SettingsEditor::settingsChanged, [&]{ + restoreSettings(&state); + }); settingsEditor->setAttribute(Qt::WA_DeleteOnClose); settingsEditor->show(); } }); - QObject::connect(mainWindow.actionQuit, &QAction::triggered, &mainWindow, &QMainWindow::close); + QObject::connect(state.mainWindow.actionQuit, &QAction::triggered, &state.mainWindow, &QMainWindow::close); #if 0 QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&]{ if (ModelData* data = currentModelData(&ui, &documents)) { @@ -539,193 +555,127 @@ } }); #endif - QObject::connect(mainWindow.actionClose, &QAction::triggered, [&mainWindow, &documents]{ - if (ModelData* data = currentModelData(&mainWindow, &documents)) { + QObject::connect(state.mainWindow.actionClose, &QAction::triggered, [&state]{ + if (ModelData* data = currentModelData(&state.mainWindow, &state.documents)) { // TODO } }); - const auto save = [&addRecentlyOpenedFile, &mainWindow](DocumentManager* documents, ModelId modelId){ - QString error; - QTextStream errorStream{&error}; - const bool succeeded = documents->saveModel(modelId, errorStream); - if (not succeeded) - { - QMessageBox::critical(&mainWindow, QObject::tr("Save error"), error); - } - else - { - const QString* pathPtr = documents->modelPath(modelId); - if (pathPtr != nullptr) { - addRecentlyOpenedFile(*pathPtr); - } - } - }; - const auto actionSaveAs = [&documents, &libraries, &mainWindow, &save]{ - const std::optional modelId = findCurrentModelId(&mainWindow); - if (modelId.has_value()) - { - const QString* pathPtr = documents.modelPath(*modelId); - QString defaultPath = (pathPtr != nullptr) ? *pathPtr : ""; - const QString newPath = QFileDialog::getSaveFileName( - &mainWindow, - QObject::tr("Save as…"), - QFileInfo{defaultPath}.absoluteDir().path(), - QObject::tr("LDraw files (*.ldr *dat);;All files (*)") - ); - if (not newPath.isEmpty()) { - QString error; - QTextStream errorStream{&error}; - documents.setModelPath(*modelId, newPath, libraries, errorStream); - QMdiSubWindow* const subWindow = mainWindow.mdiArea->currentSubWindow(); - if (subWindow != nullptr) { - subWindow->setWindowTitle(tabName(QFileInfo{newPath})); - } - save(&documents, *modelId); - } - } - }; - QObject::connect(mainWindow.actionSaveAs, &QAction::triggered, actionSaveAs); - QObject::connect(mainWindow.actionSave, &QAction::triggered, [ - &actionSaveAs, - &documents, - &save, - &mainWindow] + QObject::connect(state.mainWindow.actionSaveAs, &QAction::triggered, [&state]{ + saveCurrentModelAs(&state); + }); + QObject::connect(state.mainWindow.actionSave, &QAction::triggered, [&state] { - const std::optional modelId = findCurrentModelId(&mainWindow); + const std::optional modelId = findCurrentModelId(&state.mainWindow); if (modelId.has_value()) { - const QString* path = documents.modelPath(*modelId); + const QString* path = state.documents.modelPath(*modelId); if (path == nullptr or path->isEmpty()) { - actionSaveAs(); + saveCurrentModelAs(&state); } else { - save(&documents, *modelId); + saveCurrentModel(&state, *modelId); } } }); - QObject::connect(mainWindow.actionDrawAxes, &QAction::triggered, [ - &documents, - &renderPreferences, - &saveSettings, - &mainWindow] + QObject::connect(state.mainWindow.actionDrawAxes, &QAction::triggered, [&state] (bool drawAxes) { - renderPreferences.drawAxes = drawAxes; - saveSettings(); - updateRenderPreferences(&mainWindow, &renderPreferences, &documents); + state.renderPreferences.drawAxes = drawAxes; + saveSettings(&state); + updateRenderPreferences(&state.mainWindow, &state.renderPreferences, &state.documents); }); - QObject::connect(mainWindow.actionWireframe, &QAction::triggered, [ - &documents, - &renderPreferences, - &saveSettings, - &mainWindow] + QObject::connect(state.mainWindow.actionWireframe, &QAction::triggered, [&state] (bool enabled) { - renderPreferences.wireframe = enabled; - saveSettings(); - updateRenderPreferences(&mainWindow, &renderPreferences, &documents); + state.renderPreferences.wireframe = enabled; + saveSettings(&state); + updateRenderPreferences(&state.mainWindow, &state.renderPreferences, &state.documents); }); - QObject::connect(&mainWindow, &MainWindow::renderStyleSelected, [ - &documents, - &mainWindow, - &renderPreferences, - &saveSettings] + QObject::connect(&state.mainWindow, &MainWindow::renderStyleSelected, [&state] (gl::RenderStyle newStyle) { - renderPreferences.style = newStyle; - saveSettings(); - updateRenderPreferences(&mainWindow, &renderPreferences, &documents); + state.renderPreferences.style = newStyle; + saveSettings(&state); + updateRenderPreferences(&state.mainWindow, &state.renderPreferences, &state.documents); }); - const auto checkEditingModeAction = [&mainWindow, &documents](EditingMode mode) { - const bool hasDocument = currentModelData(&mainWindow, &documents) != nullptr; - for (QAction* action : mainWindow.editingModesToolBar->actions()) { - action->setEnabled(hasDocument); - action->setChecked(hasDocument and action->data().value() == mode); - } - }; - initializeTools(&mainWindow, &toolWidgets, &mainWindow); - for (QAction* action : mainWindow.editingModesToolBar->actions()) { - QObject::connect(action, &QAction::triggered, [ - action, - &checkEditingModeAction, - &documents, - &mainWindow] + initializeTools(&state.mainWindow, &state.toolWidgets, &state.mainWindow); + for (QAction* action : state.mainWindow.editingModesToolBar->actions()) { + QObject::connect(action, &QAction::triggered, [action, &state] { - if (ModelData* data = currentModelData(&mainWindow, &documents)) { + if (ModelData* data = currentModelData(&state.mainWindow, &state.documents)) + { const EditingMode mode = action->data().value(); data->tools->setEditMode(mode); - checkEditingModeAction(mode); + checkEditingModeAction(&state, mode); } }); } - QObject::connect(mainWindow.mdiArea, &QMdiArea::subWindowActivated, [ - &checkEditingModeAction, - &documents, - &mainWindow, - &updateTitle] - (QMdiSubWindow* subWindow) + QObject::connect(state.mainWindow.mdiArea, &QMdiArea::subWindowActivated, + [&state](QMdiSubWindow* subWindow) { ModelSubWindow* modelSubWindow = qobject_cast(subWindow); - if (modelSubWindow != nullptr) { - if (ModelData* data = documents.findPayload(modelSubWindow->modelId)) { - checkEditingModeAction(data->tools->currentEditingMode()); - mainWindow.modelEdit->setDocument(data->model); - mainWindow.modelEdit->setTextCursor(*data->textcursor); - mainWindow.modelEdit->setFont(codeEditorFontFromSettings()); + if (modelSubWindow != nullptr) + { + if (ModelData* data = state.documents.findPayload(modelSubWindow->modelId)) + { + checkEditingModeAction(&state, data->tools->currentEditingMode()); + state.mainWindow.modelEdit->setDocument(data->model); + state.mainWindow.modelEdit->setTextCursor(*data->textcursor); + state.mainWindow.modelEdit->setFont(codeEditorFontFromSettings()); } } - else { - checkEditingModeAction(EditingMode::SelectMode); + else + { + checkEditingModeAction(&state, EditingMode::SelectMode); } - mainWindow.modelEdit->setEnabled(modelSubWindow != nullptr); - updateTitle(); + state.mainWindow.modelEdit->setEnabled(modelSubWindow != nullptr); }); - mainWindow.messageLog->setModel(&messageLog); - QObject::connect(&documents, &DocumentManager::message, &messageLog, &MessageLog::addMessage); - QObject::connect(&messageLog, &MessageLog::rowsAboutToBeInserted, [&mainWindow]{ - const auto bar = mainWindow.messageLog->verticalScrollBar(); - mainWindow.messageLog->setProperty("shouldAutoScroll", bar->value() == bar->maximum()); + state.mainWindow.messageLog->setModel(&state.messageLog); + QObject::connect(&state.documents, &DocumentManager::message, &state.messageLog, &MessageLog::addMessage); + QObject::connect(&state.messageLog, &MessageLog::rowsAboutToBeInserted, [&state]{ + const auto bar = state.mainWindow.messageLog->verticalScrollBar(); + state.mainWindow.messageLog->setProperty("shouldAutoScroll", bar->value() == bar->maximum()); }); - QObject::connect(&messageLog, &MessageLog::rowsInserted, [&mainWindow]{ - mainWindow.messageLog->resizeRowsToContents(); - if (mainWindow.messageLog->property("shouldAutoScroll").toBool()) { - mainWindow.messageLog->scrollToBottom(); + QObject::connect(&state.messageLog, &MessageLog::rowsInserted, [&state]{ + state.mainWindow.messageLog->resizeRowsToContents(); + if (state.mainWindow.messageLog->property("shouldAutoScroll").toBool()) { + state.mainWindow.messageLog->scrollToBottom(); } }); QObject::connect( - toolWidgets.circleToolOptions, + state.toolWidgets.circleToolOptions, &CircleToolOptionsWidget::optionsChanged, - [&mainWindow, &documents](const CircleToolOptions& options) { - if (ModelData* data = currentModelData(&mainWindow, &documents)) { + [&state](const CircleToolOptions& options) { + if (ModelData* data = currentModelData(&state.mainWindow, &state.documents)) { data->tools->setCircleToolOptions(options); } }); QObject::connect( - mainWindow.actionMakeUnofficial, + state.mainWindow.actionMakeUnofficial, &QAction::triggered, - [&documents, &mainWindow]{ - if (ModelData* data = currentModelData(&mainWindow, &documents)) { + [&state]{ + if (ModelData* data = currentModelData(&state.mainWindow, &state.documents)) { QTextDocument* const model = data->model; for (const ModelAction& action : ldraw::makeUnofficial(model)) { executeAction(model, action); } } }); - QObject::connect(mainWindow.actionAboutQt, &QAction::triggered, &app, &QApplication::aboutQt); + QObject::connect(state.mainWindow.actionAboutQt, &QAction::triggered, &QApplication::aboutQt); QObject::connect( - mainWindow.modelEdit, + state.mainWindow.modelEdit, &QPlainTextEdit::textChanged, - [&documents, &libraries, &mainWindow]{ - if (ModelData* data = currentModelData(&mainWindow, &documents)) { - documents.loadDependenciesForAllModels(libraries); + [&state]{ + if (ModelData* data = currentModelData(&state.mainWindow, &state.documents)) { + state.documents.loadDependenciesForAllModels(state.libraries); data->canvas->update(); } }); QObject::connect( - mainWindow.gridMatrix, + state.mainWindow.gridMatrix, &MatrixEditor::valueChanged, [&](const glm::mat4& newGridMatrix) { - forEachModel(&documents, [&](const void*, const ModelData* data) + forEachModel(&state.documents, [&](const void*, const ModelData* data) { if (data->gridLayer != nullptr and data->tools != nullptr and data->canvas != nullptr) { @@ -737,21 +687,9 @@ }); } ); - mainWindow.gridMatrix->setValue(DEFAULT_GRID_MATRIX); - mainWindow.tabifyDockWidget(mainWindow.messageLogDock, mainWindow.toolOptionsDock); - mainWindow.restoreGeometry(setting()); - mainWindow.restoreState(setting()); - // If a dock is made floating and the app is closed, the dock becomes invisible - // after the restoreState call. So we make them visible again here. - for (QDockWidget* dock : mainWindow.findChildren()) { - dock->setVisible(true); - } - restoreSettings(); - updateRenderPreferences(&mainWindow, &renderPreferences, &documents); - mainWindow.actionAbout->setText(mainWindow.actionAbout->text().arg(CMAKE_PROJECT_NAME)); - updateTitle(); - mainWindow.show(); + restoreSettings(&state); + updateRenderPreferences(&state.mainWindow, &state.renderPreferences, &state.documents); const int result = app.exec(); - saveSettings(); + saveSettings(&state); return result; } diff -r c5e8b68e34f8 -r e1d646a4cbd8 src/mainwindow.cpp --- a/src/mainwindow.cpp Sun Apr 09 13:28:36 2023 +0300 +++ b/src/mainwindow.cpp Sun Apr 09 15:59:08 2023 +0300 @@ -4,6 +4,7 @@ #include #include #include +#include "src/settings.h" static constexpr MemberData renderStyleButtons[] = { { offsetof(MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal }, @@ -26,6 +27,19 @@ }); } this->connect(this->actionAbout, &QAction::triggered, this, &MainWindow::showAboutDialog); + this->connect(this->mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::updateTitle); + this->gridMatrix->setValue(DEFAULT_GRID_MATRIX); + this->tabifyDockWidget(this->messageLogDock, this->toolOptionsDock); + this->restoreGeometry(setting()); + this->restoreState(setting()); + // If a dock is made floating and the app is closed, the dock becomes invisible + // after the restoreState call. So we make them visible again here. + for (QDockWidget* dock : this->findChildren()) { + dock->setVisible(true); + } + this->actionAbout->setText(this->actionAbout->text().arg(CMAKE_PROJECT_NAME)); + this->updateTitle(); + this->show(); } void MainWindow::setRenderStyle(gl::RenderStyle style) @@ -100,3 +114,28 @@ }); } } + +static QString title(MainWindow* ui) +{ + QMdiSubWindow* subWindow = ui->mdiArea->activeSubWindow(); + QString titlestring; + const QString versionString = fullVersionString(QLocale::ShortFormat); + if (subWindow != nullptr) { + titlestring = QObject::tr("%1 - %2").arg(subWindow->windowTitle(), versionString); + } + else { + titlestring = versionString; + } + if (/* DISABLES CODE */ (true) + and std::strcmp(CMAKE_BUILD_TYPE, "Release") != 0 + and std::strcmp(CMAKE_BUILD_TYPE, "MinSizeRel") != 0 + ) { + titlestring += QObject::tr(" [%1]").arg(CMAKE_BUILD_TYPE); + } + return titlestring; +} + +void MainWindow::updateTitle() +{ + this->setWindowTitle(title(this)); +} diff -r c5e8b68e34f8 -r e1d646a4cbd8 src/mainwindow.h --- a/src/mainwindow.h Sun Apr 09 13:28:36 2023 +0300 +++ b/src/mainwindow.h Sun Apr 09 15:59:08 2023 +0300 @@ -16,6 +16,7 @@ public Q_SLOTS: void setRenderStyle(gl::RenderStyle style); void rebuildRecentFilesMenu(const QStringList& strings); + void updateTitle(); private Q_SLOTS: void showAboutDialog(); };