Merge pull request #1017 from LittleWhite-tb/qt-recent-files
citra-qt: save path for recent files loaded
This commit is contained in:
commit
882040fde7
|
@ -7,6 +7,7 @@
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
#include "qhexedit.h"
|
#include "qhexedit.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
@ -140,6 +141,16 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
|
||||||
ui.actionDisplay_widget_title_bars->setChecked(settings.value("displayTitleBars", true).toBool());
|
ui.actionDisplay_widget_title_bars->setChecked(settings.value("displayTitleBars", true).toBool());
|
||||||
OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked());
|
OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked());
|
||||||
|
|
||||||
|
// Prepare actions for recent files
|
||||||
|
for (int i = 0; i < max_recent_files_item; ++i) {
|
||||||
|
actions_recent_files[i] = new QAction(this);
|
||||||
|
actions_recent_files[i]->setVisible(false);
|
||||||
|
connect(actions_recent_files[i], SIGNAL(triggered()), this, SLOT(OnMenuRecentFile()));
|
||||||
|
|
||||||
|
ui.menu_recent_files->addAction(actions_recent_files[i]);
|
||||||
|
}
|
||||||
|
UpdateRecentFiles();
|
||||||
|
|
||||||
// Setup connections
|
// Setup connections
|
||||||
connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()));
|
connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()));
|
||||||
connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap()));
|
connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap()));
|
||||||
|
@ -213,6 +224,10 @@ void GMainWindow::OnDisplayTitleBars(bool show)
|
||||||
void GMainWindow::BootGame(const std::string& filename) {
|
void GMainWindow::BootGame(const std::string& filename) {
|
||||||
LOG_INFO(Frontend, "Citra starting...\n");
|
LOG_INFO(Frontend, "Citra starting...\n");
|
||||||
|
|
||||||
|
// Shutdown previous session if the emu thread is still active...
|
||||||
|
if (emu_thread != nullptr)
|
||||||
|
ShutdownGame();
|
||||||
|
|
||||||
// Initialize the core emulation
|
// Initialize the core emulation
|
||||||
System::Init(render_window);
|
System::Init(render_window);
|
||||||
|
|
||||||
|
@ -272,18 +287,43 @@ void GMainWindow::ShutdownGame() {
|
||||||
render_window->hide();
|
render_window->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnMenuLoadFile()
|
void GMainWindow::UpdateRecentFiles() {
|
||||||
{
|
QSettings settings;
|
||||||
|
QStringList recent_files = settings.value("recentFiles").toStringList();
|
||||||
|
|
||||||
|
unsigned int num_recent_files = std::min(recent_files.size(), static_cast<int>(max_recent_files_item));
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < num_recent_files; i++) {
|
||||||
|
QString text = QString("&%1. %2").arg(i + 1).arg(QFileInfo(recent_files[i]).fileName());
|
||||||
|
actions_recent_files[i]->setText(text);
|
||||||
|
actions_recent_files[i]->setData(recent_files[i]);
|
||||||
|
actions_recent_files[i]->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = num_recent_files; j < max_recent_files_item; ++j) {
|
||||||
|
actions_recent_files[j]->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grey out the recent files menu if the list is empty
|
||||||
|
if (num_recent_files == 0) {
|
||||||
|
ui.menu_recent_files->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
ui.menu_recent_files->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::OnMenuLoadFile() {
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
QString rom_path = settings.value("romsPath", QString()).toString();
|
QString rom_path = settings.value("romsPath", QString()).toString();
|
||||||
|
|
||||||
QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), rom_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)"));
|
QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), rom_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)"));
|
||||||
if (filename.size()) {
|
if (filename.size()) {
|
||||||
settings.setValue("romsPath", QFileInfo(filename).path());
|
settings.setValue("romsPath", QFileInfo(filename).path());
|
||||||
|
// Update recent files list
|
||||||
// Shutdown previous session if the emu thread is still active...
|
QStringList recent_files = settings.value("recentFiles").toStringList();
|
||||||
if (emu_thread != nullptr)
|
recent_files.prepend(filename);
|
||||||
ShutdownGame();
|
settings.setValue("recentFiles", recent_files);
|
||||||
|
UpdateRecentFiles(); // Update UI
|
||||||
|
|
||||||
BootGame(filename.toLatin1().data());
|
BootGame(filename.toLatin1().data());
|
||||||
}
|
}
|
||||||
|
@ -301,8 +341,32 @@ void GMainWindow::OnMenuLoadSymbolMap() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnStartGame()
|
void GMainWindow::OnMenuRecentFile() {
|
||||||
{
|
QAction* action = qobject_cast<QAction*>(sender());
|
||||||
|
assert(action);
|
||||||
|
|
||||||
|
QString filename = action->data().toString();
|
||||||
|
QFileInfo file_info(filename);
|
||||||
|
if (file_info.exists()) {
|
||||||
|
BootGame(filename.toLatin1().data());
|
||||||
|
} else {
|
||||||
|
// Display an error message and remove the file from the list.
|
||||||
|
QMessageBox::information(this, tr("File not found"), tr("File \"%1\" not found").arg(filename));
|
||||||
|
|
||||||
|
QSettings settings;
|
||||||
|
QStringList recent_files = settings.value("recentFiles").toStringList();
|
||||||
|
recent_files.removeOne(filename);
|
||||||
|
settings.setValue("recentFiles", recent_files);
|
||||||
|
|
||||||
|
action->setVisible(false);
|
||||||
|
// Grey out the recent files menu if the list is empty
|
||||||
|
if (ui.menu_recent_files->isEmpty()) {
|
||||||
|
ui.menu_recent_files->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::OnStartGame() {
|
||||||
emu_thread->SetRunning(true);
|
emu_thread->SetRunning(true);
|
||||||
|
|
||||||
ui.action_Start->setEnabled(false);
|
ui.action_Start->setEnabled(false);
|
||||||
|
@ -312,8 +376,7 @@ void GMainWindow::OnStartGame()
|
||||||
ui.action_Stop->setEnabled(true);
|
ui.action_Stop->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnPauseGame()
|
void GMainWindow::OnPauseGame() {
|
||||||
{
|
|
||||||
emu_thread->SetRunning(false);
|
emu_thread->SetRunning(false);
|
||||||
|
|
||||||
ui.action_Start->setEnabled(true);
|
ui.action_Start->setEnabled(true);
|
||||||
|
@ -325,8 +388,7 @@ void GMainWindow::OnStopGame() {
|
||||||
ShutdownGame();
|
ShutdownGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnOpenHotkeysDialog()
|
void GMainWindow::OnOpenHotkeysDialog() {
|
||||||
{
|
|
||||||
GHotkeysDialog dialog(this);
|
GHotkeysDialog dialog(this);
|
||||||
dialog.exec();
|
dialog.exec();
|
||||||
}
|
}
|
||||||
|
@ -358,13 +420,11 @@ void GMainWindow::ToggleWindowMode() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnConfigure()
|
void GMainWindow::OnConfigure() {
|
||||||
{
|
|
||||||
//GControllerConfigDialog* dialog = new GControllerConfigDialog(controller_ports, this);
|
//GControllerConfigDialog* dialog = new GControllerConfigDialog(controller_ports, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::closeEvent(QCloseEvent* event)
|
void GMainWindow::closeEvent(QCloseEvent* event) {
|
||||||
{
|
|
||||||
// Save window layout
|
// Save window layout
|
||||||
QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra");
|
QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra");
|
||||||
settings.setValue("geometry", saveGeometry());
|
settings.setValue("geometry", saveGeometry());
|
||||||
|
@ -388,8 +448,7 @@ void GMainWindow::closeEvent(QCloseEvent* event)
|
||||||
#undef main
|
#undef main
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[]) {
|
||||||
{
|
|
||||||
Log::Filter log_filter(Log::Level::Info);
|
Log::Filter log_filter(Log::Level::Info);
|
||||||
Log::SetFilter(&log_filter);
|
Log::SetFilter(&log_filter);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ class GMainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
static const int max_recent_files_item = 10; ///< Max number of recently loaded items to keep track
|
||||||
|
|
||||||
// TODO: Make use of this!
|
// TODO: Make use of this!
|
||||||
enum {
|
enum {
|
||||||
UI_IDLE,
|
UI_IDLE,
|
||||||
|
@ -58,6 +60,8 @@ private:
|
||||||
void BootGame(const std::string& filename);
|
void BootGame(const std::string& filename);
|
||||||
void ShutdownGame();
|
void ShutdownGame();
|
||||||
|
|
||||||
|
void UpdateRecentFiles();
|
||||||
|
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -66,6 +70,7 @@ private slots:
|
||||||
void OnStopGame();
|
void OnStopGame();
|
||||||
void OnMenuLoadFile();
|
void OnMenuLoadFile();
|
||||||
void OnMenuLoadSymbolMap();
|
void OnMenuLoadSymbolMap();
|
||||||
|
void OnMenuRecentFile();
|
||||||
void OnOpenHotkeysDialog();
|
void OnOpenHotkeysDialog();
|
||||||
void OnConfigure();
|
void OnConfigure();
|
||||||
void OnDisplayTitleBars(bool);
|
void OnDisplayTitleBars(bool);
|
||||||
|
@ -86,6 +91,8 @@ private:
|
||||||
CallstackWidget* callstackWidget;
|
CallstackWidget* callstackWidget;
|
||||||
GPUCommandStreamWidget* graphicsWidget;
|
GPUCommandStreamWidget* graphicsWidget;
|
||||||
GPUCommandListWidget* graphicsCommandsWidget;
|
GPUCommandListWidget* graphicsCommandsWidget;
|
||||||
|
|
||||||
|
QAction* actions_recent_files[max_recent_files_item];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CITRA_QT_MAIN_HXX_
|
#endif // _CITRA_QT_MAIN_HXX_
|
||||||
|
|
|
@ -52,9 +52,16 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&File</string>
|
<string>&File</string>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="menu_recent_files">
|
||||||
|
<property name="title">
|
||||||
|
<string>Recent Files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
<addaction name="action_Load_File"/>
|
<addaction name="action_Load_File"/>
|
||||||
<addaction name="action_Load_Symbol_Map"/>
|
<addaction name="action_Load_Symbol_Map"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="menu_recent_files"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="action_Exit"/>
|
<addaction name="action_Exit"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menu_Emulation">
|
<widget class="QMenu" name="menu_Emulation">
|
||||||
|
|
Reference in New Issue