Implemented non-blocking download for the repository index list
[supertux.git] / src / supertux / menu / addon_menu.cpp
index d2e6c5b..5011e95 100644 (file)
@@ -24,6 +24,8 @@
 #include "addon/addon_manager.hpp"
 #include "gui/menu.hpp"
 #include "gui/menu_item.hpp"
+#include "gui/menu_manager.hpp"
+#include "supertux/menu/addon_dialog.hpp"
 #include "util/gettext.hpp"
 
 namespace {
@@ -91,14 +93,6 @@ AddonMenu::refresh()
   m_installed_addons = m_addon_manager.get_installed_addons();
   m_repository_addons = m_addon_manager.get_repository_addons();
 
-#ifdef GRUMBEL
-  std::sort(m_addons.begin(), m_addons.end(),
-            [](const Addon& lhs, const Addon& rhs)
-            {
-              return lhs.title < lhs.title;
-            });
-#endif
-
   rebuild_menu();
 }
 
@@ -109,31 +103,27 @@ AddonMenu::rebuild_menu()
   add_label(_("Add-ons"));
   add_hl();
 
-  
-  if (!m_installed_addons.empty())
+
+  if (m_installed_addons.empty())
+  {
+    add_inactive(MNID_NOTHING_NEW, _("No Addons installed"));
+  }
+  else
   {
     int idx = 0;
     for (const auto& addon_id : m_installed_addons)
     {
       const Addon& addon = m_addon_manager.get_installed_addon(addon_id);
       std::string text = generate_menu_item_text(addon);
-      add_toggle(MAKE_INSTALLED_MENU_ID(idx), text, addon.is_enabled());   
+      add_toggle(MAKE_INSTALLED_MENU_ID(idx), text, addon.is_enabled());
       idx += 1;
     }
-
-    add_hl();
   }
 
-  if (!m_addon_manager.has_online_support())
-  {
-    add_inactive(MNID_CHECK_ONLINE, std::string(_("Check Online (disabled)")));
-  }
-  else
-  {
-    add_entry(MNID_CHECK_ONLINE, std::string(_("Check Online")));
-  }
+  add_hl();
 
   {
+    bool have_new_stuff = false;
     int idx = 0;
     for (const auto& addon_id : m_repository_addons)
     {
@@ -145,13 +135,17 @@ AddonMenu::rebuild_menu()
         if (installed_addon.get_md5() == addon.get_md5() ||
             installed_addon.get_version() > addon.get_version())
         {
-          // addon alredy present, ignore it
+          log_debug << "ignoring already installed addon " << installed_addon.get_id() << std::endl;
         }
         else
         {
+          log_debug << installed_addon.get_id() << " is installed, but updated: '"
+                    << installed_addon.get_md5() << "' vs '" << addon.get_md5() << "'  '"
+                    << installed_addon.get_version() << "' vs '" << addon.get_version() << "'"
+                    << std::endl;
           std::string text = generate_menu_item_text(addon);
-          add_entry(MAKE_REPOSITORY_MENU_ID(idx), "Install " + text + "*NEW*");
-          idx += 1;
+          add_entry(MAKE_REPOSITORY_MENU_ID(idx), "Install " + text + " *NEW*");
+          have_new_stuff = true;
         }
       }
       catch(const std::exception& err)
@@ -159,11 +153,26 @@ AddonMenu::rebuild_menu()
         // addon is not installed
         std::string text = generate_menu_item_text(addon);
         add_entry(MAKE_REPOSITORY_MENU_ID(idx), "Install " + text);
-        idx += 1;
+        have_new_stuff = true;
       }
+      idx += 1;
+    }
+
+    if (!have_new_stuff && m_addon_manager.has_been_updated())
+    {
+      add_inactive(MNID_NOTHING_NEW, _("No new Addons found"));
     }
   }
 
+  if (!m_addon_manager.has_online_support())
+  {
+    add_inactive(MNID_CHECK_ONLINE, std::string(_("Check Online (disabled)")));
+  }
+  else
+  {
+    add_entry(MNID_CHECK_ONLINE, std::string(_("Check Online")));
+  }
+
   add_hl();
   add_back(_("Back"));
 }
@@ -175,8 +184,14 @@ AddonMenu::menu_action(MenuItem* item)
   {
     try
     {
-      m_addon_manager.check_online();
-      refresh();
+      AddonManager::InstallStatusPtr status = m_addon_manager.request_check_online();
+      status->then([this]{
+          MenuManager::instance().set_dialog({});
+          refresh();
+        });
+      std::unique_ptr<AddonDialog> dialog(new AddonDialog(status));
+      dialog->set_title("Downloading Add-On Repository Index");
+      MenuManager::instance().set_dialog(std::move(dialog));
     }
     catch (std::exception& e)
     {
@@ -193,7 +208,7 @@ AddonMenu::menu_action(MenuItem* item)
         const Addon& addon = m_addon_manager.get_installed_addon(m_installed_addons[idx]);
         if(addon.is_enabled())
         {
-          m_addon_manager.enable_addon(addon.get_id());
+          m_addon_manager.disable_addon(addon.get_id());
           set_toggled(item->id, addon.is_enabled());
         }
         else
@@ -209,22 +224,31 @@ AddonMenu::menu_action(MenuItem* item)
       if (0 <= idx && idx < static_cast<int>(m_repository_addons.size()))
       {
         const Addon& addon = m_addon_manager.get_repository_addon(m_repository_addons[idx]);
-        try
-        {
-          m_addon_manager.install_addon(addon.get_id());
-          m_addon_manager.enable_addon(addon.get_id());
-        }
-        catch(const std::exception& err)
-        {
-          log_warning << "Enabling addon failed: " << err.what() << std::endl;
-        }
-        refresh();
+        auto addon_id = addon.get_id();
+        AddonManager::InstallStatusPtr status = m_addon_manager.request_install_addon(addon_id);
+
+        status->then([this, addon_id]{
+            try
+            {
+              m_addon_manager.enable_addon(addon_id);
+            }
+            catch(const std::exception& err)
+            {
+              log_warning << "Enabling addon failed: " << err.what() << std::endl;
+            }
+            MenuManager::instance().set_dialog({});
+            refresh();
+          });
+
+        std::unique_ptr<AddonDialog> dialog(new AddonDialog(status));
+        dialog->set_title("Downloading " + generate_menu_item_text(addon));
+        MenuManager::instance().set_dialog(std::move(dialog));
       }
     }
   }
   else
   {
-       log_warning << "Unknown menu item clicked: " << item->id << std::endl;
+    log_warning << "Unknown menu item clicked: " << item->id << std::endl;
   }
 }