From 444ff3e2d16f811f24978a08ecdbade9e6cccc7e Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:45:08 +0100 Subject: [PATCH] swkdb: add support for setting the header. save: add support for setting the name for the save file. --- sphaira/include/swkbd.hpp | 4 +- sphaira/include/ui/menus/save_menu.hpp | 18 ++++-- sphaira/include/ui/sidebar.hpp | 5 +- sphaira/source/app.cpp | 6 +- sphaira/source/swkbd.cpp | 20 ++++-- sphaira/source/ui/menus/appstore.cpp | 5 +- sphaira/source/ui/menus/filebrowser.cpp | 19 +++--- sphaira/source/ui/menus/save_menu.cpp | 84 ++++++++++++++++++------- sphaira/source/ui/sidebar.cpp | 13 ++-- sphaira/source/utils/devoptab.cpp | 12 ++-- 10 files changed, 126 insertions(+), 60 deletions(-) diff --git a/sphaira/include/swkbd.hpp b/sphaira/include/swkbd.hpp index 0255292..c40178e 100644 --- a/sphaira/include/swkbd.hpp +++ b/sphaira/include/swkbd.hpp @@ -6,7 +6,7 @@ namespace sphaira::swkbd { -Result ShowText(std::string& out, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = PATH_MAX); -Result ShowNumPad(s64& out, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = PATH_MAX); +Result ShowText(std::string& out, const char* header = nullptr, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = PATH_MAX); +Result ShowNumPad(s64& out, const char* header = nullptr, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = PATH_MAX); } // namespace sphaira::swkbd diff --git a/sphaira/include/ui/menus/save_menu.hpp b/sphaira/include/ui/menus/save_menu.hpp index 9cfd31b..a94054e 100644 --- a/sphaira/include/ui/menus/save_menu.hpp +++ b/sphaira/include/ui/menus/save_menu.hpp @@ -12,6 +12,14 @@ namespace sphaira::ui::menu::save { +enum BackupFlag { + BackupFlag_None = 0, + // option to allow the user to set the save file name. + BackupFlag_SetName = 1 << 0, + // set if this is a auto backup (on restore). + BackupFlag_IsAuto = 1 << 1, +}; + struct Entry final : FsSaveDataInfo { NacpLanguageEntry lang{}; int image{}; @@ -82,13 +90,13 @@ private: void DisplayOptions(); - void BackupSaves(std::vector>& entries); + void BackupSaves(std::vector>& entries, u32 flags); void RestoreSave(); - auto BuildSavePath(const Entry& e, bool is_auto) const -> fs::FsPath; - Result RestoreSaveInternal(ProgressBox* pbox, const Entry& e, const fs::FsPath& path) const; - Result BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, Entry& e, bool compressed, bool is_auto = false) const; - Result BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, std::span> entries, bool compressed, bool is_auto = false) const; + auto BuildSavePath(const Entry& e, u32 flags) const -> fs::FsPath; + Result RestoreSaveInternal(ProgressBox* pbox, const Entry& e, const fs::FsPath& path); + Result BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, Entry& e, u32 flags); + Result BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, std::span> entries, u32 flags); Result MountSaveFs(); diff --git a/sphaira/include/ui/sidebar.hpp b/sphaira/include/ui/sidebar.hpp index cdd1911..1df57f0 100644 --- a/sphaira/include/ui/sidebar.hpp +++ b/sphaira/include/ui/sidebar.hpp @@ -188,9 +188,9 @@ public: public: // uses normal keyboard. - explicit SidebarEntryTextInput(const std::string& title, const std::string& value, const std::string& guide = {}, s64 len_min = -1, s64 len_max = PATH_MAX, const std::string& info = "", const Callback& callback = nullptr); + explicit SidebarEntryTextInput(const std::string& title, const std::string& value, const std::string& header = {}, const std::string& guide = {}, s64 len_min = -1, s64 len_max = PATH_MAX, const std::string& info = "", const Callback& callback = nullptr); // uses numpad. - explicit SidebarEntryTextInput(const std::string& title, s64 value, const std::string& guide = {}, s64 len_min = -1, s64 len_max = PATH_MAX, const std::string& info = "", const Callback& callback = nullptr); + explicit SidebarEntryTextInput(const std::string& title, s64 value, const std::string& header = {}, const std::string& guide = {}, s64 len_min = -1, s64 len_max = PATH_MAX, const std::string& info = "", const Callback& callback = nullptr); auto GetNumValue() const -> s64 { return std::stoul(GetValue()); @@ -200,6 +200,7 @@ public: SetValue(std::to_string(value)); } private: + const std::string m_header; const std::string m_guide; const s64 m_len_min; const s64 m_len_max; diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 29402ad..857259c 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -2338,7 +2338,7 @@ void App::DisplayFtpOptions(bool left_side) { }, "Enable FTP server to run in the background."_i18n); options->Add( - "Port", App::GetApp()->m_ftp_port.Get(), "Port number", 1, 5, + "Port", App::GetApp()->m_ftp_port.Get(), "", "", 1, 5, "Opens the FTP server on this port."_i18n, [](auto* input){ App::GetApp()->m_ftp_port.Set(input->GetNumValue()); @@ -2352,7 +2352,7 @@ void App::DisplayFtpOptions(bool left_side) { ); options->Add( - "User", App::GetApp()->m_ftp_user.Get(), "Username", -1, 64, + "User", App::GetApp()->m_ftp_user.Get(), "", "", -1, 64, "Sets the username, must be set if anon is disabled."_i18n, [](auto* input){ App::GetApp()->m_ftp_user.Set(input->GetValue()); @@ -2360,7 +2360,7 @@ void App::DisplayFtpOptions(bool left_side) { ); options->Add( - "Pass", App::GetApp()->m_ftp_pass.Get(), "Password", -1, 64, + "Pass", App::GetApp()->m_ftp_pass.Get(), "", "", -1, 64, "Sets the password, must be set if anon is disabled."_i18n, [](auto* input){ App::GetApp()->m_ftp_pass.Set(input->GetValue()); diff --git a/sphaira/source/swkbd.cpp b/sphaira/source/swkbd.cpp index 37717ee..16ae7ce 100644 --- a/sphaira/source/swkbd.cpp +++ b/sphaira/source/swkbd.cpp @@ -10,7 +10,7 @@ struct Config { bool numpad{}; }; -Result ShowInternal(Config& cfg, const char* guide, const char* initial, s64 len_min, s64 len_max) { +Result ShowInternal(Config& cfg, const char* header, const char* guide, const char* initial, s64 len_min, s64 len_max) { SwkbdConfig c; R_TRY(swkbdCreate(&c, 0)); swkbdConfigMakePresetDefault(&c); @@ -20,7 +20,17 @@ Result ShowInternal(Config& cfg, const char* guide, const char* initial, s64 len swkbdConfigSetType(&c, SwkbdType_NumPad); } + // only works if len_max <= 32. + if (header) { + swkbdConfigSetHeaderText(&c, header); + } + if (guide) { + // only works if len_max <= 32. + if (header) { + swkbdConfigSetSubText(&c, guide); + } + swkbdConfigSetGuideText(&c, guide); } @@ -41,17 +51,17 @@ Result ShowInternal(Config& cfg, const char* guide, const char* initial, s64 len } // namespace -Result ShowText(std::string& out, const char* guide, const char* initial, s64 len_min, s64 len_max) { +Result ShowText(std::string& out, const char* header, const char* guide, const char* initial, s64 len_min, s64 len_max) { Config cfg{}; - R_TRY(ShowInternal(cfg, guide, initial, len_min, len_max)); + R_TRY(ShowInternal(cfg, header, guide, initial, len_min, len_max)); out = cfg.out_text; R_SUCCEED(); } -Result ShowNumPad(s64& out, const char* guide, const char* initial, s64 len_min, s64 len_max) { +Result ShowNumPad(s64& out, const char* header, const char* guide, const char* initial, s64 len_min, s64 len_max) { Config cfg{}; cfg.numpad = true; - R_TRY(ShowInternal(cfg, guide, initial, len_min, len_max)); + R_TRY(ShowInternal(cfg, header, guide, initial, len_min, len_max)); out = std::atoll(cfg.out_text); R_SUCCEED(); } diff --git a/sphaira/source/ui/menus/appstore.cpp b/sphaira/source/ui/menus/appstore.cpp index d41a16a..9ffceb7 100644 --- a/sphaira/source/ui/menus/appstore.cpp +++ b/sphaira/source/ui/menus/appstore.cpp @@ -599,7 +599,8 @@ EntryMenu::EntryMenu(Entry& entry, const LazyImage& default_icon, Menu& menu) options->Add("Leave Feedback"_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out)) && !out.empty()) { + std::string header = "Leave feedback for " + m_entry.title; + if (R_SUCCEEDED(swkbd::ShowText(out, header.c_str())) && !out.empty()) { const auto post = "name=" "switch_user" "&package=" + m_entry.name + "&message=" + out; const auto file = BuildFeedbackCachePath(m_entry); @@ -970,7 +971,7 @@ Menu::Menu(u32 flags) : grid::Menu{"AppStore"_i18n, flags} { options->Add("Search"_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out)) && !out.empty()) { + if (R_SUCCEEDED(swkbd::ShowText(out, "Search for app")) && !out.empty()) { SetSearch(out); log_write("got %s\n", out.c_str()); } diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index 08c28de..ead63b3 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -315,17 +315,17 @@ ForwarderForm::ForwarderForm(const FileAssocEntry& assoc, const RomDatabaseIndex const auto icon = m_assoc.path; m_name = this->Add( - "Name", name, "", -1, sizeof(NacpLanguageEntry::name) - 1, + "Name", name, "", "", -1, sizeof(NacpLanguageEntry::name) - 1, "Set the name of the application"_i18n ); m_author = this->Add( - "Author", author, "", -1, sizeof(NacpLanguageEntry::author) - 1, + "Author", author, "", "", -1, sizeof(NacpLanguageEntry::author) - 1, "Set the author of the application"_i18n ); m_version = this->Add( - "Version", version, "", -1, sizeof(NacpStruct::display_version) - 1, + "Version", version, "", "", -1, sizeof(NacpStruct::display_version) - 1, "Set the display version of the application"_i18n ); @@ -1711,7 +1711,8 @@ void FsView::DisplayOptions() { std::string out; const auto& entry = GetEntry(); const auto name = entry.GetName(); - if (R_SUCCEEDED(swkbd::ShowText(out, "Set New File Name"_i18n.c_str(), name.c_str())) && !out.empty() && out != name) { + const auto header = "Set new name"_i18n; + if (R_SUCCEEDED(swkbd::ShowText(out, header.c_str(), header.c_str(), name.c_str())) && !out.empty() && out != name) { App::PopToMenu(); const auto src_path = GetNewPath(entry); @@ -1804,7 +1805,7 @@ void FsView::DisplayOptions() { options->Add("Extract to..."_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out, "Enter the path to the folder to extract into", fs::AppendPath(m_path, ""))) && !out.empty()) { + if (R_SUCCEEDED(swkbd::ShowText(out, "Extract path", "Enter the path to the folder to extract into", fs::AppendPath(m_path, ""))) && !out.empty()) { UnzipFiles(out); } }); @@ -1822,7 +1823,7 @@ void FsView::DisplayOptions() { options->Add("Compress to..."_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out, "Enter the path to the folder to extract into", m_path)) && !out.empty()) { + if (R_SUCCEEDED(swkbd::ShowText(out, "Compress path", "Enter the path to the folder to compress into", m_path)) && !out.empty()) { ZipFiles(out); } }); @@ -1842,7 +1843,8 @@ void FsView::DisplayAdvancedOptions() { if (!m_fs_entry.IsReadOnly()) { options->Add("Create File"_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out, "Set File Name"_i18n.c_str(), fs::AppendPath(m_path, ""))) && !out.empty()) { + const auto header = "Set File Name"_i18n; + if (R_SUCCEEDED(swkbd::ShowText(out, header.c_str(), header.c_str(), fs::AppendPath(m_path, ""))) && !out.empty()) { App::PopToMenu(); fs::FsPath full_path; @@ -1864,7 +1866,8 @@ void FsView::DisplayAdvancedOptions() { options->Add("Create Folder"_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out, "Set Folder Name"_i18n.c_str(), fs::AppendPath(m_path, ""))) && !out.empty()) { + const auto header = "Set Folder Name"_i18n; + if (R_SUCCEEDED(swkbd::ShowText(out, header.c_str(), header.c_str(), fs::AppendPath(m_path, ""))) && !out.empty()) { App::PopToMenu(); fs::FsPath full_path; diff --git a/sphaira/source/ui/menus/save_menu.cpp b/sphaira/source/ui/menus/save_menu.cpp index 196c881..24ab8d2 100644 --- a/sphaira/source/ui/menus/save_menu.cpp +++ b/sphaira/source/ui/menus/save_menu.cpp @@ -9,6 +9,7 @@ #include "threaded_file_transfer.hpp" #include "minizip_helper.hpp" #include "dumper.hpp" +#include "swkbd.hpp" #include "utils/devoptab.hpp" @@ -689,13 +690,38 @@ void Menu::DisplayOptions() { entries.emplace_back(m_entries[m_index]); } - BackupSaves(entries); - }, true); + BackupSaves(entries, BackupFlag_None); + }, true, + "Backup the selected save(s) to a location of your choice."_i18n + ); + + if (!m_selected_count || m_selected_count == 1) { + options->Add("Backup to..."_i18n, [this](){ + std::vector> entries; + if (m_selected_count) { + for (auto& e : m_entries) { + if (e.selected) { + entries.emplace_back(e); + } + } + } else { + entries.emplace_back(m_entries[m_index]); + } + + BackupSaves(entries, BackupFlag_SetName); + }, true, + "Backup the selected save(s) to a location of your choice, and set the name of the backup."_i18n + ); + } if (m_entries[m_index].save_data_type == FsSaveDataType_Account || m_entries[m_index].save_data_type == FsSaveDataType_Bcat) { options->Add("Restore"_i18n, [this](){ RestoreSave(); - }, true); + }, true, + "Restore the save for the current title.\n" + "if \"Auto backup\" is enabled, the save will first be backed up and then restored. " + "Saves that are auto backed up will have \"Auto\" in their name."_i18n + ); } } @@ -705,18 +731,21 @@ void Menu::DisplayOptions() { options->Add("Auto backup on restore"_i18n, m_auto_backup_on_restore.Get(), [this](bool& v_out){ m_auto_backup_on_restore.Set(v_out); - }); + }, "If enabled, when restoring a save, the current save will first be backed up."_i18n); options->Add("Compress backup"_i18n, m_compress_save_backup.Get(), [this](bool& v_out){ m_compress_save_backup.Set(v_out); - }); + }, "If enabled, backups will be compressed to a zip file.\n\n" + "NOTE: Disabling this option does not disable the zip file, it only disables compressing " + "the files stored in the zip.\n" + "Disabling will result in a much faster backup, at the cost of the file size."_i18n); }); } -void Menu::BackupSaves(std::vector>& entries) { - dump::DumpGetLocation("Select backup location"_i18n, dump::DumpLocationFlag_SdCard|dump::DumpLocationFlag_Stdio|dump::DumpLocationFlag_Usb, [this, entries](const dump::DumpLocation& location){ - App::Push(0, "Backup"_i18n, "", [this, entries, location](auto pbox) -> Result { - return BackupSaveInternal(pbox, location, entries, m_compress_save_backup.Get()); +void Menu::BackupSaves(std::vector>& entries, u32 flags) { + dump::DumpGetLocation("Select backup location"_i18n, dump::DumpLocationFlag_SdCard|dump::DumpLocationFlag_Stdio|dump::DumpLocationFlag_Usb, [this, entries, flags](const dump::DumpLocation& location){ + App::Push(0, "Backup"_i18n, "", [this, entries, location, flags](auto pbox) -> Result { + return BackupSaveInternal(pbox, location, entries, flags); }, [](Result rc){ App::PushErrorBox(rc, "Backup failed!"_i18n); @@ -794,7 +823,7 @@ void Menu::RestoreSave() { if (m_auto_backup_on_restore.Get()) { pbox->SetActionName("Auto backup"_i18n); - R_TRY(BackupSaveInternal(pbox, location, m_entries[m_index], m_compress_save_backup.Get(), true)); + R_TRY(BackupSaveInternal(pbox, location, m_entries[m_index], BackupFlag_IsAuto)); } pbox->SetActionName("Restore"_i18n); @@ -814,7 +843,7 @@ void Menu::RestoreSave() { }); } -auto Menu::BuildSavePath(const Entry& e, bool is_auto) const -> fs::FsPath { +auto Menu::BuildSavePath(const Entry& e, u32 flags) const -> fs::FsPath { const auto t = std::time(NULL); const auto tm = std::localtime(&t); const auto base = BuildSaveBasePath(e); @@ -822,27 +851,39 @@ auto Menu::BuildSavePath(const Entry& e, bool is_auto) const -> fs::FsPath { char time[64]; std::snprintf(time, sizeof(time), "%u.%02u.%02u @ %02u.%02u.%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - fs::FsPath path; + fs::FsPath name; if (e.save_data_type == FsSaveDataType_Account) { const auto acc = m_accounts[m_account_index]; fs::FsPath name_buf; - if (is_auto) { + if (flags & BackupFlag_IsAuto) { std::snprintf(name_buf, sizeof(name_buf), "AUTO - %s", acc.nickname); } else { std::snprintf(name_buf, sizeof(name_buf), "%s", acc.nickname); } title::utilsReplaceIllegalCharacters(name_buf, true); - std::snprintf(path, sizeof(path), "%s/%s - %s.zip", base.s, name_buf.s, time); + std::snprintf(name, sizeof(name), "%s - %s.zip", name_buf.s, time); } else { - std::snprintf(path, sizeof(path), "%s/%s.zip", base.s, time); + std::snprintf(name, sizeof(name), "%s.zip", time); } - return path; + if (flags & BackupFlag_SetName) { + std::string out; + while (out.empty()) { + const auto header = "Set name for "_i18n + e.GetName(); + if (R_FAILED(swkbd::ShowText(out, header.c_str(), "Set backup name", name, 1, 128))) { + out.clear(); + } + } + + name = out; + } + + return fs::AppendPath(base, name); } -Result Menu::RestoreSaveInternal(ProgressBox* pbox, const Entry& e, const fs::FsPath& path) const { +Result Menu::RestoreSaveInternal(ProgressBox* pbox, const Entry& e, const fs::FsPath& path) { pbox->SetTitle(e.GetName()); if (e.image) { pbox->SetImage(e.image); @@ -960,14 +1001,15 @@ Result Menu::RestoreSaveInternal(ProgressBox* pbox, const Entry& e, const fs::Fs R_SUCCEED(); } -Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, std::span> entries, bool compressed, bool is_auto) const { +Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, std::span> entries, u32 flags) { std::vector paths; for (auto& e : entries) { // ensure that we have title name and icon loaded. LoadControlEntry(e); - paths.emplace_back(BuildSavePath(e, is_auto)); + paths.emplace_back(BuildSavePath(e, flags)); } + const auto compressed = m_compress_save_backup.Get(); auto source = std::make_shared(entries, paths); return dump::Dump(pbox, source, location, paths, [&](ui::ProgressBox* pbox, dump::BaseSource* _source, dump::WriteSource* writer, const fs::FsPath& path) -> Result { @@ -1116,11 +1158,11 @@ Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& loc }); } -Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, Entry& e, bool compressed, bool is_auto) const { +Result Menu::BackupSaveInternal(ProgressBox* pbox, const dump::DumpLocation& location, Entry& e, u32 flags) { std::vector> entries; entries.emplace_back(e); - return BackupSaveInternal(pbox, location, entries, compressed, is_auto); + return BackupSaveInternal(pbox, location, entries, flags); } Result Menu::MountSaveFs() { diff --git a/sphaira/source/ui/sidebar.cpp b/sphaira/source/ui/sidebar.cpp index 36557a8..c6f72a3 100644 --- a/sphaira/source/ui/sidebar.cpp +++ b/sphaira/source/ui/sidebar.cpp @@ -309,16 +309,17 @@ void SidebarEntryTextBase::Draw(NVGcontext* vg, Theme* theme, const Vec4& root_p SidebarEntryBase::DrawEntry(vg, theme, m_title, m_value, true); } -SidebarEntryTextInput::SidebarEntryTextInput(const std::string& title, const std::string& value, const std::string& guide, s64 len_min, s64 len_max, const std::string& info, const Callback& callback) +SidebarEntryTextInput::SidebarEntryTextInput(const std::string& title, const std::string& value, const std::string& header, const std::string& guide, s64 len_min, s64 len_max, const std::string& info, const Callback& callback) : SidebarEntryTextBase{title, value, {}, info} -, m_guide{guide} +, m_header{header.empty() ? title : header} +, m_guide{guide.empty() ? title : guide} , m_len_min{len_min} , m_len_max{len_max} , m_callback{callback} { SetCallback([this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out, m_guide.c_str(), GetValue().c_str(), m_len_min, m_len_max))) { + if (R_SUCCEEDED(swkbd::ShowText(out, m_header.c_str(), m_guide.c_str(), GetValue().c_str(), m_len_min, m_len_max))) { SetValue(out); if (m_callback) { @@ -328,11 +329,11 @@ SidebarEntryTextInput::SidebarEntryTextInput(const std::string& title, const std }); } -SidebarEntryTextInput::SidebarEntryTextInput(const std::string& title, s64 value, const std::string& guide, s64 len_min, s64 len_max, const std::string& info, const Callback& callback) -: SidebarEntryTextInput{title, std::to_string(value), guide, len_min, len_max, info, callback} { +SidebarEntryTextInput::SidebarEntryTextInput(const std::string& title, s64 value, const std::string& header, const std::string& guide, s64 len_min, s64 len_max, const std::string& info, const Callback& callback) +: SidebarEntryTextInput{title, std::to_string(value), header, guide, len_min, len_max, info, callback} { SetCallback([this](){ s64 out = std::stoul(GetValue()); - if (R_SUCCEEDED(swkbd::ShowNumPad(out, m_guide.c_str(), GetValue().c_str(), m_len_min, m_len_max))) { + if (R_SUCCEEDED(swkbd::ShowNumPad(out, m_header.c_str(), m_guide.c_str(), GetValue().c_str(), m_len_min, m_len_max))) { SetValue(std::to_string(out)); if (m_callback) { diff --git a/sphaira/source/utils/devoptab.cpp b/sphaira/source/utils/devoptab.cpp index 0faf841..3d81d6f 100644 --- a/sphaira/source/utils/devoptab.cpp +++ b/sphaira/source/utils/devoptab.cpp @@ -167,17 +167,17 @@ void DevoptabForm::SetupButtons(bool type_change) { } m_name = this->Add( - "Name", m_config.name, "", -1, 32, + "Name", m_config.name, "", "", -1, 32, "Set the name of the application"_i18n ); m_url = this->Add( - "URL", m_config.url, "", -1, PATH_MAX, + "URL", m_config.url, "", "", -1, PATH_MAX, "Set the URL of the application"_i18n ); m_port = this->Add( - "Port", m_config.port, "Port number", 1, 5, + "Port", m_config.port, "", "", 1, 5, "Optional: Set the port of the server. If left empty, the default port for the protocol will be used."_i18n ); @@ -189,17 +189,17 @@ void DevoptabForm::SetupButtons(bool type_change) { #endif m_user = this->Add( - "User", m_config.user, "", -1, PATH_MAX, + "User", m_config.user, "", "", -1, PATH_MAX, "Optional: Set the username of the application"_i18n ); m_pass = this->Add( - "Pass", m_config.pass, "", -1, PATH_MAX, + "Pass", m_config.pass, "", "", -1, PATH_MAX, "Optional: Set the password of the application"_i18n ); m_dump_path = this->Add( - "Dump path", m_config.dump_path, "", -1, PATH_MAX, + "Dump path", m_config.dump_path, "", "", -1, PATH_MAX, "Optional: Set the dump path used when exporting games and saves."_i18n );