diff --git a/include/mainwindow.h b/include/mainwindow.h index 6cb2f37d..59e13ed7 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -310,6 +310,11 @@ private: void closeSupplementaryWindows(); void setWindowDisabled(bool); + void initTilesetEditor(); + bool initRegionMapEditor(); + void initShortcutsEditor(); + void connectSubEditorsToShortcutsEditor(); + bool isProjectOpen(); void showExportMapImageWindow(bool stitchMode); void redrawMetatileSelection(); diff --git a/include/ui/regionmapeditor.h b/include/ui/regionmapeditor.h index 484103f3..cba14251 100644 --- a/include/ui/regionmapeditor.h +++ b/include/ui/regionmapeditor.h @@ -47,6 +47,11 @@ public: void resize(int width, int height); + QObjectList shortcutableObjects() const; + +public slots: + void applyUserShortcuts(); + private: Ui::RegionMapEditor *ui; Project *project; @@ -81,6 +86,7 @@ private: RegionMapPixmapItem *region_map_item = nullptr; CityMapPixmapItem *city_map_item = nullptr; + void initShortcuts(); void displayRegionMap(); void displayRegionMapImage(); void displayRegionMapLayout(); diff --git a/include/ui/shortcutseditor.h b/include/ui/shortcutseditor.h index 85d3fa69..31b0279e 100644 --- a/include/ui/shortcutseditor.h +++ b/include/ui/shortcutseditor.h @@ -23,9 +23,12 @@ class ShortcutsEditor : public QMainWindow Q_OBJECT public: - explicit ShortcutsEditor(const QObjectList &objectList, QWidget *parent = nullptr); + explicit ShortcutsEditor(QWidget *parent = nullptr); + explicit ShortcutsEditor(const QObjectList &shortcutableObjects, QWidget *parent = nullptr); ~ShortcutsEditor(); + void setShortcutableObjects(const QObjectList &shortcutableObjects); + signals: void shortcutsSaved(); diff --git a/include/ui/tileseteditor.h b/include/ui/tileseteditor.h index 283f9cde..6cf7350c 100644 --- a/include/ui/tileseteditor.h +++ b/include/ui/tileseteditor.h @@ -42,6 +42,11 @@ public: void updateTilesets(QString primaryTilsetLabel, QString secondaryTilesetLabel); bool selectMetatile(uint16_t metatileId); + QObjectList shortcutableObjects() const; + +public slots: + void applyUserShortcuts(); + private slots: void onHoveredMetatileChanged(uint16_t); void onHoveredMetatileCleared(); @@ -102,6 +107,7 @@ private: void initTileSelector(); void initSelectedTileItem(); void initMetatileLayersItem(); + void initShortcuts(); void restoreWindowState(); void initMetatileHistory(); void setTilesets(QString primaryTilesetLabel, QString secondaryTilesetLabel); @@ -112,6 +118,7 @@ private: void refresh(); void saveMetatileLabel(); void closeEvent(QCloseEvent*); + Ui::TilesetEditor *ui; History metatileHistory; TilesetEditorMetatileSelector *metatileSelector = nullptr; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5085483b..489365aa 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -129,10 +129,10 @@ void MainWindow::initExtraShortcuts() { QObjectList MainWindow::shortcutableObjects() const { QObjectList shortcutable_objects; for (auto *action : findChildren()) - if (!action->objectName().isEmpty()) + if (ShortcutsConfig::objectNameIsValid(action)) shortcutable_objects.append(qobject_cast(action)); for (auto *shortcut : findChildren()) - if (!shortcut->objectName().isEmpty()) + if (ShortcutsConfig::objectNameIsValid(shortcut)) shortcutable_objects.append(qobject_cast(shortcut)); return shortcutable_objects; @@ -140,10 +140,10 @@ QObjectList MainWindow::shortcutableObjects() const { void MainWindow::applyUserShortcuts() { for (auto *action : findChildren()) - if (!action->objectName().isEmpty()) + if (ShortcutsConfig::objectNameIsValid(action)) action->setShortcuts(shortcutsConfig.userShortcuts(action)); for (auto *shortcut : findChildren()) - if (!shortcut->objectName().isEmpty()) + if (ShortcutsConfig::objectNameIsValid(shortcut)) shortcut->setKeys(shortcutsConfig.userShortcuts(shortcut)); } @@ -1449,12 +1449,8 @@ void MainWindow::on_actionUse_Poryscript_triggered(bool checked) void MainWindow::on_actionEdit_Shortcuts_triggered() { - if (!shortcutsEditor) { - shortcutsEditor = new ShortcutsEditor(shortcutableObjects(), this); - connect(shortcutsEditor, &QObject::destroyed, [=](QObject *) { shortcutsEditor = nullptr; }); - connect(shortcutsEditor, &ShortcutsEditor::shortcutsSaved, - this, &MainWindow::applyUserShortcuts); - } + if (!shortcutsEditor) + initShortcutsEditor(); if (shortcutsEditor->isHidden()) shortcutsEditor->show(); @@ -1464,6 +1460,35 @@ void MainWindow::on_actionEdit_Shortcuts_triggered() shortcutsEditor->activateWindow(); } +void MainWindow::initShortcutsEditor() { + shortcutsEditor = new ShortcutsEditor(this); + connect(shortcutsEditor, &ShortcutsEditor::shortcutsSaved, + this, &MainWindow::applyUserShortcuts); + connect(shortcutsEditor, &QObject::destroyed, [=](QObject *) { shortcutsEditor = nullptr; }); + + connectSubEditorsToShortcutsEditor(); + + shortcutsEditor->setShortcutableObjects(shortcutableObjects()); +} + +void MainWindow::connectSubEditorsToShortcutsEditor() { + /* Initialize sub-editors so that their children are added to MainWindow's object tree and will + * be returned by shortcutableObjects() to be passed to ShortcutsEditor. */ + if (!tilesetEditor) + initTilesetEditor(); + connect(shortcutsEditor, &ShortcutsEditor::shortcutsSaved, + tilesetEditor, &TilesetEditor::applyUserShortcuts); + + // TODO: Remove this check when the region map editor supports pokefirered. + if (projectConfig.getBaseGameVersion() != BaseGameVersion::pokefirered) { + if (!regionMapEditor) + initRegionMapEditor(); + if (regionMapEditor) + connect(shortcutsEditor, &ShortcutsEditor::shortcutsSaved, + regionMapEditor, &RegionMapEditor::applyUserShortcuts); + } +} + void MainWindow::on_actionPencil_triggered() { on_toolButton_Paint_clicked(); @@ -2551,9 +2576,7 @@ void MainWindow::on_checkBox_ToggleBorder_stateChanged(int selected) void MainWindow::on_actionTileset_Editor_triggered() { if (!this->tilesetEditor) { - this->tilesetEditor = new TilesetEditor(this->editor->project, this->editor->map, this); - connect(this->tilesetEditor, SIGNAL(tilesetsSaved(QString, QString)), this, SLOT(onTilesetsSaved(QString, QString))); - connect(this->tilesetEditor, &QObject::destroyed, [=](QObject *) { this->tilesetEditor = nullptr; }); + initTilesetEditor(); } if (!this->tilesetEditor->isVisible()) { @@ -2566,6 +2589,12 @@ void MainWindow::on_actionTileset_Editor_triggered() this->tilesetEditor->selectMetatile(this->editor->metatile_selector_item->getSelectedMetatiles()->at(0)); } +void MainWindow::initTilesetEditor() { + this->tilesetEditor = new TilesetEditor(this->editor->project, this->editor->map, this); + connect(this->tilesetEditor, SIGNAL(tilesetsSaved(QString, QString)), this, SLOT(onTilesetsSaved(QString, QString))); + connect(this->tilesetEditor, &QObject::destroyed, [=](QObject *) { this->tilesetEditor = nullptr; }); +} + void MainWindow::on_toolButton_ExpandAll_clicked() { if (ui->mapList) { @@ -2680,20 +2709,9 @@ void MainWindow::on_horizontalSlider_MetatileZoom_valueChanged(int value) { void MainWindow::on_actionRegion_Map_Editor_triggered() { if (!this->regionMapEditor) { - this->regionMapEditor = new RegionMapEditor(this, this->editor->project); - bool success = this->regionMapEditor->loadRegionMapData() - && this->regionMapEditor->loadCityMaps(); - if (!success) { - delete this->regionMapEditor; - this->regionMapEditor = nullptr; - QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening the region map data. Please see %1 for full error details.\n\n%3") - .arg(getLogPath()) - .arg(getMostRecentError()); - msgBox.critical(nullptr, "Error Opening Region Map Editor", errorMsg); + if (!initRegionMapEditor()) { return; } - connect(this->regionMapEditor, &QObject::destroyed, [=](QObject *) { this->regionMapEditor = nullptr; }); } if (!this->regionMapEditor->isVisible()) { @@ -2705,6 +2723,26 @@ void MainWindow::on_actionRegion_Map_Editor_triggered() { } } +bool MainWindow::initRegionMapEditor() { + this->regionMapEditor = new RegionMapEditor(this, this->editor->project); + bool success = this->regionMapEditor->loadRegionMapData() + && this->regionMapEditor->loadCityMaps(); + if (!success) { + delete this->regionMapEditor; + this->regionMapEditor = nullptr; + QMessageBox msgBox(this); + QString errorMsg = QString("There was an error opening the region map data. Please see %1 for full error details.\n\n%3") + .arg(getLogPath()) + .arg(getMostRecentError()); + msgBox.critical(nullptr, "Error Opening Region Map Editor", errorMsg); + + return false; + } + connect(this->regionMapEditor, &QObject::destroyed, [=](QObject *) { this->regionMapEditor = nullptr; }); + + return true; +} + void MainWindow::closeSupplementaryWindows() { if (this->tilesetEditor) delete this->tilesetEditor; @@ -2714,6 +2752,8 @@ void MainWindow::closeSupplementaryWindows() { delete this->mapImageExporter; if (this->newmapprompt) delete this->newmapprompt; + if (this->shortcutsEditor) + delete this->shortcutsEditor; } void MainWindow::closeEvent(QCloseEvent *event) { @@ -2740,6 +2780,7 @@ void MainWindow::closeEvent(QCloseEvent *event) { ); porymapConfig.save(); projectConfig.save(); + shortcutsConfig.save(); QMainWindow::closeEvent(event); } diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index ce3440dd..b025b90e 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -1,6 +1,7 @@ #include "regionmapeditor.h" #include "ui_regionmapeditor.h" #include "imageexport.h" +#include "shortcut.h" #include "config.h" #include "log.h" @@ -92,6 +93,33 @@ bool RegionMapEditor::loadCityMaps() { return true; } +void RegionMapEditor::initShortcuts() { + shortcutsConfig.load(); + shortcutsConfig.setDefaultShortcuts(shortcutableObjects()); + applyUserShortcuts(); +} + +QObjectList RegionMapEditor::shortcutableObjects() const { + QObjectList shortcutable_objects; + for (auto *action : findChildren()) + if (ShortcutsConfig::objectNameIsValid(action)) + shortcutable_objects.append(qobject_cast(action)); + for (auto *shortcut : findChildren()) + if (ShortcutsConfig::objectNameIsValid(shortcut)) + shortcutable_objects.append(qobject_cast(shortcut)); + + return shortcutable_objects; +} + +void RegionMapEditor::applyUserShortcuts() { + for (auto *action : findChildren()) + if (ShortcutsConfig::objectNameIsValid(action)) + action->setShortcuts(shortcutsConfig.userShortcuts(action)); + for (auto *shortcut : findChildren()) + if (ShortcutsConfig::objectNameIsValid(shortcut)) + shortcut->setKeys(shortcutsConfig.userShortcuts(shortcut)); +} + void RegionMapEditor::displayRegionMap() { displayRegionMapTileSelector(); displayCityMapTileSelector(); diff --git a/src/ui/shortcutseditor.cpp b/src/ui/shortcutseditor.cpp index efafc556..0e0843f0 100644 --- a/src/ui/shortcutseditor.cpp +++ b/src/ui/shortcutseditor.cpp @@ -13,7 +13,7 @@ #include -ShortcutsEditor::ShortcutsEditor(const QObjectList &objectList, QWidget *parent) : +ShortcutsEditor::ShortcutsEditor(QWidget *parent) : QMainWindow(parent), ui(new Ui::ShortcutsEditor), main_container(nullptr) @@ -21,12 +21,16 @@ ShortcutsEditor::ShortcutsEditor(const QObjectList &objectList, QWidget *parent) ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); main_container = ui->scrollAreaWidgetContents_Shortcuts; - main_container->setLayout(new QVBoxLayout(main_container)); + auto *formLayout = new QVBoxLayout(main_container); + formLayout->setSpacing(12); connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &ShortcutsEditor::dialogButtonClicked); - - parseObjectList(objectList); - populateMainContainer(); +} + +ShortcutsEditor::ShortcutsEditor(const QObjectList &shortcutableObjects, QWidget *parent) : + ShortcutsEditor(parent) +{ + setShortcutableObjects(shortcutableObjects); } ShortcutsEditor::~ShortcutsEditor() @@ -34,11 +38,19 @@ ShortcutsEditor::~ShortcutsEditor() delete ui; } +void ShortcutsEditor::setShortcutableObjects(const QObjectList &shortcutableObjects) { + parseObjectList(shortcutableObjects); + populateMainContainer(); +} + void ShortcutsEditor::saveShortcuts() { QMultiMap objects_keySequences; - for (auto it = multiKeyEdits_objects.cbegin(); it != multiKeyEdits_objects.cend(); ++it) + for (auto it = multiKeyEdits_objects.cbegin(); it != multiKeyEdits_objects.cend(); ++it) { + if (it.key()->keySequences().isEmpty()) + objects_keySequences.insert(it.value(), QKeySequence()); for (auto keySequence : it.key()->keySequences()) objects_keySequences.insert(it.value(), keySequence); + } shortcutsConfig.setUserShortcuts(objects_keySequences); emit shortcutsSaved(); diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index 1c6b620e..5e0b9eed 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -6,6 +6,7 @@ #include "paletteutil.h" #include "imageexport.h" #include "config.h" +#include "shortcut.h" #include #include #include @@ -86,7 +87,6 @@ void TilesetEditor::setTilesets(QString primaryTilesetLabel, QString secondaryTi void TilesetEditor::initUi() { ui->setupUi(this); - ui->actionRedo->setShortcuts({ui->actionRedo->shortcut(), QKeySequence("Ctrl+Shift+Z")}); this->tileXFlip = ui->checkBox_xFlip->isChecked(); this->tileYFlip = ui->checkBox_yFlip->isChecked(); this->paletteId = ui->spinBox_paletteSelector->value(); @@ -102,6 +102,7 @@ void TilesetEditor::initUi() { this->initMetatileLayersItem(); this->initTileSelector(); this->initSelectedTileItem(); + this->initShortcuts(); this->metatileSelector->select(0); this->restoreWindowState(); } @@ -209,6 +210,35 @@ void TilesetEditor::initSelectedTileItem() { this->ui->graphicsView_selectedTile->setFixedSize(this->selectedTilePixmapItem->pixmap().width() + 2, this->selectedTilePixmapItem->pixmap().height() + 2); } +void TilesetEditor::initShortcuts() { + ui->actionRedo->setShortcuts({ui->actionRedo->shortcut(), QKeySequence("Ctrl+Shift+Z")}); + + shortcutsConfig.load(); + shortcutsConfig.setDefaultShortcuts(shortcutableObjects()); + applyUserShortcuts(); +} + +QObjectList TilesetEditor::shortcutableObjects() const { + QObjectList shortcutable_objects; + for (auto *action : findChildren()) + if (ShortcutsConfig::objectNameIsValid(action)) + shortcutable_objects.append(qobject_cast(action)); + for (auto *shortcut : findChildren()) + if (ShortcutsConfig::objectNameIsValid(shortcut)) + shortcutable_objects.append(qobject_cast(shortcut)); + + return shortcutable_objects; +} + +void TilesetEditor::applyUserShortcuts() { + for (auto *action : findChildren()) + if (ShortcutsConfig::objectNameIsValid(action)) + action->setShortcuts(shortcutsConfig.userShortcuts(action)); + for (auto *shortcut : findChildren()) + if (ShortcutsConfig::objectNameIsValid(shortcut)) + shortcut->setKeys(shortcutsConfig.userShortcuts(shortcut)); +} + void TilesetEditor::restoreWindowState() { logInfo("Restoring tileset editor geometry from previous session."); QMap geometry = porymapConfig.getTilesetEditorGeometry();