Sun, 03 Nov 2019 12:56:42 +0200
added saving of splitter state and recent files
locale/fi.ts | file | annotate | diff | comparison | revisions | |
locale/sv.ts | file | annotate | diff | comparison | revisions | |
src/document.cpp | file | annotate | diff | comparison | revisions | |
src/document.h | file | annotate | diff | comparison | revisions | |
src/mainwindow.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.h | file | annotate | diff | comparison | revisions | |
src/mainwindow.ui | file | annotate | diff | comparison | revisions |
--- a/locale/fi.ts Sun Nov 03 12:17:41 2019 +0200 +++ b/locale/fi.ts Sun Nov 03 12:56:42 2019 +0200 @@ -113,32 +113,37 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.ui" line="48"/> + <location filename="../src/mainwindow.ui" line="38"/> + <source>Recent files</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/mainwindow.ui" line="54"/> <source>Quit</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.ui" line="53"/> + <location filename="../src/mainwindow.ui" line="59"/> <source>Open…</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.ui" line="56"/> + <location filename="../src/mainwindow.ui" line="62"/> <source>Ctrl+O</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.ui" line="61"/> + <location filename="../src/mainwindow.ui" line="67"/> <source>New</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.ui" line="64"/> + <location filename="../src/mainwindow.ui" line="70"/> <source>Ctrl+N</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.ui" line="69"/> + <location filename="../src/mainwindow.ui" line="75"/> <source>Preferences…</source> <translation type="unfinished"></translation> </message> @@ -153,13 +158,13 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="58"/> - <source>Could not open %1: %2</source> + <location filename="../src/mainwindow.cpp" line="65"/> + <source>Problem opening file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/mainwindow.cpp" line="61"/> - <source>Problem opening file</source> + <location filename="../src/mainwindow.cpp" line="67"/> + <source>Could not open %1: %2</source> <translation type="unfinished"></translation> </message> </context>
--- a/locale/sv.ts Sun Nov 03 12:17:41 2019 +0200 +++ b/locale/sv.ts Sun Nov 03 12:56:42 2019 +0200 @@ -189,6 +189,10 @@ <source>Preferences…</source> <translation>Inställningar…</translation> </message> + <message> + <source>Recent files</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SettingsEditor</name>
--- a/src/document.cpp Sun Nov 03 12:17:41 2019 +0200 +++ b/src/document.cpp Sun Nov 03 12:56:42 2019 +0200 @@ -9,9 +9,20 @@ { this->ui.setupUi(this); this->ui.listView->setModel(model); + connect(this->ui.splitter, &QSplitter::splitterMoved, this, &Document::splitterChanged); } Document::~Document() { delete &this->ui; } + +QByteArray Document::saveSplitterState() const +{ + return this->ui.splitter->saveState(); +} + +void Document::restoreSplitterState(const QByteArray& state) +{ + this->ui.splitter->restoreState(state); +}
--- a/src/document.h Sun Nov 03 12:17:41 2019 +0200 +++ b/src/document.h Sun Nov 03 12:56:42 2019 +0200 @@ -15,7 +15,10 @@ public: explicit Document(Model* model, QWidget *parent = nullptr); ~Document(); - + QByteArray saveSplitterState() const; + void restoreSplitterState(const QByteArray& state); +signals: + void splitterChanged(); private: Model* model; Ui::Document& ui;
--- a/src/mainwindow.cpp Sun Nov 03 12:17:41 2019 +0200 +++ b/src/mainwindow.cpp Sun Nov 03 12:56:42 2019 +0200 @@ -23,6 +23,7 @@ connect(ui->actionSettingsEditor, &QAction::triggered, this, &MainWindow::runSettingsEditor); this->updateTitle(); this->restoreSettings(); + this->newModel(); } MainWindow::~MainWindow() @@ -31,8 +32,7 @@ void MainWindow::newModel() { - documents.newModel(); - this->updateTabs(); + this->openModelForEditing(documents.newModel()); } void MainWindow::openModel() @@ -44,22 +44,29 @@ tr("LDraw models (*.ldr *.dat)")); if (not path.isEmpty()) { - QString errorString; - QTextStream errorStream{&errorString}; - QString modelName = this->documents.openModel(path, errorStream); - if (not modelName.isEmpty()) - { - Document* document = new Document{this->documents.findModelByName(modelName)}; - this->ui->tabs->addTab(document, modelName); - } - else - { - const QString errorMessage = utility::format( + this->openModelFromPath(path); + } +} + +void MainWindow::openModelFromPath(const QString& path) +{ + QString errorString; + QTextStream errorStream{&errorString}; + QString modelName = this->documents.openModel(path, errorStream); + if (not modelName.isEmpty()) + { + this->openModelForEditing(modelName); + this->addRecentlyOpenedFile(path); + } + else + { + QMessageBox::critical( + this, + tr("Problem opening file"), + utility::format( tr("Could not open %1: %2"), path, - errorString); - QMessageBox::critical(this, tr("Problem opening file"), errorMessage); - } + errorString)); } } @@ -86,6 +93,27 @@ } } +void MainWindow::addRecentlyOpenedFile(const QString& path) +{ + this->recentlyOpenedFiles.removeAll(path); + this->recentlyOpenedFiles.insert(0, path); + while (this->recentlyOpenedFiles.size() > maxRecentlyOpenedFiles) + { + this->recentlyOpenedFiles.removeLast(); + } + this->saveSettings(); + this->updateRecentlyOpenedDocumentsMenu(); +} + +void MainWindow::openModelForEditing(const QString& modelName) +{ + Document* document = new Document{this->documents.findModelByName(modelName)}; + this->ui->tabs->addTab(document, modelName); + this->ui->tabs->setCurrentWidget(document); + document->restoreSplitterState(this->documentSplitterState); + connect(document, &Document::splitterChanged, this, &MainWindow::handleDocumentSplitterChange); +} + void MainWindow::runSettingsEditor() { SettingsEditor settingsEditor{&this->settings, this}; @@ -96,6 +124,46 @@ } } +void MainWindow::handleDocumentSplitterChange() +{ + Document* currentDocument = qobject_cast<Document*>(this->ui->tabs->currentWidget()); + if (currentDocument != nullptr) + { + this->documentSplitterState = currentDocument->saveSplitterState(); + for (int i = 0; i < this->ui->tabs->count(); i += 1) + { + Document* document = qobject_cast<Document*>(this->ui->tabs->widget(i)); + if (document != nullptr and document != currentDocument) + { + document->restoreSplitterState(this->documentSplitterState); + } + } + this->settings.setValue("MainWindow/DocumentSplitterState", this->documentSplitterState); + } +} + +void MainWindow::updateRecentlyOpenedDocumentsMenu() +{ + this->ui->menuRecentFiles->clear(); + for (const QString& path : this->recentlyOpenedFiles) + { + QAction* action = new QAction{path, this}; + action->setData(path); + this->ui->menuRecentFiles->addAction(action); + connect(action, &QAction::triggered, this, &MainWindow::openRecentFile); + } +} + +void MainWindow::openRecentFile() +{ + QAction* action = qobject_cast<QAction*>(this->sender()); + if (action != nullptr) + { + const QString path = action->data().toString(); + this->openModelFromPath(path); + } +} + void MainWindow::changeEvent(QEvent* event) { if (event != nullptr) @@ -123,51 +191,6 @@ } /** - * @brief Creates a new tab widget for the specified model. - * @param model Model to get a new tab widget for - * @return widget - */ -QWidget* MainWindow::createWidgetForModel(Model* model) -{ - Q_UNUSED(model); - QWidget* widget = new QWidget(ui->tabs); - QLabel* label = new QLabel("asdf", widget); - QVBoxLayout* layout = new QVBoxLayout; - layout->addWidget(label); - widget->setLayout(layout); - return widget; -} - -/** - * @brief Gets a tab widget for the specified model. If it does not exist, - * it will be created. - * @param model Model to get a tab widget for - * @return widget - */ -QWidget* MainWindow::getWidgetForModel(Model* model) -{ - QWidget* widget = this->modelWidgets.value(model); - if (widget == nullptr) - { - QWidget* const new_widget = createWidgetForModel(model); - this->modelWidgets[model] = new_widget; - return new_widget; - } - else - { - return widget; - } -} - -/** - * @brief Updates the tab widget - */ -void MainWindow::updateTabs() -{ - -} - -/** * @brief Updates the title of the main window so to contain the app's name * and version as well as the open document name. */ @@ -184,7 +207,9 @@ */ void MainWindow::saveSettings() { - this->settings.setValue("mainwindow/geometry", this->saveGeometry()); + this->settings.setValue("MainWindow/Geometry", this->saveGeometry()); + this->settings.setValue("MainWindow/RecentlyOpened", this->recentlyOpenedFiles); + this->settings.setValue("MainWindow/DocumentSplitterState", this->documentSplitterState); this->libraries.storeToSettings(&this->settings); } @@ -193,11 +218,14 @@ */ void MainWindow::restoreSettings() { - this->restoreGeometry(this->settings.value("mainwindow/geometry").toByteArray()); + this->restoreGeometry(this->settings.value("MainWindow/Geometry").toByteArray()); + this->recentlyOpenedFiles = this->settings.value("MainWindow/RecentlyOpened").toStringList(); + this->documentSplitterState = this->settings.value("MainWindow/DocumentSplitterState").toByteArray(); const QString systemLocale = QLocale::system().name(); const QVariant defaultLocale = this->settings.value("locale", systemLocale); changeLanguage(defaultLocale.toString()); this->libraries.restoreFromSettings(&this->settings); + this->updateRecentlyOpenedDocumentsMenu(); } QString MainWindow::pathToTranslation(const QString& localeCode)
--- a/src/mainwindow.h Sun Nov 03 12:17:41 2019 +0200 +++ b/src/mainwindow.h Sun Nov 03 12:56:42 2019 +0200 @@ -16,7 +16,11 @@ private slots: void newModel(); void openModel(); + void openModelFromPath(const QString& path); void runSettingsEditor(); + void handleDocumentSplitterChange(); + void updateRecentlyOpenedDocumentsMenu(); + void openRecentFile(); protected: void changeEvent(QEvent* event) override; void closeEvent(QCloseEvent* event) override; @@ -28,12 +32,14 @@ QTranslator translator; QSettings settings; LibraryManager libraries; - QWidget* createWidgetForModel(Model* model); - QWidget* getWidgetForModel(Model* model); - void updateTabs(); + QByteArray documentSplitterState; + static constexpr int maxRecentlyOpenedFiles = 10; + QStringList recentlyOpenedFiles; void updateTitle(); void saveSettings(); void restoreSettings(); void changeLanguage(QString localeCode); + void addRecentlyOpenedFile(const QString& path); + void openModelForEditing(const QString& modelName); static QString pathToTranslation(const QString& localeCode); };
--- a/src/mainwindow.ui Sun Nov 03 12:17:41 2019 +0200 +++ b/src/mainwindow.ui Sun Nov 03 12:56:42 2019 +0200 @@ -33,8 +33,14 @@ <property name="title"> <string>File</string> </property> + <widget class="QMenu" name="menuRecentFiles"> + <property name="title"> + <string>Recent files</string> + </property> + </widget> <addaction name="actionNew"/> <addaction name="actionOpen"/> + <addaction name="menuRecentFiles"/> <addaction name="separator"/> <addaction name="actionSettingsEditor"/> <addaction name="separator"/>