From c0bffa010783db72d6b42919562df052f16a1039 Mon Sep 17 00:00:00 2001
From: garakmon <garakmon@gmail.com>
Date: Tue, 7 Apr 2020 14:20:31 -0400
Subject: [PATCH] add some destructors, prevent value set on combobox update

    - add destructors to Project and Editor
    - properly close project when opening a new one
    - when reloading comboboxes, do not set map values
      with the new first item
---
 include/editor.h     |  6 ++++
 include/mainwindow.h |  7 ++++-
 include/project.h    | 12 ++++++--
 src/editor.cpp       |  8 +++++
 src/main.cpp         |  2 +-
 src/mainwindow.cpp   | 31 ++++++++++++++-----
 src/project.cpp      | 71 ++++++++++++++++++++++++++++++--------------
 7 files changed, 101 insertions(+), 36 deletions(-)

diff --git a/include/editor.h b/include/editor.h
index a0ab0e7e..52c3fdc7 100644
--- a/include/editor.h
+++ b/include/editor.h
@@ -31,6 +31,12 @@ class Editor : public QObject
     Q_OBJECT
 public:
     Editor(Ui::MainWindow* ui);
+    ~Editor();
+
+    Editor() = delete;
+    Editor(const Editor &) = delete;
+    Editor & operator = (const Editor &) = delete;
+
 public:
     Ui::MainWindow* ui;
     QObject *parent = nullptr;
diff --git a/include/mainwindow.h b/include/mainwindow.h
index 27fe541c..02f12cfa 100644
--- a/include/mainwindow.h
+++ b/include/mainwindow.h
@@ -30,9 +30,13 @@ class MainWindow : public QMainWindow
     Q_OBJECT
 
 public:
-    explicit MainWindow(QWidget *parent = nullptr);
+    explicit MainWindow(QWidget *parent);
     ~MainWindow();
 
+    MainWindow() = delete;
+    MainWindow(const MainWindow &) = delete;
+    MainWindow & operator = (const MainWindow &) = delete;
+
 public slots:
     void scaleMapView(int);
 
@@ -188,6 +192,7 @@ private:
     bool setMap(QString, bool scrollTreeView = false);
     void redrawMapScene();
     bool loadDataStructures();
+    bool loadProjectCombos();
     bool populateMapList();
     void sortMapList();
     QString getExistingDirectory(QString);
diff --git a/include/project.h b/include/project.h
index f4f59d7d..5fec4a1b 100644
--- a/include/project.h
+++ b/include/project.h
@@ -23,9 +23,15 @@ class Project
 {
 public:
     Project();
+    ~Project();
+
+    Project(const Project &) = delete;
+    Project & operator = (const Project &) = delete;
+
+public:
     QString root;
     QStringList *groupNames = nullptr;
-    QMap<QString, int> *map_groups;
+    QMap<QString, int> *mapGroups;
     QList<QStringList> groupedMapNames;
     QStringList *mapNames = nullptr;
     QMap<QString, QVariant> miscConstants;
@@ -66,11 +72,11 @@ public:
     DataQualifiers getDataQualifiers(QString, QString);
     QMap<QString, DataQualifiers> dataQualifiers;
 
-    QMap<QString, Map*> *map_cache;
+    QMap<QString, Map*> *mapCache;
     Map* loadMap(QString);
     Map* getMap(QString);
 
-    QMap<QString, Tileset*> *tileset_cache = nullptr;
+    QMap<QString, Tileset*> *tilesetCache = nullptr;
     Tileset* loadTileset(QString, Tileset *tileset = nullptr);
     Tileset* getTileset(QString, bool forceLoad = false);
     QMap<QString, QStringList> tilesetLabels;
diff --git a/src/editor.cpp b/src/editor.cpp
index 2f8e38da..cf7466cb 100644
--- a/src/editor.cpp
+++ b/src/editor.cpp
@@ -23,6 +23,14 @@ Editor::Editor(Ui::MainWindow* ui)
     this->cursorMapTileRect = new CursorTileRect(&this->settings->cursorTileRectEnabled, qRgb(255, 255, 255));
 }
 
+Editor::~Editor()
+{
+    delete this->selected_events;
+    delete this->settings;
+    delete this->playerViewRect;
+    delete this->cursorMapTileRect;
+}
+
 void Editor::saveProject() {
     if (project) {
         saveUiFields();
diff --git a/src/main.cpp b/src/main.cpp
index ab638672..967ed9b2 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5,7 +5,7 @@ int main(int argc, char *argv[])
 {
     QApplication a(argc, argv);
     a.setStyle("fusion");
-    MainWindow w;
+    MainWindow w(nullptr);
     w.show();
 
     return a.exec();
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index e0e64da0..40b8b364 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -28,6 +28,7 @@
 #include <QSysInfo>
 #include <QDesktopServices>
 #include <QMatrix>
+#include <QSignalBlocker>
 
 MainWindow::MainWindow(QWidget *parent) :
     QMainWindow(parent),
@@ -298,13 +299,14 @@ bool MainWindow::openProject(QString dir) {
 
     bool already_open = isProjectOpen() && (editor->project->root == dir);
     if (!already_open) {
+        editor->closeProject();
         editor->project = new Project;
         editor->project->set_root(dir);
         success = loadDataStructures()
                && populateMapList()
                && setMap(getDefaultMap(), true);
     } else {
-        success = loadDataStructures() && populateMapList();
+        success = loadDataStructures() && populateMapList() && setMap(editor->map->name, true);
     }
 
     if (success) {
@@ -658,14 +660,25 @@ bool MainWindow::loadDataStructures() {
         success = success 
                && project->readSecretBaseIds() 
                && project->readCoordEventWeatherNames();
-    if (!success) {
-        return false;
-    }
+    
+    return success && loadProjectCombos();
+}
 
+bool MainWindow::loadProjectCombos() {
     // set up project ui comboboxes
-    QStringList songs = project->getSongNames();
+    Project *project = editor->project;
+
+    // Block signals to the comboboxes while they are being modified
+    const QSignalBlocker blocker1(ui->comboBox_Song);
+    const QSignalBlocker blocker2(ui->comboBox_Location);
+    const QSignalBlocker blocker3(ui->comboBox_PrimaryTileset);
+    const QSignalBlocker blocker4(ui->comboBox_SecondaryTileset);
+    const QSignalBlocker blocker5(ui->comboBox_Weather);
+    const QSignalBlocker blocker6(ui->comboBox_BattleScene);
+    const QSignalBlocker blocker7(ui->comboBox_Type);
+
     ui->comboBox_Song->clear();
-    ui->comboBox_Song->addItems(songs);
+    ui->comboBox_Song->addItems(project->getSongNames());
     ui->comboBox_Location->clear();
     ui->comboBox_Location->addItems(project->mapSectionValueToName.values());
 
@@ -673,6 +686,7 @@ bool MainWindow::loadDataStructures() {
     if (tilesets.isEmpty()) {
         return false;
     }
+
     ui->comboBox_PrimaryTileset->clear();
     ui->comboBox_PrimaryTileset->addItems(tilesets.value("primary"));
     ui->comboBox_SecondaryTileset->clear();
@@ -683,6 +697,7 @@ bool MainWindow::loadDataStructures() {
     ui->comboBox_BattleScene->addItems(*project->mapBattleScenes);
     ui->comboBox_Type->clear();
     ui->comboBox_Type->addItems(*project->mapTypes);
+
     return true;
 }
 
@@ -1099,10 +1114,10 @@ void MainWindow::drawMapListIcons(QAbstractItemModel *model) {
             QVariant data = index.data(Qt::UserRole);
             if (!data.isNull()) {
                 QString map_name = data.toString();
-                if (editor->project && editor->project->map_cache->contains(map_name)) {
+                if (editor->project && editor->project->mapCache->contains(map_name)) {
                     QStandardItem *map = mapListModel->itemFromIndex(mapListIndexes.value(map_name));
                     map->setIcon(*mapIcon);
-                    if (editor->project->map_cache->value(map_name)->hasUnsavedChanges()) {
+                    if (editor->project->mapCache->value(map_name)->hasUnsavedChanges()) {
                         map->setIcon(*mapEditedIcon);
                         projectHasUnsavedChanges = true;
                     }
diff --git a/src/project.cpp b/src/project.cpp
index fcdb1dcb..f04f3870 100644
--- a/src/project.cpp
+++ b/src/project.cpp
@@ -37,7 +37,7 @@ int Project::num_pals_total = 13;
 Project::Project()
 {
     groupNames = new QStringList;
-    map_groups = new QMap<QString, int>;
+    mapGroups = new QMap<QString, int>;
     mapNames = new QStringList;
     itemNames = new QStringList;
     flagNames = new QStringList;
@@ -50,10 +50,35 @@ Project::Project()
     secretBaseIds = new QStringList;
     bgEventFacingDirections = new QStringList;
     trainerTypes = new QStringList;
-    map_cache = new QMap<QString, Map*>;
+    mapCache = new QMap<QString, Map*>;
     mapConstantsToMapNames = new QMap<QString, QString>;
     mapNamesToMapConstants = new QMap<QString, QString>;
-    tileset_cache = new QMap<QString, Tileset*>;
+    tilesetCache = new QMap<QString, Tileset*>;
+}
+
+Project::~Project()
+{
+    delete this->groupNames;
+    delete this->mapGroups;
+    delete this->mapNames;
+    delete this->itemNames;
+    delete this->flagNames;
+    delete this->varNames;
+    delete this->weatherNames;
+    delete this->coordEventWeatherNames;
+
+    delete this->secretBaseIds;
+    delete this->movementTypes;
+    delete this->bgEventFacingDirections;
+    delete this->mapBattleScenes;
+    delete this->trainerTypes;
+    delete this->mapTypes;
+
+    delete this->mapConstantsToMapNames;
+    delete this->mapNamesToMapConstants;
+    
+    delete this->mapCache;
+    delete this->tilesetCache;
 }
 
 void Project::set_root(QString dir) {
@@ -71,8 +96,8 @@ QString Project::getProjectTitle() {
 
 Map* Project::loadMap(QString map_name) {
     Map *map;
-    if (map_cache->contains(map_name)) {
-        map = map_cache->value(map_name);
+    if (mapCache->contains(map_name)) {
+        map = mapCache->value(map_name);
         // TODO: uncomment when undo/redo history is fully implemented for all actions.
         if (true/*map->hasUnsavedChanges()*/) {
             return map;
@@ -87,7 +112,7 @@ Map* Project::loadMap(QString map_name) {
 
     map->commit();
     map->metatileHistory.save();
-    map_cache->insert(map_name, map);
+    mapCache->insert(map_name, map);
     return map;
 }
 
@@ -390,8 +415,8 @@ bool Project::loadMapData(Map* map) {
 }
 
 QString Project::readMapLayoutId(QString map_name) {
-    if (map_cache->contains(map_name)) {
-        return map_cache->value(map_name)->layoutId;
+    if (mapCache->contains(map_name)) {
+        return mapCache->value(map_name)->layoutId;
     }
 
     QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name);
@@ -406,8 +431,8 @@ QString Project::readMapLayoutId(QString map_name) {
 }
 
 QString Project::readMapLocation(QString map_name) {
-    if (map_cache->contains(map_name)) {
-        return map_cache->value(map_name)->location;
+    if (mapCache->contains(map_name)) {
+        return mapCache->value(map_name)->location;
     }
 
     QString mapFilepath = QString("%1/data/maps/%2/map.json").arg(root).arg(map_name);
@@ -1109,7 +1134,7 @@ Tileset* Project::loadTileset(QString label, Tileset *tileset) {
 
     loadTilesetAssets(tileset);
 
-    tileset_cache->insert(label, tileset);
+    tilesetCache->insert(label, tileset);
     return tileset;
 }
 
@@ -1199,10 +1224,10 @@ void Project::writeBlockdata(QString path, Blockdata *blockdata) {
 }
 
 void Project::saveAllMaps() {
-    QList<QString> keys = map_cache->keys();
+    QList<QString> keys = mapCache->keys();
     for (int i = 0; i < keys.length(); i++) {
         QString key = keys.value(i);
-        Map* map = map_cache->value(key);
+        Map* map = mapCache->value(key);
         saveMap(map);
     }
 }
@@ -1640,8 +1665,8 @@ Blockdata* Project::readBlockdata(QString path) {
 }
 
 Map* Project::getMap(QString map_name) {
-    if (map_cache->contains(map_name)) {
-        return map_cache->value(map_name);
+    if (mapCache->contains(map_name)) {
+        return mapCache->value(map_name);
     } else {
         Map *map = loadMap(map_name);
         return map;
@@ -1650,12 +1675,12 @@ Map* Project::getMap(QString map_name) {
 
 Tileset* Project::getTileset(QString label, bool forceLoad) {
     Tileset *existingTileset = nullptr;
-    if (tileset_cache->contains(label)) {
-        existingTileset = tileset_cache->value(label);
+    if (tilesetCache->contains(label)) {
+        existingTileset = tilesetCache->value(label);
     }
 
     if (existingTileset && !forceLoad) {
-        return tileset_cache->value(label);
+        return tilesetCache->value(label);
     } else {
         Tileset *tileset = loadTileset(label, existingTileset);
         return tileset;
@@ -1762,7 +1787,7 @@ bool Project::readWildMonData() {
 bool Project::readMapGroups() {
     mapConstantsToMapNames->clear();
     mapNamesToMapConstants->clear();
-    map_groups->clear();
+    mapGroups->clear();
 
     QString mapGroupsFilepath = QString("%1/data/maps/map_groups.json").arg(root);
     QJsonDocument mapGroupsDoc;
@@ -1784,7 +1809,7 @@ bool Project::readMapGroups() {
         groups->append(groupName);
         for (int j = 0; j < mapNames.size(); j++) {
             QString mapName = mapNames.at(j).toString();
-            map_groups->insert(mapName, groupIndex);
+            mapGroups->insert(mapName, groupIndex);
             groupedMaps[groupIndex].append(mapName);
             maps->append(mapName);
 
@@ -1808,7 +1833,7 @@ bool Project::readMapGroups() {
 Map* Project::addNewMapToGroup(QString mapName, int groupNum) {
     // Setup new map in memory, but don't write to file until map is actually saved later.
     mapNames->append(mapName);
-    map_groups->insert(mapName, groupNum);
+    mapGroups->insert(mapName, groupNum);
     groupedMapNames[groupNum].append(mapName);
 
     Map *map = new Map;
@@ -1825,14 +1850,14 @@ Map* Project::addNewMapToGroup(QString mapName, int groupNum) {
     setNewMapConnections(map);
     map->commit();
     map->metatileHistory.save();
-    map_cache->insert(mapName, map);
+    mapCache->insert(mapName, map);
 
     return map;
 }
 
 Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool existingLayout) {
     mapNames->append(mapName);
-    map_groups->insert(mapName, groupNum);
+    mapGroups->insert(mapName, groupNum);
     groupedMapNames[groupNum].append(mapName);
 
     Map *map = new Map;