diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 76670b57..34ee86c6 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -3021,7 +3021,13 @@ File + + + Open Recent Project + + + diff --git a/include/config.h b/include/config.h index 16dc29f0..7ae31839 100644 --- a/include/config.h +++ b/include/config.h @@ -51,7 +51,7 @@ public: reset(); } virtual void reset() override { - this->recentProject = ""; + this->recentProjects.clear(); this->reopenOnLaunch = true; this->mapSortOrder = MapSortOrder::Group; this->prettyCursors = true; @@ -73,7 +73,8 @@ public: this->projectSettingsTab = 0; this->warpBehaviorWarningDisabled = false; } - void setRecentProject(QString project); + void addRecentProject(QString project); + void setRecentProjects(QStringList projects); void setReopenOnLaunch(bool enabled); void setMapSortOrder(MapSortOrder order); void setPrettyCursors(bool enabled); @@ -101,6 +102,7 @@ public: void setProjectSettingsTab(int tab); void setWarpBehaviorWarningDisabled(bool disabled); QString getRecentProject(); + QStringList getRecentProjects(); bool getReopenOnLaunch(); MapSortOrder getMapSortOrder(); bool getPrettyCursors(); @@ -134,7 +136,7 @@ protected: virtual void onNewConfigFileCreated() override {}; virtual void setUnreadKeys() override {}; private: - QString recentProject; + QStringList recentProjects; bool reopenOnLaunch; QString stringFromByteArray(QByteArray); QByteArray bytesFromString(QString); diff --git a/include/mainwindow.h b/include/mainwindow.h index 1b1b9123..6ff8a1d3 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -354,6 +354,7 @@ private: bool setInitialMap(); void setRecentMap(QString map_name); QStandardItem* createMapItem(QString mapName, int groupNum, int inGroupNum); + void refreshRecentProjectsMenu(); void drawMapListIcons(QAbstractItemModel *model); void updateMapList(); diff --git a/src/config.cpp b/src/config.cpp index 088fa8b3..61a6fc21 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -319,7 +319,8 @@ QString PorymapConfig::getConfigFilepath() { void PorymapConfig::parseConfigKeyValue(QString key, QString value) { if (key == "recent_project") { - this->recentProject = value; + this->recentProjects = value.split(",", Qt::SkipEmptyParts); + this->recentProjects.removeDuplicates(); } else if (key == "reopen_on_launch") { this->reopenOnLaunch = getConfigBool(key, value); } else if (key == "pretty_cursors") { @@ -404,7 +405,7 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) { QMap PorymapConfig::getKeyValueMap() { QMap map; - map.insert("recent_project", this->recentProject); + map.insert("recent_project", this->recentProjects.join(",")); map.insert("reopen_on_launch", this->reopenOnLaunch ? "1" : "0"); map.insert("pretty_cursors", this->prettyCursors ? "1" : "0"); map.insert("map_sort_order", mapSortOrderMap.value(this->mapSortOrder)); @@ -460,8 +461,14 @@ QByteArray PorymapConfig::bytesFromString(QString in) { return ba; } -void PorymapConfig::setRecentProject(QString project) { - this->recentProject = project; +void PorymapConfig::addRecentProject(QString project) { + this->recentProjects.removeOne(project); + this->recentProjects.prepend(project); + this->save(); +} + +void PorymapConfig::setRecentProjects(QStringList projects) { + this->recentProjects = projects; this->save(); } @@ -599,7 +606,11 @@ void PorymapConfig::setProjectSettingsTab(int tab) { } QString PorymapConfig::getRecentProject() { - return this->recentProject; + return this->recentProjects.value(0); +} + +QStringList PorymapConfig::getRecentProjects() { + return this->recentProjects; } bool PorymapConfig::getReopenOnLaunch() { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d9067343..2028f5b6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -65,12 +65,8 @@ MainWindow::MainWindow(QWidget *parent) : cleanupLargeLog(); this->initWindow(); - if (!this->openRecentProject()) { - setWindowDisabled(true); - } else { - setWindowDisabled(false); + if (this->openRecentProject()) on_toolButton_Paint_clicked(); - } // there is a bug affecting macOS users, where the trackpad deilveres a bad touch-release gesture // the warning is a bit annoying, so it is disabled here @@ -93,6 +89,8 @@ void MainWindow::setWindowDisabled(bool disabled) { ui->menuBar->setDisabled(false); ui->menuFile->setDisabled(false); ui->action_Open_Project->setDisabled(false); + ui->menuOpen_Recent_Project->setDisabled(false); + refreshRecentProjectsMenu(); ui->action_Exit->setDisabled(false); ui->menuHelp->setDisabled(false); ui->actionAbout_Porymap->setDisabled(false); @@ -506,6 +504,7 @@ bool MainWindow::openRecentProject() { bool MainWindow::openProject(QString dir) { if (dir.isNull()) { projectOpenFailure = true; + setWindowDisabled(true); return false; } @@ -553,18 +552,23 @@ bool MainWindow::openProject(QString dir) { .arg(getLogPath()) .arg(getMostRecentError()); msgBox.critical(nullptr, "Error Opening Project", errorMsg); + setWindowDisabled(true); return false; } showWindowTitle(); this->statusBar()->showMessage(QString("Opened project %1").arg(nativeDir)); + porymapConfig.addRecentProject(dir); + refreshRecentProjectsMenu(); + prefab.initPrefabUI( editor->metatile_selector_item, ui->scrollAreaWidgetContents_Prefabs, ui->label_prefabHelp, editor->map); Scripting::cb_ProjectOpened(dir); + setWindowDisabled(false); return true; } @@ -599,6 +603,36 @@ bool MainWindow::setInitialMap() { return false; } +void MainWindow::refreshRecentProjectsMenu() { + ui->menuOpen_Recent_Project->clear(); + QStringList recentProjects = porymapConfig.getRecentProjects(); + + if (isProjectOpen()) { + // Don't show the currently open project in this menu + recentProjects.removeOne(this->editor->project->root); + } + + // Add project paths to menu. Arbitrary limit of 10 items. + const int numItems = qMin(10, recentProjects.length()); + for (int i = 0; i < numItems; i++) { + const QString path = recentProjects.at(i); + ui->menuOpen_Recent_Project->addAction(path, [this, path](){ + this->openProject(path); + }); + } + + // Add action to clear list of paths + if (!recentProjects.isEmpty()) ui->menuOpen_Recent_Project->addSeparator(); + QAction *clearAction = ui->menuOpen_Recent_Project->addAction("Clear Items", [this](){ + QStringList paths = QStringList(); + if (isProjectOpen()) + paths.append(this->editor->project->root); + porymapConfig.setRecentProjects(paths); + this->refreshRecentProjectsMenu(); + }); + clearAction->setEnabled(!recentProjects.isEmpty()); +} + void MainWindow::openSubWindow(QWidget * window) { if (!window) return; @@ -628,8 +662,7 @@ void MainWindow::on_action_Open_Project_triggered() Scripting::cb_ProjectClosed(this->editor->project->root); this->ui->graphicsView_Map->clearOverlayMap(); } - porymapConfig.setRecentProject(dir); - setWindowDisabled(!openProject(dir)); + openProject(dir); } } @@ -642,10 +675,8 @@ void MainWindow::on_action_Reload_Project_triggered() { warning.setDefaultButton(QMessageBox::Cancel); warning.setIcon(QMessageBox::Warning); - if (warning.exec() == QMessageBox::Ok) { - if (!openProject(editor->project->root)) - setWindowDisabled(true); - } + if (warning.exec() == QMessageBox::Ok) + openProject(editor->project->root); } bool MainWindow::setMap(QString map_name, bool scrollTreeView) {