diff --git a/Common/StringUtils.h b/Common/StringUtils.h index d48ad12993..46a44cd799 100644 --- a/Common/StringUtils.h +++ b/Common/StringUtils.h @@ -184,3 +184,33 @@ size_t SplitSearch(std::string_view needle, std::string_view part1, std::string_ // For mixes of strings and ints, manually convert the ints to strings. std::string ApplySafeSubstitutions(std::string_view format, std::string_view string1, std::string_view string2 = "", std::string_view string3 = "", std::string_view string4 = ""); std::string ApplySafeSubstitutions(std::string_view format, int i1, int i2 = 0, int i3 = 0, int i4 = 0); + +// Not really a string util. +template +bool Contains(const std::vector &vec, const T &needle) { + for (const auto &item : vec) { + if (item == needle) { + return true; + } + } + return false; +} + +inline bool ContainsNoCase(const std::vector &vec, std::string_view needle) { + for (const auto &item : vec) { + if (equalsNoCase(item, needle)) { + return true; + } + } + return false; +} + +inline bool RemoveNoCase(std::vector &vec, std::string_view needle) { + for (auto it = vec.begin(); it != vec.end(); ++it) { + if (equalsNoCase(*it, needle)) { + vec.erase(it); + return true; + } + } + return false; +} diff --git a/UI/AdhocServerScreen.cpp b/UI/AdhocServerScreen.cpp index 4e87037c0c..abb324bba8 100644 --- a/UI/AdhocServerScreen.cpp +++ b/UI/AdhocServerScreen.cpp @@ -8,7 +8,7 @@ class AdhocAddServerPopupScreen : public UI::PopupScreen { public: - AdhocAddServerPopupScreen() : PopupScreen(T(I18NCat::NETWORKING, "Add server"), T(I18NCat::DIALOG, "Add"), T(I18NCat::DIALOG, "Cancel")) { + AdhocAddServerPopupScreen(std::string *outEditValue) : PopupScreen(T(I18NCat::NETWORKING, "Add server"), T(I18NCat::DIALOG, "Add"), T(I18NCat::DIALOG, "Cancel")), outEditValue_(outEditValue) { } void CreatePopupContents(UI::ViewGroup *parent) override { @@ -21,12 +21,29 @@ public: virtual void OnCompleted(DialogResult result) { if (result == DialogResult::DR_OK) { - if (hasRelay_) { - // Insert at the start of the vector. - g_Config.vCustomAdhocServerListWithRelay.insert(g_Config.vCustomAdhocServerListWithRelay.begin(), editValue_); - } else { - g_Config.vCustomAdhocServerList.insert(g_Config.vCustomAdhocServerList.begin(), editValue_); + std::vector servers = AdhocGetServerList(AdhocLoadListMode::CacheOnlySync); + bool preset = false; + for (auto &iter : servers) { + if (equalsNoCase(editValue_, iter.host)) { + // We have this predefined. + preset = true; + } } + if (!preset) { + if (hasRelay_) { + // Insert at the start of the vector. + if (!ContainsNoCase(g_Config.vCustomAdhocServerListWithRelay, editValue_) && + !ContainsNoCase(g_Config.vCustomAdhocServerList, editValue_)) { + g_Config.vCustomAdhocServerListWithRelay.insert(g_Config.vCustomAdhocServerListWithRelay.begin(), editValue_); + } + } else { + if (!ContainsNoCase(g_Config.vCustomAdhocServerList, editValue_) && + !ContainsNoCase(g_Config.vCustomAdhocServerListWithRelay, editValue_)) { + g_Config.vCustomAdhocServerList.insert(g_Config.vCustomAdhocServerList.begin(), editValue_); + } + } + } + *outEditValue_ = editValue_; } } virtual bool CanComplete(DialogResult result) { return result == DR_OK ? !editValue_.empty() : true; } @@ -35,6 +52,7 @@ public: private: std::string editValue_; + std::string *outEditValue_; bool hasRelay_ = true; }; @@ -164,8 +182,8 @@ private: AdhocServerListEntry entry_; }; -AdhocServerRow::AdhocServerRow(std::string *value, const AdhocServerListEntry &entry, bool showDeleteButton, ScreenManager *screenManager, UI::LayoutParams *layoutParams) - : UI::LinearLayout(ORIENT_HORIZONTAL, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::WRAP_CONTENT, UI::Margins(5.0f, 0.0f))), value_(value), entry_(entry) { +AdhocServerRow::AdhocServerRow(std::string *editValue, const AdhocServerListEntry &entry, bool showDeleteButton, ScreenManager *screenManager, UI::LayoutParams *layoutParams) + : UI::LinearLayout(ORIENT_HORIZONTAL, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::WRAP_CONTENT, UI::Margins(5.0f, 0.0f))), value_(editValue), entry_(entry) { using namespace UI; int number = 0; @@ -188,22 +206,17 @@ AdhocServerRow::AdhocServerRow(std::string *value, const AdhocServerListEntry &e } if (showDeleteButton) { Choice *deleteButton = Add(new Choice(ImageID("I_TRASHCAN"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity::G_VCENTER, Margins(0, 0, 10, 0)))); - deleteButton->OnClick.Add([host = entry.host, screenManager](UI::EventParams &e) { + deleteButton->OnClick.Add([host = entry.host, screenManager, editValue](UI::EventParams &e) { auto di = GetI18NCategory(I18NCat::DIALOG); - std::string message = ApplySafeSubstitutions(di->T("Are you sure you want to delete %1"), host); - screenManager->push(new UI::MessagePopupScreen(di->T("Delete"), message, di->T("Delete"), di->T("Cancel"), [host](bool confirmed) { + const std::string quotedHost = "\"" + host + "\""; + const std::string message = ApplySafeSubstitutions(di->T("Are you sure you want to delete %1?"), quotedHost); + screenManager->push(new UI::MessagePopupScreen(di->T("Delete"), message, di->T("Delete"), di->T("Cancel"), [host, editValue](bool confirmed) { if (confirmed) { - auto f = std::find(g_Config.vCustomAdhocServerList.begin(), g_Config.vCustomAdhocServerList.end(), host); - if (f != g_Config.vCustomAdhocServerList.end()) { - g_Config.vCustomAdhocServerList.erase(f); - } - f = std::find(g_Config.vCustomAdhocServerListWithRelay.begin(), g_Config.vCustomAdhocServerListWithRelay.end(), host); - if (f != g_Config.vCustomAdhocServerListWithRelay.end()) { - g_Config.vCustomAdhocServerListWithRelay.erase(f); - } - if (g_Config.sProAdhocServer == host) { + RemoveNoCase(g_Config.vCustomAdhocServerList, host); + RemoveNoCase(g_Config.vCustomAdhocServerListWithRelay, host); + if (*editValue == host) { // Reset to socom.cc, which will always be in a list. - g_Config.sProAdhocServer = DefaultProAdhocServer(); + *editValue = DefaultProAdhocServer(); } } })); @@ -256,7 +269,7 @@ void AdhocServerScreen::CreatePopupContents(UI::ViewGroup *parent) { Choice *addServer = parent->Add(new Choice(n->T("Add server"), ImageID("I_PLUS"))); addServer->OnClick.Add([this](UI::EventParams &e) { - AdhocAddServerPopupScreen *addScreen = new AdhocAddServerPopupScreen(); + AdhocAddServerPopupScreen *addScreen = new AdhocAddServerPopupScreen(&editValue_); screenManager()->push(addScreen); }); diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index 688c5e9081..1e2e17fa1a 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -117,16 +117,6 @@ void InstallZipScreen::CreateSettingsViews(UI::ViewGroup *parent) { } } -template -bool Contains(const std::vector &vec, const T &needle) { - for (const auto &item : vec) { - if (item == needle) { - return true; - } - } - return false; -} - void InstallZipScreen::CreateContentViews(UI::ViewGroup *parent) { using namespace UI;