Add 'Set Up System Files' option (#642)
* Add 'Set Up System Files' option * Fix CIA installation and HLE module loading when no console unique data provided.
This commit is contained in:
@@ -489,7 +489,7 @@ void GMainWindow::InitializeWidgets() {
|
||||
|
||||
artic_traffic_label = new QLabel();
|
||||
artic_traffic_label->setToolTip(
|
||||
tr("Current Artic Base traffic speed. Higher values indicate bigger transfer loads."));
|
||||
tr("Current Artic traffic speed. Higher values indicate bigger transfer loads."));
|
||||
|
||||
emu_speed_label = new QLabel();
|
||||
emu_speed_label->setToolTip(tr("Current emulation speed. Values higher or lower than 100% "
|
||||
@@ -982,6 +982,7 @@ void GMainWindow::ConnectMenuEvents() {
|
||||
connect_menu(ui->action_Load_File, &GMainWindow::OnMenuLoadFile);
|
||||
connect_menu(ui->action_Install_CIA, &GMainWindow::OnMenuInstallCIA);
|
||||
connect_menu(ui->action_Connect_Artic, &GMainWindow::OnMenuConnectArticBase);
|
||||
connect_menu(ui->action_Setup_System_Files, &GMainWindow::OnMenuSetUpSystemFiles);
|
||||
for (u32 region = 0; region < Core::NUM_SYSTEM_TITLE_REGIONS; region++) {
|
||||
connect_menu(ui->menu_Boot_Home_Menu->actions().at(region),
|
||||
[this, region] { OnMenuBootHomeMenu(region); });
|
||||
@@ -1367,9 +1368,9 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
|
||||
case Core::System::ResultStatus::ErrorArticDisconnected:
|
||||
QMessageBox::critical(
|
||||
this, tr("Artic Base Server"),
|
||||
this, tr("Artic Server"),
|
||||
tr(fmt::format(
|
||||
"An error has occurred whilst communicating with the Artic Base Server.\n{}",
|
||||
"An error has occurred whilst communicating with the Artic Server.\n{}",
|
||||
system.GetStatusDetails())
|
||||
.c_str()));
|
||||
break;
|
||||
@@ -1401,7 +1402,9 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
ShutdownGame();
|
||||
}
|
||||
|
||||
const bool is_artic = filename.startsWith(QString::fromStdString("articbase://"));
|
||||
const bool is_artic = filename.startsWith(QString::fromStdString("articbase:/")) ||
|
||||
filename.startsWith(QString::fromStdString("articinio:/")) ||
|
||||
filename.startsWith(QString::fromStdString("articinin:/"));
|
||||
|
||||
if (!is_artic && filename.endsWith(QStringLiteral(".cia"))) {
|
||||
const auto answer = QMessageBox::question(
|
||||
@@ -1444,7 +1447,7 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
QtConfig per_game_config(config_file_name, QtConfig::ConfigType::PerGameConfig);
|
||||
}
|
||||
|
||||
// Artic Base Server cannot accept a client multiple times, so multiple loaders are not
|
||||
// Artic Server cannot accept a client multiple times, so multiple loaders are not
|
||||
// possible. Instead register the app loader early and do not create it again on system load.
|
||||
if (!loader->SupportsMultipleInstancesForSameFile()) {
|
||||
system.RegisterAppLoaderEarly(loader);
|
||||
@@ -2192,6 +2195,92 @@ void GMainWindow::OnMenuLoadFile() {
|
||||
BootGame(filename);
|
||||
}
|
||||
|
||||
void GMainWindow::OnMenuSetUpSystemFiles() {
|
||||
QDialog dialog(this);
|
||||
dialog.setWindowTitle(tr("Set Up System Files"));
|
||||
|
||||
QVBoxLayout layout(&dialog);
|
||||
|
||||
QLabel label_description(
|
||||
tr("<p>Azahar needs files from a real console to be able to use some of its features.<br>"
|
||||
"You can get such files with the <a "
|
||||
"href=https://github.com/azahar-emu/ArticSetupTool>Azahar "
|
||||
"Artic Setup Tool</a><br> Notes:<ul><li><b>This operation will install console unique "
|
||||
"files "
|
||||
"to Azahar, do not share your user or nand folders<br>after performing the setup "
|
||||
"process!</b></li><li>Old 3DS setup is needed for the New 3DS setup to "
|
||||
"work.</li><li>Both setup modes will work regardless of the model of the console "
|
||||
"running the setup tool.</li></ul><hr></p>"),
|
||||
&dialog);
|
||||
label_description.setOpenExternalLinks(true);
|
||||
layout.addWidget(&label_description);
|
||||
|
||||
QHBoxLayout layout_h(&dialog);
|
||||
layout.addLayout(&layout_h);
|
||||
|
||||
QLabel label_enter(tr("Enter Azahar Artic Setup Tool address:"), &dialog);
|
||||
|
||||
layout_h.addWidget(&label_enter);
|
||||
|
||||
QLineEdit textInput(UISettings::values.last_artic_base_addr, &dialog);
|
||||
layout_h.addWidget(&textInput);
|
||||
|
||||
QLabel label_select(tr("<br>Choose setup mode:"), &dialog);
|
||||
layout.addWidget(&label_select);
|
||||
|
||||
std::pair<bool, bool> install_state = Core::AreSystemTitlesInstalled();
|
||||
|
||||
QRadioButton radio1(&dialog);
|
||||
QRadioButton radio2(&dialog);
|
||||
if (!install_state.first) {
|
||||
radio1.setText(tr("(\u2139\uFE0F) Old 3DS setup"));
|
||||
radio1.setToolTip(tr("Setup is possible."));
|
||||
|
||||
radio2.setText(tr("(\u26A0) New 3DS setup"));
|
||||
radio2.setToolTip(tr("Old 3DS setup is required first."));
|
||||
radio2.setEnabled(false);
|
||||
} else {
|
||||
radio1.setText(tr("(\u2705) Old 3DS setup"));
|
||||
radio1.setToolTip(tr("Setup completed."));
|
||||
|
||||
if (!install_state.second) {
|
||||
radio2.setText(tr("(\u2139\uFE0F) New 3DS setup"));
|
||||
radio2.setToolTip(tr("Setup is possible."));
|
||||
} else {
|
||||
radio2.setText(tr("(\u2705) New 3DS setup"));
|
||||
radio2.setToolTip(tr("Setup completed."));
|
||||
}
|
||||
}
|
||||
radio1.setChecked(true);
|
||||
layout.addWidget(&radio1);
|
||||
layout.addWidget(&radio2);
|
||||
|
||||
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
|
||||
connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
||||
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||||
layout.addWidget(&buttonBox);
|
||||
|
||||
int res = dialog.exec();
|
||||
if (res == QDialog::Accepted) {
|
||||
bool is_o3ds = radio1.isChecked();
|
||||
if ((is_o3ds && install_state.first) || (!is_o3ds && install_state.second)) {
|
||||
QMessageBox::StandardButton answer =
|
||||
QMessageBox::question(this, tr("Set Up System Files"),
|
||||
tr("The system files for the selected mode are already set "
|
||||
"up.\nReinstall the files anyway?"),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
if (answer != QMessageBox::Yes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Core::UninstallSystemFiles(is_o3ds ? Core::SystemTitleSet::Old3ds
|
||||
: Core::SystemTitleSet::New3ds);
|
||||
QString addr = textInput.text();
|
||||
UISettings::values.last_artic_base_addr = addr;
|
||||
BootGame(QString::fromStdString(is_o3ds ? "articinio://" : "articinin://").append(addr));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::OnMenuInstallCIA() {
|
||||
QStringList filepaths = QFileDialog::getOpenFileNames(
|
||||
this, tr("Load Files"), UISettings::values.roms_path,
|
||||
@@ -3131,16 +3220,16 @@ void GMainWindow::UpdateStatusBar() {
|
||||
QStringLiteral("QLabel { color: %0; }").arg(label_color[style_index]);
|
||||
|
||||
artic_traffic_label->setText(
|
||||
tr("Artic Base Traffic: %1 %2%3").arg(value, 0, 'f', 0).arg(unit).arg(event));
|
||||
tr("Artic Traffic: %1 %2%3").arg(value, 0, 'f', 0).arg(unit).arg(event));
|
||||
artic_traffic_label->setStyleSheet(style_sheet);
|
||||
}
|
||||
|
||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||
if (Settings::GetFrameLimit() == 0) {
|
||||
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
||||
} else {
|
||||
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
||||
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
||||
.arg(Settings::values.frame_limit.GetValue()));
|
||||
.arg(Settings::GetFrameLimit()));
|
||||
}
|
||||
game_fps_label->setText(tr("App: %1 FPS").arg(results.game_fps, 0, 'f', 0));
|
||||
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
|
||||
@@ -3321,7 +3410,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
|
||||
message = QString::fromStdString(details);
|
||||
error_severity_icon = QMessageBox::Icon::Warning;
|
||||
} else if (result == Core::System::ResultStatus::ErrorArticDisconnected) {
|
||||
title = tr("Artic Base Server");
|
||||
title = tr("Artic Server");
|
||||
message =
|
||||
tr(fmt::format("A communication error has occurred. The game will quit.\n{}", details)
|
||||
.c_str());
|
||||
|
||||
@@ -244,6 +244,7 @@ private slots:
|
||||
void OnGameListOpenPerGameProperties(const QString& file);
|
||||
void OnConfigurePerGame();
|
||||
void OnMenuLoadFile();
|
||||
void OnMenuSetUpSystemFiles();
|
||||
void OnMenuInstallCIA();
|
||||
void OnMenuConnectArticBase();
|
||||
void OnMenuBootHomeMenu(u32 region);
|
||||
|
||||
@@ -237,8 +237,7 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
||||
&ConfigureSystem::UpdateInitTicks);
|
||||
connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
|
||||
&ConfigureSystem::RefreshConsoleID);
|
||||
connect(ui->button_start_download, &QPushButton::clicked, this,
|
||||
&ConfigureSystem::DownloadFromNUS);
|
||||
connect(ui->button_regenerate_mac, &QPushButton::clicked, this, &ConfigureSystem::RefreshMAC);
|
||||
|
||||
connect(ui->button_secure_info, &QPushButton::clicked, this, [this] {
|
||||
ui->button_secure_info->setEnabled(false);
|
||||
@@ -281,34 +280,6 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
||||
}
|
||||
|
||||
SetupPerGameUI();
|
||||
|
||||
ui->combo_download_set->setCurrentIndex(0); // set to Minimal
|
||||
ui->combo_download_region->setCurrentIndex(0); // set to the base region
|
||||
|
||||
HW::AES::InitKeys(true);
|
||||
bool keys_available = HW::AES::IsKeyXAvailable(HW::AES::KeySlotID::NCCHSecure1) &&
|
||||
HW::AES::IsKeyXAvailable(HW::AES::KeySlotID::NCCHSecure2);
|
||||
for (u8 i = 0; i < HW::AES::MaxCommonKeySlot && keys_available; i++) {
|
||||
HW::AES::SelectCommonKeyIndex(i);
|
||||
if (!HW::AES::IsNormalKeyAvailable(HW::AES::KeySlotID::TicketCommonKey)) {
|
||||
keys_available = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keys_available) {
|
||||
ui->button_start_download->setEnabled(true);
|
||||
ui->combo_download_set->setEnabled(true);
|
||||
ui->combo_download_region->setEnabled(true);
|
||||
ui->label_nus_download->setText(tr("Download System Files from Nintendo servers"));
|
||||
} else {
|
||||
ui->button_start_download->setEnabled(false);
|
||||
ui->combo_download_set->setEnabled(false);
|
||||
ui->combo_download_region->setEnabled(false);
|
||||
ui->label_nus_download->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
ui->label_nus_download->setOpenExternalLinks(true);
|
||||
ui->label_nus_download->setText(tr("Azahar is missing keys to download system files."));
|
||||
}
|
||||
|
||||
ConfigureTime();
|
||||
}
|
||||
|
||||
@@ -385,14 +356,13 @@ void ConfigureSystem::ReadSystemSettings() {
|
||||
u64 console_id = cfg->GetConsoleUniqueId();
|
||||
ui->label_console_id->setText(
|
||||
tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper()));
|
||||
mac_address = cfg->GetMacAddress();
|
||||
ui->label_mac->setText(tr("MAC: %1").arg(QString::fromStdString(mac_address)));
|
||||
|
||||
// set play coin
|
||||
play_coin = Service::PTM::Module::GetPlayCoins();
|
||||
ui->spinBox_play_coins->setValue(play_coin);
|
||||
|
||||
// set firmware download region
|
||||
ui->combo_download_region->setCurrentIndex(static_cast<int>(cfg->GetRegionValue()));
|
||||
|
||||
// Refresh secure data status
|
||||
RefreshSecureDataStatus();
|
||||
}
|
||||
@@ -484,6 +454,9 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||
|
||||
Settings::values.plugin_loader_enabled.SetValue(ui->plugin_loader->isChecked());
|
||||
Settings::values.allow_plugin_loader.SetValue(ui->allow_plugin_loader->isChecked());
|
||||
|
||||
cfg->GetMacAddress() = mac_address;
|
||||
cfg->SaveMacAddress();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,10 +521,11 @@ void ConfigureSystem::UpdateInitTicks(int init_ticks_type) {
|
||||
|
||||
void ConfigureSystem::RefreshConsoleID() {
|
||||
QMessageBox::StandardButton reply;
|
||||
QString warning_text = tr("This will replace your current virtual 3DS with a new one. "
|
||||
"Your current virtual 3DS will not be recoverable. "
|
||||
"This might have unexpected effects in applications. This might fail "
|
||||
"if you use an outdated config save. Continue?");
|
||||
QString warning_text =
|
||||
tr("This will replace your current virtual 3DS console ID with a new one. "
|
||||
"Your current virtual 3DS console ID will not be recoverable. "
|
||||
"This might have unexpected effects in applications. This might fail "
|
||||
"if you use an outdated config save. Continue?");
|
||||
reply = QMessageBox::critical(this, tr("Warning"), warning_text,
|
||||
QMessageBox::No | QMessageBox::Yes);
|
||||
if (reply == QMessageBox::No) {
|
||||
@@ -565,6 +539,21 @@ void ConfigureSystem::RefreshConsoleID() {
|
||||
tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper()));
|
||||
}
|
||||
|
||||
void ConfigureSystem::RefreshMAC() {
|
||||
QMessageBox::StandardButton reply;
|
||||
QString warning_text = tr("This will replace your current MAC address with a new one. "
|
||||
"It is not recommended to do this if you got the MAC address from "
|
||||
"your real console using the setup tool. Continue?");
|
||||
reply =
|
||||
QMessageBox::warning(this, tr("Warning"), warning_text, QMessageBox::No | QMessageBox::Yes);
|
||||
if (reply == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
|
||||
mac_address = Service::CFG::GenerateRandomMAC();
|
||||
ui->label_mac->setText(tr("MAC: %1").arg(QString::fromStdString(mac_address)));
|
||||
}
|
||||
|
||||
void ConfigureSystem::InstallSecureData(const std::string& from_path, const std::string& to_path) {
|
||||
std::string from =
|
||||
FileUtil::SanitizePath(from_path, FileUtil::DirectorySeparator::PlatformDefault);
|
||||
@@ -655,20 +644,9 @@ void ConfigureSystem::SetupPerGameUI() {
|
||||
ui->label_plugin_loader->setVisible(false);
|
||||
ui->plugin_loader->setVisible(false);
|
||||
ui->allow_plugin_loader->setVisible(false);
|
||||
// Disable the system firmware downloader.
|
||||
ui->label_nus_download->setVisible(false);
|
||||
ui->body_nus_download->setVisible(false);
|
||||
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_new_3ds, Settings::values.is_new_3ds,
|
||||
is_new_3ds);
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_lle_applets, Settings::values.lle_applets,
|
||||
lle_applets);
|
||||
}
|
||||
|
||||
void ConfigureSystem::DownloadFromNUS() {
|
||||
ui->button_start_download->setEnabled(false);
|
||||
|
||||
QMessageBox::critical(this, tr("Azahar"), tr("Downloading from NUS has been deprecated."));
|
||||
|
||||
ui->button_start_download->setEnabled(true);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -51,14 +51,13 @@ private:
|
||||
void UpdateInitTime(int init_clock);
|
||||
void UpdateInitTicks(int init_ticks_type);
|
||||
void RefreshConsoleID();
|
||||
void RefreshMAC();
|
||||
|
||||
void InstallSecureData(const std::string& from_path, const std::string& to_path);
|
||||
void RefreshSecureDataStatus();
|
||||
|
||||
void SetupPerGameUI();
|
||||
|
||||
void DownloadFromNUS();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::ConfigureSystem> ui;
|
||||
Core::System& system;
|
||||
@@ -75,4 +74,5 @@ private:
|
||||
u8 country_code;
|
||||
u16 play_coin;
|
||||
bool system_setup;
|
||||
std::string mac_address;
|
||||
};
|
||||
|
||||
@@ -455,113 +455,49 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QLabel" name="label_mac">
|
||||
<property name="text">
|
||||
<string>MAC:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<widget class="QPushButton" name="button_regenerate_mac">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Regenerate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QLabel" name="label_plugin_loader">
|
||||
<property name="text">
|
||||
<string>3GX Plugin Loader:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<item row="17" column="1">
|
||||
<widget class="QCheckBox" name="plugin_loader">
|
||||
<property name="text">
|
||||
<string>Enable 3GX plugin loader</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<item row="18" column="1">
|
||||
<widget class="QCheckBox" name="allow_plugin_loader">
|
||||
<property name="text">
|
||||
<string>Allow applications to change plugin loader state</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="label_nus_download">
|
||||
<property name="text">
|
||||
<string>Download System Files from Nintendo servers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="1">
|
||||
<widget class="QWidget" name="body_nus_download">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_nus_download">
|
||||
<item>
|
||||
<widget class="QComboBox" name="combo_download_set">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Minimal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Old 3DS</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>New 3DS</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="combo_download_region">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>JPN</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>USA</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>EUR</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>AUS</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CHN</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>KOR</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TWN</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="button_start_download">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Download</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -762,6 +698,7 @@
|
||||
<tabstop>spinBox_play_coins</tabstop>
|
||||
<tabstop>spinBox_steps_per_hour</tabstop>
|
||||
<tabstop>button_regenerate_console_id</tabstop>
|
||||
<tabstop>button_regenerate_mac</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
<addaction name="action_Load_File"/>
|
||||
<addaction name="action_Install_CIA"/>
|
||||
<addaction name="action_Connect_Artic"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Setup_System_Files"/>
|
||||
<addaction name="menu_Boot_Home_Menu"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="menu_recent_files"/>
|
||||
@@ -238,6 +240,11 @@
|
||||
<string>Connect to Artic Base...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Setup_System_Files">
|
||||
<property name="text">
|
||||
<string>Set Up System Files...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Boot_Home_Menu_JPN">
|
||||
<property name="text">
|
||||
<string>JPN</string>
|
||||
|
||||
Reference in New Issue
Block a user