gui2/taddon_uninstall_list: New add-ons...

...uninstall menu with multiple selection

I bet there was a FR for this in the tracker, but I couldn't find it.
This commit is contained in:
Ignacio R. Morelle 2011-10-29 19:32:05 +00:00
parent 8768e9a783
commit 3953d976ce
7 changed files with 425 additions and 39 deletions

View file

@ -59,6 +59,8 @@ Version 1.9.9+svn:
format to be used
* Reenabled "delay shroud updates"
* Chanaged: Disable pango markup in unit names (bug #17788)
* It is now possible to remove multiple installed add-ons at the same
time
* WML engine:
* Readded the liminal alignment
* Added four-difficulty versions of certain macros: QUANTITY4,

View file

@ -0,0 +1,192 @@
#textdomain wesnoth-lib
###
### Definition of the window to select an addon for installation.
###
[window]
id = "addon_uninstall_list"
description = "List of add-ons for uninstalling."
[resolution]
definition = "default"
automatic_placement = "true"
vertical_placement = "center"
horizontal_placement = "center"
maximum_width = 800
maximum_height = 600
[linked_group]
id = "checkbox"
fixed_width = "true"
[/linked_group]
[linked_group]
id = "name"
fixed_width = "true"
[/linked_group]
[tooltip]
id = "tooltip_large"
[/tooltip]
[helptip]
id = "tooltip_large"
[/helptip]
[grid]
[row]
grow_factor = 0
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
definition = "title"
label = _ "Uninstall Add-ons"
[/label]
[/column]
[/row]
[row]
grow_factor = 0
[column]
grow_factor = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
[scroll_label]
definition = "default"
label = _ "Choose the add-ons you want to remove."
[/scroll_label]
[/column]
[/row]
[row]
grow_factor = 1
[column]
grow_factor = 1
horizontal_grow = "true"
vertical_grow = "true"
border = "all"
border_size = 5
[listbox]
id = "addons_list"
definition = "default"
[list_definition]
[row]
[column]
vertical_grow = "true"
horizontal_grow = "true"
[toggle_panel]
definition = "default"
return_value_id = "ok"
[grid]
[row]
[column]
grow_factor = 0
horizontal_alignment = "left"
border = "all"
border_size = 5
[toggle_button]
id = "checkbox"
definition = "default"
linked_group = "checkbox"
[/toggle_button]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
[label]
id = "name"
definition = "default"
linked_group = "name"
[/label]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[/listbox]
[/column]
[/row]
[row]
grow_factor = 0
[column]
grow_factor = 1
horizontal_grow = "true"
[grid]
[row]
grow_factor = 0
[column]
border = "all"
border_size = 5
horizontal_alignment = "right"
[button]
id = "ok"
definition = "default"
label = _ "Remove"
[/button]
[/column]
[column]
border = "all"
border_size = 5
horizontal_alignment = "right"
[button]
id = "cancel"
definition = "default"
label = _ "Cancel"
[/button]
[/column]
[/row]
[/grid]
[/column]
[/row]
[/grid]
[/resolution]
[/window]

View file

@ -452,6 +452,7 @@ set(wesnoth-main_SRC
gui/auxiliary/window_builder/tree_view.cpp
gui/auxiliary/window_builder/vertical_scrollbar.cpp
gui/dialogs/addon/description.cpp
gui/dialogs/addon/uninstall_list.cpp
gui/dialogs/addon_connect.cpp
gui/dialogs/addon_list.cpp
gui/dialogs/campaign_difficulty.cpp

View file

@ -296,6 +296,7 @@ wesnoth_sources = Split("""
gui/auxiliary/window_builder/tree_view.cpp
gui/auxiliary/window_builder/vertical_scrollbar.cpp
gui/dialogs/addon/description.cpp
gui/dialogs/addon/uninstall_list.cpp
gui/dialogs/addon_connect.cpp
gui/dialogs/addon_list.cpp
gui/dialogs/campaign_difficulty.cpp

View file

@ -27,6 +27,7 @@
#include "gui/dialogs/addon_connect.hpp"
#include "gui/dialogs/addon_list.hpp"
#include "gui/dialogs/addon/description.hpp"
#include "gui/dialogs/addon/uninstall_list.hpp"
#include "gui/dialogs/message.hpp"
#include "gui/dialogs/network_transmission.hpp"
#include "gui/dialogs/simple_item_selector.hpp"
@ -357,7 +358,7 @@ namespace {
/**
* Strip the ".cfg" extension and replace "_" with " " for display.
* Strip the ".cfg" extension..
*
* @param files List of files in the add-ons directory.
* @param dirs List of subdirectories in the add-ons directory.
@ -382,7 +383,6 @@ namespace {
break;
}
};
std::replace(i->begin(), i->end(), '_', ' ');
++i;
}
}
@ -391,7 +391,6 @@ namespace {
while(i != dirs.end())
{
if (file_exists(parent_dir + *i + "/_main.cfg")) {
std::replace(i->begin(), i->end(), '_', ' ');
files.push_back(*i);
++i;
} else {
@ -1338,9 +1337,25 @@ namespace {
e.show(disp);
}
}
/** Replaces underscores to dress up file or dirnames as add-on names.
*
* @todo In the future we should store more local information about add-ons and use
* this only as a fallback; it could be desirable to fetch translated names as well
* somehow.
*/
std::string get_addon_name(const std::string& id)
{
std::string retv(id);
std::replace(retv.begin(), retv.end(), '_', ' ');
return retv;
}
void uninstall_local_addons(game_display& disp, bool* should_reload_cfg)
{
static const std::string list_lead = "\n\n";
static const std::string list_sep = "\n";
std::vector<std::string> addons;
std::vector<std::string> addon_dirs;
@ -1360,54 +1375,73 @@ namespace {
int index = -1;
int res;
std::vector<std::string> remove_ids, remove_names;
do {
gui2::tsimple_item_selector dlg(
_("Uninstall add-ons"), _("Choose the add-on to remove."), addons);
dlg.set_selected_index(index);
dlg.set_ok_label(_("Remove"));
gui2::taddon_uninstall_list dlg(addons);
dlg.show(disp.video());
index = dlg.selected_index();
if(index == -1)
remove_ids = dlg.selected_addons();
if(remove_ids.empty()) {
return;
}
remove_names.clear();
foreach(const std::string& id, remove_ids) {
remove_names.push_back(get_addon_name(id));
}
std::string confirm_message = _("Are you sure you want to remove the add-on '$addon|'?");
utils::string_map symbols;
symbols["addon"] = addons.at(static_cast<size_t>(index));
confirm_message = utils::interpolate_variables_into_string(confirm_message, &symbols);
const std::string confirm_message = _n(
"Are you sure you want to remove the following installed add-on?",
"Are you sure you want to remove the following installed add-ons?",
remove_ids.size()) + list_lead + utils::join(remove_names, list_sep);
res = gui2::show_message(disp.video()
, _("Confirm")
, confirm_message
, gui2::tmessage::yes_no_buttons);
} while (res != gui2::twindow::OK);
// Put underscores back in the name
std::string addon_id = addons.at(index);
std::replace(addon_id.begin(), addon_id.end(), ' ', '_');
// Try to remove add-on and report results
std::string removal_log;
if(remove_local_addon(addon_id, &removal_log))
{
std::string message = _("Add-on '$addon|' deleted.");
utils::string_map symbols;
symbols["addon"] = addons.at(index);
message = utils::interpolate_variables_into_string(message, &symbols);
gui2::show_transient_message(disp.video()
, _("Add-on deleted")
, message);
if(should_reload_cfg != NULL)
*should_reload_cfg = true;
std::vector<std::string> failed_names, succeeded_names;
//std::string all_errors;
foreach(const std::string& id, remove_ids) {
std::string errors;
const std::string& name = get_addon_name(id);
//if(remove_local_addon(id, &errors)) {
if(remove_local_addon(id)) {
succeeded_names.push_back(name);
} else {
failed_names.push_back(name);
//all_errors += errors;
}
}
else
{
std::string err_msg = _("Add-on could not be deleted properly:");
err_msg += '\n';
err_msg += removal_log;
gui2::show_error_message(disp.video(), err_msg);
if(!failed_names.empty()) {
gui2::show_error_message(disp.video(), _n(
"The following add-on could not be deleted properly:",
"The following add-ons could not be deleted properly:",
failed_names.size()) + list_lead + utils::join(failed_names, list_sep));
}
if(!succeeded_names.empty()) {
const std::string dlg_title =
_n("Add-on Deleted", "Add-ons Deleted", succeeded_names.size());
const std::string dlg_msg = _n(
"The following add-on was successfully deleted:",
"The following add-ons were successfully deleted:",
succeeded_names.size());
gui2::show_transient_message(
disp.video(), dlg_title,
dlg_msg + list_lead + utils::join(succeeded_names, list_sep));
if(should_reload_cfg != NULL) {
*should_reload_cfg = true;
}
}
}

View file

@ -0,0 +1,100 @@
/* $Id$ */
/*
Copyright (C) 2011 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "gui/dialogs/addon/uninstall_list.hpp"
#include "foreach.hpp"
#include "gui/widgets/grid.hpp"
#ifdef GUI2_EXPERIMENTAL_LISTBOX
#include "gui/widgets/list.hpp"
#else
#include "gui/widgets/listbox.hpp"
#endif
#include "gui/widgets/settings.hpp"
#include "gui/widgets/toggle_button.hpp"
#include "gui/widgets/window.hpp"
#include <algorithm>
namespace {
std::string make_addon_name(const std::string& id)
{
std::string r(id);
std::replace(r.begin(), r.end(), '_', ' ');
return r;
}
}
namespace gui2 {
REGISTER_DIALOG(addon_uninstall_list)
void taddon_uninstall_list::pre_show(CVideo& /*video*/, twindow& window)
{
tlistbox& list = find_widget<tlistbox>(&window, "addons_list", false);
window.keyboard_capture(&list);
this->names_.clear();
this->selections_.clear();
foreach(const std::string& id, this->ids_) {
this->names_.push_back(make_addon_name(id));
this->selections_[id] = false;
std::map<std::string, string_map> data;
string_map column;
column["label"] = this->names_.back();
data.insert(std::make_pair("name", column));
list.add_row(data);
}
}
void taddon_uninstall_list::post_show(twindow& window)
{
const tlistbox& list = find_widget<tlistbox>(&window, "addons_list", false);
const unsigned rows = list.get_item_count();
assert(rows == this->ids_.size() && rows == this->names_.size());
if(!rows || get_retval() != twindow::OK) {
return;
}
for(unsigned k = 0; k < rows; ++k) {
tgrid const* g = list.get_row_grid(k);
const ttoggle_button& checkbox = find_widget<const ttoggle_button>(g, "checkbox", false);
this->selections_[this->ids_[k]] = checkbox.get_value();
}
}
std::vector<std::string> taddon_uninstall_list::selected_addons() const
{
std::vector<std::string> retv;
typedef std::map<std::string, bool> selections_map_type;
foreach(const selections_map_type::value_type& entry, this->selections_) {
if(entry.second) {
retv.push_back(entry.first);
}
}
return retv;
}
} // namespace gui2

View file

@ -0,0 +1,56 @@
/* $Id$ */
/*
Copyright (C) 2011 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef GUI_DIALOGS_ADDON_UNINSTALL_LIST_HPP_INCLUDED
#define GUI_DIALOGS_ADDON_UNINSTALL_LIST_HPP_INCLUDED
#include "gui/dialogs/dialog.hpp"
#include <map>
namespace gui2 {
class taddon_uninstall_list : public tdialog
{
public:
/**
* Constructor.
*
* @param addon_ids The information about the addon to show.
*/
explicit taddon_uninstall_list(const std::vector<std::string>& addon_ids)
: ids_(addon_ids), names_(), selections_() {}
std::vector<std::string> selected_addons() const;
private:
std::vector<std::string> ids_;
std::vector<std::string> names_;
std::map<std::string, bool> selections_;
/** Inherited from tdialog, implemented by REGISTER_DIALOG. */
virtual const std::string& window_id() const;
/** Inherited from tdialog. */
void pre_show(CVideo& video, twindow& window);
/** Inherited from tdialog. */
void post_show(twindow& window);
};
} // namespace gui2
#endif