diff --git a/CHANGES b/CHANGES index a8c0ca04b..09f0f22cb 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ Features: - Scripting: New `storage` API for saving data for a script, e.g. settings - Scripting: New `image` and `canvas` APIs for drawing images and displaying on-screen - Scripting: Debugger integration to allow for breakpoints and watchpoints + - Scripting: Add support for running scripts at startup - New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81, Sintax - Initial support for bootleg GBA multicarts - Debugger: Add range watchpoints diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 433e8c061..0dcfbaefb 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -297,12 +297,15 @@ endif() if(ENABLE_SCRIPTING) list(APPEND SOURCE_FILES + scripting/AutorunScriptModel.cpp + scripting/AutorunScriptView.cpp scripting/ScriptingController.cpp scripting/ScriptingTextBuffer.cpp scripting/ScriptingTextBufferModel.cpp scripting/ScriptingView.cpp) list(APPEND UI_FILES + scripting/AutorunScriptView.ui scripting/ScriptingView.ui) endif() diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index eae75fea4..5b65ac2ea 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -7,6 +7,7 @@ #include "ActionMapper.h" #include "CoreController.h" +#include "scripting/AutorunScriptModel.h" #include #include @@ -122,6 +123,8 @@ QString ConfigController::s_configDir; ConfigController::ConfigController(QObject* parent) : QObject(parent) { + qRegisterMetaType(); + QString fileName = configDir(); fileName.append(QDir::separator()); fileName.append("qt.ini"); @@ -379,6 +382,36 @@ void ConfigController::setMRU(const QStringList& mru, ConfigController::MRU mruT m_settings->endGroup(); } +QList ConfigController::getList(const QString& group) const { + QList list; + m_settings->beginGroup(group); + for (int i = 0; ; ++i) { + QVariant item = m_settings->value(QString::number(i)); + if (item.isNull() || !item.isValid()) { + break; + } + list.append(item); + } + m_settings->endGroup(); + return list; +} + +void ConfigController::setList(const QString& group, const QList& list) { + int i = 0; + m_settings->beginGroup(group); + QStringList keys = m_settings->childKeys(); + for (const QVariant& item : list) { + QString key = QString::number(i); + keys.removeAll(key); + m_settings->setValue(key, item); + ++i; + } + for (const auto& key: keys) { + m_settings->remove(key); + } + m_settings->endGroup(); +} + constexpr const char* ConfigController::mruName(ConfigController::MRU mru) { switch (mru) { case MRU::ROM: diff --git a/src/platform/qt/ConfigController.h b/src/platform/qt/ConfigController.h index 5aa9b7ac2..25c307b47 100644 --- a/src/platform/qt/ConfigController.h +++ b/src/platform/qt/ConfigController.h @@ -90,7 +90,7 @@ public: QVariant takeArgvOption(const QString& key); QStringList getMRU(MRU = MRU::ROM) const; - void setMRU(const QStringList& mru, MRU = MRU::ROM); + QList getList(const QString& group) const; Configuration* overrides() { return mCoreConfigGetOverrides(&m_config); } void saveOverride(const Override&); @@ -116,6 +116,8 @@ public slots: void setOption(const char* key, const char* value); void setOption(const char* key, const QVariant& value); void setQtOption(const QString& key, const QVariant& value, const QString& group = QString()); + void setMRU(const QStringList& mru, MRU = MRU::ROM); + void setList(const QString& group, const QList& list); void makePortable(); void write(); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 967cf1a4d..2099ce7f4 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -69,6 +69,8 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC reloadConfig(); + connect(m_ui.autorunScripts, &QAbstractButton::pressed, this, &SettingsView::openAutorunScripts); + connect(m_ui.volume, static_cast(&QSlider::valueChanged), [this](int v) { if (v < m_ui.volumeFf->value()) { m_ui.volumeFf->setValue(v); diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 710456958..4a697151d 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -63,6 +63,7 @@ signals: void languageChanged(); void libraryCleared(); void saveSettingsRequested(); + void openAutorunScripts(); public slots: void selectPage(Page); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index bce56f730..e66059d41 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -569,14 +569,21 @@ - + + + + Edit autorun scripts + + + + Qt::Horizontal - + Periodically autosave state @@ -586,7 +593,7 @@ - + Save entered cheats @@ -596,21 +603,21 @@ - + Qt::Horizontal - + Save state extra data: - + Screenshot @@ -620,7 +627,7 @@ - + Save game @@ -630,7 +637,7 @@ - + Cheat codes @@ -640,21 +647,21 @@ - + Qt::Horizontal - + Load state extra data: - + Screenshot @@ -664,28 +671,28 @@ - + Save game - + Cheat codes - + Qt::Horizontal - + Enable Discord Rich Presence diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 9611f0dda..8f09d439f 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -305,6 +305,10 @@ void Window::loadConfig() { updateMRU(); m_inputController.setConfiguration(m_config); + + if (!m_config->getList("autorunSettings").isEmpty()) { + ensureScripting(); + } } void Window::reloadConfig() { @@ -550,6 +554,10 @@ void Window::openSettingsWindow(SettingsView::Page page) { #ifdef USE_SQLITE3 connect(settingsWindow, &SettingsView::libraryCleared, m_libraryView, &LibraryController::clear); #endif + connect(settingsWindow, &SettingsView::openAutorunScripts, this, [this]() { + ensureScripting(); + m_scripting->openAutorunEdit(); + }); connect(this, &Window::shaderSelectorAdded, settingsWindow, &SettingsView::setShaderSelector); openView(settingsWindow); settingsWindow->selectPage(page); @@ -639,17 +647,7 @@ void Window::consoleOpen() { #ifdef ENABLE_SCRIPTING void Window::scriptingOpen() { - if (!m_scripting) { - m_scripting = std::make_unique(); - m_scripting->setInputController(&m_inputController); - m_shortcutController->setScriptingController(m_scripting.get()); - if (m_controller) { - m_scripting->setController(m_controller); - m_display->installEventFilter(m_scripting.get()); - } - - m_scripting->setVideoBackend(m_display->videoBackend()); - } + ensureScripting(); ScriptingView* view = new ScriptingView(m_scripting.get(), m_config); openView(view); } @@ -2057,6 +2055,25 @@ void Window::updateMRU() { m_actions.rebuildMenu(menuBar(), this, *m_shortcutController); } +void Window::ensureScripting() { + if (m_scripting) { + return; + } + m_scripting = std::make_unique(m_config); + m_scripting->setInputController(&m_inputController); + m_shortcutController->setScriptingController(m_scripting.get()); + if (m_controller) { + m_scripting->setController(m_controller); + m_display->installEventFilter(m_scripting.get()); + } + + if (m_display) { + m_scripting->setVideoBackend(m_display->videoBackend()); + } + + connect(m_scripting.get(), &ScriptingController::autorunScriptsOpened, this, &Window::openView); +} + std::shared_ptr Window::addGameAction(const QString& visibleName, const QString& name, Action::Function function, const QString& menu, const QKeySequence& shortcut) { auto action = m_actions.addAction(visibleName, name, [this, function = std::move(function)]() { if (m_controller) { diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 0ae94397d..d4126100b 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -109,6 +109,8 @@ public slots: void startVideoLog(); + void openView(QWidget* widget); + #ifdef ENABLE_DEBUGGERS void consoleOpen(); #endif @@ -173,7 +175,7 @@ private: void clearMRU(); void updateMRU(); - void openView(QWidget* widget); + void ensureScripting(); template std::function openTView(A... arg); template std::function openControllerTView(A... arg); diff --git a/src/platform/qt/scripting/AutorunScriptModel.cpp b/src/platform/qt/scripting/AutorunScriptModel.cpp new file mode 100644 index 000000000..35431b855 --- /dev/null +++ b/src/platform/qt/scripting/AutorunScriptModel.cpp @@ -0,0 +1,131 @@ +/* Copyright (c) 2013-2025 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "scripting/AutorunScriptModel.h" + +#include "ConfigController.h" + +using namespace QGBA; + +AutorunScriptModel::AutorunScriptModel(ConfigController* config, QObject* parent) + : QAbstractListModel(parent) + , m_config(config) +{ + QList autorun = m_config->getList("autorunSettings"); + for (const auto& item: autorun) { + if (!item.canConvert()) { + continue; + } + m_scripts.append(qvariant_cast(item)); + } +} + +int AutorunScriptModel::rowCount(const QModelIndex& parent) const { + if (parent.isValid()) { + return 0; + } + return m_scripts.count(); +} + +bool AutorunScriptModel::setData(const QModelIndex& index, const QVariant& data, int role) { + if (!index.isValid() || index.parent().isValid() || index.row() >= m_scripts.count()) { + return {}; + } + + switch (role) { + case Qt::CheckStateRole: + m_scripts[index.row()].active = data.value() == Qt::Checked; + save(); + return true; + } + return false; + +} + +QVariant AutorunScriptModel::data(const QModelIndex& index, int role) const { + if (!index.isValid() || index.parent().isValid() || index.row() >= m_scripts.count()) { + return {}; + } + + switch (role) { + case Qt::DisplayRole: + return m_scripts.at(index.row()).filename; + case Qt::CheckStateRole: + return m_scripts.at(index.row()).active ? Qt::Checked : Qt::Unchecked; + } + return {}; +} + +Qt::ItemFlags AutorunScriptModel::flags(const QModelIndex& index) const { + if (!index.isValid() || index.parent().isValid()) { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren; +} + +bool AutorunScriptModel::removeRows(int row, int count, const QModelIndex& parent) { + if (parent.isValid()) { + return false; + } + if (m_scripts.size() < row) { + return false; + } + if (m_scripts.size() < row + count) { + count = m_scripts.size() - row; + } + m_scripts.erase(m_scripts.begin() + row, m_scripts.begin() + row + count); + save(); + return true; +} + +bool AutorunScriptModel::moveRows(const QModelIndex& sourceParent, int sourceRow, int count, const QModelIndex& destinationParent, int destinationChild) { + if (sourceParent.isValid() || destinationParent.isValid()) { + return false; + } + + if (sourceRow < 0 || destinationChild < 0) { + return false; + } + + if (sourceRow >= m_scripts.size() || destinationChild >= m_scripts.size()) { + return false; + } + + if (count > 1) { + qWarning() << tr("Moving more than one row at once is not yet supported"); + return false; + } + + auto item = m_scripts.takeAt(sourceRow); + m_scripts.insert(destinationChild, item); + save(); + return true; +} + +void AutorunScriptModel::addScript(const QString& filename) { + beginInsertRows({}, m_scripts.count(), m_scripts.count()); + m_scripts.append(ScriptInfo { filename, true }); + endInsertRows(); + save(); +} + +QList AutorunScriptModel::activeScripts() const { + QList scripts; + for (const auto& pair: m_scripts) { + if (!pair.active) { + continue; + } + scripts.append(pair.filename); + } + return scripts; +} + +void AutorunScriptModel::save() { + QList list; + for (const auto& script : m_scripts) { + list.append(QVariant::fromValue(script)); + } + m_config->setList("autorunSettings", list); +} diff --git a/src/platform/qt/scripting/AutorunScriptModel.h b/src/platform/qt/scripting/AutorunScriptModel.h new file mode 100644 index 000000000..c41402b90 --- /dev/null +++ b/src/platform/qt/scripting/AutorunScriptModel.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2013-2025 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#pragma once + +#include + +namespace QGBA { + +class ConfigController; + +class AutorunScriptModel : public QAbstractListModel { +Q_OBJECT + +public: + struct ScriptInfo { + QString filename; + bool active; + + friend QDataStream& operator<<(QDataStream& stream, const ScriptInfo& object) { + stream << object.filename; + stream << object.active; + return stream; + } + + friend QDataStream& operator>>(QDataStream& stream, ScriptInfo& object) { + stream >> object.filename; + stream >> object.active; + return stream; + } + + }; + + AutorunScriptModel(ConfigController* config, QObject* parent = nullptr); + + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + virtual bool setData(const QModelIndex& index, const QVariant& data, int role = Qt::DisplayRole) override; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; + virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override; + virtual bool moveRows(const QModelIndex& sourceParent, int sourceRow, int count, const QModelIndex& destinationParent, int destinationChild) override; + + void addScript(const QString& filename); + QList activeScripts() const; + +private: + ConfigController* m_config; + QList m_scripts; + + void save(); +}; + +} + +Q_DECLARE_METATYPE(QGBA::AutorunScriptModel::ScriptInfo); diff --git a/src/platform/qt/scripting/AutorunScriptView.cpp b/src/platform/qt/scripting/AutorunScriptView.cpp new file mode 100644 index 000000000..10d3cfb25 --- /dev/null +++ b/src/platform/qt/scripting/AutorunScriptView.cpp @@ -0,0 +1,52 @@ +/* Copyright (c) 2013-2025 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "scripting/AutorunScriptView.h" + +#include "GBAApp.h" +#include "scripting/AutorunScriptModel.h" +#include "scripting/ScriptingController.h" + +using namespace QGBA; + +AutorunScriptView::AutorunScriptView(AutorunScriptModel* model, ScriptingController* controller, QWidget* parent) + : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) + , m_controller(controller) +{ + m_ui.setupUi(this); + + m_ui.autorunList->setModel(model); +} + +void AutorunScriptView::addScript() { + QString filename = GBAApp::app()->getOpenFileName(this, tr("Select a script"), m_controller->getFilenameFilters()); + if (filename.isEmpty()) { + return; + } + + AutorunScriptModel* model = static_cast(m_ui.autorunList->model()); + model->addScript(filename); +} + +void AutorunScriptView::removeScript(const QModelIndex& index) { + QAbstractItemModel* model = m_ui.autorunList->model(); + model->removeRow(index.row(), index.parent()); +} + +void AutorunScriptView::removeScript() { + removeScript(m_ui.autorunList->currentIndex()); +} + +void AutorunScriptView::moveUp() { + QModelIndex index = m_ui.autorunList->currentIndex(); + QAbstractItemModel* model = m_ui.autorunList->model(); + model->moveRows(index.parent(), index.row(), 1, index.parent(), index.row() - 1); +} + +void AutorunScriptView::moveDown() { + QModelIndex index = m_ui.autorunList->currentIndex(); + QAbstractItemModel* model = m_ui.autorunList->model(); + model->moveRows(index.parent(), index.row(), 1, index.parent(), index.row() + 1); +} diff --git a/src/platform/qt/scripting/AutorunScriptView.h b/src/platform/qt/scripting/AutorunScriptView.h new file mode 100644 index 000000000..3657f7248 --- /dev/null +++ b/src/platform/qt/scripting/AutorunScriptView.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2013-2025 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#pragma once + +#include "ui_AutorunScriptView.h" + +namespace QGBA { + +class AutorunScriptModel; +class ScriptingController; + +class AutorunScriptView : public QDialog { +Q_OBJECT + +public: + AutorunScriptView(AutorunScriptModel* model, ScriptingController* controller, QWidget* parent = nullptr); + void removeScript(const QModelIndex&); + +private slots: + void addScript(); + void removeScript(); + void moveUp(); + void moveDown(); + +private: + Ui::AutorunScriptView m_ui; + ScriptingController* m_controller; +}; + +} diff --git a/src/platform/qt/scripting/AutorunScriptView.ui b/src/platform/qt/scripting/AutorunScriptView.ui new file mode 100644 index 000000000..219e40d33 --- /dev/null +++ b/src/platform/qt/scripting/AutorunScriptView.ui @@ -0,0 +1,157 @@ + + + QGBA::AutorunScriptView + + + + 0 + 0 + 400 + 300 + + + + Autorun scripts + + + + + + Add + + + + + + + + + + Remove + + + + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + Move up + + + + + + + + + + Move down + + + + + + + + + + Run scripts when starting a game + + + + + + + + + + + + + + add + clicked() + QGBA::AutorunScriptView + addScript() + + + 47 + 276 + + + 199 + 149 + + + + + remove + clicked() + QGBA::AutorunScriptView + removeScript() + + + 138 + 276 + + + 199 + 149 + + + + + up + clicked() + QGBA::AutorunScriptView + moveUp() + + + 238 + 276 + + + 199 + 149 + + + + + down + clicked() + QGBA::AutorunScriptView + moveDown() + + + 341 + 276 + + + 199 + 149 + + + + + + addScript() + removeScript() + moveUp() + moveDown() + + diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index b1d68e22a..3c2d8fa4d 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -10,14 +10,17 @@ #include #include +#include "ConfigController.h" #include "CoreController.h" #include "Display.h" #include "input/Gamepad.h" #include "input/GamepadButtonEvent.h" #include "input/GamepadHatEvent.h" #include "InputController.h" +#include "scripting/AutorunScriptView.h" #include "scripting/ScriptingTextBuffer.h" #include "scripting/ScriptingTextBufferModel.h" +#include "Window.h" #include #include @@ -25,8 +28,9 @@ using namespace QGBA; -ScriptingController::ScriptingController(QObject* parent) +ScriptingController::ScriptingController(ConfigController* config, QObject* parent) : QObject(parent) + , m_model(config) { m_logger.p = this; m_logger.log = [](mLogger* log, int, enum mLogLevel level, const char* format, va_list args) { @@ -154,9 +158,6 @@ void ScriptingController::reset() { m_engines.clear(); m_activeEngine = nullptr; init(); - if (m_controller && m_controller->hasStarted()) { - attach(); - } } void ScriptingController::runCode(const QString& code) { @@ -164,6 +165,11 @@ void ScriptingController::runCode(const QString& code) { load(vf, "*prompt"); } +void ScriptingController::openAutorunEdit() { + AutorunScriptView* view = new AutorunScriptView(&m_model, this); + emit autorunScriptsOpened(view); +} + void ScriptingController::flushStorage() { #ifdef USE_JSON_C mScriptStorageFlushAll(&m_scriptContext); @@ -259,6 +265,15 @@ void ScriptingController::scriptingEvent(QObject* obj, QEvent* event) { } } +QString ScriptingController::getFilenameFilters() const { + QStringList filters; +#ifdef USE_LUA + filters.append(tr("Lua scripts (*.lua)")); +#endif + filters.append(tr("All files (*.*)")); + return filters.join(";;"); +} + void ScriptingController::updateGamepad() { InputDriver* driver = m_inputController->gamepadDriver(); if (!driver) { @@ -354,6 +369,14 @@ void ScriptingController::init() { #ifdef USE_JSON_C m_storageFlush.start(); #endif + + if (m_controller && m_controller->hasStarted()) { + attach(); + } + + for (const auto& script: m_model.activeScripts()) { + loadFile(script); + } } uint32_t ScriptingController::qtToScriptingKey(const QKeyEvent* event) { diff --git a/src/platform/qt/scripting/ScriptingController.h b/src/platform/qt/scripting/ScriptingController.h index 5c579a768..8e2b111f9 100644 --- a/src/platform/qt/scripting/ScriptingController.h +++ b/src/platform/qt/scripting/ScriptingController.h @@ -13,6 +13,7 @@ #include #include +#include "scripting/AutorunScriptModel.h" #include "VFileDevice.h" #include @@ -24,6 +25,7 @@ struct VideoBackend; namespace QGBA { +class ConfigController; class CoreController; class InputController; class ScriptingTextBuffer; @@ -33,7 +35,7 @@ class ScriptingController : public QObject { Q_OBJECT public: - ScriptingController(QObject* parent = nullptr); + ScriptingController(ConfigController* config, QObject* parent = nullptr); ~ScriptingController(); void setController(std::shared_ptr controller); @@ -48,17 +50,22 @@ public: mScriptContext* context() { return &m_scriptContext; } ScriptingTextBufferModel* textBufferModel() const { return m_bufferModel; } + QString getFilenameFilters() const; + signals: void log(const QString&); void warn(const QString&); void error(const QString&); void textBufferCreated(ScriptingTextBuffer*); + void autorunScriptsOpened(QWidget* view); + public slots: void clearController(); void updateVideoScale(); void reset(); void runCode(const QString& code); + void openAutorunEdit(); void flushStorage(); @@ -91,6 +98,7 @@ private: mScriptGamepad m_gamepad; + AutorunScriptModel m_model; std::shared_ptr m_controller; InputController* m_inputController = nullptr; diff --git a/src/platform/qt/scripting/ScriptingView.cpp b/src/platform/qt/scripting/ScriptingView.cpp index d31a9c738..ff1f98577 100644 --- a/src/platform/qt/scripting/ScriptingView.cpp +++ b/src/platform/qt/scripting/ScriptingView.cpp @@ -40,6 +40,7 @@ ScriptingView::ScriptingView(ScriptingController* controller, ConfigController* connect(m_ui.buffers->selectionModel(), &QItemSelectionModel::currentChanged, this, &ScriptingView::selectBuffer); connect(m_ui.load, &QAction::triggered, this, &ScriptingView::load); connect(m_ui.loadMostRecent, &QAction::triggered, this, &ScriptingView::loadMostRecent); + connect(m_ui.editAutorunScripts, &QAction::triggered, controller, &ScriptingController::openAutorunEdit); connect(m_ui.reset, &QAction::triggered, controller, &ScriptingController::reset); m_mruFiles = m_config->getMRU(ConfigController::MRU::Script); @@ -58,7 +59,7 @@ void ScriptingView::submitRepl() { } void ScriptingView::load() { - QString filename = GBAApp::app()->getOpenFileName(this, tr("Select script to load"), getFilters()); + QString filename = GBAApp::app()->getOpenFileName(this, tr("Select script to load"), m_controller->getFilenameFilters()); if (!filename.isEmpty()) { if (!m_controller->loadFile(filename)) { return; @@ -84,15 +85,6 @@ void ScriptingView::selectBuffer(const QModelIndex& current, const QModelIndex&) } } -QString ScriptingView::getFilters() const { - QStringList filters; -#ifdef USE_LUA - filters.append(tr("Lua scripts (*.lua)")); -#endif - filters.append(tr("All files (*.*)")); - return filters.join(";;"); -} - void ScriptingView::appendMRU(const QString& fname) { int index = m_mruFiles.indexOf(fname); if (index >= 0) { @@ -121,4 +113,4 @@ void ScriptingView::updateMRU() { void ScriptingView::checkEmptyMRU() { m_ui.loadMostRecent->setEnabled(!m_mruFiles.isEmpty()); -} \ No newline at end of file +} diff --git a/src/platform/qt/scripting/ScriptingView.h b/src/platform/qt/scripting/ScriptingView.h index a62bd2314..d7b49955c 100644 --- a/src/platform/qt/scripting/ScriptingView.h +++ b/src/platform/qt/scripting/ScriptingView.h @@ -28,8 +28,6 @@ private slots: void selectBuffer(const QModelIndex& current, const QModelIndex& = QModelIndex()); private: - QString getFilters() const; - void appendMRU(const QString&); void updateMRU(); void checkEmptyMRU(); diff --git a/src/platform/qt/scripting/ScriptingView.ui b/src/platform/qt/scripting/ScriptingView.ui index 4d55a8707..6de7ec8f9 100644 --- a/src/platform/qt/scripting/ScriptingView.ui +++ b/src/platform/qt/scripting/ScriptingView.ui @@ -98,9 +98,10 @@ - + + @@ -110,7 +111,7 @@ Load script... - + &Load most recent @@ -125,6 +126,11 @@ 0 + + + Edit autorun scripts... + +