Skip to content

Commit

Permalink
Addon List: catch user_exit exceptions when performing addon ops
Browse files Browse the repository at this point in the history
This fixes an issue where the manager would close if canceling operations invoked by the
inline addon list buttons.
  • Loading branch information
Vultraz authored and GregoryLundberg committed Nov 30, 2017
1 parent 37aa8b3 commit 5c644c0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 59 deletions.
79 changes: 30 additions & 49 deletions src/gui/widgets/addon_list.cpp
Expand Up @@ -15,6 +15,7 @@

#include "gui/widgets/addon_list.hpp"

#include "addon/client.hpp"
#include "color.hpp"
#include "font/text_formatting.hpp"
#include "formatter.hpp"
Expand Down Expand Up @@ -125,6 +126,17 @@ std::string addon_list::describe_status(const addon_tracking_info& info)
return colorize_addon_state_string(tx, info.state, true);
}

void addon_list::addon_action_wrapper(addon_op_func_t& func, const addon_info& addon, bool& handled, bool& halt)
{
try {
func(addon);

handled = halt = true;
} catch(const addons_client::user_exit&) {
// User canceled the op.
}
}

void addon_list::set_addons(const addons_list& addons)
{
listbox& list = get_listbox();
Expand Down Expand Up @@ -214,41 +226,28 @@ void addon_list::set_addons(const addons_list& addons)
install_update_stack.select_layer(static_cast<int>(is_updatable));

if(!is_updatable) {
find_widget<button>(control_grid, "single_install", false).set_active(!is_installed);
button& install_button = find_widget<button>(control_grid, "single_install", false);
install_button.set_active(!is_installed);

if(install_function_ != nullptr) {
gui2::event::connect_signal_mouse_left_click(
find_widget<button>(control_grid, "single_install", false),
[this, addon](gui2::event::dispatcher&, const gui2::event::ui_event, bool& handled, bool& halt)
{
install_function_(addon);
handled = true;
halt = true;
});
connect_signal_mouse_left_click(install_button,
std::bind(&addon_list::addon_action_wrapper, this, install_function_, std::ref(addon), _3, _4));
}
} else {
find_widget<button>(control_grid, "single_update", false).set_active(true);
button& update_button = find_widget<button>(control_grid, "single_update", false);
update_button.set_active(true);

if(update_function_ != nullptr) {
gui2::event::connect_signal_mouse_left_click(
find_widget<button>(control_grid, "single_update", false),
[this, addon](gui2::event::dispatcher&, const gui2::event::ui_event, bool& handled, bool& halt)
{
update_function_(addon);
handled = true;
halt = true;
});
connect_signal_mouse_left_click(update_button,
std::bind(&addon_list::addon_action_wrapper, this, update_function_, std::ref(addon), _3, _4));
}
}

if(is_installed) {
if(uninstall_function_ != nullptr) {
gui2::event::connect_signal_mouse_left_click(
connect_signal_mouse_left_click(
find_widget<button>(control_grid, "single_uninstall", false),
[this, addon](gui2::event::dispatcher&, const gui2::event::ui_event, bool& handled, bool& halt)
{
uninstall_function_(addon);
handled = true;
halt = true;
});
std::bind(&addon_list::addon_action_wrapper, this, uninstall_function_, std::ref(addon), _3, _4));
}
}

Expand All @@ -269,40 +268,22 @@ void addon_list::set_addons(const addons_list& addons)
uninstall_button.set_active(can_delete);

if(true) {
gui2::event::connect_signal_mouse_left_click(
install_button,
[this, addon](gui2::event::dispatcher&, const gui2::event::ui_event, bool& handled, bool& halt)
{
publish_function_(addon);
handled = true;
halt = true;
});
connect_signal_mouse_left_click(install_button,
std::bind(&addon_list::addon_action_wrapper, this, publish_function_, std::ref(addon), _3, _4));

install_button.set_tooltip(_("Publish add-on"));
}

if(is_updatable) {
gui2::event::connect_signal_mouse_left_click(
update_button,
[this, addon](gui2::event::dispatcher&, const gui2::event::ui_event, bool& handled, bool& halt)
{
publish_function_(addon);
handled = true;
halt = true;
});
connect_signal_mouse_left_click(update_button,
std::bind(&addon_list::addon_action_wrapper, this, publish_function_, std::ref(addon), _3, _4));

update_button.set_tooltip(_("Send new version to server"));
}

if(can_delete) {
gui2::event::connect_signal_mouse_left_click(
uninstall_button,
[this, addon](gui2::event::dispatcher&, const gui2::event::ui_event, bool& handled, bool& halt)
{
delete_function_(addon);
handled = true;
halt = true;
});
connect_signal_mouse_left_click(uninstall_button,
std::bind(&addon_list::addon_action_wrapper, this, delete_function_, std::ref(addon), _3, _4));

uninstall_button.set_tooltip(_("Delete add-on from server"));
}
Expand Down
29 changes: 19 additions & 10 deletions src/gui/widgets/addon_list.hpp
Expand Up @@ -61,32 +61,41 @@ class addon_list : public container_base
/** Selects the add-on with the given ID. */
void select_addon(const std::string& id);

using addon_op_func_t = std::function<void(const addon_info&)>;

/**
* Helper to wrap the execution of any of the addon operation functions.
* It catches addons_client::user_exit exceptions and halts GUI2 event execution
* after calling the given function.
*/
void addon_action_wrapper(addon_op_func_t& func, const addon_info& addon, bool& handled, bool& halt);

/** Sets the function to call when the player clicks the install button. */
void set_install_function(std::function<void(const addon_info&)> function)
void set_install_function(addon_op_func_t function)
{
install_function_ = function;
}

/** Sets the function to call when the player clicks the uninstall button. */
void set_uninstall_function(std::function<void(const addon_info&)> function)
void set_uninstall_function(addon_op_func_t function)
{
uninstall_function_ = function;
}

/** Sets the function to call when the player clicks the update button. */
void set_update_function(std::function<void(const addon_info&)> function)
void set_update_function(addon_op_func_t function)
{
update_function_ = function;
}

/** Sets the function to upload an addon to the addons server. */
void set_publish_function(std::function<void(const addon_info&)> function)
void set_publish_function(addon_op_func_t function)
{
publish_function_ = function;
}

/** Sets the function to install an addon from the addons server. */
void set_delete_function(std::function<void(const addon_info&)> function)
void set_delete_function(addon_op_func_t function)
{
delete_function_ = function;
}
Expand Down Expand Up @@ -142,12 +151,12 @@ class addon_list : public container_base
visibility install_status_visibility_;
visibility install_buttons_visibility_;

std::function<void(const addon_info&)> install_function_;
std::function<void(const addon_info&)> uninstall_function_;
std::function<void(const addon_info&)> update_function_;
addon_op_func_t install_function_;
addon_op_func_t uninstall_function_;
addon_op_func_t update_function_;

std::function<void(const addon_info&)> publish_function_;
std::function<void(const addon_info&)> delete_function_;
addon_op_func_t publish_function_;
addon_op_func_t delete_function_;

static std::string describe_status(const addon_tracking_info& info);

Expand Down

0 comments on commit 5c644c0

Please sign in to comment.