Greatly extend addon_info struct to store more information...

...about add-ons and teach it to read campaignd's WML responses

This will allow me later to get rid of some vectors that are passed
around a lot between the add-on management UI functions.

Additionally, the static format_file_size() function was moved from
addon/manager.cpp to addon/info.* because addon_info no longer stores
the add-on size display string and a GUI2 codepath needs it. I'm not
quite sure what this function's definitive home will be.
This commit is contained in:
Ignacio R. Morelle 2012-02-22 17:23:48 +00:00
parent 1aefaf6d3f
commit 1550a653ba
6 changed files with 139 additions and 68 deletions

View file

@ -313,6 +313,7 @@ set(wesnoth-main_SRC
about.cpp
actions.cpp
addon/client.cpp
addon/info.cpp
addon/manager.cpp
addon/validation.cpp
ai/actions.cpp

View file

@ -155,6 +155,7 @@ wesnoth_sources = Split("""
about.cpp
actions.cpp
addon/client.cpp
addon/info.cpp
addon/manager.cpp
addon/validation.cpp
ai/actions.cpp

48
src/addon/info.cpp Normal file
View file

@ -0,0 +1,48 @@
/* $Id$ */
/*
Copyright (C) 2012 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 "addon/info.hpp"
#include "foreach.hpp"
#include "gettext.hpp"
#include "serialization/string_utils.hpp"
void addon_info::read(const config& cfg)
{
this->title = cfg["title"].str();
this->description = cfg["description"].str();
this->icon = cfg["icon"].str();
this->version = cfg["version"].str();
this->author = cfg["author"].str();
this->size = cfg["size"];
this->downloads = cfg["downloads"];
this->uploads = cfg["uploads"];
this->type = get_addon_type(cfg["type"].str());
const config::const_child_itors& locales = cfg.child_range("translation");
foreach(const config& locale, locales) {
this->locales.push_back(locale["language"].str());
}
}
std::string size_display_string(double size)
{
if(size > 0.0) {
return utils::si_string(size, true, _("unit_byte^B"));
} else {
return "";
}
}

View file

@ -16,29 +16,76 @@
#ifndef ADDON_INFO_HPP_INCLUDED
#define ADDON_INFO_HPP_INCLUDED
#include <string>
#include <vector>
#include "config.hpp"
#include "version.hpp"
#include "addon/validation.hpp"
struct addon_info
{
std::string title;
std::string description;
std::string icon;
version_info version;
std::string author;
int size;
int downloads;
int uploads;
ADDON_TYPE type;
std::vector<std::string> locales;
addon_info()
: name()
, description()
, icon()
, version()
, author()
, sizestr()
, translations()
: title(), description(), icon()
, version(), author(), size(), downloads()
, uploads(), type(), locales()
{}
addon_info(const addon_info& o)
: title(o.title), description(o.description), icon(o.icon)
, version(o.version), author(o.author), size(o.size)
, downloads(o.downloads), uploads(o.uploads), type(o.type)
, locales(o.locales)
{}
addon_info(const config& cfg)
: title(), description(), icon()
, version(), author(), size(), downloads()
, uploads(), type(), locales()
{
this->read(cfg);
}
std::string name;
std::string description;
std::string icon;
std::string version;
std::string author;
std::string sizestr;
std::vector<std::string> translations;
addon_info& operator=(const addon_info& o) {
if(this != &o) {
this->title = o.title;
this->description = o.description;
this->icon = o.icon;
this->version = o.version;
this->author = o.author;
this->size = o.size;
this->downloads = o.downloads;
this->uploads = o.uploads;
this->type = o.type;
this->locales = o.locales;
}
return *this;
}
void read(const config& cfg);
};
/**
* Get a human-readable representation of the specified byte count.
*
* The result includes the size unit, which is the largest byte multiply
* that makes sense. (e.g. 1 MiB for 1048576 bytes.)
*/
std::string size_display_string(double size);
#endif

View file

@ -342,13 +342,13 @@ namespace {
class display_description : public gui::dialog_button_action
{
display& disp_;
std::vector<addon_info> infov_;
std::vector<addon_info> addons_;
gui::filter_textbox* filter_;
public:
display_description(display& disp, std::vector<addon_info> const& infov, gui::filter_textbox* filter)
display_description(display& disp, std::vector<addon_info> const& addons, gui::filter_textbox* filter)
: disp_(disp)
, infov_(infov)
, addons_(addons)
, filter_(filter)
{}
@ -359,9 +359,9 @@ namespace {
if(menu_selection < 0) { return gui::CONTINUE_DIALOG; }
size_t const uchoice = static_cast<size_t>(menu_selection);
if(uchoice < infov_.size()) {
if(uchoice < addons_.size()) {
gui2::taddon_description::display(
infov_[uchoice]
addons_[uchoice]
, disp_.video());
}
@ -412,21 +412,6 @@ namespace {
}
}
/**
* Creates a more human-readable representation of a file size.
*
* @returns Representation of file size in the biggest byte multiply
* possible.
*/
static std::string format_file_size(double size)
{
if(size > 0.0) {
return utils::si_string(size, true, _("unit_byte^B"));
} else {
return "";
}
}
/**
* Return a short string describing an add-on's type.
*
@ -579,7 +564,7 @@ namespace {
const std::string& type = c["type"];
const std::string& name = c["name"];
int size = c["size"];
std::string sizef = format_file_size(size);
std::string sizef = size_display_string(size);
const std::string& version = remote_version_map[name];
std::string author = c["author"];
@ -780,7 +765,7 @@ namespace {
const std::string& name = c["name"];
int size = c["size"];
std::string sizef = format_file_size(size);
std::string sizef = size_display_string(size);
const std::string& oldver = safe_local_versions[i];
const std::string& newver = remote_version_map[name];
@ -992,6 +977,8 @@ namespace {
return;
}
std::vector<addon_info> parsed_list;
// column contents
std::vector<std::string> addons, titles, versions, uploads, types, options, options_to_filter, descriptions;
std::vector<int> sizes;
@ -1007,29 +994,33 @@ namespace {
std::vector< std::string > delete_options;
std::vector< addon_info > infos;
foreach(const config &c, addon_cfgs)
{
parsed_list.push_back(c);
const std::string& name = c["name"];
// Fix icons in the parsed list itself so
// other codepaths can use the fix. This really
// needs to be hidden through a method of addon_info
// instead.
std::string icon = c["icon"];
do_addon_icon_fixups(icon, name);
parsed_list.back().icon = icon;
const std::string& downloads = c["downloads"].str();
int size = c["size"];
std::string sizef = format_file_size(size);
std::string sizef = size_display_string(size);
const std::string& type_str = c["type"];
const ADDON_TYPE type = get_addon_type(type_str);
const std::string& type_label_str = get_translatable_addon_type(type);
addon_info inf;
inf.sizestr = sizef;
addons.push_back(name);
versions.push_back(c["version"]);
uploads.push_back(c["uploads"]);
descriptions.push_back(c["description"]);
inf.description = c["description"].str();
types.push_back(type_str);
if(std::count(publish_options.begin(), publish_options.end(), name) != 0) {
@ -1043,21 +1034,11 @@ namespace {
}
titles.push_back(title);
inf.name = title;
std::string version = c["version"], author = c["author"];
inf.version = version;
inf.author = author;
//add negative sizes to reverse the sort order
sizes.push_back(-size);
std::string icon = c["icon"];
do_addon_icon_fixups(icon, name);
inf.icon = icon;
std::string text_columns =
title + COLUMN_SEPARATOR +
version + COLUMN_SEPARATOR +
@ -1083,13 +1064,6 @@ namespace {
sizef + COLUMN_SEPARATOR;
options.push_back(text_columns);
config::const_child_itors const& linguas = c.child_range("translation");
for(config::const_child_iterator i = linguas.first; i != linguas.second; ++i) {
inf.translations.push_back((*i)["language"]);
}
infos.push_back(inf);
}
foreach(const std::string& pub, publish_options) {
@ -1134,7 +1108,7 @@ namespace {
_("Filter: "), options, options_to_filter, 1, addon_dialog, 300);
addon_dialog.set_textbox(filter);
display_description description_helper(disp, infos, filter);
display_description description_helper(disp, parsed_list, filter);
gui::dialog_button* description = new gui::dialog_button(disp.video(), _("Description"), gui::button::TYPE_PRESS, gui::CONTINUE_DIALOG, &description_helper);
addon_dialog.add_button(description, gui::dialog::BUTTON_EXTRA);

View file

@ -80,17 +80,17 @@ REGISTER_DIALOG(addon_description)
taddon_description::taddon_description(const addon_info& addon)
{
register_label("image", true, addon.icon);
register_label("title", true, addon.name);
register_label("title", true, addon.title);
register_label("version", true, addon.version);
register_label("author", true, addon.author);
register_label("size", true, addon.sizestr);
register_label("size", true, size_display_string(addon.size));
if(!addon.description.empty()) {
register_label("description", true, addon.description);
}
std::string languages;
foreach(const std::string& lc, addon.translations) {
foreach(const std::string& lc, addon.locales) {
const std::string& langlabel = langcode_to_string(lc);
if(!langlabel.empty()) {
if(!languages.empty()) {