From e237c1d07d4a257329ba4db1631f40054510d445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Doser?= Date: Tue, 22 Jan 2013 17:03:38 +0100 Subject: [PATCH 1/4] Fix crash when no world is selected and configure button is pressed. by moving return statement out of if-then-else clause... --- src/guiMainMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guiMainMenu.cpp b/src/guiMainMenu.cpp index 77a5a85b..68ee990c 100644 --- a/src/guiMainMenu.cpp +++ b/src/guiMainMenu.cpp @@ -1048,8 +1048,8 @@ bool GUIMainMenu::OnEvent(const SEvent& event) GUIConfigureWorld *menu = new GUIConfigureWorld(env, parent, -1, menumgr, wspec); menu->drop(); - return true; } + return true; } case GUI_ID_SERVERLIST_DELETE: { gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST); From 26a0efae2359334eb418f91bf85c0eae9db45646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Doser?= Date: Tue, 22 Jan 2013 17:06:25 +0100 Subject: [PATCH 2/4] Improve behaviour for empty modpacks and when no mods at all are installed: Only show enable all / disable all buttons for all add-ons when at least one add-on is installed. When no add-on ist installed, don't show any buttons or checkboxes. Added is_modpack flag to ModSpec to distinguish empty modpacks from normal mods and check this flag in mod selection gui so that empty modpacks are not treated like mods that can be enabled or disabled. --- src/guiConfigureWorld.cpp | 62 +++++++++++++++++++++++++-------------- src/mods.cpp | 5 ++-- src/mods.h | 3 ++ 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/guiConfigureWorld.cpp b/src/guiConfigureWorld.cpp index a77697f8..38f1a554 100644 --- a/src/guiConfigureWorld.cpp +++ b/src/guiConfigureWorld.cpp @@ -69,15 +69,13 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env, m_worldmods = flattenModTree(getModsInPath(worldmods_path)); // fill m_addontree with add-on mods - ModSpec addons("Add-Ons"); std::set paths = m_gspec.addon_mods_paths; for(std::set::iterator it=paths.begin(); it != paths.end(); ++it) { std::map mods = getModsInPath(*it); - addons.modpack_content.insert(mods.begin(), mods.end()); + m_addontree.insert(mods.begin(), mods.end()); } - m_addontree.insert(std::make_pair(addons.name,addons)); // expand modpacks m_addonmods = flattenModTree(m_addontree); @@ -116,7 +114,7 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env, ModSpec mod = (*it).second; // a mod is new if it is not a modpack, and does not occur in // mod_names - if(mod.modpack_content.empty() && + if(!mod.is_modpack && mod_names.count(modname) == 0) m_new_mod_names.insert(modname); } @@ -253,7 +251,9 @@ void GUIConfigureWorld::regenerateGui(v2u32 screensize) rect += v2s32(220, 0) + topleft; m_treeview = Environment->addTreeView(rect, this, GUI_ID_MOD_TREEVIEW,true); - buildTreeView(m_addontree, m_treeview->getRoot()); + gui::IGUITreeViewNode* node + = m_treeview->getRoot()->addChildBack(L"Add-Ons"); + buildTreeView(m_addontree, node); } { core::rect rect(0, 0, 120, 30); @@ -407,8 +407,12 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event) return true; } case GUI_ID_ENABLEALL: { - if(selected_node != NULL && selected_node->getText() != NULL) - { + if(selected_node != NULL && selected_node->getParent() == m_treeview->getRoot()) + { + enableAllMods(m_addonmods,true); + } + else if(selected_node != NULL && selected_node->getText() != NULL) + { std::string modname = wide_to_narrow(selected_node->getText()); ModSpec mod = m_addonmods[modname]; enableAllMods(mod.modpack_content,true); @@ -416,6 +420,10 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event) return true; } case GUI_ID_DISABLEALL: { + if(selected_node != NULL && selected_node->getParent() == m_treeview->getRoot()) + { + enableAllMods(m_addonmods,false); + } if(selected_node != NULL && selected_node->getText() != NULL) { std::string modname = wide_to_narrow(selected_node->getText()); @@ -517,7 +525,7 @@ void GUIConfigureWorld::buildTreeView(std::map mods, gui::IGUITreeViewNode* new_node = node->addChildBack(narrow_to_wide(modname).c_str()); m_nodes.insert(std::make_pair(modname, new_node)); - if(!mod.modpack_content.empty()) + if(mod.is_modpack) buildTreeView(mod.modpack_content, new_node); else { @@ -552,23 +560,33 @@ void GUIConfigureWorld::adjustSidebar() modname_w = L"N/A"; std::string modname = wide_to_narrow(modname_w); - // if modpack, show enable/disable all buttons. otherwise, show - // enabled checkbox - if(node->hasChilds()) - { - m_enabled_checkbox->setVisible(false); - m_disableall->setVisible(true); - m_enableall->setVisible(true); - m_modname_text->setText((L"Modpack: "+modname_w).c_str()); - } - else + // if no mods installed, don't show buttons or checkbox on the sidebar + if(node->getParent() == m_treeview->getRoot() && !node->hasChilds()) { m_disableall->setVisible(false); m_enableall->setVisible(false); - m_enabled_checkbox->setVisible(true); - m_modname_text->setText((L"Mod: "+modname_w).c_str()); + m_enabled_checkbox->setVisible(false); + } + else + { + // if modpack, show enable/disable all buttons. otherwise, show + // enabled checkbox + if(node->getParent() == m_treeview->getRoot() || + m_addonmods[modname].is_modpack) + { + m_enabled_checkbox->setVisible(false); + m_disableall->setVisible(true); + m_enableall->setVisible(true); + m_modname_text->setText((L"Modpack: "+modname_w).c_str()); + } + else + { + m_disableall->setVisible(false); + m_enableall->setVisible(false); + m_enabled_checkbox->setVisible(true); + m_modname_text->setText((L"Mod: "+modname_w).c_str()); + } } - // the mod is enabled unless it is disabled in the world.mt settings. bool mod_enabled = true; if(m_settings.exists("load_mod_"+modname)) @@ -616,7 +634,7 @@ void GUIConfigureWorld::enableAllMods(std::map mods,bool e it != mods.end(); ++it) { ModSpec mod = (*it).second; - if(!mod.modpack_content.empty()) + if(mod.is_modpack) // a modpack, recursively enable all mods in it enableAllMods(mod.modpack_content,enable); else // not a modpack diff --git a/src/mods.cpp b/src/mods.cpp index 9e3c7d5d..f6e3d58d 100644 --- a/src/mods.cpp +++ b/src/mods.cpp @@ -46,6 +46,7 @@ std::map getModsInPath(std::string path) modpack_is.close(); // We don't actually need the file ModSpec spec(modname,modpath); spec.modpack_content = getModsInPath(modpath); + spec.is_modpack = true; result.insert(std::make_pair(modname,spec)); } else // not a modpack, add the modspec @@ -76,7 +77,7 @@ std::map flattenModTree(std::map mod it != mods.end(); ++it) { ModSpec mod = (*it).second; - if(!mod.modpack_content.empty()) //is a modpack + if(mod.is_modpack) { std::map content = flattenModTree(mod.modpack_content); @@ -98,7 +99,7 @@ std::vector flattenMods(std::map mods) it != mods.end(); ++it) { ModSpec mod = (*it).second; - if(!mod.modpack_content.empty()) //is a modpack + if(mod.is_modpack) { std::vector content = flattenMods(mod.modpack_content); result.reserve(result.size() + content.size()); diff --git a/src/mods.h b/src/mods.h index 37e2cd2d..59dffdad 100644 --- a/src/mods.h +++ b/src/mods.h @@ -53,6 +53,8 @@ struct ModSpec //if normal mod: std::set depends; std::set unsatisfied_depends; + + bool is_modpack; // if modpack: std::map modpack_content; ModSpec(const std::string name_="", const std::string path_="", @@ -61,6 +63,7 @@ struct ModSpec path(path_), depends(depends_), unsatisfied_depends(depends_), + is_modpack(false), modpack_content() {} }; From f214940c96d9fef72b06a65641d01115a582b098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Doser?= Date: Tue, 22 Jan 2013 16:55:50 +0100 Subject: [PATCH 3/4] Fix crash when pressing delete button in server browser and no server is selected. A check for that was there, but was comparing an unsigned variable to -1, which doesn't work. --- src/guiMainMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guiMainMenu.cpp b/src/guiMainMenu.cpp index 68ee990c..9291bb4e 100644 --- a/src/guiMainMenu.cpp +++ b/src/guiMainMenu.cpp @@ -1053,7 +1053,7 @@ bool GUIMainMenu::OnEvent(const SEvent& event) } case GUI_ID_SERVERLIST_DELETE: { gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST); - u16 selected = ((gui::IGUIListBox*)serverlist)->getSelected(); + s32 selected = ((gui::IGUIListBox*)serverlist)->getSelected(); if (selected == -1) return true; ServerList::deleteEntry(m_data->servers[selected]); m_data->servers = ServerList::getLocal(); From f0998612457ddc3027618e7e446ed968a14385e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Doser?= Date: Tue, 22 Jan 2013 19:00:48 +0100 Subject: [PATCH 4/4] Make sure that settings are written to config file when settings are removed. Previously, settings where only written when a value has changed, and removal of a setting value didn't count as a change. --- src/settings.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/settings.h b/src/settings.h index 6d6db220..2b46676c 100644 --- a/src/settings.h +++ b/src/settings.h @@ -244,7 +244,9 @@ public: updated[name] = true; } - + else //file contains a setting which is not in m_settings + value_changed=true; + return true; }