Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added optional reason to the ignore feature #1

Merged
merged 4 commits into from

5 participants

@fbastani

In multiplayer, this supports players to associate a reason with ignored users that is displayed with the ignored username. Resolves http://wiki.wesnoth.org/EasyCoding#Add_possibility_to_give_reason_for_.22ignore.22.

@mordante
Collaborator

Please post patches at patches.wesnoth.org

@mordante mordante closed this
@soliton- soliton- reopened this
@boucman
Collaborator

I agree with soliton on this one, PR are easier to discuss than patches in the bug database...

@fbastani

Updated to remove unnecessary stripping and the unnecessary why_ignored function. Also there was a problem while rebasing with the merged commits, so the unnecessary merge commit is also gone now apparently.

src/game_preferences.cpp
((6 lines not shown))
if (!utils::isvalid_wildcard(nick)) return false;
- ignores.insert(nick);
- preferences::set("ignores", utils::join(ignores));
+
+ std::string sNick = std::string(nick);
@soliton- Collaborator

Superfluous now, no?

Ok, I updated it to match the coding style.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/game_preferences.cpp
((6 lines not shown))
if (!utils::isvalid_wildcard(nick)) return false;
- ignores.insert(nick);
- preferences::set("ignores", utils::join(ignores));
+
+ std::string sNick = std::string(nick);
+ std::string sReason = std::string(reason);
@soliton- Collaborator

Could be changed to just std::string sReason = reason;

Ah, that's interesting, didn't know that works with the const; actually I just realized since strip is removed I don't need to get a mutable form like that anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@fbastani

Oops, current commit is incorrect.
Edit: updated.

src/menu_events.cpp
((8 lines not shown))
} else {
- for(int i = 1; !get_arg(i).empty(); i++){
- utils::string_map symbols;
- symbols["nick"] = get_arg(i);
- if (preferences::add_ignore(get_arg(i))) {
- print(_("ignores list"), VGETTEXT("Added to ignore list: $nick", symbols));
- chat_handler_.user_relation_changed(get_arg(i));
- } else {
- command_failed(VGETTEXT("Invalid username: $nick", symbols));
- }
+ std::string reason = "";
+
+ for(int i = 2; !get_arg(i).empty(); i++) {
@soliton- Collaborator
soliton- added a note

Here you're removing all whitespace in the reason. Use get_data() instead.

And test your patch on the command line as well. Easiest is to open a multiplayer game and type /ignore .... into the chat field.
Note also how a plain /ignore (which lists current ignores) looks ugly now. I suggest using newlines as separatore there.

@fbastani
fbastani added a note

Ok, I made it show in parentheses in the GUI and with newline/colon separator in the /ignore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@uakfdotb uakfdotb Added optional reason to the ignore feature.
In multiplayer, this supports players to associate a reason with ignored users that is displayed with the ignored username. Resolves http://wiki.wesnoth.org/EasyCoding#Add_possibility_to_give_reason_for_.22ignore.22.
6263e97
@soliton-
Collaborator

Looks like ignores are saved correctly in the preferences file but not read out again properly. When i start wesnoth again the ignore list is empty.

@uakfdotb uakfdotb Improved friends storage system to store "acquaintances" as separate …
…children.

The current attributes are status (either friend or ignore), the nickname, and any attached notes.
d637be4
@soliton-

The todo seems obsolete now.

@soliton-

The replace shouldn't be needed anymore.

@soliton-
Collaborator

Looks much nicer now!

Now that ignore and friend code paths are better unified we should also have user interface symmetry. I.e. allow giving a note when adding a friend. (both in the GUI dialog and via /commands)

On the command line ignores are shown as <nick>:<reason>. 1) There is a space missing. 2) I'd display it as in the GUI as <nick> (<reason>).

@fbastani

Updated the pull request.

@soliton- soliton- merged commit e827728 into from
@shikadilord shikadilord referenced this pull request from a commit
@shikadilord shikadilord preferences: Implement a "combo" advanced preferences entry type
Usage example:

    [advanced_preference]
        field=test_combo
        name= _ "Combo test"
        type=combo
        default=option1
        [option]
            id=option1
            name= _ "Option #1"
        [/option]
        [option]
            id=option2
            name= _ "Option #2"
        [/option]
        [option]
            id=option3
            name= _ "Option #3"
        [/option]
    [/advanced_preference]

NOTE:

Now that there are more than two types of advanced preferences entries,
a problem with the saving and restoring of the previous screen surface
contents with the three GUI1 widgets involved (the checkbox, the combo,
and the slider) has appeared, resulting in the advanced preferences
slider glitching into view under certain conditions. This is apparently
related to the widget hiding/unhiding order; for example,
hiding/unhiding the advanced preferences combobox after the slider and
its label results in the combobox glitching into view when switching the
advanced preferences list selection instead.
db95b23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 2, 2013
  1. @uakfdotb

    Added optional reason to the ignore feature.

    uakfdotb authored
    In multiplayer, this supports players to associate a reason with ignored users that is displayed with the ignored username. Resolves http://wiki.wesnoth.org/EasyCoding#Add_possibility_to_give_reason_for_.22ignore.22.
Commits on May 4, 2013
  1. @uakfdotb

    Improved friends storage system to store "acquaintances" as separate …

    uakfdotb authored
    …children.
    
    The current attributes are status (either friend or ignore), the nickname, and any attached notes.
Commits on May 10, 2013
  1. @uakfdotb
  2. @uakfdotb

    Added notes for friends.

    uakfdotb authored
This page is out of date. Refresh to see the latest.
View
126 src/game_preferences.cpp
@@ -46,11 +46,9 @@ std::set<t_translation::t_terrain> encountered_terrains_set;
std::map<std::string, std::vector<std::string> > history_map;
const unsigned max_history_saved = 50;
-std::set<std::string> friends;
-std::set<std::string> ignores;
+std::map<std::string, preferences::acquaintance> acquaintances;
-bool friends_initialized = false;
-bool ignores_initialized = false;
+bool acquaintances_initialized = false;
std::vector<std::string> mp_modifications;
bool modifications_initialized = false;
@@ -187,73 +185,101 @@ void parse_admin_authentication(const std::string& sender, const std::string& me
}
}
-static void initialize_friends() {
- if(!friends_initialized) {
- std::vector<std::string> names = utils::split(preferences::get("friends"));
- std::set<std::string> tmp(names.begin(), names.end());
- friends.swap(tmp);
+void load_acquaintances() {
+ if(!acquaintances_initialized) {
+ acquaintances.clear();
+ BOOST_FOREACH(const config &acfg, preferences::get_prefs()->child_range("acquaintance")) {
+ acquaintance ac = acquaintance(acfg);
+ acquaintances[ac.get_nick()] = ac;
+ }
+ }
+}
- friends_initialized = true;
+void save_acquaintances()
+{
+ config *cfg = preferences::get_prefs();
+ cfg->clear_children("acquaintance");
+
+ for(std::map<std::string, acquaintance>::iterator i = acquaintances.begin();
+ i != acquaintances.end(); ++i)
+ {
+ config& item = cfg->add_child("acquaintance");
+ i->second.save(item);
}
}
-const std::set<std::string> & get_friends() {
- initialize_friends();
- return friends;
+const std::map<std::string, acquaintance> & get_acquaintances() {
+ load_acquaintances();
+ return acquaintances;
}
-static void initialize_ignores() {
- if(!ignores_initialized) {
- std::vector<std::string> names = utils::split(preferences::get("ignores"));
- std::set<std::string> tmp(names.begin(), names.end());
- ignores.swap(tmp);
+//returns acquaintances in the form nick => notes where the status = filter
+std::map<std::string, std::string> get_acquaintances_nice(const std::string& filter) {
+ load_acquaintances();
+ std::map<std::string, std::string> ac_nice;
- ignores_initialized = true;
+ for(std::map<std::string, acquaintance>::iterator i = acquaintances.begin(); i != acquaintances.end(); ++i)
+ {
+ if(i->second.get_status() == filter) {
+ ac_nice[i->second.get_nick()] = i->second.get_notes();
+ }
}
-}
-const std::set<std::string> & get_ignores() {
- return ignores;
+ return ac_nice;
}
-bool add_friend(const std::string& nick) {
+bool add_friend(const std::string& nick, const std::string& notes) {
if (!utils::isvalid_wildcard(nick)) return false;
- friends.insert(nick);
- preferences::set("friends", utils::join(friends));
+ acquaintances[nick] = preferences::acquaintance(nick, "friend", notes);
+ save_acquaintances();
return true;
}
-bool add_ignore(const std::string& nick) {
+bool add_ignore(const std::string& nick, const std::string& reason) {
if (!utils::isvalid_wildcard(nick)) return false;
- ignores.insert(nick);
- preferences::set("ignores", utils::join(ignores));
+ acquaintances[nick] = preferences::acquaintance(nick, "ignore", reason);
+ save_acquaintances();
return true;
}
-void remove_friend(const std::string& nick) {
- std::set<std::string>::iterator i = friends.find(nick);
- if(i != friends.end()) {
- friends.erase(i);
- preferences::set("friends", utils::join(friends));
+void remove_acquaintance(const std::string& nick) {
+ std::map<std::string, acquaintance>::iterator i = acquaintances.find(nick);
+
+ //nick might include the notes, depending on how we're removing
+ if(i == acquaintances.end()) {
+ size_t pos = nick.find_first_of(' ');
+
+ if(pos != std::string::npos) {
+ i = acquaintances.find(nick.substr(0, pos));
+ }
}
-}
-void remove_ignore(const std::string& nick) {
- std::set<std::string>::iterator i = ignores.find(nick);
- if(i != ignores.end()) {
- ignores.erase(i);
- preferences::set("ignores", utils::join(ignores));
+ if(i != acquaintances.end()) {
+ acquaintances.erase(i);
+ save_acquaintances();
}
}
bool is_friend(const std::string& nick) {
- initialize_friends();
- return friends.find(nick) != friends.end();
+ load_acquaintances();
+ std::map<std::string, acquaintance>::iterator it = acquaintances.find(nick);
+
+ if(it == acquaintances.end()) {
+ return false;
+ } else {
+ return it->second.get_status() == "friend";
+ }
}
bool is_ignored(const std::string& nick) {
- initialize_ignores();
- return ignores.find(nick) != ignores.end();
+ load_acquaintances();
+ std::map<std::string, acquaintance>::iterator it = acquaintances.find(nick);
+
+ if(it == acquaintances.end()) {
+ return false;
+ } else {
+ return it->second.get_status() == "ignore";
+ }
}
void add_completed_campaign(const std::string& campaign_id) {
@@ -1022,4 +1048,18 @@ void encounter_map_terrain(gamemap& map){
}
}
+void acquaintance::load_from_config(const config& cfg)
+{
+ nick_ = cfg["nick"].str();
+ status_ = cfg["status"].str();
+ notes_ = cfg["notes"].str();
+}
+
+void acquaintance::save(config& item)
+{
+ item["nick"] = nick_;
+ item["status"] = status_;
+ item["notes"] = notes_;
+}
+
} // preferences namespace
View
52 src/game_preferences.hpp
@@ -26,6 +26,8 @@ class unit_map;
namespace preferences {
+class acquaintance;
+
struct manager
{
manager();
@@ -44,13 +46,12 @@ namespace preferences {
bool new_lobby();
- const std::set<std::string> & get_friends();
- const std::set<std::string> & get_ignores();
- bool add_friend(const std::string& nick);
- bool add_ignore(const std::string& nick);
+ const std::map<std::string, acquaintance> & get_acquaintances();
+ std::map<std::string, std::string> get_acquaintances_nice(const std::string& filter);
+ bool add_friend(const std::string& nick, const std::string& notes);
+ bool add_ignore(const std::string& nick, const std::string& reason);
void add_completed_campaign(const std::string& campaign_id);
- void remove_friend(const std::string& nick);
- void remove_ignore(const std::string& nick);
+ void remove_acquaintance(const std::string& nick);
bool is_friend(const std::string& nick);
bool is_ignored(const std::string& nick);
bool is_campaign_completed(const std::string& campaign_id);
@@ -263,6 +264,45 @@ namespace preferences {
// Add all terrains on the map as encountered terrains.
void encounter_map_terrain(gamemap& map);
+class acquaintance {
+public:
+
+ explicit acquaintance()
+ {
+ }
+
+ explicit acquaintance(const config& cfg)
+ {
+ load_from_config(cfg);
+ }
+
+ explicit acquaintance(const std::string &nick, const std::string status, const std::string notes):
+ nick_(nick), status_(status), notes_(notes)
+ {
+
+ }
+
+ void load_from_config(const config& cfg);
+
+ const std::string get_nick() const { return nick_; };
+ const std::string get_status() const { return status_; };
+ const std::string get_notes() const { return notes_; };
+
+ void save(config& cfg);
+
+protected:
+
+ // acquaintance's MP nick
+ std::string nick_;
+
+ // status (e.g., "friend", "ignore")
+ std::string status_;
+
+ // notes on the acquaintance
+ std::string notes_;
+
+};
+
}
#endif
View
65 src/game_preferences_display.cpp
@@ -389,8 +389,8 @@ preferences_dialog::preferences_dialog(display& disp, const config& game_cfg)
mp_server_search_button_.set_help_string(_("Find and set path to MP server to host LAN games"));
friends_list_button_.set_help_string(_("View and edit your friends and ignores list"));
friends_back_button_.set_help_string(_("Back to the multiplayer options"));
- friends_add_friend_button_.set_help_string(_("Add this username to your friends list"));
- friends_add_ignore_button_.set_help_string(_("Add this username to your ignores list"));
+ friends_add_friend_button_.set_help_string(_("Add this username to your friends list (add optional notes, e.g., 'player_name notes on friend')"));
+ friends_add_ignore_button_.set_help_string(_("Add this username to your ignores list (add optional reason, e.g., 'player_name reason ignored')"));
friends_remove_button_.set_help_string(_("Remove this username from your list"));
friends_input_.set_text("");
@@ -953,15 +953,33 @@ void preferences_dialog::process_event()
set_selection(MULTIPLAYER_TAB);
if (friends_add_friend_button_.pressed()) {
- if (preferences::add_friend(friends_input_.text())) {
+ std::string notes = "";
+ std::string username = friends_input_.text();
+ size_t pos = username.find_first_of(' ');
+
+ if(pos != std::string::npos) {
+ notes = username.substr(pos + 1);
+ username = username.substr(0, pos);
+ }
+
+ if (preferences::add_friend(username, notes)) {
friends_input_.clear();
set_friends_menu();
} else {
gui2::show_transient_error_message(disp_.video(), _("Invalid username"));
- }
- }
+ }
+ }
if (friends_add_ignore_button_.pressed()) {
- if (preferences::add_ignore(friends_input_.text())) {
+ std::string reason = "";
+ std::string username = friends_input_.text();
+ size_t pos = username.find_first_of(' ');
+
+ if(pos != std::string::npos) {
+ reason = username.substr(pos + 1);
+ username = username.substr(0, pos);
+ }
+
+ if (preferences::add_ignore(username, reason)) {
friends_input_.clear();
set_friends_menu();
} else {
@@ -975,8 +993,7 @@ void preferences_dialog::process_event()
}
if(!to_remove.empty()) {
/** @todo Better to remove from a specific relation. */
- preferences::remove_friend(to_remove);
- preferences::remove_ignore(to_remove);
+ preferences::remove_acquaintance(to_remove);
friends_input_.clear();
set_friends_menu();
}
@@ -1093,25 +1110,31 @@ void preferences_dialog::sort_advanced_preferences()
void preferences_dialog::set_friends_menu()
{
- const std::set<std::string>& friends = preferences::get_friends();
- const std::set<std::string>& ignores = preferences::get_ignores();
+ const std::map<std::string, acquaintance>& acquaintances = preferences::get_acquaintances();
std::vector<std::string> friends_items;
std::vector<std::string> friends_names;
std::string const imgpre = IMAGE_PREFIX + std::string("misc/status-");
- std::set<std::string>::const_iterator i;
- for (i = friends.begin(); i != friends.end(); ++i)
- {
- friends_items.push_back(imgpre + "friend.png" + COLUMN_SEPARATOR
- + *i + COLUMN_SEPARATOR + _("friend"));
- friends_names.push_back(*i);
- }
- for (i = ignores.begin(); i != ignores.end(); ++i)
+ for (std::map<std::string, acquaintance>::const_iterator i = acquaintances.begin(); i != acquaintances.end(); ++i)
{
- friends_items.push_back(imgpre + "ignore.png" + COLUMN_SEPARATOR
- + *i + COLUMN_SEPARATOR + _("ignored"));
- friends_names.push_back(*i);
+ std::string image = "friend.png";
+ std::string descriptor = _("friend");
+
+ if(i->second.get_status() == "ignore") {
+ image = "ignore.png";
+ descriptor = _("ignored");
+ }
+
+ std::string notes;
+
+ if(!i->second.get_notes().empty()) {
+ notes = " (" + i->second.get_notes() + ")";
+ }
+
+ friends_items.push_back(imgpre + image + COLUMN_SEPARATOR
+ + i->second.get_nick() + notes + COLUMN_SEPARATOR + descriptor);
+ friends_names.push_back(i->first);
}
if (friends_items.empty()) {
friends_items.push_back(_("(empty list)"));
View
15 src/gui/dialogs/chat_log.cpp
@@ -90,21 +90,12 @@ class tchat_log::model {
msg_label->set_label("");
}
- std::string replace(std::string str, const std::string &src, const std::string &dst)
- {
- std::string::size_type pos = 0;
- while ( (pos = str.find(src, pos)) != std::string::npos ) {
- str.replace( pos, src.size(), dst );
- pos++;
- }
- return str;
- }
std::string escape(const std::string &str)
{
// need pango escape here
- std::string result = replace(str,"&","&amp;");
- result = replace(result,"<","&lt;");
- result = replace(result,">","&gt;");
+ std::string result = utils::replace(str, "&", "&amp;");
+ result = utils::replace(result, "<", "&lt;");
+ result = utils::replace(result, ">", "&gt;");
return result;
}
View
7 src/gui/dialogs/lobby_player_info.cpp
@@ -151,22 +151,21 @@ void tlobby_player_info::update_relation(twindow& w)
void tlobby_player_info::add_to_friends_button_callback(twindow& w)
{
- preferences::add_friend(info_.name);
+ preferences::add_friend(info_.name, "");
info_.relation = user_info::FRIEND;
update_relation(w);
}
void tlobby_player_info::add_to_ignores_button_callback(twindow& w)
{
- preferences::add_ignore(info_.name);
+ preferences::add_ignore(info_.name, "");
info_.relation = user_info::IGNORED;
update_relation(w);
}
void tlobby_player_info::remove_from_list_button_callback(twindow& w)
{
- preferences::remove_friend(info_.name);
- preferences::remove_ignore(info_.name);
+ preferences::remove_acquaintance(info_.name);
info_.relation = user_info::NEUTRAL;
update_relation(w);
}
View
56 src/menu_events.cpp
@@ -2409,18 +2409,18 @@ void chat_command_handler::do_log()
void chat_command_handler::do_ignore()
{
if (get_arg(1).empty()) {
- const std::set<std::string>& tmp = preferences::get_ignores();
- print(_("ignores list"), tmp.empty() ? _("(empty)") : utils::join(tmp));
+ const std::map<std::string, std::string>& tmp = preferences::get_acquaintances_nice("ignore");
+ print(_("ignores list"), tmp.empty() ? _("(empty)") : utils::join_map(tmp, ")\n", " (") + ")");
} else {
- for(int i = 1; !get_arg(i).empty(); i++){
- utils::string_map symbols;
- symbols["nick"] = get_arg(i);
- if (preferences::add_ignore(get_arg(i))) {
- print(_("ignores list"), VGETTEXT("Added to ignore list: $nick", symbols));
- chat_handler_.user_relation_changed(get_arg(i));
- } else {
- command_failed(VGETTEXT("Invalid username: $nick", symbols));
- }
+ std::string reason = get_data(2);
+ utils::string_map symbols;
+ symbols["nick"] = get_arg(1);
+
+ if (preferences::add_ignore(get_arg(1), reason)) {
+ print(_("ignores list"), VGETTEXT("Added to ignore list: $nick", symbols));
+ chat_handler_.user_relation_changed(get_arg(1));
+ } else {
+ command_failed(VGETTEXT("Invalid username: $nick", symbols));
}
}
}
@@ -2428,18 +2428,18 @@ void chat_command_handler::do_ignore()
void chat_command_handler::do_friend()
{
if (get_arg(1).empty()) {
- const std::set<std::string>& tmp = preferences::get_friends();
- print(_("friends list"), tmp.empty() ? _("(empty)") : utils::join(tmp));
+ const std::map<std::string, std::string>& tmp = preferences::get_acquaintances_nice("friend");
+ print(_("friends list"), tmp.empty() ? _("(empty)") : utils::join_map(tmp, ")\n", " (") + ")");
} else {
- for(int i = 1;!get_arg(i).empty();i++){
- utils::string_map symbols;
- symbols["nick"] = get_arg(i);
- if (preferences::add_friend(get_arg(i))) {
- chat_handler_.user_relation_changed(get_arg(i));
- print(_("friends list"), VGETTEXT("Added to friends list: $nick", symbols));
- } else {
- command_failed(VGETTEXT("Invalid username: $nick", symbols));
- }
+ std::string notes = get_data(2);
+ utils::string_map symbols;
+ symbols["nick"] = get_arg(1);
+
+ if (preferences::add_friend(get_arg(1), notes)) {
+ print(_("friends list"), VGETTEXT("Added to friends list: $nick", symbols));
+ chat_handler_.user_relation_changed(get_arg(1));
+ } else {
+ command_failed(VGETTEXT("Invalid username: $nick", symbols));
}
}
}
@@ -2447,8 +2447,7 @@ void chat_command_handler::do_friend()
void chat_command_handler::do_remove()
{
for(int i = 1;!get_arg(i).empty();i++){
- preferences::remove_friend(get_arg(i));
- preferences::remove_ignore(get_arg(i));
+ preferences::remove_acquaintance(get_arg(i));
chat_handler_.user_relation_changed(get_arg(i));
utils::string_map symbols;
symbols["nick"] = get_arg(i);
@@ -2458,15 +2457,15 @@ void chat_command_handler::do_remove()
void chat_command_handler::do_display()
{
- const std::set<std::string> & friends = preferences::get_friends();
- const std::set<std::string> & ignores = preferences::get_ignores();
+ const std::map<std::string, std::string>& friends = preferences::get_acquaintances_nice("friend");
+ const std::map<std::string, std::string>& ignores = preferences::get_acquaintances_nice("ignore");
if (!friends.empty()) {
- print(_("friends list"), utils::join(friends));
+ print(_("friends list"), utils::join_map(friends, ")\n", " (") + ")");
}
if (!ignores.empty()) {
- print(_("ignores list"), utils::join(ignores));
+ print(_("ignores list"), utils::join_map(ignores, ")\n", " (") + ")");
}
if (friends.empty() && ignores.empty()) {
@@ -3292,4 +3291,3 @@ void menu_handler::change_side_controller(const std::string& side, const std::st
network::send_data(cfg, 0);
}
} // end namespace events
-
View
46 src/serialization/string_utils.cpp
@@ -65,6 +65,16 @@ bool notspace(const char c)
return !portable_isspace(c);
}
+std::string replace(std::string str, const std::string &src, const std::string &dst)
+{
+ std::string::size_type pos = 0;
+ while ( (pos = str.find(src, pos)) != std::string::npos ) {
+ str.replace( pos, src.size(), dst );
+ pos++;
+ }
+ return str;
+}
+
std::string &strip(std::string &str)
{
// If all the string contains is whitespace,
@@ -97,7 +107,7 @@ std::vector< std::string > split(std::string const &val, const char c, const int
++i1;
}
i2=i1;
-
+
while (i2 != val.end()) {
if (*i2 == c) {
std::string new_val(i1, i2);
@@ -151,7 +161,7 @@ std::vector< std::string > square_parenthetical_split(std::string const &val,
j1=i1;
if (i1 == val.end()) return res;
-
+
if (!separator) {
ERR_GENERAL << "Separator must be specified for square bracket split funtion.\n";
return res;
@@ -220,7 +230,7 @@ std::vector< std::string > square_parenthetical_split(std::string const &val,
}
size_square_exp = square_expansion.size();
}
-
+
//combine square contents and rest of string for comma zone block
size_t j = 0;
size_t j_max = 0;
@@ -245,7 +255,7 @@ std::vector< std::string > square_parenthetical_split(std::string const &val,
res.push_back(new_val);
j++;
} while (j<j_max);
-
+
if (i2 == val.end()) //escape loop
break;
++i2;
@@ -291,6 +301,32 @@ std::vector< std::string > square_parenthetical_split(std::string const &val,
return res;
}
+std::map< std::string, std::string > map_split(std::string const &val, char major, char minor, int flags, std::string const default_value)
+{
+ //first split by major so that we get a vector with the key-value pairs
+ std::vector< std::string > v = split(val, major, flags);
+
+ //now split by minor to extract keys and values
+ std::map< std::string, std::string > res;
+
+ for( std::vector< std::string >::iterator i = v.begin(); i != v.end(); ++i) {
+ size_t pos = i->find_first_of(minor);
+ std::string key, value;
+
+ if(pos == std::string::npos) {
+ key = (*i);
+ value = default_value;
+ } else {
+ key = i->substr(0, pos);
+ value = i->substr(pos + 1);
+ }
+
+ res[key] = value;
+ }
+
+ return res;
+}
+
std::vector< std::string > parenthetical_split(std::string const &val,
const char separator, std::string const &left,
std::string const &right,const int flags)
@@ -309,7 +345,7 @@ std::vector< std::string > parenthetical_split(std::string const &val,
++i1;
}
i2=i1;
-
+
if(left.size()!=right.size()){
ERR_GENERAL << "Left and Right Parenthesis lists not same length\n";
return res;
View
30 src/serialization/string_utils.hpp
@@ -55,6 +55,18 @@ enum { REMOVE_EMPTY = 0x01, /**< REMOVE_EMPTY : remove empty elements. */
std::vector< std::string > split(std::string const &val, const char c = ',', const int flags = REMOVE_EMPTY | STRIP_SPACES);
/**
+ * Splits a string based on two separators into a map.
+ * major: the separator between elements of the map
+ * minor: the separator between keys and values in one element
+ *
+ * For example, the string 'a:b,c:d,e:f' would be parsed into:
+ * a => b
+ * c => d
+ * e => f
+*/
+std::map< std::string, std::string > map_split(std::string const &val, char major = ',', char minor = ':', int flags = REMOVE_EMPTY | STRIP_SPACES, std::string const default_value = "");
+
+/**
* Splits a string based either on a separator where text within parenthesis
* is protected from splitting (Note that one can use the same character for
* both the left and right parenthesis. In this mode it usually makes only
@@ -84,7 +96,7 @@ std::vector< std::string > parenthetical_split(std::string const &val,
* must match in each section.
* Leading zeros are preserved if specified between square brackets.
* An asterisk as in [a*n] indicates to expand 'a' n times
- *
+ *
* This is useful to expand animation WML code.
* Examples:
* square_parenthetical_split("a[1-3](1,[5,6,7]),b[8,9]",",") should return
@@ -123,6 +135,19 @@ std::string join(T const &v, const std::string& s = ",")
return str.str();
}
+template <typename T>
+std::string join_map(T const &v, std::string major = ",", std::string minor = ":")
+{
+ std::stringstream str;
+ for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
+ str << i->first << minor << i->second;
+ if (boost::next(i) != v.end())
+ str << major;
+ }
+
+ return str.str();
+}
+
/**
* Generates a new string containing a bullet list.
*
@@ -184,6 +209,9 @@ inline std::string escape(const std::string &str)
/** Remove all escape characters (backslash) */
std::string unescape(const std::string &str);
+/** Replace all instances of src in str with dst */
+std::string replace(std::string str, const std::string &src, const std::string &dst);
+
/** Remove whitespace from the front and back of the string 'str'. */
std::string &strip(std::string &str);
Something went wrong with that request. Please try again.