New add-on manager: initial implementation of add-on installing

This commit is contained in:
Jyrki Vesterinen 2017-01-07 20:05:32 +02:00
parent cb7ea10155
commit 1914ba3488
4 changed files with 147 additions and 70 deletions

View file

@ -984,7 +984,6 @@
[button]
id = "install"
return_value_id = "ok"
definition = "addon_install"
[/button]
@ -998,7 +997,6 @@
[button]
id = "uninstall"
return_value_id = "ok"
definition = "addon_uninstall"
[/button]

View file

@ -1018,18 +1018,9 @@ bool addons_manager_ui(CVideo& v, const std::string& remote_address)
addons_list addons;
if(gui2::new_widgets) {
config cfg;
client.request_addons_list(cfg);
if(!cfg) {
gui2::show_error_message(
v
, _("An error occurred while downloading the "
"add-ons list from the server."));
return need_wml_cache_refresh;
}
gui2::dialogs::addon_manager dlg(cfg);
gui2::dialogs::addon_manager dlg(client);
dlg.show(v);
return need_wml_cache_refresh;
return true;
}
if(!get_addons_list(client, addons)) {

View file

@ -27,6 +27,7 @@
#include "gui/auxiliary/filter.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/dialogs/helper.hpp"
#include "gui/dialogs/message.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/stacked_widget.hpp"
@ -159,15 +160,15 @@ namespace {
REGISTER_DIALOG(addon_manager)
addon_manager::addon_manager(const config& cfg)
addon_manager::addon_manager(addons_client& client)
: orders_()
, cfg_(cfg)
, client_(client)
, cfg_()
, cfg_iterators_(cfg_.child_range("campaign"))
, addons_()
, tracking_info_()
, ids_()
{
read_addons_list(cfg, addons_);
}
void addon_manager::on_filtertext_changed(text_box_base* textbox, const std::string& text)
@ -316,8 +317,84 @@ static std::string describe_status_verbose(const addon_tracking_info& state)
void addon_manager::pre_show(window& window)
{
load_addon_list(window);
listbox& list = find_widget<listbox>(&window, "addons", false);
list.register_sorting_option(0, [this](const int i) { return addon_at(ids_[i], addons_).title; });
list.register_sorting_option(1, [this](const int i) { return addon_at(ids_[i], addons_).author; });
list.register_sorting_option(2, [this](const int i) { return addon_at(ids_[i], addons_).size; });
list.register_sorting_option(3, [this](const int i) { return addon_at(ids_[i], addons_).downloads; });
list.register_sorting_option(4, [this](const int i) { return addon_at(ids_[i], addons_).type; });
find_widget<text_box>(&window, "filter", false).set_text_changed_callback(
std::bind(&addon_manager::on_filtertext_changed, this, _1, _2));
#ifdef GUI2_EXPERIMENTAL_LISTBOX
connect_signal_notify_modified(list,
std::bind(&addon_manager::on_addon_select,
*this,
std::ref(window)));
#else
list.set_callback_value_change(
dialog_callback<addon_manager, &addon_manager::on_addon_select>);
#endif
button& url_go_button = find_widget<button>(&window, "url_go", false);
button& url_copy_button = find_widget<button>(&window, "url_copy", false);
text_box& url_textbox = find_widget<text_box>(&window, "url", false);
url_textbox.set_active(false);
if (!desktop::clipboard::available()) {
url_copy_button.set_active(false);
url_copy_button.set_tooltip(_("Clipboard support not found, contact your packager"));
}
if(!desktop::open_object_is_supported()) {
// No point in displaying the button on platforms that can't do
// open_object().
url_go_button.set_visible(styled_widget::visibility::invisible);
}
connect_signal_mouse_left_click(
find_widget<button>(&window, "install", false),
std::bind(&addon_manager::install_selected_addon, this, std::ref(window)));
connect_signal_mouse_left_click(
url_go_button,
std::bind(&addon_manager::browse_url_callback, this, std::ref(url_textbox)));
connect_signal_mouse_left_click(
url_copy_button,
std::bind(&addon_manager::copy_url_callback, this, std::ref(url_textbox)));
connect_signal_mouse_left_click(
find_widget<button>(&window, "options", false),
std::bind(&addon_manager::options_button_callback, this, std::ref(window)));
connect_signal_mouse_left_click(
find_widget<button>(&window, "show_help", false),
std::bind(&addon_manager::show_help, this, std::ref(window)));
on_addon_select(window);
}
void addon_manager::load_addon_list(window& window)
{
client_.request_addons_list(cfg_);
if(!cfg_)
{
show_error_message(window.video(),
_("An error occurred while downloading the "
"add-ons list from the server."));
window.close();
}
read_addons_list(cfg_, addons_);
listbox& list = find_widget<listbox>(&window, "addons", false);
list.clear();
for(const auto & c : cfg_.child_range("campaign"))
{
ids_.push_back(c["name"]);
@ -368,60 +445,22 @@ void addon_manager::pre_show(window& window)
find_widget<button>(row_grid, "single_uninstall", false).set_active(is_installed);
}
}
list.register_sorting_option(0, [this](const int i) { return addon_at(ids_[i], addons_).title; });
list.register_sorting_option(1, [this](const int i) { return addon_at(ids_[i], addons_).author; });
list.register_sorting_option(2, [this](const int i) { return addon_at(ids_[i], addons_).size; });
list.register_sorting_option(3, [this](const int i) { return addon_at(ids_[i], addons_).downloads; });
list.register_sorting_option(4, [this](const int i) { return addon_at(ids_[i], addons_).type; });
find_widget<text_box>(&window, "filter", false).set_text_changed_callback(
std::bind(&addon_manager::on_filtertext_changed, this, _1, _2));
#ifdef GUI2_EXPERIMENTAL_LISTBOX
connect_signal_notify_modified(list,
std::bind(&addon_manager::on_addon_select,
*this,
std::ref(window)));
#else
list.set_callback_value_change(
dialog_callback<addon_manager, &addon_manager::on_addon_select>);
#endif
button& url_go_button = find_widget<button>(&window, "url_go", false);
button& url_copy_button = find_widget<button>(&window, "url_copy", false);
text_box& url_textbox = find_widget<text_box>(&window, "url", false);
url_textbox.set_active(false);
if (!desktop::clipboard::available()) {
url_copy_button.set_active(false);
url_copy_button.set_tooltip(_("Clipboard support not found, contact your packager"));
unsigned int addon_manager::get_addon_index(listbox& addon_list, const std::string& id)
{
const addon_info& info = addon_at(id, addons_);
for(unsigned int i = 0u; i < addon_list.get_item_count(); ++i)
{
grid* row = addon_list.get_row_grid(i);
const label& name_label = find_widget<label>(row, "name", false);
if(name_label.get_label().base_str() == info.display_title())
{
return i;
}
}
if(!desktop::open_object_is_supported()) {
// No point in displaying the button on platforms that can't do
// open_object().
url_go_button.set_visible(styled_widget::visibility::invisible);
}
connect_signal_mouse_left_click(
url_go_button,
std::bind(&addon_manager::browse_url_callback, this, std::ref(url_textbox)));
connect_signal_mouse_left_click(
url_copy_button,
std::bind(&addon_manager::copy_url_callback, this, std::ref(url_textbox)));
connect_signal_mouse_left_click(
find_widget<button>(&window, "options", false),
std::bind(&addon_manager::options_button_callback, this, std::ref(window)));
connect_signal_mouse_left_click(
find_widget<button>(&window, "show_help", false),
std::bind(&addon_manager::show_help, this, std::ref(window)));
on_addon_select(window);
return 0xFFFFFFFFu;
}
void addon_manager::options_button_callback(window& window)
@ -438,6 +477,43 @@ void addon_manager::options_button_callback(window& window)
UNUSED(window); // Remove this once the code works.
}
void addon_manager::install_selected_addon(window& window)
{
listbox& addon_list = find_widget<listbox>(&window, "addons", false);
const int index = addon_list.get_selected_row();
if(index == -1) {
return;
}
// We take a copy because reloading the addon list invalidates references.
const addon_info info = addon_at(ids_[index], addons_);
config archive;
bool download_succeeded = client_.download_addon(archive, info.id, info.title);
if(download_succeeded)
{
bool install_succeeded = client_.install_addon(archive, info);
if(install_succeeded)
{
load_addon_list(window);
// Reselect the add-on.
addon_list.select_row(get_addon_index(addon_list, info.id));
on_addon_select(window);
return;
}
}
// failure
const std::string& server_error = client_.get_last_server_error();
if(server_error != "") {
show_error_message(window.video(),
_("The server responded with an error:") + "\n" + server_error);
}
}
void addon_manager::show_help(window& window)
{
help::show_help(window.video(), "installing_addons");
@ -508,7 +584,10 @@ void addon_manager::on_addon_select(window& window)
find_widget<stacked_widget>(&window, "feedback_stack", false).select_layer(0);
}
find_widget<button>(&window, "uninstall", false).set_active(tracking_info_[info.id].state == ADDON_INSTALLED);
bool installed = is_installed_addon_status(tracking_info_[info.id].state);
find_widget<button>(&window, "install", false).set_active(!installed);
find_widget<button>(&window, "uninstall", false).set_active(installed);
}
} // namespace dialogs

View file

@ -15,6 +15,7 @@
#ifndef GUI_DIALOGS_ADDON_LIST_HPP_INCLUDED
#define GUI_DIALOGS_ADDON_LIST_HPP_INCLUDED
#include "addon/client.hpp"
#include "addon/info.hpp"
#include "addon/state.hpp"
@ -25,6 +26,7 @@
namespace gui2
{
class listbox;
class text_box_base;
class text_box;
class pane;
@ -36,7 +38,7 @@ namespace dialogs
class addon_manager : public modal_dialog
{
public:
explicit addon_manager(const config& cfg);
explicit addon_manager(addons_client& client);
private:
void on_filtertext_changed(text_box_base* textbox, const std::string& text);
@ -50,20 +52,27 @@ private:
/** Inherited from modal_dialog. */
void pre_show(window& window);
void load_addon_list(window& window);
unsigned int get_addon_index(listbox& addon_list, const std::string& id);
/** Config which contains the list with the campaigns. */
const config& cfg_;
config cfg_;
/**
* Debug iterators for testing with --new-widgets
*/
config::const_child_itors cfg_iterators_;
addons_client& client_;
addons_list addons_;
addons_tracking_list tracking_info_;
std::vector<std::string> ids_;
void install_selected_addon(window& window);
void browse_url_callback(text_box& url_box);
void copy_url_callback(text_box& url_box);
void options_button_callback(window& window);