diff --git a/changelog b/changelog index b86fc960bf0b..f81b7ce9fe59 100644 --- a/changelog +++ b/changelog @@ -60,6 +60,10 @@ Version 1.13.0-dev: * Changed: A listbox can now update its size when rows are added. * Changed: Avoid listboxes to handle mouse clicks twice. * Fixed bug #22144: An assertion failure with empty labels in a listbox. + * The :inspect dialog now uses the same function as saved games to generate + WML in text form instead of a simplified version. + * Added a button to copy the currently displayed content from the :inspect + dialog to clipboard. * WML engine: * Added customizable recall costs for unit types and individual units, using the new recall_cost attribute in [unit_type] and [unit]. diff --git a/data/gui/default/window/gamestate_inspector.cfg b/data/gui/default/window/gamestate_inspector.cfg index 44df78989578..c69a78549a70 100644 --- a/data/gui/default/window/gamestate_inspector.cfg +++ b/data/gui/default/window/gamestate_inspector.cfg @@ -204,29 +204,54 @@ [column] grow_factor = 6 - border = "all" - border_size = 5 vertical_alignment = "top" horizontal_alignment = "left" [grid] [row] [column] - # - # Emulate the listbox headers' top/bottom padding - # here relative to the scroll_label below. - # - border = "top,bottom" - border_size = 5 - horizontal_alignment = "left" - [label] - definition = "default" - label = _ "Contents" - [/label] + horizontal_grow = "true" + [grid] + [row] + [column] + # + # Emulate the listbox headers' top/bottom padding + # here relative to the scroll_label below. + # + border = "top,left,right" + border_size = 5 + horizontal_alignment = "left" + + [label] + definition = "default" + label = _ "Contents" + [/label] + [/column] + + [column] + border = "top,left,right" + border_size = 5 + horizontal_alignment = "right" + + [button] + id = "copy" + definition = "action_copy" + label = _ "clipboard^Copy" + # FIXME: tooltips cause weird interactions with map + # labels while running a GUI2 dialog, so let's + # not use a tooltip yet. + #tooltip = _ "Copy this report to clipboard" + [/button] + [/column] + [/row] + [/grid] [/column] [/row] [row] [column] + border = "left,bottom,right" + border_size = 5 horizontal_alignment = "left" + [scroll_label] id = "inspect" definition = "default" diff --git a/src/gui/dialogs/gamestate_inspector.cpp b/src/gui/dialogs/gamestate_inspector.cpp index 0f1711b91bea..2834af1e6eef 100644 --- a/src/gui/dialogs/gamestate_inspector.cpp +++ b/src/gui/dialogs/gamestate_inspector.cpp @@ -26,6 +26,9 @@ #endif #include "gui/widgets/settings.hpp" #include "gui/widgets/window.hpp" + +#include "clipboard.hpp" +#include "serialization/parser.hpp" // for write() #include "utils/foreach.tpp" #include "../../gamestatus.hpp" @@ -37,6 +40,18 @@ #include #include +namespace +{ + +inline std::string config_to_string(const config& cfg) +{ + std::ostringstream s; + write(s, cfg); + return s.str(); +} + +} + namespace gui2 { @@ -59,6 +74,9 @@ namespace gui2 * inspect & & control & m & * The state of the variable or event. $ * + * copy & & button & m & + * A button to copy the state to clipboard. $ + * * @end{table} */ @@ -70,7 +88,7 @@ static void inspect_ai(twindow& window, int side) NEW_find_widget( &window, "inspect", - false).set_label(ai_cfg.debug()); + false).set_label(config_to_string(ai_cfg.debug)); } */ @@ -105,6 +123,7 @@ class tgamestate_inspector::model , stuff_types_list() , inspect() , inspector_name() + , copy_button() { name = cfg["name"].str(); } @@ -116,6 +135,7 @@ class tgamestate_inspector::model tlistbox* stuff_types_list; tcontrol* inspect; tcontrol* inspector_name; + tbutton* copy_button; void clear_stuff_list() @@ -243,7 +263,7 @@ class variable_mode_controller : public single_mode_controller FOREACH(const AUTO & c, vars.all_children_range()) { if(selected == i) { - model_.set_inspect_window_text(c.cfg.debug()); + model_.set_inspect_window_text(config_to_string(c.cfg)); return; } i++; @@ -317,7 +337,9 @@ class unit_mode_controller : public single_mode_controller if(selected == i) { config c_unit; u->write(c_unit); - model_.set_inspect_window_text(c_unit.debug()); + std::ostringstream cfg_str; + write(cfg_str, c_unit); + model_.set_inspect_window_text(cfg_str.str()); return; } i++; @@ -375,7 +397,7 @@ class team_mode_controller : public single_mode_controller : config(); c.clear_children("ai"); c.clear_children("village"); - model_.set_inspect_window_text(c.debug()); + model_.set_inspect_window_text(config_to_string(c)); return; } @@ -387,7 +409,7 @@ class team_mode_controller : public single_mode_controller if(selected == 2) { model_.set_inspect_window_text( - ai::manager::to_config(side_).debug()); + config_to_string(ai::manager::to_config(side_))); return; } @@ -427,7 +449,7 @@ class team_mode_controller : public single_mode_controller u.write(c_unit); c.add_child("unit", c_unit); } - model_.set_inspect_window_text(c.debug()); + model_.set_inspect_window_text(config_to_string(c)); return; } @@ -557,6 +579,11 @@ class tgamestate_inspector::controller c->update_view_from_model(); // TODO: 'activate' } + void handle_copy_button_clicked() + { + copy_to_clipboard(model_.inspect->label(), false); + } + private: model& model_; @@ -590,6 +617,11 @@ class tgamestate_inspector::view controller_.handle_stuff_types_list_item_clicked(); } + void handle_copy_button_clicked(twindow& /*window*/) + { + controller_.handle_copy_button_clicked(); + } + void bind(twindow& window) { @@ -600,6 +632,8 @@ class tgamestate_inspector::view model_.inspect = find_widget(&window, "inspect", false, true); model_.inspector_name = &find_widget(&window, "inspector_name", false); + model_.copy_button + = &find_widget(&window, "copy", false); #ifdef GUI2_EXPERIMENTAL_LISTBOX connect_signal_notify_modified( @@ -627,6 +661,12 @@ class tgamestate_inspector::view &tgamestate_inspector::view:: handle_stuff_types_list_item_clicked>); #endif + + connect_signal_mouse_left_click( + *model_.copy_button, + boost::bind(&tgamestate_inspector::view::handle_copy_button_clicked, + this, + boost::ref(window))); } private: