Freeciv-3.2
Loading...
Searching...
No Matches
editprop.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <limits.h> /* USHRT_MAX */
19
20#include <gtk/gtk.h>
21#include <gdk/gdkkeysyms.h>
22
23/* utility */
24#include "bitvector.h"
25#include "fc_cmdline.h"
26#include "fcintl.h"
27#include "log.h"
28#include "mem.h"
29
30/* common */
31#include "fc_interface.h"
32#include "game.h"
33#include "government.h"
34#include "map.h"
35#include "movement.h"
36#include "nation.h"
37#include "research.h"
38#include "tile.h"
39
40/* client */
41#include "client_main.h"
42#include "climisc.h"
43#include "editor.h"
44#include "mapview_common.h"
45#include "tilespec.h"
46
47/* client/gui-gtk-3.22 */
48#include "canvas.h"
49#include "gui_main.h"
50#include "gui_stuff.h"
51#include "plrdlg.h"
52#include "sprite.h"
53
54#include "editprop.h"
55
56
57/* Forward declarations. */
58struct objprop;
59struct objbind;
60struct property_page;
61struct property_editor;
62struct extviewer;
63
64/****************************************************************************
65 Miscellaneous helpers.
66****************************************************************************/
67static GdkPixbuf *create_pixbuf_from_layers(const struct tile *ptile,
68 const struct unit *punit,
69 const struct city *pcity,
70 enum layer_category category);
71static GdkPixbuf *create_tile_pixbuf(const struct tile *ptile);
72static GdkPixbuf *create_unit_pixbuf(const struct unit *punit);
73static GdkPixbuf *create_city_pixbuf(const struct city *pcity);
74
75static void add_column(GtkWidget *view,
76 int col_id,
77 const char *name,
79 bool editable,
80 bool is_radio,
83
84static bool can_create_unit_at_tile(struct tile *ptile);
85
86static int get_next_unique_tag(void);
87
88/* 'struct stored_tag_hash' and related functions. */
89#define SPECHASH_TAG stored_tag
90#define SPECHASH_INT_KEY_TYPE
91#define SPECHASH_INT_DATA_TYPE
92#include "spechash.h"
93
94/* NB: If packet definitions change, be sure to
95 * update objbind_pack_current_values()!!! */
111
112/* Helpers for the OPID_TILE_VISION property. */
116const char *vision_layer_get_name(enum vision_layer);
117
118#define PF_MAX_CLAUSES 16
119#define PF_DISJUNCTION_SEPARATOR "|"
120#define PF_CONJUNCTION_SEPARATOR "&"
121
123 bool negate;
124 char *text;
125};
126
131
136
137static struct property_filter *property_filter_new(const char *filter);
138static bool property_filter_match(struct property_filter *pf,
139 const struct objprop *op);
140static void property_filter_free(struct property_filter *pf);
141
142
143/****************************************************************************
144 Object type declarations.
145
146 To add a new object type:
147 1. Add a value in enum editor_object_type in client/editor.h.
148 2. Add a string name to objtype_get_name.
149 3. Add code in objtype_get_id_from_object.
150 4. Add code in objtype_get_object_from_id.
151 5. Add a case handler in objtype_is_conserved, and if
152 the object type is not conserved, then also in
153 objbind_request_destroy_object and property_page_create_objects.
154 6. Add an if-block in objbind_get_value_from_object.
155 7. Add an if-block in objbind_get_allowed_value_span.
156 9. Add a case handler in property_page_setup_objprops.
157 10. Add a case handler in property_page_add_objbinds_from_tile
158 if applicable.
159
160 Furthermore, if the object type is to be editable:
161 11. Define its edit packet in common/networking/packets.def.
162 12. Add the packet handler in server/edithand.c.
163 13. Add its edit packet type to union packetdata.
164 14. Add an if-block in objbind_pack_current_values.
165 15. Add an if-block in objbind_pack_modified_value.
166 16. Add code in property_page_new_packet.
167 17. Add code in property_page_send_packet.
168 18. Add calls to editgui_notify_object_changed in
169 client/packhand.c or where applicable.
170
171****************************************************************************/
172
173/* OBJTYPE_* enum values defined in client/editor.h */
174
175static const char *objtype_get_name(enum editor_object_type objtype);
177 gpointer object);
179 int id);
181
182
183/****************************************************************************
184 Value type declarations.
185
186 To add a new value type:
187 1. Add a value in enum value_types.
188 2. Add its field in union propval_data.
189 3. Add a case handler in valtype_get_name.
190 4. Add a case handler in propval_copy if needed.
191 5. Add a case handler in propval_free if needed.
192 6. Add a case handler in propval_equal if needed.
193 7. Add a case handler in objprop_get_gtype.
194 8. Add a case handler in property_page_set_store_value.
195 9. Add a case handler in propval_as_string if needed.
196****************************************************************************/
213
214static const char *valtype_get_name(enum value_types valtype);
215
216
217/****************************************************************************
218 Propstate and propval declarations.
219
220 To add a new member to union propval_data, see the steps for adding a
221 new value type above.
222
223 New property values are "constructed" by objbind_get_value_from_object().
224****************************************************************************/
242
248
249static void propval_free(struct propval *pv);
250static void propval_free_data(struct propval *pv);
251static struct propval *propval_copy(struct propval *pv);
252static bool propval_equal(struct propval *pva, struct propval *pvb);
253
258
259static struct propstate *propstate_new(struct objprop *op,
260 struct propval *pv);
261static void propstate_destroy(struct propstate *ps);
262static void propstate_clear_value(struct propstate *ps);
263static void propstate_set_value(struct propstate *ps,
264 struct propval *pv);
265static struct propval *propstate_get_value(struct propstate *ps);
266
267#define SPECHASH_TAG propstate
268#define SPECHASH_INT_KEY_TYPE
269#define SPECHASH_IDATA_TYPE struct propstate *
270#define SPECHASH_IDATA_FREE propstate_destroy
271#include "spechash.h"
272
273
274/****************************************************************************
275 Objprop declarations.
276
277 To add a new object property:
278 1. Add a value in enum object_property_ids (grouped by
279 object type).
280 2. Define the property in property_page_setup_objprops.
281 3. Add a case handler in objbind_get_value_from_object
282 in the appropriate object type block.
283 4. Add a case handler in objprop_setup_widget.
284 5. Add a case handler in objprop_refresh_widget.
285
286 Furthermore, if the property is editable:
287 5. Add a field for this property in the edit
288 packet for this object type in common/networking/packets.def.
289 6. Add a case handler in objbind_pack_modified_value.
290 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
291 !!! 7. Add code to set the packet field in !!!
292 !!! objbind_pack_current_values(). !!!
293 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
294 8. Add code to handle changes in the packet field in
295 server/edithand.c handle_edit_<objtype>.
296
297 If the property makes use of an extviewer:
298 9. Handle widget creation in extviewer_new.
299 10. Handle refresh in extviewer_refresh_widgets.
300 11. Handle clear in extviewer_clear_widgets.
301 12. Handle any signal callbacks (e.g. toggled) if needed.
302
303 TODO: Add more object properties.
304****************************************************************************/
312#ifdef FREECIV_DEBUG
314#endif /* FREECIV_DEBUG */
322 OPID_TILE_VISION, /* tile_known and tile_seen */
324
329
331#ifdef FREECIV_DEBUG
333#endif /* FREECIV_DEBUG */
344
347#ifdef FREECIV_DEBUG
349#endif /* FREECIV_DEBUG */
357
362#ifdef FREECIV_DEBUG
364#endif /* FREECIV_DEBUG */
370
382
389
402
403static struct objprop *objprop_new(int id,
404 const char *name,
405 const char *tooltip,
407 enum value_types valtype,
408 struct property_page *parent);
409static int objprop_get_id(const struct objprop *op);
410static const char *objprop_get_name(const struct objprop *op);
411static const char *objprop_get_tooltip(const struct objprop *op);
412static enum value_types objprop_get_valtype(const struct objprop *op);
413static struct property_page *
415
416static bool objprop_show_in_listview(const struct objprop *op);
417static bool objprop_is_sortable(const struct objprop *op);
418static bool objprop_is_readonly(const struct objprop *op);
419static bool objprop_has_widget(const struct objprop *op);
420
421static GType objprop_get_gtype(const struct objprop *op);
422static const char *objprop_get_attribute_type_string(const struct objprop *op);
423static void objprop_set_column_id(struct objprop *op, int col_id);
424static int objprop_get_column_id(const struct objprop *op);
425static void objprop_set_treeview_column(struct objprop *op,
429
430static void objprop_setup_widget(struct objprop *op);
431static GtkWidget *objprop_get_widget(struct objprop *op);
432static void objprop_set_child_widget(struct objprop *op,
433 const char *widget_name,
436 const char *widget_name);
437static void objprop_set_extviewer(struct objprop *op,
438 struct extviewer *ev);
439static struct extviewer *objprop_get_extviewer(struct objprop *op);
440static void objprop_refresh_widget(struct objprop *op,
441 struct objbind *ob);
447
448#define SPECHASH_TAG objprop
449#define SPECHASH_INT_KEY_TYPE
450#define SPECHASH_IDATA_TYPE struct objprop *
451#include "spechash.h"
452
453
454/****************************************************************************
455 Objbind declarations.
456****************************************************************************/
464
466 gpointer object);
467static void objbind_destroy(struct objbind *ob);
468static enum editor_object_type objbind_get_objtype(const struct objbind *ob);
469static void objbind_bind_properties(struct objbind *ob,
470 struct property_page *pp);
471static gpointer objbind_get_object(struct objbind *ob);
472static int objbind_get_object_id(struct objbind *ob);
473static void objbind_request_destroy_object(struct objbind *ob);
474static struct propval *objbind_get_value_from_object(struct objbind *ob,
475 struct objprop *op);
476static bool objbind_get_allowed_value_span(struct objbind *ob,
477 struct objprop *op,
478 double *pmin,
479 double *pmax,
480 double *pstep,
481 double *pbig_step);
482static bool objbind_set_modified_value(struct objbind *ob,
483 struct objprop *op,
484 struct propval *pv);
485static struct propval *objbind_get_modified_value(struct objbind *ob,
486 struct objprop *op);
487static void objbind_clear_modified_value(struct objbind *ob,
488 struct objprop *op);
489static bool objbind_property_is_modified(struct objbind *ob,
490 struct objprop *op);
491static bool objbind_has_modified_properties(struct objbind *ob);
492static void objbind_clear_all_modified_values(struct objbind *ob);
493static void objbind_pack_current_values(struct objbind *ob,
494 union packetdata packet);
495static void objbind_pack_modified_value(struct objbind *ob,
496 struct objprop *op,
497 union packetdata packet);
498static void objbind_set_rowref(struct objbind *ob,
501
502#define SPECHASH_TAG objbind
503#define SPECHASH_INT_KEY_TYPE
504#define SPECHASH_IDATA_TYPE struct objbind *
505#define SPECHASH_IDATA_FREE objbind_destroy
506#include "spechash.h"
507
508
509/****************************************************************************
510 Extended property viewer declarations. This is a set of widgets used
511 for viewing and/or editing properties with complex values (e.g. arrays).
512****************************************************************************/
528
529static struct extviewer *extviewer_new(struct objprop *op);
530static struct objprop *extviewer_get_objprop(struct extviewer *ev);
533static void extviewer_refresh_widgets(struct extviewer *ev,
534 struct propval *pv);
535static void extviewer_clear_widgets(struct extviewer *ev);
536static void extviewer_panel_button_clicked(GtkButton *button,
539 gchar *path,
541static void extviewer_textbuf_changed(GtkTextBuffer *textbuf,
543
544
545/****************************************************************************
546 Property page declarations.
547****************************************************************************/
564
565static struct property_page *
567 struct property_editor *parent);
569static const char *property_page_get_name(const struct property_page *pp);
570static enum editor_object_type
572static void property_page_load_tiles(struct property_page *pp,
573 const struct tile_list *tiles);
575 const struct tile *ptile);
576static int property_page_get_num_objbinds(const struct property_page *pp);
578static void property_page_add_objbind(struct property_page *pp,
580static void property_page_fill_widgets(struct property_page *pp);
581static struct objbind *
584 struct objbind *ob);
586 int object_id);
590 GtkTreeModel *model,
591 GtkTreePath *path,
593 gpointer data);
597 struct objprop *op,
598 struct propval *pv);
599static void property_page_send_values(struct property_page *pp);
603 struct tile_list *hint_tiles);
605static void property_page_send_packet(struct property_page *pp,
606 union packetdata packet);
607static void property_page_free_packet(struct property_page *pp,
608 union packetdata packet);
610 int object_id,
611 bool remove);
613 int tag, int object_id);
615 struct extviewer *ev);
617 struct extviewer *ev);
619 int tag, int count);
621 int tag);
622static bool property_page_tag_is_known(struct property_page *pp, int tag);
623static void property_page_clear_tags(struct property_page *pp);
632
633
634#define property_page_objprop_iterate(ARG_pp, NAME_op) \
635 TYPED_HASH_DATA_ITERATE(struct objprop *, (ARG_pp)->objprop_table, NAME_op)
636#define property_page_objprop_iterate_end HASH_DATA_ITERATE_END
637
638#define property_page_objbind_iterate(ARG_pp, NAME_ob) \
639 TYPED_HASH_DATA_ITERATE(struct objbind *, (ARG_pp)->objbind_table, NAME_ob)
640#define property_page_objbind_iterate_end HASH_DATA_ITERATE_END
641
642
643/****************************************************************************
644 Property editor declarations.
645****************************************************************************/
652
653static struct property_editor *property_editor_new(void);
656static struct property_page *
659
661
662
663/************************************************************************/
667{
668 switch (objtype) {
669 case OBJTYPE_TILE:
670 return _("Tile");
671 case OBJTYPE_STARTPOS:
672 return _("Start Position");
673 case OBJTYPE_UNIT:
674 return _("Unit");
675 case OBJTYPE_CITY:
676 return _("City");
677 case OBJTYPE_PLAYER:
678 return _("Player");
679 case OBJTYPE_GAME:
680 return Q_("?play:Game");
681 case NUM_OBJTYPES:
682 break;
683 }
684
685 log_error("%s() Unhandled request to get name of object type %d.",
687 return "Unknown";
688}
689
690/************************************************************************/
696 gpointer object)
697{
698 switch (objtype) {
699 case OBJTYPE_TILE:
700 return tile_index((struct tile *) object);
701 case OBJTYPE_STARTPOS:
702 return startpos_number((struct startpos *) object);
703 case OBJTYPE_UNIT:
704 return ((struct unit *) object)->id;
705 case OBJTYPE_CITY:
706 return ((struct city *) object)->id;
707 case OBJTYPE_PLAYER:
708 return player_number((struct player *) object);
709 case OBJTYPE_GAME:
710 return 1;
711 case NUM_OBJTYPES:
712 break;
713 }
714
715 log_error("%s(): Unhandled request to get object ID from object %p of "
716 "type %d (%s).", __FUNCTION__, object, objtype,
718 return -1;
719}
720
721/************************************************************************/
725 int id)
726{
727 switch (objtype) {
728 case OBJTYPE_TILE:
729 return index_to_tile(&(wld.map), id);
730 case OBJTYPE_STARTPOS:
731 return map_startpos_by_number(id);
732 case OBJTYPE_UNIT:
733 return game_unit_by_number(id);
734 case OBJTYPE_CITY:
735 return game_city_by_number(id);
736 case OBJTYPE_PLAYER:
737 return player_by_number(id);
738 case OBJTYPE_GAME:
739 return &game;
740 case NUM_OBJTYPES:
741 break;
742 }
743
744 log_error("%s(): Unhandled request to get object of type %d (%s) "
745 "with ID %d.", __FUNCTION__, objtype,
747 return NULL;
748}
749
750/************************************************************************/
756{
757 switch (objtype) {
758 case OBJTYPE_TILE:
759 case OBJTYPE_GAME:
760 return TRUE;
761 case OBJTYPE_STARTPOS:
762 case OBJTYPE_UNIT:
763 case OBJTYPE_CITY:
764 case OBJTYPE_PLAYER:
765 return FALSE;
766 case NUM_OBJTYPES:
767 break;
768 }
769
770 log_error("%s(): Unhandled request for object type %d (%s)).",
772 return TRUE;
773}
774
775/************************************************************************/
778static const char *valtype_get_name(enum value_types valtype)
779{
780 switch (valtype) {
781 case VALTYPE_NONE:
782 return "none";
783 case VALTYPE_STRING:
784 return "string";
785 case VALTYPE_INT:
786 return "int";
787 case VALTYPE_BOOL:
788 return "bool";
789 case VALTYPE_PIXBUF:
790 return "pixbuf";
792 return "struct built_status[B_LAST]";
794 return "bool[A_LAST]";
796 return "bv_special";
797 case VALTYPE_BV_ROADS:
798 return "bv_roads";
799 case VALTYPE_BV_BASES:
800 return "bv_bases";
801 case VALTYPE_NATION:
802 return "nation";
804 return "struct nation_hash";
805 case VALTYPE_GOV:
806 return "government";
808 return "struct tile_vision_data";
809 }
810
811 log_error("%s(): unhandled value type %d.", __FUNCTION__, valtype);
812 return "void";
813}
814
815/************************************************************************/
820 int col_id,
821 const char *name,
822 GType gtype,
823 bool editable,
824 bool is_radio,
827{
830 const char *attr = NULL;
831
832 if (gtype == G_TYPE_BOOLEAN) {
835 is_radio);
836 if (editable) {
838 }
839 attr = "active";
840 } else if (gtype == GDK_TYPE_PIXBUF) {
842 attr = "pixbuf";
843 } else {
845 if (editable) {
846 g_object_set(cell, "editable", TRUE, NULL);
848 }
849 attr = "text";
850 }
851
853 attr, col_id, NULL);
855}
856
857/************************************************************************/
862{
863 int count = 0;
864
866
867 switch (pv->valtype) {
868 case VALTYPE_NONE:
869 return g_strdup("");
870
871 case VALTYPE_INT:
872 return g_strdup_printf("%d", pv->data.v_int);
873
874 case VALTYPE_BOOL:
875 return g_strdup_printf("%s", pv->data.v_bool ? _("TRUE") : _("FALSE"));
876
877 case VALTYPE_NATION:
878 return g_strdup_printf("%s", nation_adjective_translation(pv->data.v_nation));
879
880 case VALTYPE_GOV:
881 return g_strdup_printf("%s", government_name_translation(pv->data.v_gov));
882
884 {
885 int great_wonder_count = 0, small_wonder_count = 0, building_count = 0;
886 int id;
887
888 improvement_iterate(pimprove) {
889 id = improvement_index(pimprove);
890 if (pv->data.v_built[id].turn < 0) {
891 continue;
892 }
893 if (is_great_wonder(pimprove)) {
895 } else if (is_small_wonder(pimprove)) {
897 } else {
898 building_count++;
899 }
901 /* TRANS: "Number of buildings, number of small
902 * wonders (e.g. palace), number of great wonders." */
903 return g_strdup_printf(_("%db %ds %dW"),
904 building_count, small_wonder_count,
906 }
907
910 if (BV_ISSET(pv->data.v_bv_inventions, tech)) {
911 count++;
912 }
914 /* TRANS: "Number of technologies known". */
915 return g_strdup_printf(_("%d known"), count);
916
919 if (BV_ISSET(pv->data.v_bv_special, spe->data.special_idx)) {
920 count++;
921 }
923 /* TRANS: "The number of terrain specials (e.g. hut,
924 * river, pollution, etc.) present on a tile." */
925 return g_strdup_printf(_("%d present"), count);
926
927 case VALTYPE_BV_ROADS:
929 struct road_type *proad = extra_road_get(pextra);
930
931 if (BV_ISSET(pv->data.v_bv_roads, road_number(proad))) {
932 count++;
933 }
935 return g_strdup_printf(_("%d present"), count);
936
937 case VALTYPE_BV_BASES:
939 struct base_type *pbase = extra_base_get(pextra);
940
941 if (BV_ISSET(pv->data.v_bv_bases, base_number(pbase))) {
942 count++;
943 }
945 return g_strdup_printf(_("%d present"), count);
946
948 count = nation_hash_size(pv->data.v_nation_hash);
949 if (0 == count) {
950 return g_strdup(_("All nations"));
951 } else {
952 return g_strdup_printf(PL_("%d nation", "%d nations",
953 count), count);
954 }
955
956 case VALTYPE_STRING:
957 /* Assume it is a very long string. */
958 count = strlen(pv->data.v_const_string);
959 return g_strdup_printf(PL_("%d byte", "%d bytes", count),
960 count);
961
962 case VALTYPE_PIXBUF:
964 break;
965 }
966
967 log_error("%s(): Unhandled value type %d for property value %p.",
968 __FUNCTION__, pv->valtype, pv);
969 return g_strdup("");
970}
971
972/************************************************************************/
977{
978 int turn_built;
979
980 turn_built = bs->turn;
981
982 if (turn_built == I_NEVER) {
983 /* TRANS: Improvement never built. */
984 return g_strdup(_("(never)"));
985 } else if (turn_built == I_DESTROYED) {
986 /* TRANS: Improvement was destroyed. */
987 return g_strdup(_("(destroyed)"));
988 } else {
989 return g_strdup_printf("%d", turn_built);
990 }
991}
992
993/************************************************************************/
997static bool can_create_unit_at_tile(struct tile *ptile)
998{
999 struct unit *vunit;
1000 struct city *pcity;
1001 struct player *pplayer;
1002 bool ret;
1003
1004 if (!ptile) {
1005 return FALSE;
1006 }
1007
1009 if (!vunit) {
1010 return FALSE;
1011 }
1012
1013 pcity = tile_city(ptile);
1014 pplayer = unit_owner(vunit);
1015
1016 ret = (can_unit_exist_at_tile(&(wld.map), vunit, ptile)
1017 && !is_non_allied_unit_tile(ptile, pplayer)
1018 && (pcity == NULL
1019 || pplayers_allied(city_owner(pcity),
1020 unit_owner(vunit))));
1021 free(vunit);
1022
1023 return ret;
1024}
1025
1026/************************************************************************/
1029static int get_next_unique_tag(void)
1030{
1031 static int tag_series = 0;
1032
1033 tag_series++;
1034 return tag_series;
1035}
1036
1037/************************************************************************/
1040static struct propval *propval_copy(struct propval *pv)
1041{
1042 struct propval *pv_copy;
1043 size_t size;
1044
1045 if (!pv) {
1046 return NULL;
1047 }
1048
1049 pv_copy = fc_calloc(1, sizeof(*pv));
1050 pv_copy->valtype = pv->valtype;
1051
1052 switch (pv->valtype) {
1053 case VALTYPE_NONE:
1054 return pv_copy;
1055 case VALTYPE_INT:
1056 pv_copy->data.v_int = pv->data.v_int;
1057 return pv_copy;
1058 case VALTYPE_BOOL:
1059 pv_copy->data.v_bool = pv->data.v_bool;
1060 return pv_copy;
1061 case VALTYPE_STRING:
1062 pv_copy->data.v_string = fc_strdup(pv->data.v_string);
1063 pv_copy->must_free = TRUE;
1064 return pv_copy;
1065 case VALTYPE_PIXBUF:
1066 g_object_ref(pv->data.v_pixbuf);
1067 pv_copy->data.v_pixbuf = pv->data.v_pixbuf;
1068 pv_copy->must_free = TRUE;
1069 return pv_copy;
1071 size = B_LAST * sizeof(struct built_status);
1072 pv_copy->data.v_pointer = fc_malloc(size);
1073 memcpy(pv_copy->data.v_pointer, pv->data.v_pointer, size);
1074 pv_copy->must_free = TRUE;
1075 return pv_copy;
1076 case VALTYPE_BV_SPECIAL:
1077 pv_copy->data.v_bv_special = pv->data.v_bv_special;
1078 return pv_copy;
1079 case VALTYPE_BV_ROADS:
1080 pv_copy->data.v_bv_roads = pv->data.v_bv_roads;
1081 return pv_copy;
1082 case VALTYPE_BV_BASES:
1083 pv_copy->data.v_bv_bases = pv->data.v_bv_bases;
1084 return pv_copy;
1085 case VALTYPE_NATION:
1086 pv_copy->data.v_nation = pv->data.v_nation;
1087 return pv_copy;
1088 case VALTYPE_GOV:
1089 pv_copy->data.v_gov = pv->data.v_gov;
1090 return pv_copy;
1092 pv_copy->data.v_nation_hash
1093 = nation_hash_copy(pv->data.v_nation_hash);
1094 pv_copy->must_free = TRUE;
1095 return pv_copy;
1097 pv_copy->data.v_bv_inventions = pv->data.v_bv_inventions;
1098 return pv_copy;
1100 size = sizeof(struct tile_vision_data);
1101 pv_copy->data.v_tile_vision = fc_malloc(size);
1102 pv_copy->data.v_tile_vision->tile_known
1103 = pv->data.v_tile_vision->tile_known;
1105 pv_copy->data.v_tile_vision->tile_seen[v]
1106 = pv->data.v_tile_vision->tile_seen[v];
1108 pv_copy->must_free = TRUE;
1109 return pv_copy;
1110 }
1111
1112 log_error("%s(): Unhandled value type %d for property value %p.",
1113 __FUNCTION__, pv->valtype, pv);
1114 pv_copy->data = pv->data;
1115 return pv_copy;
1116}
1117
1118/************************************************************************/
1122static void propval_free(struct propval *pv)
1123{
1124 if (!pv) {
1125 return;
1126 }
1127
1129 free(pv);
1130}
1131
1132/************************************************************************/
1136static void propval_free_data(struct propval *pv)
1137{
1138 if (!pv || !pv->must_free) {
1139 return;
1140 }
1141
1142 switch (pv->valtype) {
1143 case VALTYPE_NONE:
1144 case VALTYPE_INT:
1145 case VALTYPE_BOOL:
1146 case VALTYPE_BV_SPECIAL:
1147 case VALTYPE_BV_ROADS:
1148 case VALTYPE_BV_BASES:
1149 case VALTYPE_NATION:
1150 case VALTYPE_GOV:
1151 return;
1152 case VALTYPE_PIXBUF:
1153 g_object_unref(pv->data.v_pixbuf);
1154 return;
1155 case VALTYPE_STRING:
1159 free(pv->data.v_pointer);
1160 return;
1162 nation_hash_destroy(pv->data.v_nation_hash);
1163 return;
1164 }
1165
1166 log_error("%s(): Unhandled request to free data %p (type %s).",
1167 __FUNCTION__, pv->data.v_pointer, valtype_get_name(pv->valtype));
1168}
1169
1170/************************************************************************/
1173static bool propval_equal(struct propval *pva,
1174 struct propval *pvb)
1175{
1176 if (!pva || !pvb) {
1177 return pva == pvb;
1178 }
1179
1180 if (pva->valtype != pvb->valtype) {
1181 return FALSE;
1182 }
1183
1184 switch (pva->valtype) {
1185 case VALTYPE_NONE:
1186 return TRUE;
1187 case VALTYPE_INT:
1188 return pva->data.v_int == pvb->data.v_int;
1189 case VALTYPE_BOOL:
1190 return pva->data.v_bool == pvb->data.v_bool;
1191 case VALTYPE_STRING:
1192 if (pva->data.v_const_string != NULL
1193 && pvb->data.v_const_string != NULL) {
1194 return !strcmp(pva->data.v_const_string,
1195 pvb->data.v_const_string);
1196 }
1197 return pva->data.v_const_string == pvb->data.v_const_string;
1198 case VALTYPE_PIXBUF:
1199 return pva->data.v_pixbuf == pvb->data.v_pixbuf;
1201 if (pva->data.v_pointer == pvb->data.v_pointer) {
1202 return TRUE;
1203 } else if (!pva->data.v_pointer || !pvb->data.v_pointer) {
1204 return FALSE;
1205 }
1206
1207 improvement_iterate(pimprove) {
1208 int id, vatb, vbtb;
1209 id = improvement_index(pimprove);
1210 vatb = pva->data.v_built[id].turn;
1211 vbtb = pvb->data.v_built[id].turn;
1212 if (vatb < 0 && vbtb < 0) {
1213 continue;
1214 }
1215 if (vatb != vbtb) {
1216 return FALSE;
1217 }
1219 return TRUE;
1221 return BV_ARE_EQUAL(pva->data.v_bv_inventions, pvb->data.v_bv_inventions);
1222 case VALTYPE_BV_SPECIAL:
1223 return BV_ARE_EQUAL(pva->data.v_bv_special, pvb->data.v_bv_special);
1224 case VALTYPE_BV_ROADS:
1225 return BV_ARE_EQUAL(pva->data.v_bv_roads, pvb->data.v_bv_roads);
1226 case VALTYPE_BV_BASES:
1227 return BV_ARE_EQUAL(pva->data.v_bv_bases, pvb->data.v_bv_bases);
1228 case VALTYPE_NATION:
1229 return pva->data.v_nation == pvb->data.v_nation;
1231 return nation_hashes_are_equal(pva->data.v_nation_hash,
1232 pvb->data.v_nation_hash);
1233 case VALTYPE_GOV:
1234 return pva->data.v_gov == pvb->data.v_gov;
1236 if (!BV_ARE_EQUAL(pva->data.v_tile_vision->tile_known,
1237 pvb->data.v_tile_vision->tile_known)) {
1238 return FALSE;
1239 }
1241 if (!BV_ARE_EQUAL(pva->data.v_tile_vision->tile_seen[v],
1242 pvb->data.v_tile_vision->tile_seen[v])) {
1243 return FALSE;
1244 }
1246 return TRUE;
1247 }
1248
1249 log_error("%s(): Unhandled value type %d for property values %p and %p.",
1250 __FUNCTION__, pva->valtype, pva, pvb);
1251 return pva->data.v_pointer == pvb->data.v_pointer;
1252}
1253
1254/************************************************************************/
1260static struct propstate *propstate_new(struct objprop *op,
1261 struct propval *pv)
1262{
1263 struct propstate *ps;
1264
1265 if (!op) {
1266 return NULL;
1267 }
1268
1269 ps = fc_calloc(1, sizeof(*ps));
1270 ps->property_id = objprop_get_id(op);
1271 ps->property_value = pv;
1272
1273 return ps;
1274}
1275
1276/************************************************************************/
1280{
1281 if (!ps) {
1282 return;
1283 }
1284
1285 propval_free(ps->property_value);
1286 ps->property_value = NULL;
1287}
1288
1289/************************************************************************/
1292static void propstate_destroy(struct propstate *ps)
1293{
1294 if (!ps) {
1295 return;
1296 }
1298 free(ps);
1299}
1300
1301/************************************************************************/
1308 struct propval *pv)
1309{
1310 if (!ps) {
1311 return;
1312 }
1314 ps->property_value = pv;
1315}
1316
1317/************************************************************************/
1323{
1324 if (!ps) {
1325 return NULL;
1326 }
1327 return ps->property_value;
1328}
1329
1330/************************************************************************/
1335 gpointer object)
1336{
1337 struct objbind *ob;
1338 int id;
1339
1340 if (object == NULL) {
1341 return NULL;
1342 }
1343
1344 id = objtype_get_id_from_object(objtype, object);
1345 if (id < 0) {
1346 return NULL;
1347 }
1348
1349 ob = fc_calloc(1, sizeof(*ob));
1350 ob->object_id = id;
1351 ob->objtype = objtype;
1352 ob->propstate_table = propstate_hash_new();
1353
1354 return ob;
1355}
1356
1357/************************************************************************/
1361{
1362 int id;
1363
1364 if (!ob) {
1365 return NULL;
1366 }
1367
1369
1370 return objtype_get_object_from_id(ob->objtype, id);
1371}
1372
1373/************************************************************************/
1377{
1378 if (NULL == ob) {
1379 return -1;
1380 }
1381 return ob->object_id;
1382}
1383
1384/************************************************************************/
1390{
1391 struct connection *my_conn = &client.conn;
1393 int id;
1394
1395 if (!ob) {
1396 return;
1397 }
1398
1401 return;
1402 }
1403
1405
1406 switch (objtype) {
1407 case OBJTYPE_STARTPOS:
1409 return;
1410 case OBJTYPE_UNIT:
1412 return;
1413 case OBJTYPE_CITY:
1415 return;
1416 case OBJTYPE_PLAYER:
1418 return;
1419 case OBJTYPE_TILE:
1420 case OBJTYPE_GAME:
1421 case NUM_OBJTYPES:
1422 break;
1423 }
1424
1425 log_error("%s(): Unhandled request to destroy object %p (ID %d) of type "
1426 "%d (%s).", __FUNCTION__, objbind_get_object(ob), id, objtype,
1428}
1429
1430/************************************************************************/
1438 struct objprop *op)
1439{
1442 struct propval *pv;
1443
1444 if (!ob || !op) {
1445 return NULL;
1446 }
1447
1450
1451 pv = fc_calloc(1, sizeof(*pv));
1452 pv->valtype = objprop_get_valtype(op);
1453
1454 switch (objtype) {
1455 case OBJTYPE_TILE:
1456 {
1457 const struct tile *ptile = objbind_get_object(ob);
1458 int tile_x, tile_y, nat_x, nat_y;
1459
1460 if (NULL == ptile) {
1461 goto FAILED;
1462 }
1463
1466
1467 switch (propid) {
1468 case OPID_TILE_IMAGE:
1469 pv->data.v_pixbuf = create_tile_pixbuf(ptile);
1470 pv->must_free = TRUE;
1471 break;
1472#ifdef FREECIV_DEBUG
1473 case OPID_TILE_ADDRESS:
1474 pv->data.v_string = g_strdup_printf("%p", ptile);
1475 pv->must_free = TRUE;
1476 break;
1477#endif /* FREECIV_DEBUG */
1478 case OPID_TILE_TERRAIN:
1479 {
1480 const struct terrain *pterrain = tile_terrain(ptile);
1481
1482 if (NULL != pterrain) {
1483 pv->data.v_const_string = terrain_name_translation(pterrain);
1484 } else {
1485 pv->data.v_const_string = "";
1486 }
1487 }
1488 break;
1489 case OPID_TILE_RESOURCE:
1490 {
1491 const struct extra_type *presource = tile_resource(ptile);
1492
1493 if (NULL != presource) {
1494 pv->data.v_const_string = extra_name_translation(presource);
1495 } else {
1496 pv->data.v_const_string = "";
1497 }
1498 }
1499 break;
1500 case OPID_TILE_XY:
1501 pv->data.v_string = g_strdup_printf("(%d, %d)", tile_x, tile_y);
1502 pv->must_free = TRUE;
1503 break;
1504 case OPID_TILE_INDEX:
1505 pv->data.v_int = tile_index(ptile);
1506 break;
1507 case OPID_TILE_X:
1508 pv->data.v_int = tile_x;
1509 break;
1510 case OPID_TILE_Y:
1511 pv->data.v_int = tile_y;
1512 break;
1513 case OPID_TILE_NAT_X:
1514 pv->data.v_int = nat_x;
1515 break;
1516 case OPID_TILE_NAT_Y:
1517 pv->data.v_int = nat_y;
1518 break;
1520 pv->data.v_int = ptile->continent;
1521 break;
1522 case OPID_TILE_SPECIALS:
1523 BV_CLR_ALL(pv->data.v_bv_special);
1525 if (tile_has_extra(ptile, pextra)) {
1526 BV_SET(pv->data.v_bv_special, pextra->data.special_idx);
1527 }
1529 break;
1530 case OPID_TILE_ROADS:
1531 BV_CLR_ALL(pv->data.v_bv_roads);
1533 if (tile_has_extra(ptile, pextra)) {
1534 BV_SET(pv->data.v_bv_roads, road_number(extra_road_get(pextra)));
1535 }
1537 break;
1538 case OPID_TILE_BASES:
1539 BV_CLR_ALL(pv->data.v_bv_bases);
1541 if (tile_has_extra(ptile, pextra)) {
1542 BV_SET(pv->data.v_bv_bases, base_number(extra_base_get(pextra)));
1543 }
1545 break;
1546 case OPID_TILE_VISION:
1547 pv->data.v_tile_vision = fc_malloc(sizeof(struct tile_vision_data));
1548
1549 /* The server saves the known tiles and the player vision in special
1550 * bitvectors with the number of tiles as index. Here we want the
1551 * information for one tile. Thus, the data is transformed to
1552 * bitvectors with the number of player slots as index. */
1553 BV_CLR_ALL(pv->data.v_tile_vision->tile_known);
1554 players_iterate(pplayer) {
1555 if (dbv_isset(&pplayer->tile_known, tile_index(ptile))) {
1556 BV_SET(pv->data.v_tile_vision->tile_known,
1557 player_index(pplayer));
1558 }
1560
1562 BV_CLR_ALL(pv->data.v_tile_vision->tile_seen[v]);
1563 players_iterate(pplayer) {
1564 if (fc_funcs->player_tile_vision_get(ptile, pplayer, v)) {
1565 BV_SET(pv->data.v_tile_vision->tile_seen[v],
1566 player_index(pplayer));
1567 }
1570 pv->must_free = TRUE;
1571 break;
1572 case OPID_TILE_LABEL:
1573 if (ptile->label != NULL) {
1574 pv->data.v_const_string = ptile->label;
1575 } else {
1576 pv->data.v_const_string = "";
1577 }
1578 break;
1579 default:
1580 log_error("%s(): Unhandled request for value of property %d "
1581 "(%s) from object of type \"%s\".", __FUNCTION__,
1583 goto FAILED;
1584 }
1585 }
1586 return pv;
1587
1588 case OBJTYPE_STARTPOS:
1589 {
1590 const struct startpos *psp = objbind_get_object(ob);
1591 const struct tile *ptile;
1592
1593 if (NULL == psp) {
1594 goto FAILED;
1595 }
1596
1597 switch (propid) {
1599 ptile = startpos_tile(psp);
1600 pv->data.v_pixbuf = create_tile_pixbuf(ptile);
1601 pv->must_free = TRUE;
1602 break;
1603 case OPID_STARTPOS_XY:
1604 ptile = startpos_tile(psp);
1605 pv->data.v_string = g_strdup_printf("(%d, %d)", TILE_XY(ptile));
1606 pv->must_free = TRUE;
1607 break;
1609 pv->data.v_bool = startpos_is_excluding(psp);
1610 break;
1612 pv->data.v_nation_hash = nation_hash_copy(startpos_raw_nations(psp));
1613 pv->must_free = TRUE;
1614 break;
1615 default:
1616 log_error("%s(): Unhandled request for value of property %d "
1617 "(%s) from object of type \"%s\".", __FUNCTION__,
1619 goto FAILED;
1620 }
1621 }
1622 return pv;
1623
1624 case OBJTYPE_UNIT:
1625 {
1626 struct unit *punit = objbind_get_object(ob);
1627
1628 if (NULL == punit) {
1629 goto FAILED;
1630 }
1631
1632 switch (propid) {
1633 case OPID_UNIT_IMAGE:
1634 pv->data.v_pixbuf = create_unit_pixbuf(punit);
1635 pv->must_free = TRUE;
1636 break;
1637#ifdef FREECIV_DEBUG
1638 case OPID_UNIT_ADDRESS:
1639 pv->data.v_string = g_strdup_printf("%p", punit);
1640 pv->must_free = TRUE;
1641 break;
1642#endif /* FREECIV_DEBUG */
1643 case OPID_UNIT_XY:
1644 {
1645 const struct tile *ptile = unit_tile(punit);
1646
1647 pv->data.v_string = g_strdup_printf("(%d, %d)", TILE_XY(ptile));
1648 pv->must_free = TRUE;
1649 }
1650 break;
1651 case OPID_UNIT_ID:
1652 pv->data.v_int = punit->id;
1653 break;
1654 case OPID_UNIT_TYPE:
1655 {
1656 const struct unit_type *putype = unit_type_get(punit);
1657
1658 pv->data.v_const_string = utype_name_translation(putype);
1659 }
1660 break;
1662 pv->data.v_int = punit->moves_left;
1663 break;
1664 case OPID_UNIT_FUEL:
1665 pv->data.v_int = punit->fuel;
1666 break;
1667 case OPID_UNIT_MOVED:
1668 pv->data.v_bool = punit->moved;
1669 break;
1671 pv->data.v_bool = punit->done_moving;
1672 break;
1673 case OPID_UNIT_HP:
1674 pv->data.v_int = punit->hp;
1675 break;
1676 case OPID_UNIT_VETERAN:
1677 pv->data.v_int = punit->veteran;
1678 break;
1679 case OPID_UNIT_STAY:
1680 pv->data.v_bool = punit->stay;
1681 break;
1682 default:
1683 log_error("%s(): Unhandled request for value of property %d "
1684 "(%s) from object of type \"%s\".", __FUNCTION__,
1686 goto FAILED;
1687 }
1688 }
1689 return pv;
1690
1691 case OBJTYPE_CITY:
1692 {
1693 const struct city *pcity = objbind_get_object(ob);
1694
1695 if (NULL == pcity) {
1696 goto FAILED;
1697 }
1698
1699 switch (propid) {
1700 case OPID_CITY_IMAGE:
1701 pv->data.v_pixbuf = create_city_pixbuf(pcity);
1702 pv->must_free = TRUE;
1703 break;
1704#ifdef FREECIV_DEBUG
1705 case OPID_CITY_ADDRESS:
1706 pv->data.v_string = g_strdup_printf("%p", pcity);
1707 pv->must_free = TRUE;
1708 break;
1709#endif /* FREECIV_DEBUG */
1710 case OPID_CITY_XY:
1711 {
1712 const struct tile *ptile = city_tile(pcity);
1713
1714 pv->data.v_string = g_strdup_printf("(%d, %d)", TILE_XY(ptile));
1715 pv->must_free = TRUE;
1716 }
1717 break;
1718 case OPID_CITY_ID:
1719 pv->data.v_int = pcity->id;
1720 break;
1721 case OPID_CITY_NAME:
1722 pv->data.v_const_string = pcity->name;
1723 break;
1724 case OPID_CITY_SIZE:
1725 pv->data.v_int = city_size_get(pcity);
1726 break;
1727 case OPID_CITY_HISTORY:
1728 pv->data.v_int = pcity->history;
1729 break;
1731 pv->data.v_built = fc_malloc(sizeof(pcity->built));
1732 memcpy(pv->data.v_built, pcity->built, sizeof(pcity->built));
1733 pv->must_free = TRUE;
1734 break;
1736 pv->data.v_int = pcity->food_stock;
1737 break;
1739 pv->data.v_int = pcity->shield_stock;
1740 break;
1741 default:
1742 log_error("%s(): Unhandled request for value of property %d "
1743 "(%s) from object of type \"%s\".", __FUNCTION__,
1745 goto FAILED;
1746 }
1747 }
1748 return pv;
1749
1750 case OBJTYPE_PLAYER:
1751 {
1752 const struct player *pplayer = objbind_get_object(ob);
1753 const struct research *presearch;
1754
1755 if (NULL == pplayer) {
1756 goto FAILED;
1757 }
1758
1759 switch (propid) {
1760 case OPID_PLAYER_NAME:
1761 pv->data.v_const_string = pplayer->name;
1762 break;
1763 case OPID_PLAYER_NATION:
1764 pv->data.v_nation = nation_of_player(pplayer);
1765 break;
1766 case OPID_PLAYER_GOV:
1767 pv->data.v_gov = pplayer->government;
1768 break;
1769 case OPID_PLAYER_AGE:
1770 pv->data.v_int = pplayer->turns_alive;
1771 break;
1772#ifdef FREECIV_DEBUG
1774 pv->data.v_string = g_strdup_printf("%p", pplayer);
1775 pv->must_free = TRUE;
1776 break;
1777#endif /* FREECIV_DEBUG */
1779 presearch = research_get(pplayer);
1780 BV_CLR_ALL(pv->data.v_bv_inventions);
1783 BV_SET(pv->data.v_bv_inventions, tech);
1784 }
1786 break;
1788 pv->data.v_bool = player_has_flag(pplayer, PLRF_SCENARIO_RESERVED);
1789 break;
1791 pv->data.v_int = pplayer->autoselect_weight;
1792 break;
1794 presearch = research_get(pplayer);
1795 pv->data.v_int = presearch->bulbs_researched;
1796 break;
1797 case OPID_PLAYER_GOLD:
1798 pv->data.v_int = pplayer->economic.gold;
1799 break;
1800 default:
1801 log_error("%s(): Unhandled request for value of property %d "
1802 "(%s) from object of type \"%s\".", __FUNCTION__,
1804 goto FAILED;
1805 }
1806 }
1807 return pv;
1808
1809 case OBJTYPE_GAME:
1810 {
1811 const struct civ_game *pgame = objbind_get_object(ob);
1812
1813 if (NULL == pgame) {
1814 goto FAILED;
1815 }
1816
1817 switch (propid) {
1818 case OPID_GAME_SCENARIO:
1819 pv->data.v_bool = pgame->scenario.is_scenario;
1820 break;
1822 pv->data.v_const_string = pgame->scenario.name;
1823 break;
1825 pv->data.v_const_string = pgame->scenario.authors;
1826 break;
1828 pv->data.v_const_string = pgame->scenario_desc.description;
1829 break;
1831 pv->data.v_bool = pgame->scenario.save_random;
1832 break;
1834 pv->data.v_bool = pgame->scenario.players;
1835 break;
1837 pv->data.v_bool = pgame->scenario.startpos_nations;
1838 break;
1840 pv->data.v_bool = pgame->scenario.prevent_new_cities;
1841 break;
1843 pv->data.v_bool = pgame->scenario.lake_flooding;
1844 break;
1846 pv->data.v_bool = pgame->scenario.ruleset_locked;
1847 break;
1848 default:
1849 log_error("%s(): Unhandled request for value of property %d "
1850 "(%s) from object of type \"%s\".", __FUNCTION__,
1852 goto FAILED;
1853 }
1854 }
1855 return pv;
1856
1857 case NUM_OBJTYPES:
1858 break;
1859 }
1860
1861 log_error("%s(): Unhandled request for object type \"%s\" (nb %d).",
1863
1864FAILED:
1865 if (NULL != pv) {
1866 free(pv);
1867 }
1868 return NULL;
1869}
1870
1871/************************************************************************/
1876 struct objprop *op,
1877 double *pmin,
1878 double *pmax,
1879 double *pstep,
1880 double *pbig_step)
1881{
1884 double dummy;
1885
1886 /* Fill the values with something. */
1887 if (NULL != pmin) {
1888 *pmin = 0;
1889 } else {
1890 pmin = &dummy;
1891 }
1892 if (NULL != pmax) {
1893 *pmax = 1;
1894 } else {
1895 pmax = &dummy;
1896 }
1897 if (NULL != pstep) {
1898 *pstep = 1;
1899 } else {
1900 pstep = &dummy;
1901 }
1902 if (NULL != pbig_step) {
1903 *pbig_step = 1;
1904 } else {
1905 pbig_step = &dummy;
1906 }
1907
1908 if (!ob || !op) {
1909 return FALSE;
1910 }
1911
1914
1915 switch (objtype) {
1916 case OBJTYPE_TILE:
1917 case OBJTYPE_STARTPOS:
1918 log_error("%s(): Unhandled request for value range of property %d (%s) "
1919 "from object of type \"%s\".", __FUNCTION__,
1921 return FALSE;
1922
1923 case OBJTYPE_UNIT:
1924 {
1925 const struct unit *punit = objbind_get_object(ob);
1926 const struct unit_type *putype;
1927
1928 if (NULL == punit) {
1929 return FALSE;
1930 }
1931
1933
1934 switch (propid) {
1936 *pmin = 0;
1938 *pstep = 1;
1939 *pbig_step = 5;
1940 return TRUE;
1941 case OPID_UNIT_FUEL:
1942 *pmin = 0;
1944 *pstep = 1;
1945 *pbig_step = 5;
1946 return TRUE;
1947 case OPID_UNIT_HP:
1948 *pmin = 1;
1949 *pmax = putype->hp;
1950 *pstep = 1;
1951 *pbig_step = 10;
1952 return TRUE;
1953 case OPID_UNIT_VETERAN:
1954 *pmin = 0;
1956 *pstep = 1;
1957 *pbig_step = 3;
1958 return TRUE;
1959 default:
1960 break;
1961 }
1962 }
1963 log_error("%s(): Unhandled request for value range of property %d (%s) "
1964 "from object of type \"%s\".", __FUNCTION__,
1966 return FALSE;
1967
1968 case OBJTYPE_CITY:
1969 {
1970 const struct city *pcity = objbind_get_object(ob);
1971
1972 if (NULL == pcity) {
1973 return FALSE;
1974 }
1975
1976 switch (propid) {
1977 case OPID_CITY_SIZE:
1978 *pmin = 1;
1980 *pstep = 1;
1981 *pbig_step = 5;
1982 return TRUE;
1983 case OPID_CITY_HISTORY:
1984 *pmin = 0;
1985 *pmax = USHRT_MAX;
1986 *pstep = 1;
1987 *pbig_step = 10;
1988 return TRUE;
1990 *pmin = 0;
1992 *pstep = 1;
1993 *pbig_step = 5;
1994 return TRUE;
1996 *pmin = 0;
1997 *pmax = USHRT_MAX; /* Limited to uint16 by city info packet. */
1998 *pstep = 1;
1999 *pbig_step = 10;
2000 return TRUE;
2001 default:
2002 break;
2003 }
2004 }
2005 log_error("%s(): Unhandled request for value range of property %d (%s) "
2006 "from object of type \"%s\".", __FUNCTION__,
2008 return FALSE;
2009
2010 case OBJTYPE_PLAYER:
2011 switch (propid) {
2013 *pmin = 0;
2014 *pmax = 1000000; /* Arbitrary. */
2015 *pstep = 1;
2016 *pbig_step = 100;
2017 return TRUE;
2018 case OPID_PLAYER_GOLD:
2019 *pmin = 0;
2020 *pmax = 1000000; /* Arbitrary. */
2021 *pstep = 1;
2022 *pbig_step = 100;
2023 return TRUE;
2025 *pmin = -1;
2026 *pmax = 10000; /* Keep it under SINT16 */
2027 *pstep = 1;
2028 *pbig_step = 10;
2029 return TRUE;
2030 default:
2031 break;
2032 }
2033 log_error("%s(): Unhandled request for value range of property %d (%s) "
2034 "from object of type \"%s\".", __FUNCTION__,
2036 return FALSE;
2037
2038 case OBJTYPE_GAME:
2039 log_error("%s(): Unhandled request for value range of property %d (%s) "
2040 "from object of type \"%s\".", __FUNCTION__,
2042 return FALSE;
2043
2044 case NUM_OBJTYPES:
2045 break;
2046 }
2047
2048 log_error("%s(): Unhandled request for object type \"%s\" (nb %d).",
2050 return FALSE;
2051}
2052
2053/************************************************************************/
2057 struct objprop *op)
2058{
2059 if (!ob || !op || !ob->propstate_table) {
2060 return;
2061 }
2062
2063 propstate_hash_remove(ob->propstate_table, objprop_get_id(op));
2064}
2065
2066/************************************************************************/
2071 struct objprop *op)
2072{
2073 if (!ob || !op) {
2074 return FALSE;
2075 }
2076
2077 if (objprop_is_readonly(op)) {
2078 return FALSE;
2079 }
2080
2081 return propstate_hash_lookup(ob->propstate_table,
2083}
2084
2085/************************************************************************/
2090{
2091 if (!ob) {
2092 return FALSE;
2093 }
2094
2095 return (0 < propstate_hash_size(ob->propstate_table));
2096}
2097
2098/************************************************************************/
2102{
2103 if (!ob) {
2104 return;
2105 }
2106 propstate_hash_clear(ob->propstate_table);
2107}
2108
2109/************************************************************************/
2116 struct objprop *op,
2117 struct propval *pv)
2118{
2119 struct propstate *ps;
2120 bool equal;
2121 struct propval *pv_old, *pv_copy;
2123
2124 if (!ob || !op) {
2125 return FALSE;
2126 }
2127
2129
2131 if (!pv_old) {
2132 return FALSE;
2133 }
2134
2137
2138 if (equal) {
2140 return FALSE;
2141 }
2142
2144
2145 if (propstate_hash_lookup(ob->propstate_table, propid, &ps)) {
2147 } else {
2149 propstate_hash_insert(ob->propstate_table, propid, ps);
2150 }
2151
2152 return TRUE;
2153}
2154
2155/************************************************************************/
2162 struct objprop *op)
2163{
2164 struct propstate *ps;
2165
2166 if (!ob || !op) {
2167 return NULL;
2168 }
2169
2170 if (propstate_hash_lookup(ob->propstate_table, objprop_get_id(op), &ps)) {
2171 return propstate_get_value(ps);
2172 } else {
2173 return NULL;
2174 }
2175}
2176
2177/************************************************************************/
2180static void objbind_destroy(struct objbind *ob)
2181{
2182 if (!ob) {
2183 return;
2184 }
2185 if (ob->propstate_table) {
2186 propstate_hash_destroy(ob->propstate_table);
2187 ob->propstate_table = NULL;
2188 }
2189 if (ob->rowref) {
2191 ob->rowref = NULL;
2192 }
2193 free(ob);
2194}
2195
2196/************************************************************************/
2200{
2201 if (!ob) {
2202 return NUM_OBJTYPES;
2203 }
2204 return ob->objtype;
2205}
2206
2207/************************************************************************/
2211 struct property_page *pp)
2212{
2213 if (!ob) {
2214 return;
2215 }
2216 ob->parent_property_page = pp;
2217}
2218
2219/************************************************************************/
2225 union packetdata pd)
2226{
2228
2229 if (!ob || !pd.pointers.v_pointer1) {
2230 return;
2231 }
2232
2234
2235 switch (objtype) {
2236 case OBJTYPE_TILE:
2237 {
2238 struct packet_edit_tile *packet = pd.tile;
2239 const struct tile *ptile = objbind_get_object(ob);
2240
2241 if (NULL == ptile) {
2242 return;
2243 }
2244
2245 packet->tile = tile_index(ptile);
2246 packet->extras = *tile_extras(ptile);
2247 /* TODO: Set more packet fields. */
2248 }
2249 return;
2250
2251 case OBJTYPE_STARTPOS:
2252 {
2253 struct packet_edit_startpos_full *packet = pd.startpos;
2254 const struct startpos *psp = objbind_get_object(ob);
2255
2256 if (NULL != psp) {
2257 startpos_pack(psp, packet);
2258 }
2259 }
2260 return;
2261
2262 case OBJTYPE_UNIT:
2263 {
2264 struct packet_edit_unit *packet = pd.unit;
2265 const struct unit *punit = objbind_get_object(ob);
2266
2267 if (NULL == punit) {
2268 return;
2269 }
2270
2271 packet->id = punit->id;
2272 packet->moves_left = punit->moves_left;
2273 packet->fuel = punit->fuel;
2274 packet->moved = punit->moved;
2275 packet->done_moving = punit->done_moving;
2276 packet->hp = punit->hp;
2277 packet->veteran = punit->veteran;
2278 packet->stay = punit->stay;
2279 /* TODO: Set more packet fields. */
2280 }
2281 return;
2282
2283 case OBJTYPE_CITY:
2284 {
2285 struct packet_edit_city *packet = pd.city;
2286 const struct city *pcity = objbind_get_object(ob);
2287 int i;
2288
2289 if (NULL == pcity) {
2290 return;
2291 }
2292
2293 packet->id = pcity->id;
2294 sz_strlcpy(packet->name, pcity->name);
2295 packet->size = city_size_get(pcity);
2296 packet->history = pcity->history;
2297 for (i = 0; i < B_LAST; i++) {
2298 packet->built[i] = pcity->built[i].turn;
2299 }
2300 packet->food_stock = pcity->food_stock;
2301 packet->shield_stock = pcity->shield_stock;
2302 /* TODO: Set more packet fields. */
2303 }
2304 return;
2305
2306 case OBJTYPE_PLAYER:
2307 {
2308 struct packet_edit_player *packet = pd.player;
2309 const struct player *pplayer = objbind_get_object(ob);
2310 const struct nation_type *pnation;
2311 const struct research *presearch;
2312
2313 if (NULL == pplayer) {
2314 return;
2315 }
2316
2317 packet->id = player_number(pplayer);
2318 sz_strlcpy(packet->name, pplayer->name);
2319 pnation = nation_of_player(pplayer);
2320 packet->nation = nation_index(pnation);
2321 presearch = research_get(pplayer);
2323 packet->inventions[tech]
2326 packet->autoselect_weight = pplayer->autoselect_weight;
2327 packet->gold = pplayer->economic.gold;
2328 packet->government = government_index(pplayer->government);
2330 /* TODO: Set more packet fields. */
2331 }
2332 return;
2333
2334 case OBJTYPE_GAME:
2335 {
2336 struct packet_edit_game *packet = pd.game.game;
2337 const struct civ_game *pgame = objbind_get_object(ob);
2338
2339 if (NULL == pgame) {
2340 return;
2341 }
2342
2343 packet->scenario = pgame->scenario.is_scenario;
2344 sz_strlcpy(packet->scenario_name, pgame->scenario.name);
2345 sz_strlcpy(packet->scenario_authors, pgame->scenario.authors);
2346 sz_strlcpy(pd.game.desc->scenario_desc, pgame->scenario_desc.description);
2347 packet->scenario_random = pgame->scenario.save_random;
2348 packet->scenario_players = pgame->scenario.players;
2349 packet->startpos_nations = pgame->scenario.startpos_nations;
2350 packet->prevent_new_cities = pgame->scenario.prevent_new_cities;
2351 packet->lake_flooding = pgame->scenario.lake_flooding;
2352 }
2353 return;
2354
2355 case NUM_OBJTYPES:
2356 break;
2357 }
2358
2359 log_error("%s(): Unhandled object type %s (nb %d).", __FUNCTION__,
2361}
2362
2363/************************************************************************/
2367 struct objprop *op,
2368 union packetdata pd)
2369{
2370 struct propval *pv;
2373
2374 if (!op || !ob || !pd.pointers.v_pointer1) {
2375 return;
2376 }
2377
2378 if (NULL == objbind_get_object(ob)) {
2379 return;
2380 }
2381
2383 return;
2384 }
2385
2387 if (!pv) {
2388 return;
2389 }
2390
2393
2394 switch (objtype) {
2395 case OBJTYPE_TILE:
2396 {
2397 struct packet_edit_tile *packet = pd.tile;
2398
2399 switch (propid) {
2400 case OPID_TILE_SPECIALS:
2402 if (BV_ISSET(pv->data.v_bv_special, pextra->data.special_idx)) {
2403 BV_SET(packet->extras, pextra->data.special_idx);
2404 } else {
2405 BV_CLR(packet->extras, pextra->data.special_idx);
2406 }
2408 return;
2409 case OPID_TILE_ROADS:
2411 int ridx = road_number(extra_road_get(pextra));
2412
2413 if (BV_ISSET(pv->data.v_bv_roads, ridx)) {
2414 BV_SET(packet->extras, extra_index(pextra));
2415 } else {
2416 BV_CLR(packet->extras, extra_index(pextra));
2417 }
2419 return;
2420 case OPID_TILE_BASES:
2422 int bidx = base_number(extra_base_get(pextra));
2423
2424 if (BV_ISSET(pv->data.v_bv_bases, bidx)) {
2425 BV_SET(packet->extras, extra_index(pextra));
2426 } else {
2427 BV_CLR(packet->extras, extra_index(pextra));
2428 }
2430 return;
2431 case OPID_TILE_LABEL:
2432 sz_strlcpy(packet->label, pv->data.v_string);
2433 return;
2434 default:
2435 break;
2436 }
2437 }
2438 log_error("%s(): Unhandled request to pack value of property "
2439 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2441 return;
2442
2443 case OBJTYPE_STARTPOS:
2444 {
2445 struct packet_edit_startpos_full *packet = pd.startpos;
2446
2447 switch (propid) {
2449 packet->exclude = pv->data.v_bool;
2450 return;
2452 BV_CLR_ALL(packet->nations);
2453 nation_hash_iterate(pv->data.v_nation_hash, pnation) {
2454 BV_SET(packet->nations, nation_number(pnation));
2456 return;
2457 default:
2458 break;
2459 }
2460 }
2461 log_error("%s(): Unhandled request to pack value of property "
2462 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2464 return;
2465
2466 case OBJTYPE_UNIT:
2467 {
2468 struct packet_edit_unit *packet = pd.unit;
2469
2470 switch (propid) {
2472 packet->moves_left = pv->data.v_int;
2473 return;
2474 case OPID_UNIT_FUEL:
2475 packet->fuel = pv->data.v_int;
2476 return;
2477 case OPID_UNIT_MOVED:
2478 packet->moved = pv->data.v_bool;
2479 return;
2481 packet->done_moving = pv->data.v_bool;
2482 return;
2483 case OPID_UNIT_HP:
2484 packet->hp = pv->data.v_int;
2485 return;
2486 case OPID_UNIT_VETERAN:
2487 packet->veteran = pv->data.v_int;
2488 return;
2489 case OPID_UNIT_STAY:
2490 packet->stay = pv->data.v_bool;
2491 return;
2492 default:
2493 break;
2494 }
2495 }
2496 log_error("%s(): Unhandled request to pack value of property "
2497 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2499 return;
2500
2501 case OBJTYPE_CITY:
2502 {
2503 struct packet_edit_city *packet = pd.city;
2504
2505 switch (propid) {
2506 case OPID_CITY_NAME:
2507 sz_strlcpy(packet->name, pv->data.v_string);
2508 return;
2509 case OPID_CITY_SIZE:
2510 packet->size = pv->data.v_int;
2511 return;
2512 case OPID_CITY_HISTORY:
2513 packet->history = pv->data.v_int;
2514 return;
2516 packet->food_stock = pv->data.v_int;
2517 return;
2519 packet->shield_stock = pv->data.v_int;
2520 return;
2522 {
2523 int i;
2524
2525 for (i = 0; i < B_LAST; i++) {
2526 packet->built[i] = pv->data.v_built[i].turn;
2527 }
2528 }
2529 return;
2530 default:
2531 break;
2532 }
2533 }
2534 log_error("%s(): Unhandled request to pack value of property "
2535 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2537 return;
2538
2539 case OBJTYPE_PLAYER:
2540 {
2541 struct packet_edit_player *packet = pd.player;
2542
2543 switch (propid) {
2544 case OPID_PLAYER_NAME:
2545 sz_strlcpy(packet->name, pv->data.v_string);
2546 return;
2547 case OPID_PLAYER_NATION:
2548 packet->nation = nation_index(pv->data.v_nation);
2549 return;
2550 case OPID_PLAYER_GOV:
2551 packet->government = government_index(pv->data.v_gov);
2552 return;
2555 packet->inventions[tech] = BV_ISSET(pv->data.v_bv_inventions, tech);
2557 return;
2559 packet->scenario_reserved = pv->data.v_bool;
2560 return;
2562 packet->autoselect_weight = pv->data.v_int;
2563 return;
2565 packet->bulbs_researched = pv->data.v_int;
2566 return;
2567 case OPID_PLAYER_GOLD:
2568 packet->gold = pv->data.v_int;
2569 return;
2570 default:
2571 break;
2572 }
2573 }
2574 log_error("%s(): Unhandled request to pack value of property "
2575 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2577 return;
2578
2579 case OBJTYPE_GAME:
2580 {
2581 struct packet_edit_game *packet = pd.game.game;
2582
2583 switch (propid) {
2584 case OPID_GAME_SCENARIO:
2585 packet->scenario = pv->data.v_bool;
2586 return;
2588 sz_strlcpy(packet->scenario_name, pv->data.v_const_string);
2589 return;
2591 sz_strlcpy(packet->scenario_authors, pv->data.v_const_string);
2592 return;
2594 sz_strlcpy(pd.game.desc->scenario_desc, pv->data.v_const_string);
2595 return;
2597 packet->scenario_random = pv->data.v_bool;
2598 return;
2600 packet->scenario_players = pv->data.v_bool;
2601 return;
2603 packet->startpos_nations = pv->data.v_bool;
2604 return;
2606 packet->prevent_new_cities = pv->data.v_bool;
2607 return;
2609 packet->lake_flooding = pv->data.v_bool;
2610 return;
2612 packet->ruleset_locked = pv->data.v_bool;
2613 return;
2614 default:
2615 break;
2616 }
2617 }
2618 log_error("%s(): Unhandled request to pack value of property "
2619 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2621 return;
2622
2623 case NUM_OBJTYPES:
2624 break;
2625 }
2626
2627 log_error("%s(): Unhandled request for object type \"%s\" (nb %d).",
2629
2630}
2631
2632/************************************************************************/
2635static void objbind_set_rowref(struct objbind *ob,
2637{
2638 if (!ob) {
2639 return;
2640 }
2641 ob->rowref = rr;
2642}
2643
2644/************************************************************************/
2648{
2649 if (!ob) {
2650 return NULL;
2651 }
2652 return ob->rowref;
2653}
2654
2655/************************************************************************/
2658static int objprop_get_id(const struct objprop *op)
2659{
2660 if (!op) {
2661 return -1;
2662 }
2663 return op->id;
2664}
2665
2666/************************************************************************/
2673static GType objprop_get_gtype(const struct objprop *op)
2674{
2676
2677 switch (op->valtype) {
2678 case VALTYPE_NONE:
2680 return G_TYPE_NONE;
2681 case VALTYPE_INT:
2682 return G_TYPE_INT;
2683 case VALTYPE_BOOL:
2684 /* We want to show it as translated string, not as untranslated G_TYPE_BOOLEAN */
2685 return G_TYPE_STRING;
2686 case VALTYPE_STRING:
2689 case VALTYPE_BV_SPECIAL:
2690 case VALTYPE_BV_ROADS:
2691 case VALTYPE_BV_BASES:
2693 return G_TYPE_STRING;
2694 case VALTYPE_PIXBUF:
2695 case VALTYPE_NATION:
2696 case VALTYPE_GOV:
2697 return GDK_TYPE_PIXBUF;
2698 }
2699 log_error("%s(): Unhandled value type %d.", __FUNCTION__, op->valtype);
2700 return G_TYPE_NONE;
2701}
2702
2703/************************************************************************/
2706static enum value_types objprop_get_valtype(const struct objprop *op)
2707{
2708 if (!op) {
2709 return VALTYPE_NONE;
2710 }
2711 return op->valtype;
2712}
2713
2714/************************************************************************/
2717static bool objprop_show_in_listview(const struct objprop *op)
2718{
2719 if (!op) {
2720 return FALSE;
2721 }
2722 return op->flags & OPF_IN_LISTVIEW;
2723}
2724
2725/************************************************************************/
2728static bool objprop_has_widget(const struct objprop *op)
2729{
2730 if (!op) {
2731 return FALSE;
2732 }
2733 return op->flags & OPF_HAS_WIDGET;
2734}
2735
2736/************************************************************************/
2742static const char *objprop_get_attribute_type_string(const struct objprop *op)
2743{
2744 GType gtype;
2745
2746 if (!op) {
2747 return NULL;
2748 }
2749
2751 if (gtype == G_TYPE_INT || gtype == G_TYPE_STRING
2752 || gtype == G_TYPE_BOOLEAN) {
2753 return "text";
2754 } else if (gtype == GDK_TYPE_PIXBUF) {
2755 return "pixbuf";
2756 }
2757
2758 return NULL;
2759}
2760
2761/************************************************************************/
2767static void objprop_set_column_id(struct objprop *op, int col_id)
2768{
2769 if (!op) {
2770 return;
2771 }
2772 op->column_id = col_id;
2773}
2774
2775/************************************************************************/
2780static int objprop_get_column_id(const struct objprop *op)
2781{
2782 if (!op) {
2783 return -1;
2784 }
2785 return op->column_id;
2786}
2787
2788/************************************************************************/
2793{
2794 if (!op) {
2795 return;
2796 }
2797 op->view_column = col;
2798}
2799
2800/************************************************************************/
2805{
2806 if (!op) {
2807 return NULL;
2808 }
2809 return op->view_column;
2810}
2811
2812/************************************************************************/
2815static const char *objprop_get_name(const struct objprop *op)
2816{
2817 if (!op) {
2818 return NULL;
2819 }
2820 return op->name;
2821}
2822
2823/************************************************************************/
2826static const char *objprop_get_tooltip(const struct objprop *op)
2827{
2828 if (!op) {
2829 return NULL;
2830 }
2831 return op->tooltip;
2832}
2833
2834/************************************************************************/
2840{
2842 GType gtype;
2843
2845
2846 if (gtype == G_TYPE_INT || gtype == G_TYPE_STRING
2847 || gtype == G_TYPE_BOOLEAN) {
2849 } else if (gtype == GDK_TYPE_PIXBUF) {
2851 }
2852
2853 return cell;
2854}
2855
2856/************************************************************************/
2860static bool objprop_is_sortable(const struct objprop *op)
2861{
2862 GType gtype;
2863 if (!op) {
2864 return FALSE;
2865 }
2867 return gtype == G_TYPE_INT || gtype == G_TYPE_STRING;
2868}
2869
2870/************************************************************************/
2874static bool objprop_is_readonly(const struct objprop *op)
2875{
2876 if (!op) {
2877 return TRUE;
2878 }
2879 return !(op->flags & OPF_EDITABLE);
2880}
2881
2882/************************************************************************/
2886{
2887 struct objprop *op;
2888 struct property_page *pp;
2889 struct propval value = {{0,}, VALTYPE_STRING, FALSE};
2890
2891 op = userdata;
2894
2895 property_page_change_value(pp, op, &value);
2896}
2897
2898/************************************************************************/
2903{
2904 struct objprop *op;
2905 struct property_page *pp;
2906 struct propval value = {{0,}, VALTYPE_INT, FALSE};
2907
2908 op = userdata;
2911
2912 property_page_change_value(pp, op, &value);
2913}
2914
2915/************************************************************************/
2920{
2921 struct objprop *op;
2922 struct property_page *pp;
2923 struct propval value = {{0,}, VALTYPE_BOOL, FALSE};
2924
2925 op = userdata;
2928
2930}
2931
2932/************************************************************************/
2935static void objprop_setup_widget(struct objprop *op)
2936{
2937 GtkWidget *ebox, *hbox, *hbox2, *label, *image, *entry, *spin, *button;
2938 struct extviewer *ev = NULL;
2940
2941 if (!op) {
2942 return;
2943 }
2944
2945 if (!objprop_has_widget(op)) {
2946 return;
2947 }
2948
2949 ebox = gtk_event_box_new();
2950 op->widget = ebox;
2951
2952 hbox = gtk_grid_new();
2954
2956
2961 objprop_set_child_widget(op, "name-label", label);
2962
2964
2965 switch (propid) {
2966 case OPID_TILE_INDEX:
2967 case OPID_TILE_X:
2968 case OPID_TILE_Y:
2969 case OPID_TILE_NAT_X:
2970 case OPID_TILE_NAT_Y:
2972 case OPID_TILE_TERRAIN:
2973 case OPID_TILE_RESOURCE:
2974 case OPID_TILE_XY:
2975 case OPID_STARTPOS_XY:
2976 case OPID_UNIT_ID:
2977 case OPID_UNIT_XY:
2978 case OPID_UNIT_TYPE:
2979 case OPID_CITY_ID:
2980 case OPID_CITY_XY:
2981 case OPID_PLAYER_AGE:
2982#ifdef FREECIV_DEBUG
2983 case OPID_TILE_ADDRESS:
2984 case OPID_UNIT_ADDRESS:
2985 case OPID_CITY_ADDRESS:
2987#endif /* FREECIV_DEBUG */
2988 label = gtk_label_new(NULL);
2993 objprop_set_child_widget(op, "value-label", label);
2994 return;
2995
2996 case OPID_TILE_IMAGE:
2998 case OPID_UNIT_IMAGE:
2999 case OPID_CITY_IMAGE:
3000 image = gtk_image_new();
3006 return;
3007
3008 case OPID_CITY_NAME:
3009 case OPID_PLAYER_NAME:
3011 case OPID_TILE_LABEL:
3012 entry = gtk_entry_new();
3016 g_signal_connect(entry, "changed",
3020 return;
3021
3023 case OPID_CITY_SIZE:
3024 case OPID_CITY_HISTORY:
3028 case OPID_PLAYER_GOLD:
3029 spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0);
3032 g_signal_connect(spin, "value-changed",
3036 return;
3037
3038 case OPID_UNIT_FUEL:
3039 case OPID_UNIT_HP:
3040 case OPID_UNIT_VETERAN:
3042 hbox2 = gtk_grid_new();
3047 spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0);
3048 g_signal_connect(spin, "value-changed",
3052 label = gtk_label_new(NULL);
3056 objprop_set_child_widget(op, "max-value-label", label);
3057 return;
3058
3059 case OPID_TILE_SPECIALS:
3060 case OPID_TILE_ROADS:
3061 case OPID_TILE_BASES:
3062 case OPID_TILE_VISION:
3065 case OPID_PLAYER_NATION:
3066 case OPID_PLAYER_GOV:
3070 ev = extviewer_new(op);
3076 return;
3077
3079 case OPID_UNIT_MOVED:
3081 case OPID_UNIT_STAY:
3082 case OPID_GAME_SCENARIO:
3090 button = gtk_check_button_new();
3093 g_signal_connect(button, "toggled",
3096 objprop_set_child_widget(op, "checkbutton", button);
3097 return;
3098 }
3099
3100 log_error("%s(): Unhandled request to create widget for property %d (%s).",
3102}
3103
3104/************************************************************************/
3113 struct objbind *ob)
3114{
3115 GtkWidget *w, *label, *image, *entry, *spin, *button;
3116 struct extviewer *ev;
3117 struct propval *pv;
3118 bool modified;
3120 double min, max, step, big_step;
3121 char buf[256];
3122
3123 if (!op || !objprop_has_widget(op)) {
3124 return;
3125 }
3126
3128 if (!w) {
3129 return;
3130 }
3131
3133
3134 /* NB: We must take care to propval_free the return value of
3135 * objbind_get_value_from_object(), since it always makes a
3136 * copy, but to NOT free the result of objbind_get_modified_value()
3137 * since it returns its own stored value. */
3140
3141 if (pv && modified) {
3142 struct propval *pv_mod;
3143
3145 if (pv_mod) {
3146 if (propval_equal(pv, pv_mod)) {
3148 modified = FALSE;
3149 } else {
3151 pv = pv_mod;
3152 modified = TRUE;
3153 }
3154 } else {
3155 modified = FALSE;
3156 }
3157 }
3158
3159 switch (propid) {
3160 case OPID_TILE_IMAGE:
3162 case OPID_UNIT_IMAGE:
3163 case OPID_CITY_IMAGE:
3164 image = objprop_get_child_widget(op, "image");
3165 if (pv) {
3166 gtk_image_set_from_pixbuf(GTK_IMAGE(image), pv->data.v_pixbuf);
3167 } else {
3169 }
3170 break;
3171
3172 case OPID_TILE_XY:
3173 case OPID_TILE_TERRAIN:
3174 case OPID_TILE_RESOURCE:
3175 case OPID_STARTPOS_XY:
3176 case OPID_UNIT_XY:
3177 case OPID_UNIT_TYPE:
3178 case OPID_CITY_XY:
3179#ifdef FREECIV_DEBUG
3180 case OPID_TILE_ADDRESS:
3181 case OPID_UNIT_ADDRESS:
3182 case OPID_CITY_ADDRESS:
3184#endif /* FREECIV_DEBUG */
3185 label = objprop_get_child_widget(op, "value-label");
3186 if (pv) {
3187 gtk_label_set_text(GTK_LABEL(label), pv->data.v_string);
3188 } else {
3190 }
3191 break;
3192
3193 case OPID_TILE_INDEX:
3194 case OPID_TILE_X:
3195 case OPID_TILE_Y:
3196 case OPID_TILE_NAT_X:
3197 case OPID_TILE_NAT_Y:
3199 case OPID_UNIT_ID:
3200 case OPID_CITY_ID:
3201 case OPID_PLAYER_AGE:
3202 label = objprop_get_child_widget(op, "value-label");
3203 if (pv) {
3204 char agebuf[16];
3205
3206 fc_snprintf(agebuf, sizeof(agebuf), "%d", pv->data.v_int);
3208 } else {
3210 }
3211 break;
3212
3213 case OPID_CITY_NAME:
3214 case OPID_PLAYER_NAME:
3216 case OPID_TILE_LABEL:
3217 entry = objprop_get_child_widget(op, "entry");
3218 if (pv) {
3219 gtk_entry_set_text(GTK_ENTRY(entry), pv->data.v_string);
3220 } else {
3222 }
3224 break;
3225
3227 case OPID_CITY_SIZE:
3228 case OPID_CITY_HISTORY:
3232 case OPID_PLAYER_GOLD:
3233 spin = objprop_get_child_widget(op, "spin");
3234 if (pv) {
3237 if (objbind_get_allowed_value_span(ob, op, &min, &max,
3238 &step, &big_step)) {
3241 step, big_step);
3242 }
3246 }
3248 break;
3249
3250 case OPID_UNIT_FUEL:
3251 case OPID_UNIT_HP:
3252 case OPID_UNIT_VETERAN:
3254 spin = objprop_get_child_widget(op, "spin");
3255 label = objprop_get_child_widget(op, "max-value-label");
3256 if (pv) {
3259 if (objbind_get_allowed_value_span(ob, op, &min, &max,
3260 &step, &big_step)) {
3263 step, big_step);
3264 fc_snprintf(buf, sizeof(buf), "/%d", (int) max);
3266 } else {
3268 }
3272 } else {
3274 }
3276 break;
3277
3278 case OPID_TILE_SPECIALS:
3279 case OPID_TILE_ROADS:
3280 case OPID_TILE_BASES:
3281 case OPID_TILE_VISION:
3284 case OPID_PLAYER_NATION:
3285 case OPID_PLAYER_GOV:
3290 if (pv) {
3292 } else {
3294 }
3295 break;
3296
3298 case OPID_UNIT_MOVED:
3300 case OPID_UNIT_STAY:
3301 case OPID_GAME_SCENARIO:
3309 button = objprop_get_child_widget(op, "checkbutton");
3312 if (pv) {
3314 pv->data.v_bool);
3315 } else {
3317 }
3320 gtk_widget_set_sensitive(button, pv != NULL);
3321 break;
3322 }
3323
3324 if (!modified) {
3326 }
3327
3328 label = objprop_get_child_widget(op, "name-label");
3329 if (label) {
3330 const char *name = objprop_get_name(op);
3331 if (modified) {
3332 char namebuf[128];
3333
3334 fc_snprintf(namebuf, sizeof(namebuf),
3335 "<span foreground=\"red\">%s</span>", name);
3337 } else {
3339 }
3340 }
3341}
3342
3343/************************************************************************/
3348{
3349 if (!op) {
3350 return NULL;
3351 }
3352 if (!op->widget) {
3354 }
3355 return op->widget;
3356}
3357
3358/************************************************************************/
3363 const char *widget_name,
3365{
3366 GtkWidget *w;
3367
3368 if (!op || !widget_name || !widget) {
3369 return;
3370 }
3371
3373 if (!w) {
3374 log_error("Cannot store child widget %p under name "
3375 "\"%s\" using objprop_set_child_widget for object "
3376 "property %d (%s) because objprop_get_widget does "
3377 "not return a valid widget.",
3379 return;
3380 }
3381
3383}
3384
3385/************************************************************************/
3390 const char *widget_name)
3391{
3392 GtkWidget *w, *child;
3393
3394 if (!op || !widget_name) {
3395 return NULL;
3396 }
3397
3399 if (!w) {
3400 log_error("Cannot retrieve child widget under name "
3401 "\"%s\" using objprop_get_child_widget for object "
3402 "property %d (%s) because objprop_get_widget does "
3403 "not return a valid widget.",
3405 return NULL;
3406 }
3407
3409 if (!child) {
3410 log_error("Child widget \"%s\" not found for object "
3411 "property %d (%s) via objprop_get_child_widget.",
3413 return NULL;
3414 }
3415
3416 return child;
3417}
3418
3419/************************************************************************/
3423 struct extviewer *ev)
3424{
3425 if (!op) {
3426 return;
3427 }
3428 op->extviewer = ev;
3429}
3430
3431/************************************************************************/
3435{
3436 if (!op) {
3437 return NULL;
3438 }
3439 return op->extviewer;
3440}
3441
3442/************************************************************************/
3446{
3447 if (!op) {
3448 return NULL;
3449 }
3450 return op->parent_page;
3451}
3452
3453/************************************************************************/
3456static struct objprop *objprop_new(int id,
3457 const char *name,
3458 const char *tooltip,
3460 enum value_types valtype,
3461 struct property_page *parent)
3462{
3463 struct objprop *op;
3464
3465 op = fc_calloc(1, sizeof(*op));
3466 op->id = id;
3467 op->name = name;
3468 op->tooltip = tooltip;
3469 op->flags = flags;
3470 op->valtype = valtype;
3471 op->column_id = -1;
3472 op->parent_page = parent;
3473
3474 return op;
3475}
3476
3477/************************************************************************/
3481static struct extviewer *extviewer_new(struct objprop *op)
3482{
3483 struct extviewer *ev;
3484 GtkWidget *hbox, *vbox, *label, *button, *scrollwin, *image;
3485 GtkWidget *view = NULL;
3489 GType *gtypes;
3491 int num_cols;
3492
3493 if (!op) {
3494 return NULL;
3495 }
3496
3497 ev = fc_calloc(1, sizeof(*ev));
3498 ev->objprop = op;
3499
3501
3502
3503 /* Create the panel widget. */
3504
3505 switch (propid) {
3506 case OPID_TILE_SPECIALS:
3507 case OPID_TILE_ROADS:
3508 case OPID_TILE_BASES:
3514 hbox = gtk_grid_new();
3516 ev->panel_widget = hbox;
3517
3518 label = gtk_label_new(NULL);
3522 ev->panel_label = label;
3523 break;
3524
3525 case OPID_PLAYER_NATION:
3526 case OPID_PLAYER_GOV:
3527 vbox = gtk_grid_new();
3531 ev->panel_widget = vbox;
3532
3533 label = gtk_label_new(NULL);
3536 gtk_container_add(GTK_CONTAINER(vbox), label);
3537 ev->panel_label = label;
3538
3539 hbox = gtk_grid_new();
3542
3543 image = gtk_image_new();
3547 ev->panel_image = image;
3548 break;
3549
3550 case OPID_TILE_VISION:
3551 hbox = gtk_grid_new();
3553 ev->panel_widget = hbox;
3554 break;
3555
3556 default:
3557 log_error("Unhandled request to create panel widget "
3558 "for property %d (%s) in extviewer_new().",
3560 hbox = gtk_grid_new();
3562 ev->panel_widget = hbox;
3563 break;
3564 }
3565
3566 if (objprop_is_readonly(op)) {
3567 button = gtk_button_new_with_label(Q_("?verb:View"));
3568 } else {
3569 button = gtk_button_new_with_label(_("Edit"));
3570 }
3571 g_signal_connect(button, "clicked",
3574 ev->panel_button = button;
3575
3576
3577 /* Create the data store. */
3578
3579 switch (propid) {
3580 case OPID_TILE_SPECIALS:
3581 case OPID_TILE_ROADS:
3582 case OPID_TILE_BASES:
3586 break;
3587 case OPID_TILE_VISION:
3588 num_cols = 3 + 1 + V_COUNT;
3589 gtypes = fc_malloc(num_cols * sizeof(GType));
3590 gtypes[0] = G_TYPE_INT; /* player number */
3591 gtypes[1] = GDK_TYPE_PIXBUF; /* player flag */
3592 gtypes[2] = G_TYPE_STRING; /* player name */
3593 gtypes[3] = G_TYPE_BOOLEAN; /* tile_known */
3595 gtypes[4 + v] = G_TYPE_BOOLEAN; /* tile_seen[v] */
3598 free(gtypes);
3599 break;
3603 break;
3605 case OPID_PLAYER_NATION:
3606 case OPID_PLAYER_GOV:
3609 break;
3613 break;
3614 default:
3615 log_error("Unhandled request to create data store "
3616 "for property %d (%s) in extviewer_new().",
3618 break;
3619 }
3620
3621 ev->store = store;
3622 ev->textbuf = textbuf;
3623
3624 /* Create the view widget. */
3625
3626 vbox = gtk_grid_new();
3631 ev->view_widget = vbox;
3632
3636 gtk_container_add(GTK_CONTAINER(vbox), label);
3637 ev->view_label = label;
3638
3639 if (store || textbuf) {
3647
3648 if (store) {
3652 } else {
3653 const bool editable = !objprop_is_readonly(op);
3657 }
3660
3662 }
3663
3664 switch (propid) {
3665
3666 case OPID_TILE_SPECIALS:
3667 case OPID_TILE_ROADS:
3668 case OPID_TILE_BASES:
3669 /* TRANS: As in "this tile special is present". */
3670 add_column(view, 0, _("Present"), G_TYPE_BOOLEAN, TRUE, FALSE,
3672 add_column(view, 1, _("ID"), G_TYPE_INT,
3673 FALSE, FALSE, NULL, NULL);
3674 add_column(view, 2, _("Name"), G_TYPE_STRING,
3675 FALSE, FALSE, NULL, NULL);
3676 break;
3677
3678 case OPID_TILE_VISION:
3679 add_column(view, 0, _("ID"), G_TYPE_INT,
3680 FALSE, FALSE, NULL, NULL);
3681 add_column(view, 1, _("Nation"), GDK_TYPE_PIXBUF,
3682 FALSE, FALSE, NULL, NULL);
3683 add_column(view, 2, _("Name"), G_TYPE_STRING,
3684 FALSE, FALSE, NULL, NULL);
3685 add_column(view, 3, _("Known"), G_TYPE_BOOLEAN,
3686 FALSE, FALSE, NULL, NULL);
3691 break;
3692
3694 /* TRANS: As in "this building is present". */
3695 add_column(view, 0, _("Present"), G_TYPE_BOOLEAN, TRUE, FALSE,
3697 add_column(view, 1, _("ID"), G_TYPE_INT,
3698 FALSE, FALSE, NULL, NULL);
3699 add_column(view, 2, _("Name"), G_TYPE_STRING,
3700 FALSE, FALSE, NULL, NULL);
3701 /* TRANS: As in "the turn when this building was built". */
3702 add_column(view, 3, _("Turn Built"), G_TYPE_STRING,
3703 FALSE, FALSE, NULL, NULL);
3704 break;
3705
3707 /* TRANS: As in "the player has set this nation". */
3708 add_column(view, 0, _("Set"), G_TYPE_BOOLEAN, TRUE, FALSE,
3710 add_column(view, 1, _("ID"), G_TYPE_INT,
3711 FALSE, FALSE, NULL, NULL);
3712 add_column(view, 2, _("Flag"), GDK_TYPE_PIXBUF,
3713 FALSE, FALSE, NULL, NULL);
3714 add_column(view, 3, _("Name"), G_TYPE_STRING,
3715 FALSE, FALSE, NULL, NULL);
3716 break;
3717
3718 case OPID_PLAYER_NATION:
3719 case OPID_PLAYER_GOV:
3720 /* TRANS: As in "the player has set this nation". */
3721 add_column(view, 0, _("Set"), G_TYPE_BOOLEAN, TRUE, TRUE,
3723 add_column(view, 1, _("ID"), G_TYPE_INT,
3724 FALSE, FALSE, NULL, NULL);
3725 add_column(view, 2,
3726 propid == OPID_PLAYER_GOV ? _("Icon") : _("Flag"),
3728 FALSE, FALSE, NULL, NULL);
3729 add_column(view, 3, _("Name"), G_TYPE_STRING,
3730 FALSE, FALSE, NULL, NULL);
3731 break;
3732
3734 /* TRANS: As in "this invention is known". */
3735 add_column(view, 0, _("Known"), G_TYPE_BOOLEAN, TRUE, FALSE,
3737 add_column(view, 1, _("ID"), G_TYPE_INT,
3738 FALSE, FALSE, NULL, NULL);
3739 add_column(view, 2, _("Name"), G_TYPE_STRING,
3740 FALSE, FALSE, NULL, NULL);
3741 break;
3742
3745 g_signal_connect(textbuf, "changed",
3747 break;
3748
3749 default:
3750 log_error("Unhandled request to configure view widget "
3751 "for property %d (%s) in extviewer_new().",
3753 break;
3754 }
3755
3756 gtk_widget_show_all(ev->panel_widget);
3757 gtk_widget_show_all(ev->view_widget);
3758
3759 return ev;
3760}
3761
3762/************************************************************************/
3766{
3767 if (!ev) {
3768 return NULL;
3769 }
3770 return ev->objprop;
3771}
3772
3773/************************************************************************/
3778{
3779 if (!ev) {
3780 return NULL;
3781 }
3782 return ev->panel_widget;
3783}
3784
3785/************************************************************************/
3790{
3791 if (!ev) {
3792 return NULL;
3793 }
3794 return ev->view_widget;
3795}
3796
3797/************************************************************************/
3801 struct propval *pv)
3802{
3803 struct objprop *op;
3805 int id, turn_built;
3806 bool present, all;
3807 const char *name;
3809 GtkListStore *store;
3810 GtkTextBuffer *textbuf;
3812 gchar *buf;
3813
3814 if (!ev) {
3815 return;
3816 }
3817
3820
3821 if (propval_equal(pv, ev->pv_cached)) {
3822 return;
3823 }
3824 propval_free(ev->pv_cached);
3825 ev->pv_cached = propval_copy(pv);
3826 store = ev->store;
3827 textbuf = ev->textbuf;
3828
3829
3830 /* NB: Remember to have -1 as the last argument to
3831 * gtk_list_store_set() and to use the correct column
3832 * number when inserting data. :) */
3833 switch (propid) {
3834
3835 case OPID_TILE_SPECIALS:
3836 gtk_list_store_clear(store);
3838 id = spe->data.special_idx;
3840 present = BV_ISSET(pv->data.v_bv_special, id);
3841 gtk_list_store_append(store, &iter);
3842 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
3845 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3846 g_free(buf);
3847 break;
3848
3849 case OPID_TILE_ROADS:
3850 gtk_list_store_clear(store);
3852 struct road_type *proad = extra_road_get(pextra);
3853
3854 id = road_number(proad);
3855 name = extra_name_translation(pextra);
3856 present = BV_ISSET(pv->data.v_bv_roads, id);
3857 gtk_list_store_append(store, &iter);
3858 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
3861 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3862 g_free(buf);
3863 break;
3864
3865 case OPID_TILE_BASES:
3866 gtk_list_store_clear(store);
3868 struct base_type *pbase = extra_base_get(pextra);
3869
3870 id = base_number(pbase);
3871 name = extra_name_translation(pextra);
3872 present = BV_ISSET(pv->data.v_bv_bases, id);
3873 gtk_list_store_append(store, &iter);
3874 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
3877 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3878 g_free(buf);
3879 break;
3880
3881 case OPID_TILE_VISION:
3882 gtk_list_store_clear(store);
3883 player_slots_iterate(pslot) {
3884 id = player_slot_index(pslot);
3885 if (player_slot_is_used(pslot)) {
3886 struct player *pplayer = player_slot_get_player(pslot);
3887 name = player_name(pplayer);
3888 pixbuf = get_flag(pplayer->nation);
3889 } else {
3890 name = "";
3891 pixbuf = NULL;
3892 }
3893 gtk_list_store_append(store, &iter);
3894 gtk_list_store_set(store, &iter, 0, id, 2, name, -1);
3895 if (pixbuf) {
3896 gtk_list_store_set(store, &iter, 1, pixbuf, -1);
3898 pixbuf = NULL;
3899 }
3900 present = BV_ISSET(pv->data.v_tile_vision->tile_known, id);
3901 gtk_list_store_set(store, &iter, 3, present, -1);
3903 present = BV_ISSET(pv->data.v_tile_vision->tile_seen[v], id);
3904 gtk_list_store_set(store, &iter, 4 + v, present, -1);
3907 break;
3908
3910 gtk_list_store_clear(store);
3911 gtk_list_store_append(store, &iter);
3912 all = (0 == nation_hash_size(pv->data.v_nation_hash));
3913 gtk_list_store_set(store, &iter, 0, all, 1, -1, 3,
3914 _("All nations"), -1);
3915 nations_iterate(pnation) {
3917 && is_nation_playable(pnation)) {
3918 present = (!all && nation_hash_lookup(pv->data.v_nation_hash,
3919 pnation, NULL));
3920 id = nation_number(pnation);
3921 pixbuf = get_flag(pnation);
3923 gtk_list_store_append(store, &iter);
3924 gtk_list_store_set(store, &iter, 0, present, 1, id,
3925 2, pixbuf, 3, name, -1);
3926 if (pixbuf) {
3928 }
3929 }
3932 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3933 g_free(buf);
3934 break;
3935
3937 gtk_list_store_clear(store);
3938 improvement_iterate(pimprove) {
3939 if (is_special_improvement(pimprove)) {
3940 continue;
3941 }
3942 id = improvement_index(pimprove);
3944 turn_built = pv->data.v_built[id].turn;
3945 present = turn_built >= 0;
3946 buf = built_status_to_string(&pv->data.v_built[id]);
3947 gtk_list_store_append(store, &iter);
3948 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name,
3949 3, buf, -1);
3950 g_free(buf);
3953 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3954 g_free(buf);
3955 break;
3956
3957 case OPID_PLAYER_NATION:
3958 {
3959 enum barbarian_type barbarian_type =
3960 nation_barbarian_type(pv->data.v_nation);
3961
3962 gtk_list_store_clear(store);
3963 nations_iterate(pnation) {
3965 && nation_barbarian_type(pnation) == barbarian_type
3966 && (barbarian_type != NOT_A_BARBARIAN
3967 || is_nation_playable(pnation))) {
3968 present = (pnation == pv->data.v_nation);
3969 id = nation_index(pnation);
3970 pixbuf = get_flag(pnation);
3972 gtk_list_store_append(store, &iter);
3973 gtk_list_store_set(store, &iter, 0, present, 1, id,
3974 2, pixbuf, 3, name, -1);
3975 if (pixbuf) {
3977 }
3978 }
3980 gtk_label_set_text(GTK_LABEL(ev->panel_label),
3981 nation_adjective_translation(pv->data.v_nation));
3982 pixbuf = get_flag(pv->data.v_nation);
3984 if (pixbuf) {
3986 }
3987 }
3988 break;
3989
3990 case OPID_PLAYER_GOV:
3991 {
3992 gtk_list_store_clear(store);
3994 present = (pgov == pv->data.v_gov);
3995 id = government_index(pgov);
3998 gtk_list_store_append(store, &iter);
3999 gtk_list_store_set(store, &iter, 0, present, 1, id,
4000 2, pixbuf, 3, name, -1);
4001 if (pixbuf) {
4003 }
4005 gtk_label_set_text(GTK_LABEL(ev->panel_label),
4006 government_name_translation(pv->data.v_gov));
4009 if (pixbuf) {
4011 }
4012 }
4013 break;
4014
4016 gtk_list_store_clear(store);
4018 id = advance_index(padvance);
4019 present = BV_ISSET(pv->data.v_bv_inventions, id);
4021 gtk_list_store_append(store, &iter);
4022 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
4025 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4026 g_free(buf);
4027 break;
4028
4033 {
4034 GtkTextIter start, end;
4035 char *oldtext;
4036
4037 /* Don't re-set content if unchanged, to avoid moving cursor */
4038 gtk_text_buffer_get_bounds(textbuf, &start, &end);
4039 oldtext = gtk_text_buffer_get_text(textbuf, &start, &end, TRUE);
4040 if (strcmp(oldtext, pv->data.v_const_string) != 0) {
4041 gtk_text_buffer_set_text(textbuf, pv->data.v_const_string, -1);
4042 }
4043 }
4046 gtk_widget_set_sensitive(ev->view_widget, TRUE);
4048 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4049 g_free(buf);
4050 break;
4051
4052 default:
4053 log_error("Unhandled request to refresh widgets "
4054 "extviewer_refresh_widgets() for objprop id=%d "
4055 "name \"%s\".", propid, objprop_get_name(op));
4056 break;
4057 }
4058}
4059
4060/************************************************************************/
4064{
4065 struct objprop *op;
4067
4068 if (!ev) {
4069 return;
4070 }
4071
4074
4075 propval_free(ev->pv_cached);
4076 ev->pv_cached = NULL;
4077
4078 if (ev->panel_label != NULL) {
4079 gtk_label_set_text(GTK_LABEL(ev->panel_label), NULL);
4080 }
4081
4082 switch (propid) {
4083 case OPID_TILE_SPECIALS:
4084 case OPID_TILE_ROADS:
4085 case OPID_TILE_BASES:
4086 case OPID_TILE_VISION:
4090 gtk_list_store_clear(ev->store);
4091 break;
4092 case OPID_PLAYER_NATION:
4093 case OPID_PLAYER_GOV:
4094 gtk_list_store_clear(ev->store);
4096 break;
4101 gtk_text_buffer_set_text(ev->textbuf, "", -1);
4104 gtk_widget_set_sensitive(ev->view_widget, FALSE);
4105 break;
4106 default:
4107 log_error("Unhandled request to clear widgets "
4108 "in extviewer_clear_widgets() for objprop id=%d "
4109 "name \"%s\".", propid, objprop_get_name(op));
4110 break;
4111 }
4112}
4113
4114/************************************************************************/
4120{
4121 struct extviewer *ev;
4122 struct property_page *pp;
4123 struct objprop *op;
4124
4125 ev = userdata;
4126 if (!ev) {
4127 return;
4128 }
4129
4133}
4134
4135/************************************************************************/
4139 gchar *path,
4141{
4142 struct extviewer *ev;
4143 struct objprop *op;
4144 struct property_page *pp;
4146 GtkTreeModel *model;
4148 int id, old_id, turn_built;
4149 struct propval *pv;
4150 bool active, present;
4151 gchar *buf;
4153
4154 ev = userdata;
4155 if (!ev) {
4156 return;
4157 }
4158
4159 pv = ev->pv_cached;
4160 if (!pv) {
4161 return;
4162 }
4163
4168
4169 model = GTK_TREE_MODEL(ev->store);
4170 if (!gtk_tree_model_get_iter_from_string(model, &iter, path)) {
4171 return;
4172 }
4173 present = !active;
4174
4175
4176 switch (propid) {
4177
4178 case OPID_TILE_SPECIALS:
4179 gtk_tree_model_get(model, &iter, 1, &id, -1);
4181 return;
4182 }
4183 if (present) {
4184 BV_SET(pv->data.v_bv_special, id);
4185 } else {
4186 BV_CLR(pv->data.v_bv_special, id);
4187 }
4188 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4190 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4191 g_free(buf);
4192 break;
4193
4194 case OPID_TILE_ROADS:
4195 gtk_tree_model_get(model, &iter, 1, &id, -1);
4196 if (!(0 <= id && id < road_count())) {
4197 return;
4198 }
4199 if (present) {
4200 BV_SET(pv->data.v_bv_roads, id);
4201 } else {
4202 BV_CLR(pv->data.v_bv_roads, id);
4203 }
4204 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4206 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4207 g_free(buf);
4208 break;
4209
4210 case OPID_TILE_BASES:
4211 gtk_tree_model_get(model, &iter, 1, &id, -1);
4212 if (!(0 <= id && id < base_count())) {
4213 return;
4214 }
4215 if (present) {
4216 BV_SET(pv->data.v_bv_bases, id);
4217 } else {
4218 BV_CLR(pv->data.v_bv_bases, id);
4219 }
4220 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4222 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4223 g_free(buf);
4224 break;
4225
4227 gtk_tree_model_get(model, &iter, 1, &id, -1);
4228 if (-1 > id && id >= nation_count()) {
4229 return;
4230 }
4231
4232 if (-1 == id) {
4233 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4235 if (present) {
4236 while (gtk_tree_model_iter_next(model, &iter)) {
4237 gtk_list_store_set(ev->store, &iter, 0, FALSE, -1);
4238 }
4239 nation_hash_clear(pv->data.v_nation_hash);
4240 } else {
4241 const struct nation_type *pnation;
4242 int id2;
4243
4245 gtk_tree_model_get(model, &iter, 0, &id2, -1);
4246 gtk_list_store_set(ev->store, &iter, 0, TRUE, -1);
4247 pnation = nation_by_number(id2);
4248 nation_hash_insert(pv->data.v_nation_hash, pnation, NULL);
4249 }
4250 } else {
4251 const struct nation_type *pnation;
4252 bool all;
4253
4254 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4255 pnation = nation_by_number(id);
4256 if (present) {
4257 nation_hash_insert(pv->data.v_nation_hash, pnation, NULL);
4258 } else {
4259 nation_hash_remove(pv->data.v_nation_hash, pnation);
4260 }
4262 all = (0 == nation_hash_size(pv->data.v_nation_hash));
4263 gtk_list_store_set(ev->store, &iter, 0, all, -1);
4264 }
4266 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4267 g_free(buf);
4268 break;
4269
4271 gtk_tree_model_get(model, &iter, 1, &id, -1);
4272 if (!(0 <= id && id < B_LAST)) {
4273 return;
4274 }
4275 turn_built = present ? game.info.turn : I_NEVER;
4276 pv->data.v_built[id].turn = turn_built;
4277 buf = built_status_to_string(&pv->data.v_built[id]);
4278 gtk_list_store_set(ev->store, &iter, 0, present, 3, buf, -1);
4279 g_free(buf);
4281 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4282 g_free(buf);
4283 break;
4284
4285 case OPID_PLAYER_NATION:
4286 gtk_tree_model_get(model, &iter, 1, &id, -1);
4287 if (!(0 <= id && id < nation_count()) || !present) {
4288 return;
4289 }
4290 old_id = nation_index(pv->data.v_nation);
4291 pv->data.v_nation = nation_by_number(id);
4292 gtk_list_store_set(ev->store, &iter, 0, TRUE, -1);
4294 gtk_list_store_set(ev->store, &iter, 0, FALSE, -1);
4295 gtk_label_set_text(GTK_LABEL(ev->panel_label),
4296 nation_adjective_translation(pv->data.v_nation));
4297 pixbuf = get_flag(pv->data.v_nation);
4299 if (pixbuf) {
4301 }
4302 break;
4303
4304 case OPID_PLAYER_GOV:
4305 gtk_tree_model_get(model, &iter, 1, &id, -1);
4306 if (!(0 <= id && id < government_count()) || !present) {
4307 return;
4308 }
4309 old_id = government_index(pv->data.v_gov);
4310 pv->data.v_gov = government_by_number(id);
4311 gtk_list_store_set(ev->store, &iter, 0, TRUE, -1);
4313 gtk_list_store_set(ev->store, &iter, 0, FALSE, -1);
4314 gtk_label_set_text(GTK_LABEL(ev->panel_label),
4315 government_name_translation(pv->data.v_gov));
4318 if (pixbuf) {
4320 }
4321 break;
4322
4324 gtk_tree_model_get(model, &iter, 1, &id, -1);
4325 if (!(A_FIRST <= id && id < advance_count())) {
4326 return;
4327 }
4328 if (present) {
4329 BV_SET(pv->data.v_bv_inventions, id);
4330 } else {
4331 BV_CLR(pv->data.v_bv_inventions, id);
4332 }
4333 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4335 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4336 g_free(buf);
4337 break;
4338
4339 default:
4340 log_error("Unhandled widget toggled signal in "
4341 "extviewer_view_cell_toggled() for objprop id=%d "
4342 "name \"%s\".", propid, objprop_get_name(op));
4343 return;
4344 break;
4345 }
4346
4348}
4349
4350/************************************************************************/
4355{
4356 struct extviewer *ev;
4357 struct objprop *op;
4358 struct property_page *pp;
4360 struct propval value = {{0,}, VALTYPE_STRING, FALSE}, *pv;
4361 GtkTextIter start, end;
4362 char *text;
4363 gchar *buf;
4364
4365 ev = userdata;
4366 if (!ev) {
4367 return;
4368 }
4369
4373
4374 gtk_text_buffer_get_start_iter(textbuf, &start);
4375 gtk_text_buffer_get_end_iter(textbuf, &end);
4376 text = gtk_text_buffer_get_text(textbuf, &start, &end, FALSE);
4377 value.data.v_const_string = text;
4378 pv = &value;
4379
4380 switch (propid) {
4384 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4385 g_free(buf);
4386 break;
4387 default:
4388 log_error("Unhandled widget modified signal in "
4389 "extviewer_textbuf_changed() for objprop id=%d "
4390 "name \"%s\".", propid, objprop_get_name(op));
4391 return;
4392 break;
4393 }
4394
4396 g_free(text);
4397}
4398
4399/************************************************************************/
4403{
4404#define ADDPROP(ARG_id, ARG_name, ARG_tooltip, ARG_flags, ARG_valtype) do { \
4405 struct objprop *MY_op = objprop_new(ARG_id, ARG_name, ARG_tooltip, \
4406 ARG_flags, ARG_valtype, pp); \
4407 objprop_hash_insert(pp->objprop_table, MY_op->id, MY_op); \
4408} while (FALSE)
4409
4410 switch (property_page_get_objtype(pp)) {
4411 case OBJTYPE_TILE:
4412 ADDPROP(OPID_TILE_IMAGE, _("Image"), NULL,
4414 ADDPROP(OPID_TILE_TERRAIN, _("Terrain"), NULL,
4416 ADDPROP(OPID_TILE_RESOURCE, _("Resource"), NULL,
4418 ADDPROP(OPID_TILE_INDEX, _("Index"), NULL,
4420 ADDPROP(OPID_TILE_X, Q_("?coordinate:X"), NULL,
4422 ADDPROP(OPID_TILE_Y, Q_("?coordinate:Y"), NULL,
4424 /* TRANS: The coordinate X in native coordinates.
4425 * The freeciv coordinate system is described in doc/HACKING. */
4426 ADDPROP(OPID_TILE_NAT_X, _("NAT X"), NULL,
4428 /* TRANS: The coordinate Y in native coordinates.
4429 * The freeciv coordinate system is described in doc/HACKING. */
4430 ADDPROP(OPID_TILE_NAT_Y, _("NAT Y"), NULL,
4432 ADDPROP(OPID_TILE_CONTINENT, _("Continent"), NULL,
4434 ADDPROP(OPID_TILE_XY, Q_("?coordinates:X,Y"), NULL,
4436 ADDPROP(OPID_TILE_SPECIALS, _("Specials"), NULL,
4439 ADDPROP(OPID_TILE_ROADS, _("Roads"), NULL,
4442 ADDPROP(OPID_TILE_BASES, _("Bases"), NULL,
4445#ifdef FREECIV_DEBUG
4446 ADDPROP(OPID_TILE_ADDRESS, _("Address"), NULL,
4448#endif /* FREECIV_DEBUG */
4449#if 0
4450 /* Disabled entirely for now as server is not sending other
4451 * players' vision information anyway. */
4452 ADDPROP(OPID_TILE_VISION, _("Vision"), NULL,
4454#endif
4455 /* TRANS: Tile property "Label" label in editor */
4456 ADDPROP(OPID_TILE_LABEL, Q_("?property:Label"), NULL,
4458 return;
4459
4460 case OBJTYPE_STARTPOS:
4461 ADDPROP(OPID_STARTPOS_IMAGE, _("Image"), NULL,
4463 ADDPROP(OPID_STARTPOS_XY, Q_("?coordinates:X,Y"), NULL,
4465 ADDPROP(OPID_STARTPOS_EXCLUDE, _("Exclude Nations"), NULL,
4467 ADDPROP(OPID_STARTPOS_NATIONS, _("Nations"), NULL,
4470 return;
4471
4472 case OBJTYPE_UNIT:
4473 ADDPROP(OPID_UNIT_IMAGE, _("Image"), NULL,
4475#ifdef FREECIV_DEBUG
4476 ADDPROP(OPID_UNIT_ADDRESS, _("Address"), NULL,
4478#endif /* FREECIV_DEBUG */
4479 ADDPROP(OPID_UNIT_TYPE, _("Type"), NULL,
4481 ADDPROP(OPID_UNIT_ID, _("ID"), NULL,
4483 ADDPROP(OPID_UNIT_XY, Q_("?coordinates:X,Y"), NULL,
4485 ADDPROP(OPID_UNIT_MOVES_LEFT, _("Moves Left"), NULL,
4487 ADDPROP(OPID_UNIT_FUEL, _("Fuel"), NULL,
4489 ADDPROP(OPID_UNIT_MOVED, _("Moved"), NULL,
4491 ADDPROP(OPID_UNIT_DONE_MOVING, _("Done Moving"), NULL,
4493 /* TRANS: HP = Hit Points of a unit. */
4494 ADDPROP(OPID_UNIT_HP, _("HP"), NULL,
4496 ADDPROP(OPID_UNIT_VETERAN, _("Veteran"), NULL,
4498 ADDPROP(OPID_UNIT_STAY, _("Stay put"), NULL,
4500 return;
4501
4502 case OBJTYPE_CITY:
4503 ADDPROP(OPID_CITY_IMAGE, _("Image"), NULL,
4505 ADDPROP(OPID_CITY_NAME, _("Name"), NULL,
4507#ifdef FREECIV_DEBUG
4508 ADDPROP(OPID_CITY_ADDRESS, _("Address"), NULL,
4510#endif /* FREECIV_DEBUG */
4511 ADDPROP(OPID_CITY_ID, _("ID"), NULL,
4513 ADDPROP(OPID_CITY_XY, Q_("?coordinates:X,Y"), NULL,
4515 ADDPROP(OPID_CITY_SIZE, _("Size"), NULL,
4517 ADDPROP(OPID_CITY_HISTORY, _("History"), NULL,
4519 ADDPROP(OPID_CITY_BUILDINGS, _("Buildings"), NULL,
4522 ADDPROP(OPID_CITY_FOOD_STOCK, _("Food Stock"), NULL,
4524 ADDPROP(OPID_CITY_SHIELD_STOCK, _("Shield Stock"), NULL,
4526 return;
4527
4528 case OBJTYPE_PLAYER:
4529 ADDPROP(OPID_PLAYER_NAME, _("Name"), NULL,
4532#ifdef FREECIV_DEBUG
4533 ADDPROP(OPID_PLAYER_ADDRESS, _("Address"), NULL,
4535#endif /* FREECIV_DEBUG */
4536 ADDPROP(OPID_PLAYER_NATION, _("Nation"), NULL,
4539 ADDPROP(OPID_PLAYER_GOV, _("Government"), NULL,
4541 VALTYPE_GOV);
4542 ADDPROP(OPID_PLAYER_AGE, _("Age"), NULL,
4544 ADDPROP(OPID_PLAYER_INVENTIONS, _("Inventions"), NULL,
4549 ADDPROP(OPID_PLAYER_SELECT_WEIGHT, _("Select Weight"),
4550 _("How likely user is to get this player by autoselect. '-1' for default behavior."),
4552 VALTYPE_INT);
4553 ADDPROP(OPID_PLAYER_SCIENCE, _("Science"), NULL,
4555 ADDPROP(OPID_PLAYER_GOLD, _("Gold"), NULL,
4557 VALTYPE_INT);
4558 return;
4559
4560 case OBJTYPE_GAME:
4561 ADDPROP(OPID_GAME_SCENARIO, _("Scenario"), NULL,
4563 VALTYPE_BOOL);
4565 _("Scenario Name"), NULL,
4569 _("Scenario Authors"), NULL,
4573 _("Scenario Description"), NULL,
4577 _("Save Random Number State"), NULL,
4580 _("Save Players"), NULL,
4583 _("Nation Start Positions"), NULL,
4586 _("Prevent New Cities"), NULL,
4589 _("Saltwater Flooding Lakes"), NULL,
4592 _("Lock to current Ruleset"), NULL,
4594 return;
4595
4596 case NUM_OBJTYPES:
4597 break;
4598 }
4599
4600 log_error("%s(): Unhandled page object type %s (nb %d).", __FUNCTION__,
4603#undef ADDPROP
4604}
4605
4606/************************************************************************/
4629
4630/************************************************************************/
4635 GtkTreeModel *model,
4638 gpointer data)
4639{
4640 struct property_page *pp;
4641 struct objbind *ob = NULL, *old_ob;
4643
4644 pp = data;
4645 if (!pp || !sel_path) {
4646 return TRUE;
4647 }
4648
4649 if (!gtk_tree_model_get_iter(model, &iter, sel_path)) {
4650 return TRUE;
4651 }
4652
4654 gtk_tree_model_get(model, &iter, 0, &ob, -1);
4655 if (currently_selected) {
4656 if (ob == old_ob) {
4657 GList *rows, *p;
4658 GtkTreePath *path;
4659 struct objbind *new_ob = NULL;
4660
4662 for (p = rows; p != NULL; p = p->next) {
4663 path = p->data;
4664 if (gtk_tree_model_get_iter(model, &iter, path)) {
4665 struct objbind *test_ob = NULL;
4666 gtk_tree_model_get(model, &iter, 0, &test_ob, -1);
4667 if (test_ob == ob) {
4668 continue;
4669 }
4670 new_ob = test_ob;
4671 break;
4672 }
4673 }
4676
4678 }
4679 } else {
4681 }
4682
4683 return TRUE;
4684}
4685
4686/************************************************************************/
4691{
4692 struct property_page *pp;
4693 const gchar *text;
4694 GtkWidget *w;
4696 struct property_filter *pf;
4697 bool matched;
4698
4699 pp = userdata;
4701 pf = property_filter_new(text);
4702
4706 continue;
4707 }
4710 if (objprop_has_widget(op) && w != NULL) {
4711 if (matched) {
4712 gtk_widget_show(w);
4713 } else {
4714 gtk_widget_hide(w);
4715 }
4716 }
4718 if (objprop_show_in_listview(op) && col != NULL) {
4720 }
4722
4724}
4725
4726/************************************************************************/
4730static struct property_page *
4732 struct property_editor *pe)
4733{
4734 struct property_page *pp;
4735 GtkWidget *vbox, *vbox2, *hbox, *hbox2, *paned, *frame, *w;
4736 GtkWidget *scrollwin, *view, *label, *entry, *notebook;
4737 GtkWidget *button, *hsep, *image;
4742 int num_columns = 0;
4744 int col_id = 1;
4745 const char *attr_type_str, *name, *tooltip;
4746 gchar *title;
4747
4748 if (!(objtype < NUM_OBJTYPES)) {
4749 return NULL;
4750 }
4751
4752 pp = fc_calloc(1, sizeof(struct property_page));
4753 pp->objtype = objtype;
4754 pp->pe_parent = pe;
4755
4757
4758 pp->objprop_table = objprop_hash_new();
4760
4761 pp->objbind_table = objbind_hash_new();
4762
4763 pp->tag_table = stored_tag_hash_new();
4764
4767 num_columns++;
4768 }
4770
4771 /* Column zero in the store holds an objbind
4772 * pointer and is never displayed. */
4773 num_columns++;
4776
4781 col_id++;
4782 }
4784
4787
4790 pp->widget = paned;
4791
4792 /* Left side object list view. */
4793
4794 vbox = gtk_grid_new();
4800
4808
4812
4815 continue;
4816 }
4817
4819 if (!attr_type_str) {
4820 continue;
4821 }
4823 if (col_id < 0) {
4824 continue;
4825 }
4827 if (!name) {
4828 continue;
4829 }
4831 if (!cell) {
4832 continue;
4833 }
4834
4837 NULL);
4838
4842 if (objprop_is_sortable(op)) {
4845 } else {
4847 }
4850
4852
4855 g_signal_connect(sel, "changed",
4859
4861 pp->object_view = view;
4862
4864 hbox = gtk_grid_new();
4867
4868 button = gtk_button_new();
4871 gtk_button_set_label(GTK_BUTTON(button), _("Create"));
4874 _("Pressing this button will create a new object of the "
4875 "same type as the current property page and add it to "
4876 "the page. The specific type and count of the objects "
4877 "is taken from the editor tool state. So for example, "
4878 "the \"tool value\" of the unit tool and its \"count\" "
4879 "parameter affect unit creation."));
4880 g_signal_connect(button, "clicked",
4883
4884 button = gtk_button_new();
4885 image = gtk_image_new_from_icon_name("list-remove",
4888 gtk_button_set_label(GTK_BUTTON(button), _("Destroy"));
4891 _("Pressing this button will send a request to the server "
4892 "to destroy (i.e. erase) the objects selected in the object "
4893 "list."));
4894 g_signal_connect(button, "clicked",
4897 }
4898
4899 /* Right side properties panel. */
4900
4901 hbox = gtk_grid_new();
4904
4905 vbox = gtk_grid_new();
4911
4912 /* Extended property viewer to the right of the properties panel.
4913 * This needs to be created before property widgets, since some
4914 * might try to append themselves to this notebook. */
4915
4916 vbox2 = gtk_grid_new();
4923
4924 notebook = gtk_notebook_new();
4925 gtk_widget_set_vexpand(notebook, TRUE);
4926 gtk_widget_set_size_request(notebook, 256, -1);
4930 pp->extviewer_notebook = notebook;
4931
4934
4935 hbox2 = gtk_grid_new();
4938
4939 button = gtk_button_new_with_mnemonic(_("_Close"));
4941 g_signal_connect_swapped(button, "clicked",
4944
4945 /* Now create the properties panel. */
4946
4947 /* TRANS: %s is a type of object that can be edited, such as "Tile",
4948 * "Unit", "Start Position", etc. */
4949 title = g_strdup_printf(_("%s Properties"),
4951 frame = gtk_frame_new(title);
4952 g_free(title);
4953 gtk_widget_set_size_request(frame, 256, -1);
4954 gtk_container_add(GTK_CONTAINER(vbox), frame);
4955
4963
4964 vbox2 = gtk_grid_new();
4971
4973 if (!objprop_has_widget(op)) {
4974 continue;
4975 }
4977 if (!w) {
4978 continue;
4979 }
4982 if (NULL != tooltip) {
4984 }
4986
4987 hbox2 = gtk_grid_new();
4992
4993 label = gtk_label_new(_("Filter:"));
4995
4996 entry = gtk_entry_new();
4998 _("Enter a filter string to limit which properties are shown. "
4999 "The filter is one or more text patterns separated by | "
5000 "(\"or\") or & (\"and\"). The symbol & has higher precedence "
5001 "than |. A pattern may also be negated by prefixing it with !."));
5002 g_signal_connect(entry, "changed",
5005
5006 hbox2 = gtk_grid_new();
5009
5010 button = gtk_button_new_with_mnemonic(_("_Refresh"));
5013 _("Pressing this button will reset all modified properties of "
5014 "the selected objects to their current values (the values "
5015 "they have on the server)."));
5016 g_signal_connect(button, "clicked",
5019
5020 button = gtk_button_new_with_mnemonic(_("_Apply"));
5023 _("Pressing this button will send all modified properties of "
5024 "the objects selected in the object list to the server. "
5025 "Modified properties' names are shown in red in the properties "
5026 "panel."));
5027 g_signal_connect(button, "clicked",
5030
5031 return pp;
5032}
5033
5034/************************************************************************/
5037static const char *property_page_get_name(const struct property_page *pp)
5038{
5039 if (!pp) {
5040 return "";
5041 }
5043}
5044
5045/************************************************************************/
5048static enum editor_object_type
5050{
5051 if (!pp) {
5052 return -1;
5053 }
5054 return pp->objtype;
5055}
5056
5057/************************************************************************/
5065static GdkPixbuf *create_tile_pixbuf(const struct tile *ptile)
5066{
5068}
5069
5070/************************************************************************/
5081
5082/************************************************************************/
5089static GdkPixbuf *create_city_pixbuf(const struct city *pcity)
5090{
5091 return create_pixbuf_from_layers(city_tile(pcity), NULL, pcity,
5093}
5094
5095/************************************************************************/
5103static GdkPixbuf *create_pixbuf_from_layers(const struct tile *ptile,
5104 const struct unit *punit,
5105 const struct city *pcity,
5106 enum layer_category category)
5107{
5109 int h, fh, fw, canvas_x, canvas_y;
5111 cairo_t *cr;
5112
5116
5118
5121 cairo_paint(cr);
5122 cairo_destroy(cr);
5123
5124 canvas_x = 0;
5125 canvas_y = 0;
5126
5127 canvas_y += (fh - h);
5128
5129 mapview_layer_iterate(layer) {
5130 if (tileset_layer_in_category(layer, category)) {
5131 put_one_element(&canvas, 1.0, layer,
5132 ptile, NULL, NULL, punit, pcity,
5134 }
5138
5139 return pixbuf;
5140}
5141
5142/************************************************************************/
5146{
5147 if (!pp) {
5148 return;
5149 }
5150
5151 gtk_list_store_clear(pp->object_store);
5152 objbind_hash_clear(pp->objbind_table);
5154}
5155
5156/************************************************************************/
5162{
5163 struct objbind *ob;
5165 int id;
5166
5167 if (!pp) {
5168 return;
5169 }
5170
5173 if (id < 0) {
5174 return;
5175 }
5176
5177 if (objbind_hash_lookup(pp->objbind_table, id, NULL)) {
5178 /* Object already exists. */
5179 return;
5180 }
5181
5183 if (!ob) {
5184 return;
5185 }
5186
5188
5189 objbind_hash_insert(pp->objbind_table, ob->object_id, ob);
5190}
5191
5192/************************************************************************/
5197 const struct tile *ptile)
5198{
5199
5200 if (!pp || !ptile) {
5201 return;
5202 }
5203
5204 switch (property_page_get_objtype(pp)) {
5205 case OBJTYPE_TILE:
5207 return;
5208
5209 case OBJTYPE_STARTPOS:
5210 {
5211 struct startpos *psp = map_startpos_get(ptile);
5212
5213 if (NULL != psp) {
5215 }
5216 }
5217 return;
5218
5219 case OBJTYPE_UNIT:
5220 unit_list_iterate(ptile->units, punit) {
5223 return;
5224
5225 case OBJTYPE_CITY:
5226 if (tile_city(ptile)) {
5228 }
5229 return;
5230
5231 case OBJTYPE_PLAYER:
5232 case OBJTYPE_GAME:
5233 return;
5234
5235 case NUM_OBJTYPES:
5236 break;
5237 }
5238
5239 log_error("%s(): Unhandled page object type %s (nb %d).", __FUNCTION__,
5242}
5243
5244/************************************************************************/
5251 struct objprop *op,
5252 struct objbind *ob,
5254{
5255 int col_id;
5256 struct propval *pv;
5257 enum value_types valtype;
5258 char buf[128], *p;
5260 GtkListStore *store;
5261 gchar *buf2;
5262
5263 if (!pp || !pp->object_store || !op || !ob) {
5264 return FALSE;
5265 }
5266
5268 return FALSE;
5269 }
5270
5272 if (col_id < 0) {
5273 return FALSE;
5274 }
5275
5277 if (!pv) {
5278 return FALSE;
5279 }
5280
5282 store = pp->object_store;
5283
5284 switch (valtype) {
5285 case VALTYPE_NONE:
5286 break;
5287 case VALTYPE_INT:
5288 gtk_list_store_set(store, iter, col_id, pv->data.v_int, -1);
5289 break;
5290 case VALTYPE_BOOL:
5291 /* Set as translated string, not as untranslated G_TYPE_BOOLEAN */
5293 break;
5294 case VALTYPE_STRING:
5295 if (fc_strlcpy(buf, pv->data.v_string, 28) >= 28) {
5296 sz_strlcat(buf, "...");
5297 }
5298 for (p = buf; *p; p++) {
5299 if (*p == '\n' || *p == '\t' || *p == '\r') {
5300 *p = ' ';
5301 }
5302 }
5303 gtk_list_store_set(store, iter, col_id, buf, -1);
5304 break;
5305 case VALTYPE_PIXBUF:
5306 gtk_list_store_set(store, iter, col_id, pv->data.v_pixbuf, -1);
5307 break;
5310 case VALTYPE_BV_SPECIAL:
5311 case VALTYPE_BV_ROADS:
5312 case VALTYPE_BV_BASES:
5315 gtk_list_store_set(store, iter, col_id, buf2, -1);
5316 g_free(buf2);
5317 break;
5318 case VALTYPE_NATION:
5319 pixbuf = get_flag(pv->data.v_nation);
5320 gtk_list_store_set(store, iter, col_id, pixbuf, -1);
5321 if (pixbuf) {
5323 }
5324 break;
5325 case VALTYPE_GOV:
5327 gtk_list_store_set(store, iter, col_id, pixbuf, -1);
5328 if (pixbuf) {
5330 }
5331 break;
5333 break;
5334 }
5335
5337
5338 return TRUE;
5339}
5340
5341/************************************************************************/
5346{
5347 struct objbind *focused;
5348
5349 if (!pp || !pp->objbind_table) {
5350 return;
5351 }
5352
5353 if (pp->object_store) {
5356 GtkTreeModel *model;
5357 GtkTreePath *path;
5358
5359 model = GTK_TREE_MODEL(pp->object_store);
5360
5362 if (objbind_get_rowref(ob)) {
5363 continue;
5364 }
5365 gtk_list_store_append(pp->object_store, &iter);
5366 gtk_list_store_set(pp->object_store, &iter, 0, ob, -1);
5367 path = gtk_tree_model_get_path(model, &iter);
5368 rr = gtk_tree_row_reference_new(model, path);
5369 gtk_tree_path_free(path);
5371
5376
5377 if (gtk_tree_model_get_iter_first(model, &iter)) {
5381 }
5382 }
5383
5388}
5389
5390/************************************************************************/
5395{
5396 if (!pp) {
5397 return NULL;
5398 }
5399 return pp->focused_objbind;
5400}
5401
5402/************************************************************************/
5407 struct objbind *ob)
5408{
5409 if (!pp) {
5410 return;
5411 }
5412 pp->focused_objbind = ob;
5413}
5414
5415/************************************************************************/
5420 int object_id)
5421{
5422 struct objbind *ob;
5423
5424 if (!pp || !pp->objbind_table) {
5425 return NULL;
5426 }
5427
5428 objbind_hash_lookup(pp->objbind_table, object_id, &ob);
5429 return ob;
5430}
5431
5432/************************************************************************/
5437 const struct tile_list *tiles)
5438{
5439 if (!pp || !tiles) {
5440 return;
5441 }
5442
5443 tile_list_iterate(tiles, ptile) {
5446
5448}
5449
5450/************************************************************************/
5454{
5455 if (!pp || !pp->objbind_table) {
5456 return 0;
5457 }
5458 return objbind_hash_size(pp->objbind_table);
5459}
5460
5461/************************************************************************/
5466 struct objprop *op,
5467 struct propval *pv)
5468{
5470 GtkTreeModel *model;
5471 GList *rows, *p;
5472 GtkTreePath *path;
5474 struct objbind *ob;
5475 bool changed = FALSE;
5476
5477 if (!pp || !op || !pp->object_view) {
5478 return;
5479 }
5480
5481 if (objprop_is_readonly(op)) {
5482 return;
5483 }
5484
5487
5488 for (p = rows; p != NULL; p = p->next) {
5489 path = p->data;
5490 if (gtk_tree_model_get_iter(model, &iter, path)) {
5491 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5492 changed |= objbind_set_modified_value(ob, op, pv);
5493 }
5494 gtk_tree_path_free(path);
5495 }
5497
5498 if (changed) {
5501 }
5502}
5503
5504/************************************************************************/
5508{
5510 GtkTreeModel *model;
5511 GList *rows, *p;
5512 GtkTreePath *path;
5514 struct objbind *ob;
5515 union packetdata packet;
5516 struct connection *my_conn = &client.conn;
5517
5518 if (!pp || !pp->object_view) {
5519 return;
5520 }
5521
5524 return;
5525 }
5526
5527 packet = property_page_new_packet(pp);
5528 if (!packet.pointers.v_pointer1) {
5529 return;
5530 }
5531
5534 for (p = rows; p != NULL; p = p->next) {
5535 path = p->data;
5536 if (gtk_tree_model_get_iter(model, &iter, path)) {
5537 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5541 if (objprop_is_readonly(op)) {
5542 continue;
5543 }
5547 }
5548 }
5549 gtk_tree_path_free(path);
5550 }
5553
5555}
5556
5557/************************************************************************/
5562{
5563 union packetdata packet;
5564
5565 packet.pointers.v_pointer2 = NULL;
5566
5567 if (!pp) {
5568 packet.pointers.v_pointer1 = NULL;
5569 return packet;
5570 }
5571
5572 switch (property_page_get_objtype(pp)) {
5573 case OBJTYPE_TILE:
5574 packet.tile = fc_calloc(1, sizeof(*packet.tile));
5575 break;
5576 case OBJTYPE_STARTPOS:
5577 packet.startpos = fc_calloc(1, sizeof(*packet.startpos));
5578 break;
5579 case OBJTYPE_UNIT:
5580 packet.unit = fc_calloc(1, sizeof(*packet.unit));
5581 break;
5582 case OBJTYPE_CITY:
5583 packet.city = fc_calloc(1, sizeof(*packet.city));
5584 break;
5585 case OBJTYPE_PLAYER:
5586 packet.player = fc_calloc(1, sizeof(*packet.player));
5587 break;
5588 case OBJTYPE_GAME:
5589 packet.game.game = fc_calloc(1, sizeof(*packet.game.game));
5590 packet.game.desc = fc_calloc(1, sizeof(*packet.game.desc));
5591 break;
5592 case NUM_OBJTYPES:
5593 break;
5594 }
5595
5596 return packet;
5597}
5598
5599/************************************************************************/
5603 union packetdata packet)
5604{
5605 struct connection *my_conn = &client.conn;
5606
5607 if (!pp || !packet.pointers.v_pointer1) {
5608 return;
5609 }
5610
5611 switch (property_page_get_objtype(pp)) {
5612 case OBJTYPE_TILE:
5614 return;
5615 case OBJTYPE_STARTPOS:
5617 return;
5618 case OBJTYPE_UNIT:
5620 return;
5621 case OBJTYPE_CITY:
5623 return;
5624 case OBJTYPE_PLAYER:
5626 return;
5627 case OBJTYPE_GAME:
5628 send_packet_edit_game(my_conn, packet.game.game);
5630 return;
5631 case NUM_OBJTYPES:
5632 break;
5633 }
5634
5635 log_error("%s(): Unhandled object type %s (nb %d).",
5638}
5639
5640/************************************************************************/
5644 union packetdata packet)
5645{
5646 if (!packet.pointers.v_pointer1) {
5647 return;
5648 }
5649
5650 free(packet.pointers.v_pointer1);
5651 packet.pointers.v_pointer1 = NULL;
5652
5653 if (packet.pointers.v_pointer2 != NULL) {
5654 free(packet.pointers.v_pointer2);
5655 packet.pointers.v_pointer2 = NULL;
5656 }
5657}
5658
5659/************************************************************************/
5664{
5666 GtkTreeModel *model;
5668 GtkTreePath *path;
5669 GList *rows, *p;
5670 struct objbind *ob;
5671
5672 if (!pp || !pp->object_view) {
5673 return;
5674 }
5675
5678 return;
5679 }
5680
5682 for (p = rows; p != NULL; p = p->next) {
5683 path = p->data;
5684 if (gtk_tree_model_get_iter(model, &iter, path)) {
5685 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5690 }
5691 gtk_tree_path_free(path);
5692 }
5694
5699}
5700
5701/************************************************************************/
5705{
5707 GtkTreeModel *model;
5709 GtkTreePath *path;
5710 GList *rows, *p;
5711 struct objbind *ob;
5712 struct connection *my_conn = &client.conn;
5713
5714 if (!pp || !pp->object_view) {
5715 return;
5716 }
5717
5720 return;
5721 }
5722
5725 for (p = rows; p != NULL; p = p->next) {
5726 path = p->data;
5727 if (gtk_tree_model_get_iter(model, &iter, path)) {
5728 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5730 }
5731 gtk_tree_path_free(path);
5732 }
5735}
5736
5737/************************************************************************/
5744 struct tile_list *hint_tiles)
5745{
5747 int apno, value, count, size;
5748 int tag;
5749 struct connection *my_conn = &client.conn;
5750 struct tile *ptile = NULL;
5751 struct player *pplayer;
5752
5753 if (!pp) {
5754 return;
5755 }
5756
5759 return;
5760 }
5761
5762 tag = get_next_unique_tag();
5763 count = 1;
5764
5765 switch (objtype) {
5766 case OBJTYPE_STARTPOS:
5767 if (hint_tiles) {
5769 if (NULL == map_startpos_get(atile)) {
5770 ptile = atile;
5771 break;
5772 }
5774 }
5775
5776 if (NULL == ptile) {
5777 ptile = get_center_tile_mapcanvas();
5778 }
5779
5780 if (NULL == ptile) {
5781 break;
5782 }
5783
5785 break;
5786
5787 case OBJTYPE_UNIT:
5788 if (hint_tiles) {
5791 ptile = atile;
5792 break;
5793 }
5795 }
5796
5797 if (!ptile) {
5798 struct unit *punit;
5802 ptile = unit_tile(punit);
5803 break;
5804 }
5806 }
5807
5808 if (!ptile) {
5809 ptile = get_center_tile_mapcanvas();
5810 }
5811
5812 if (!ptile) {
5813 break;
5814 }
5815
5820 value, count, tag);
5821 break;
5822
5823 case OBJTYPE_CITY:
5825 pplayer = player_by_number(apno);
5826 if (pplayer && hint_tiles) {
5828 if (!is_enemy_unit_tile(atile, pplayer)
5830 ptile = atile;
5831 break;
5832 }
5834 }
5835
5836 if (!ptile) {
5837 ptile = get_center_tile_mapcanvas();
5838 }
5839
5840 if (!ptile) {
5841 break;
5842 }
5843
5846 size, tag);
5847 break;
5848
5849 case OBJTYPE_PLAYER:
5851 break;
5852
5853 case OBJTYPE_TILE:
5854 case OBJTYPE_GAME:
5855 case NUM_OBJTYPES:
5856 break;
5857 }
5858
5860}
5861
5862/************************************************************************/
5868 int object_id,
5869 bool removed)
5870{
5871 struct objbind *ob;
5873
5875 if (!ob) {
5876 return;
5877 }
5878
5881 GtkTreePath *path;
5883 GtkTreeModel *model;
5884
5885 model = GTK_TREE_MODEL(pp->object_store);
5887
5888 if (gtk_tree_model_get_iter(model, &iter, path)) {
5889 if (removed) {
5890 gtk_list_store_remove(pp->object_store, &iter);
5891 } else {
5895 }
5896 }
5897
5898 gtk_tree_path_free(path);
5899 }
5900
5901 if (removed) {
5902 objbind_hash_remove(pp->objbind_table, object_id);
5903 return;
5904 }
5905
5910 }
5911}
5912
5913/************************************************************************/
5920 int tag, int object_id)
5921{
5924
5925 if (!property_page_tag_is_known(pp, tag)) {
5926 return;
5927 }
5929
5932
5933 if (!object) {
5934 return;
5935 }
5936
5939}
5940
5941/************************************************************************/
5946 struct extviewer *ev)
5947{
5948 GtkWidget *w;
5949
5950 if (!pp || !ev) {
5951 return;
5952 }
5953
5955 if (!w) {
5956 return;
5957 }
5958 gtk_notebook_append_page(GTK_NOTEBOOK(pp->extviewer_notebook), w, NULL);
5959}
5960
5961/************************************************************************/
5966 struct extviewer *ev)
5967{
5968 GtkWidget *w;
5969 GtkNotebook *notebook;
5970 int page;
5971
5972 if (!pp || !ev) {
5973 return;
5974 }
5975
5977 if (!w) {
5978 return;
5979 }
5980
5981 notebook = GTK_NOTEBOOK(pp->extviewer_notebook);
5982 page = gtk_notebook_page_num(notebook, w);
5983 gtk_notebook_set_current_page(notebook, page);
5984}
5985
5986/************************************************************************/
5991 int tag, int count)
5992{
5993 if (!pp || !pp->tag_table) {
5994 return;
5995 }
5996
5997 if (stored_tag_hash_lookup(pp->tag_table, tag, NULL)) {
5998 log_error("Attempted to insert object creation tag %d "
5999 "twice into tag table for property page %p (%d %s).",
6002 return;
6003 }
6004
6005 stored_tag_hash_insert(pp->tag_table, tag, count);
6006}
6007
6008/************************************************************************/
6013 int tag)
6014{
6015 int count;
6016
6017 if (!pp || !pp->tag_table) {
6018 return;
6019 }
6020
6021 if (stored_tag_hash_lookup(pp->tag_table, tag, &count)) {
6022 if (0 >= --count) {
6023 stored_tag_hash_remove(pp->tag_table, tag);
6024 }
6025 }
6026}
6027
6028/************************************************************************/
6031static bool property_page_tag_is_known(struct property_page *pp, int tag)
6032{
6033 if (!pp || !pp->tag_table) {
6034 return FALSE;
6035 }
6036 return stored_tag_hash_lookup(pp->tag_table, tag, NULL);
6037}
6038
6039/************************************************************************/
6043{
6044 if (!pp || !pp->tag_table) {
6045 return;
6046 }
6047 stored_tag_hash_clear(pp->tag_table);
6048}
6049
6050/************************************************************************/
6059
6060/************************************************************************/
6070
6071/************************************************************************/
6076{
6077 struct property_page *pp = userdata, *tile_pp;
6078 struct tile_list *tiles = NULL;
6079 struct tile *ptile;
6080
6081 if (!pp) {
6082 return;
6083 }
6084
6086 tiles = tile_list_new();
6087
6089 ptile = objbind_get_object(ob);
6090 if (ptile) {
6091 tile_list_append(tiles, ptile);
6092 }
6094
6096 tile_list_destroy(tiles);
6097}
6098
6099/************************************************************************/
6108
6109/************************************************************************/
6115{
6116 struct property_page *pp;
6117 GtkWidget *label;
6118 const char *name;
6119
6120 if (!pe || !pe->notebook) {
6121 return FALSE;
6122 }
6123
6124 if (!(objtype < NUM_OBJTYPES)) {
6125 return FALSE;
6126 }
6127
6129 if (!pp) {
6130 return FALSE;
6131 }
6132
6134 label = gtk_label_new(name);
6136 pp->widget, label);
6137
6138 pe->property_pages[objtype] = pp;
6139
6140 return TRUE;
6141}
6142
6143/************************************************************************/
6146static struct property_page *
6149{
6150 if (!pe || !(objtype < NUM_OBJTYPES)) {
6151 return NULL;
6152 }
6153
6154 return pe->property_pages[objtype];
6155}
6156
6157/************************************************************************/
6161{
6162 struct property_editor *pe;
6163 GtkWidget *win, *notebook, *vbox;
6165
6166 pe = fc_calloc(1, sizeof(*pe));
6167
6168 /* The property editor dialog window. */
6169
6171 gtk_window_set_title(GTK_WINDOW(win), _("Property Editor"));
6179 g_signal_connect(win, "delete-event",
6181 pe->widget = win;
6182
6183 vbox = gtk_grid_new();
6184 gtk_container_add(GTK_CONTAINER(win), vbox);
6185
6186 /* Property pages. */
6187
6191 pe->notebook = notebook;
6192
6193 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6195 }
6196
6197 return pe;
6198}
6199
6200/************************************************************************/
6210
6211/************************************************************************/
6215 const struct tile_list *tiles)
6216{
6217 struct property_page *pp;
6219 int i;
6220 const enum editor_object_type preferred[] = {
6225 };
6226
6227 if (!pe || !tiles) {
6228 return;
6229 }
6230
6231 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6234 }
6235
6236 for (i = 0; i < ARRAY_SIZE(preferred) - 1; i++) {
6239 break;
6240 }
6241 }
6242 objtype = preferred[i];
6244}
6245
6246/************************************************************************/
6252{
6253 if (!pe || !pe->widget) {
6254 return;
6255 }
6256
6257 gtk_widget_show_all(pe->widget);
6258
6260 if (objtype < NUM_OBJTYPES) {
6262 }
6263}
6264
6265/************************************************************************/
6269{
6270 if (!pe || !pe->widget) {
6271 return;
6272 }
6273 gtk_widget_hide(pe->widget);
6274}
6275
6276/************************************************************************/
6282 int object_id,
6283 bool remove)
6284{
6285 struct property_page *pp;
6286
6287 if (!pe) {
6288 return;
6289 }
6290
6291 if (!(objtype < NUM_OBJTYPES)) {
6292 return;
6293 }
6294
6297}
6298
6299/************************************************************************/
6303 int tag, int object_id)
6304{
6306 struct property_page *pp;
6307
6308 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6310 continue;
6311 }
6313 property_page_object_created(pp, tag, object_id);
6314 }
6315}
6316
6317/************************************************************************/
6321{
6323 struct property_page *pp;
6324
6325 if (!pe) {
6326 return;
6327 }
6328
6329 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6333 }
6334}
6335
6336/************************************************************************/
6342{
6343 struct property_page *pp;
6344
6345 if (!pe) {
6346 return;
6347 }
6348
6350 if (!pp) {
6351 return;
6352 }
6353
6355
6356 switch (objtype) {
6357 case OBJTYPE_PLAYER:
6358 players_iterate(pplayer) {
6359 property_page_add_objbind(pp, pplayer);
6361 break;
6362 case OBJTYPE_GAME:
6364 break;
6365 case OBJTYPE_TILE:
6366 case OBJTYPE_STARTPOS:
6367 case OBJTYPE_UNIT:
6368 case OBJTYPE_CITY:
6369 case NUM_OBJTYPES:
6370 break;
6371 }
6372
6375}
6376
6377/************************************************************************/
6388static struct property_filter *property_filter_new(const char *filter)
6389{
6390 struct property_filter *pf;
6391 struct pf_conjunction *pfc;
6392 struct pf_pattern *pfp;
6395 const char *pattern;
6396 int i, j;
6397
6398 pf = fc_calloc(1, sizeof(*pf));
6399
6400 if (!filter || filter[0] == '\0') {
6401 return pf;
6402 }
6403
6407
6408 for (i = 0; i < or_clause_count; i++) {
6409 if (or_clauses[i][0] == '\0') {
6410 continue;
6411 }
6412 pfc = &pf->disjunction[pf->count];
6413
6417
6418 for (j = 0; j < and_clause_count; j++) {
6419 if (and_clauses[j][0] == '\0') {
6420 continue;
6421 }
6422 pfp = &pfc->conjunction[pfc->count];
6423 pattern = and_clauses[j];
6424
6425 switch (pattern[0]) {
6426 case '!':
6427 pfp->negate = TRUE;
6428 pfp->text = fc_strdup(pattern + 1);
6429 break;
6430 default:
6431 pfp->text = fc_strdup(pattern);
6432 break;
6433 }
6434 pfc->count++;
6435 }
6437 pf->count++;
6438 }
6439
6441
6442 return pf;
6443}
6444
6445/************************************************************************/
6463 const struct objprop *op)
6464{
6465 struct pf_pattern *pfp;
6466 struct pf_conjunction *pfc;
6467 const char *name;
6468 bool match, or_result, and_result;
6469 int i, j;
6470
6471 if (!pf) {
6472 return TRUE;
6473 }
6474 if (!op) {
6475 return FALSE;
6476 }
6477
6479 if (!name) {
6480 return FALSE;
6481 }
6482
6483 if (pf->count < 1) {
6484 return TRUE;
6485 }
6486
6487 or_result = FALSE;
6488
6489 for (i = 0; i < pf->count; i++) {
6490 pfc = &pf->disjunction[i];
6491 and_result = TRUE;
6492 for (j = 0; j < pfc->count; j++) {
6493 pfp = &pfc->conjunction[j];
6494 match = (pfp->text[0] == '\0'
6495 || fc_strcasestr(name, pfp->text));
6496 if (pfp->negate) {
6497 match = !match;
6498 }
6499 and_result = and_result && match;
6500 if (!and_result) {
6501 break;
6502 }
6503 }
6505 if (or_result) {
6506 break;
6507 }
6508 }
6509
6510 return or_result;
6511}
6512
6513/************************************************************************/
6517{
6518 struct pf_pattern *pfp;
6519 struct pf_conjunction *pfc;
6520 int i, j;
6521
6522 if (!pf) {
6523 return;
6524 }
6525
6526 for (i = 0; i < pf->count; i++) {
6527 pfc = &pf->disjunction[i];
6528 for (j = 0; j < pfc->count; j++) {
6529 pfp = &pfc->conjunction[j];
6530 if (pfp->text != NULL) {
6531 free(pfp->text);
6532 pfp->text = NULL;
6533 }
6534 }
6535 pfc->count = 0;
6536 }
6537 pf->count = 0;
6538 free(pf);
6539}
6540
6541/************************************************************************/
6545{
6546 switch (vl) {
6547 case V_MAIN:
6548 /* TRANS: Vision layer name. Feel free to leave untranslated. */
6549 return _("Seen (Main)");
6550 case V_INVIS:
6551 /* TRANS: Vision layer name. Feel free to leave untranslated. */
6552 return _("Seen (Invis)");
6553 case V_SUBSURFACE:
6554 /* TRANS: Vision layer name. Feel free to leave untranslated. */
6555 return _("Seen (Subsurface)");
6556 case V_COUNT:
6557 break;
6558 }
6559
6560 log_error("%s(): Unrecognized vision layer %d.", __FUNCTION__, vl);
6561 return _("Unknown");
6562}
Base_type_id base_number(const struct base_type *pbase)
Definition base.c:92
Base_type_id base_count(void)
Definition base.c:109
bool dbv_isset(const struct dbv *pdbv, int bit)
Definition bitvector.c:120
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ARE_EQUAL(vec1, vec2)
Definition bitvector.h:113
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_CLR(bv, bit)
Definition bitvector.h:86
struct canvas int int canvas_y
Definition canvas_g.h:43
struct canvas int canvas_x
Definition canvas_g.h:43
int city_granary_size(int city_size)
Definition city.c:2123
bool city_can_be_built_here(const struct tile *ptile, const struct unit *punit, bool hut_test)
Definition city.c:1478
#define city_tile(_pcity_)
Definition city.h:564
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define city_owner(_pcity_)
Definition city.h:563
#define MAX_CITY_SIZE
Definition city.h:106
#define I_DESTROYED
Definition city.h:248
#define I_NEVER
Definition city.h:247
struct civclient client
bool client_nation_is_in_current_set(const struct nation_type *pnation)
Definition climisc.c:1497
char * incite_cost
Definition comments.c:74
void connection_do_buffer(struct connection *pc)
Definition connection.c:324
void connection_do_unbuffer(struct connection *pc)
Definition connection.c:336
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
int objtype
Definition editgui_g.h:28
int int id
Definition editgui_g.h:28
int editor_tool_get_size(enum editor_tool_type ett)
Definition editor.c:1218
int editor_tool_get_value(enum editor_tool_type ett)
Definition editor.c:409
int editor_tool_get_count(enum editor_tool_type ett)
Definition editor.c:1252
struct unit * editor_unit_virtual_create(void)
Definition editor.c:1405
int editor_tool_get_applied_player(enum editor_tool_type ett)
Definition editor.c:1341
editor_object_type
Definition editor.h:25
@ OBJTYPE_PLAYER
Definition editor.h:30
@ OBJTYPE_UNIT
Definition editor.h:28
@ OBJTYPE_STARTPOS
Definition editor.h:27
@ OBJTYPE_GAME
Definition editor.h:31
@ NUM_OBJTYPES
Definition editor.h:33
@ OBJTYPE_CITY
Definition editor.h:29
@ OBJTYPE_TILE
Definition editor.h:26
@ ETT_UNIT
Definition editor.h:42
@ ETT_CITY
Definition editor.h:43
struct extra_type_list * extra_type_list_by_cause(enum extra_cause cause)
Definition extras.c:249
const char * extra_name_translation(const struct extra_type *pextra)
Definition extras.c:194
#define extra_index(_e_)
Definition extras.h:183
#define extra_base_get(_e_)
Definition extras.h:190
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
void free_tokens(char **tokens, size_t ntokens)
Definition fc_cmdline.c:203
int get_tokens(const char *str, char **tokens, size_t num_tokens, const char *delimiterset)
Definition fc_cmdline.c:166
const struct functions * fc_funcs
#define EC_SPECIAL
Definition fc_types.h:1115
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:116
struct city * game_city_by_number(int id)
Definition game.c:107
const char * government_name_translation(const struct government *pgovern)
Definition government.c:143
Government_type_id government_count(void)
Definition government.c:71
struct government * government_by_number(const Government_type_id gov)
Definition government.c:103
Government_type_id government_index(const struct government *pgovern)
Definition government.c:82
#define governments_iterate(NAME_pgov)
Definition government.h:120
#define governments_iterate_end
Definition government.h:123
#define FC_STATIC_CANVAS_INIT
Definition canvas.h:28
static void add_column(GtkWidget *view, int col_id, const char *name, GType gtype, bool editable, bool is_radio, GCallback edit_callback, gpointer callback_userdata)
Definition editprop.c:819
static void property_page_reset_objbinds(struct property_page *pp)
Definition editprop.c:5663
static void property_page_send_values(struct property_page *pp)
Definition editprop.c:5507
static void objprop_setup_widget(struct objprop *op)
Definition editprop.c:2935
static void property_page_store_creation_tag(struct property_page *pp, int tag, int count)
Definition editprop.c:5990
static gchar * propval_as_string(struct propval *pv)
Definition editprop.c:861
static struct property_page * objprop_get_property_page(const struct objprop *op)
Definition editprop.c:3445
static const char * objprop_get_name(const struct objprop *op)
Definition editprop.c:2815
const char * vision_layer_get_name(enum vision_layer)
Definition editprop.c:6544
static int objbind_get_object_id(struct objbind *ob)
Definition editprop.c:1376
static void objprop_set_extviewer(struct objprop *op, struct extviewer *ev)
Definition editprop.c:3422
static GtkWidget * extviewer_get_panel_widget(struct extviewer *ev)
Definition editprop.c:3777
static gpointer objtype_get_object_from_id(enum editor_object_type objtype, int id)
Definition editprop.c:724
void property_editor_handle_object_changed(struct property_editor *pe, enum editor_object_type objtype, int object_id, bool remove)
Definition editprop.c:6280
static struct propstate * propstate_new(struct objprop *op, struct propval *pv)
Definition editprop.c:1260
static const char * valtype_get_name(enum value_types valtype)
Definition editprop.c:778
static void propstate_destroy(struct propstate *ps)
Definition editprop.c:1292
static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv)
Definition editprop.c:2115
static GtkCellRenderer * objprop_create_cell_renderer(const struct objprop *op)
Definition editprop.c:2839
static void extviewer_clear_widgets(struct extviewer *ev)
Definition editprop.c:4063
value_types
Definition editprop.c:197
@ VALTYPE_STRING
Definition editprop.c:201
@ VALTYPE_BV_SPECIAL
Definition editprop.c:205
@ VALTYPE_BV_BASES
Definition editprop.c:207
@ VALTYPE_INT
Definition editprop.c:199
@ VALTYPE_INVENTIONS_ARRAY
Definition editprop.c:204
@ VALTYPE_BV_ROADS
Definition editprop.c:206
@ VALTYPE_PIXBUF
Definition editprop.c:202
@ VALTYPE_TILE_VISION_DATA
Definition editprop.c:211
@ VALTYPE_NONE
Definition editprop.c:198
@ VALTYPE_NATION_HASH
Definition editprop.c:209
@ VALTYPE_BOOL
Definition editprop.c:200
@ VALTYPE_NATION
Definition editprop.c:208
@ VALTYPE_GOV
Definition editprop.c:210
@ VALTYPE_BUILT_ARRAY
Definition editprop.c:203
static void objprop_set_child_widget(struct objprop *op, const char *widget_name, GtkWidget *widget)
Definition editprop.c:3362
static bool property_editor_add_page(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6113
static void propstate_clear_value(struct propstate *ps)
Definition editprop.c:1279
static void objbind_pack_modified_value(struct objbind *ob, struct objprop *op, union packetdata packet)
Definition editprop.c:2366
static struct objbind * property_page_get_focused_objbind(struct property_page *pp)
Definition editprop.c:5394
static bool objprop_has_widget(const struct objprop *op)
Definition editprop.c:2728
static int objtype_get_id_from_object(enum editor_object_type objtype, gpointer object)
Definition editprop.c:695
static enum editor_object_type objbind_get_objtype(const struct objbind *ob)
Definition editprop.c:2199
static struct extviewer * objprop_get_extviewer(struct objprop *op)
Definition editprop.c:3434
static void extviewer_refresh_widgets(struct extviewer *ev, struct propval *pv)
Definition editprop.c:3800
static enum editor_object_type property_page_get_objtype(const struct property_page *pp)
Definition editprop.c:5049
#define property_page_objbind_iterate_end
Definition editprop.c:640
static void property_page_show_extviewer(struct property_page *pp, struct extviewer *ev)
Definition editprop.c:5965
static gpointer objbind_get_object(struct objbind *ob)
Definition editprop.c:1360
static const char * property_page_get_name(const struct property_page *pp)
Definition editprop.c:5037
void property_editor_handle_object_created(struct property_editor *pe, int tag, int object_id)
Definition editprop.c:6302
static bool objbind_property_is_modified(struct objbind *ob, struct objprop *op)
Definition editprop.c:2070
static struct propval * propstate_get_value(struct propstate *ps)
Definition editprop.c:1322
static void property_page_clear_tags(struct property_page *pp)
Definition editprop.c:6042
static void property_page_object_created(struct property_page *pp, int tag, int object_id)
Definition editprop.c:5919
static bool property_page_tag_is_known(struct property_page *pp, int tag)
Definition editprop.c:6031
static void property_page_remove_creation_tag(struct property_page *pp, int tag)
Definition editprop.c:6012
static void property_page_load_tiles(struct property_page *pp, const struct tile_list *tiles)
Definition editprop.c:5436
static void property_page_create_objects(struct property_page *pp, struct tile_list *hint_tiles)
Definition editprop.c:5743
static void property_page_add_extviewer(struct property_page *pp, struct extviewer *ev)
Definition editprop.c:5945
static void property_page_refresh_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6064
static void property_page_set_focused_objbind(struct property_page *pp, struct objbind *ob)
Definition editprop.c:5406
static void property_page_setup_objprops(struct property_page *pp)
Definition editprop.c:4402
static void objbind_set_rowref(struct objbind *ob, GtkTreeRowReference *rr)
Definition editprop.c:2635
object_property_flags
Definition editprop.c:383
@ OPF_IN_LISTVIEW
Definition editprop.c:386
@ OPF_EDITABLE
Definition editprop.c:385
@ OPF_HAS_WIDGET
Definition editprop.c:387
@ OPF_NO_FLAGS
Definition editprop.c:384
static void objbind_clear_modified_value(struct objbind *ob, struct objprop *op)
Definition editprop.c:2056
static struct propval * objbind_get_value_from_object(struct objbind *ob, struct objprop *op)
Definition editprop.c:1437
static void propval_free(struct propval *pv)
Definition editprop.c:1122
static struct property_filter * property_filter_new(const char *filter)
Definition editprop.c:6388
static bool property_page_set_store_value(struct property_page *pp, struct objprop *op, struct objbind *ob, GtkTreeIter *iter)
Definition editprop.c:5250
static const char * objtype_get_name(enum editor_object_type objtype)
Definition editprop.c:666
static void objprop_widget_entry_changed(GtkEntry *entry, gpointer userdata)
Definition editprop.c:2885
static void objbind_clear_all_modified_values(struct objbind *ob)
Definition editprop.c:2101
static bool property_filter_match(struct property_filter *pf, const struct objprop *op)
Definition editprop.c:6462
void property_editor_popup(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6250
static void property_page_destroy_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6102
static struct objbind * objbind_new(enum editor_object_type objtype, gpointer object)
Definition editprop.c:1334
static gboolean property_page_selection_func(GtkTreeSelection *sel, GtkTreeModel *model, GtkTreePath *path, gboolean currently_selected, gpointer data)
Definition editprop.c:4634
static int property_page_get_num_objbinds(const struct property_page *pp)
Definition editprop.c:5453
static bool objprop_show_in_listview(const struct objprop *op)
Definition editprop.c:2717
static GType objprop_get_gtype(const struct objprop *op)
Definition editprop.c:2673
static void objprop_set_treeview_column(struct objprop *op, GtkTreeViewColumn *col)
Definition editprop.c:2791
static void objbind_pack_current_values(struct objbind *ob, union packetdata packet)
Definition editprop.c:2224
static const char * objprop_get_attribute_type_string(const struct objprop *op)
Definition editprop.c:2742
static struct propval * propval_copy(struct propval *pv)
Definition editprop.c:1040
struct property_editor * editprop_get_property_editor(void)
Definition editprop.c:6203
void property_editor_reload(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6340
static GdkPixbuf * create_unit_pixbuf(const struct unit *punit)
Definition editprop.c:5077
static void extviewer_view_cell_toggled(GtkCellRendererToggle *cell, gchar *path, gpointer userdata)
Definition editprop.c:4138
static struct property_editor * property_editor_new(void)
Definition editprop.c:6160
static void property_page_send_packet(struct property_page *pp, union packetdata packet)
Definition editprop.c:5602
static gchar * built_status_to_string(struct built_status *bs)
Definition editprop.c:976
static int objprop_get_id(const struct objprop *op)
Definition editprop.c:2658
object_property_ids
Definition editprop.c:305
@ OPID_STARTPOS_IMAGE
Definition editprop.c:325
@ OPID_TILE_Y
Definition editprop.c:308
@ OPID_TILE_BASES
Definition editprop.c:321
@ OPID_CITY_XY
Definition editprop.c:351
@ OPID_UNIT_ID
Definition editprop.c:335
@ OPID_CITY_BUILDINGS
Definition editprop.c:354
@ OPID_CITY_NAME
Definition editprop.c:346
@ OPID_TILE_NAT_Y
Definition editprop.c:310
@ OPID_CITY_SIZE
Definition editprop.c:352
@ OPID_UNIT_VETERAN
Definition editprop.c:342
@ OPID_CITY_IMAGE
Definition editprop.c:345
@ OPID_CITY_SHIELD_STOCK
Definition editprop.c:356
@ OPID_PLAYER_NAME
Definition editprop.c:358
@ OPID_PLAYER_AGE
Definition editprop.c:361
@ OPID_STARTPOS_NATIONS
Definition editprop.c:328
@ OPID_GAME_LAKE_FLOODING
Definition editprop.c:379
@ OPID_UNIT_IMAGE
Definition editprop.c:330
@ OPID_TILE_TERRAIN
Definition editprop.c:315
@ OPID_TILE_SPECIALS
Definition editprop.c:319
@ OPID_TILE_RESOURCE
Definition editprop.c:318
@ OPID_TILE_IMAGE
Definition editprop.c:306
@ OPID_TILE_VISION
Definition editprop.c:322
@ OPID_PLAYER_INVENTIONS
Definition editprop.c:365
@ OPID_GAME_SCENARIO_NAME
Definition editprop.c:372
@ OPID_PLAYER_SCIENCE
Definition editprop.c:368
@ OPID_TILE_CONTINENT
Definition editprop.c:311
@ OPID_CITY_HISTORY
Definition editprop.c:353
@ OPID_TILE_XY
Definition editprop.c:317
@ OPID_GAME_SCENARIO_AUTHORS
Definition editprop.c:373
@ OPID_PLAYER_SELECT_WEIGHT
Definition editprop.c:367
@ OPID_TILE_X
Definition editprop.c:307
@ OPID_TILE_NAT_X
Definition editprop.c:309
@ OPID_PLAYER_NATION
Definition editprop.c:359
@ OPID_GAME_PREVENT_CITIES
Definition editprop.c:378
@ OPID_STARTPOS_XY
Definition editprop.c:326
@ OPID_UNIT_MOVED
Definition editprop.c:339
@ OPID_TILE_LABEL
Definition editprop.c:323
@ OPID_CITY_FOOD_STOCK
Definition editprop.c:355
@ OPID_UNIT_DONE_MOVING
Definition editprop.c:340
@ OPID_UNIT_MOVES_LEFT
Definition editprop.c:337
@ OPID_GAME_SCENARIO_DESC
Definition editprop.c:374
@ OPID_GAME_STARTPOS_NATIONS
Definition editprop.c:377
@ OPID_UNIT_HP
Definition editprop.c:341
@ OPID_UNIT_FUEL
Definition editprop.c:338
@ OPID_PLAYER_SCENARIO_RESERVED
Definition editprop.c:366
@ OPID_TILE_ROADS
Definition editprop.c:320
@ OPID_PLAYER_GOLD
Definition editprop.c:369
@ OPID_CITY_ID
Definition editprop.c:350
@ OPID_GAME_SCENARIO_RANDSTATE
Definition editprop.c:375
@ OPID_GAME_SCENARIO_PLAYERS
Definition editprop.c:376
@ OPID_UNIT_STAY
Definition editprop.c:343
@ OPID_PLAYER_GOV
Definition editprop.c:360
@ OPID_STARTPOS_EXCLUDE
Definition editprop.c:327
@ OPID_UNIT_TYPE
Definition editprop.c:334
@ OPID_GAME_SCENARIO
Definition editprop.c:371
@ OPID_GAME_RULESET_LOCKED
Definition editprop.c:380
@ OPID_UNIT_XY
Definition editprop.c:336
@ OPID_TILE_INDEX
Definition editprop.c:316
static enum value_types objprop_get_valtype(const struct objprop *op)
Definition editprop.c:2706
static int get_next_unique_tag(void)
Definition editprop.c:1029
static bool objprop_is_sortable(const struct objprop *op)
Definition editprop.c:2860
static void property_page_add_objbinds_from_tile(struct property_page *pp, const struct tile *ptile)
Definition editprop.c:5196
static const char * objprop_get_tooltip(const struct objprop *op)
Definition editprop.c:2826
static GtkTreeRowReference * objbind_get_rowref(struct objbind *ob)
Definition editprop.c:2647
static void property_filter_free(struct property_filter *pf)
Definition editprop.c:6516
static void objprop_widget_spin_button_changed(GtkSpinButton *spin, gpointer userdata)
Definition editprop.c:2901
#define PF_DISJUNCTION_SEPARATOR
Definition editprop.c:119
static GtkWidget * objprop_get_child_widget(struct objprop *op, const char *widget_name)
Definition editprop.c:3389
static void property_page_selection_changed(GtkTreeSelection *sel, gpointer userdata)
Definition editprop.c:4609
static bool objtype_is_conserved(enum editor_object_type objtype)
Definition editprop.c:755
static struct extviewer * extviewer_new(struct objprop *op)
Definition editprop.c:3481
static bool propval_equal(struct propval *pva, struct propval *pvb)
Definition editprop.c:1173
static void property_page_quick_find_entry_changed(GtkWidget *entry, gpointer userdata)
Definition editprop.c:4689
static void objprop_refresh_widget(struct objprop *op, struct objbind *ob)
Definition editprop.c:3112
#define PF_MAX_CLAUSES
Definition editprop.c:118
void property_editor_popdown(struct property_editor *pe)
Definition editprop.c:6268
static void objbind_destroy(struct objbind *ob)
Definition editprop.c:2180
static void property_page_add_objbind(struct property_page *pp, gpointer object_data)
Definition editprop.c:5160
static void objbind_request_destroy_object(struct objbind *ob)
Definition editprop.c:1389
static void property_page_create_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6074
static GdkPixbuf * create_pixbuf_from_layers(const struct tile *ptile, const struct unit *punit, const struct city *pcity, enum layer_category category)
Definition editprop.c:5103
static union packetdata property_page_new_packet(struct property_page *pp)
Definition editprop.c:5561
static void propstate_set_value(struct propstate *ps, struct propval *pv)
Definition editprop.c:1307
static int objprop_get_column_id(const struct objprop *op)
Definition editprop.c:2780
static GdkPixbuf * create_tile_pixbuf(const struct tile *ptile)
Definition editprop.c:5065
static struct objprop * extviewer_get_objprop(struct extviewer *ev)
Definition editprop.c:3765
static bool can_create_unit_at_tile(struct tile *ptile)
Definition editprop.c:997
static struct objbind * property_page_get_objbind(struct property_page *pp, int object_id)
Definition editprop.c:5419
static bool objbind_get_allowed_value_span(struct objbind *ob, struct objprop *op, double *pmin, double *pmax, double *pstep, double *pbig_step)
Definition editprop.c:1875
static void property_page_free_packet(struct property_page *pp, union packetdata packet)
Definition editprop.c:5643
static GdkPixbuf * create_city_pixbuf(const struct city *pcity)
Definition editprop.c:5089
#define ADDPROP(ARG_id, ARG_name, ARG_tooltip, ARG_flags, ARG_valtype)
static void extviewer_panel_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:4118
static void property_page_destroy_objects(struct property_page *pp)
Definition editprop.c:5704
void property_editor_load_tiles(struct property_editor *pe, const struct tile_list *tiles)
Definition editprop.c:6214
static struct property_page * property_page_new(enum editor_object_type objtype, struct property_editor *parent)
Definition editprop.c:4731
#define property_page_objprop_iterate_end
Definition editprop.c:636
static void property_page_clear_objbinds(struct property_page *pp)
Definition editprop.c:5145
void property_editor_clear(struct property_editor *pe)
Definition editprop.c:6320
#define property_page_objprop_iterate(ARG_pp, NAME_op)
Definition editprop.c:634
static void objprop_set_column_id(struct objprop *op, int col_id)
Definition editprop.c:2767
static void objbind_bind_properties(struct objbind *ob, struct property_page *pp)
Definition editprop.c:2210
static void property_page_fill_widgets(struct property_page *pp)
Definition editprop.c:5345
static bool objbind_has_modified_properties(struct objbind *ob)
Definition editprop.c:2089
static void property_page_change_value(struct property_page *pp, struct objprop *op, struct propval *pv)
Definition editprop.c:5465
static void objprop_widget_toggle_button_changed(GtkToggleButton *button, gpointer userdata)
Definition editprop.c:2918
#define PF_CONJUNCTION_SEPARATOR
Definition editprop.c:120
static void property_page_apply_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6053
static struct objprop * objprop_new(int id, const char *name, const char *tooltip, enum object_property_flags flags, enum value_types valtype, struct property_page *parent)
Definition editprop.c:3456
static GtkWidget * extviewer_get_view_widget(struct extviewer *ev)
Definition editprop.c:3789
static GtkWidget * objprop_get_widget(struct objprop *op)
Definition editprop.c:3347
static void propval_free_data(struct propval *pv)
Definition editprop.c:1136
static void extviewer_textbuf_changed(GtkTextBuffer *textbuf, gpointer userdata)
Definition editprop.c:4353
static struct property_editor * the_property_editor
Definition editprop.c:660
static void property_page_object_changed(struct property_page *pp, int object_id, bool remove)
Definition editprop.c:5867
static bool objprop_is_readonly(const struct objprop *op)
Definition editprop.c:2874
#define property_page_objbind_iterate(ARG_pp, NAME_ob)
Definition editprop.c:638
static GtkTreeViewColumn * objprop_get_treeview_column(const struct objprop *op)
Definition editprop.c:2804
static struct property_page * property_editor_get_page(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6147
static struct propval * objbind_get_modified_value(struct objbind *ob, struct objprop *op)
Definition editprop.c:2161
GtkWidget * toplevel
Definition gui_main.c:125
void disable_gobject_callback(GObject *obj, GCallback cb)
Definition gui_stuff.c:1090
void enable_gobject_callback(GObject *obj, GCallback cb)
Definition gui_stuff.c:1106
GdkPixbuf * get_flag(const struct nation_type *nation)
Definition plrdlg.c:607
const char * tooltip
Definition repodlgs.c:1315
const char * title
Definition repodlgs.c:1314
GdkPixbuf * surface_get_pixbuf(cairo_surface_t *surf, int width, int height)
Definition sprite.c:418
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
value_types
Definition editprop.c:197
object_property_flags
Definition editprop.c:383
#define PF_MAX_CLAUSES
Definition editprop.c:118
bool is_special_improvement(const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
bool is_small_wonder(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_error(message,...)
Definition log.h:103
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1883
int startpos_number(const struct startpos *psp)
Definition map.c:1633
#define nat_x
#define nat_y
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1676
const struct nation_hash * startpos_raw_nations(const struct startpos *psp)
Definition map.c:1765
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1706
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:456
bool startpos_is_excluding(const struct startpos *psp)
Definition map.c:1753
struct startpos * map_startpos_by_number(int id)
Definition map.c:1624
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:157
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:233
struct tile * get_center_tile_mapcanvas(void)
void put_one_element(struct canvas *pcanvas, float zoom, enum mapview_layer layer, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner, const struct unit *punit, const struct city *pcity, int canvas_x, int canvas_y, const struct city *citymode, const struct unit_type *putype)
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:319
#define MAX_MOVE_FRAGS
Definition movement.h:29
Nation_type_id nation_count(void)
Definition nation.c:507
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:486
const char * nation_adjective_translation(const struct nation_type *pnation)
Definition nation.c:149
struct nation_type * nation_by_number(const Nation_type_id nation)
Definition nation.c:475
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
bool is_nation_playable(const struct nation_type *nation)
Definition nation.c:200
Nation_type_id nation_index(const struct nation_type *pnation)
Definition nation.c:498
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:211
#define nation_hash_iterate(nationhash, pnation)
Definition nation.h:93
#define nations_iterate_end
Definition nation.h:336
#define nations_iterate(NAME_pnation)
Definition nation.h:333
#define nation_hash_iterate_end
Definition nation.h:95
int dsend_packet_edit_city_create(struct connection *pc, int owner, int tile, int size, int tag)
int send_packet_edit_city(struct connection *pc, const struct packet_edit_city *packet)
int send_packet_edit_game(struct connection *pc, const struct packet_edit_game *packet)
int send_packet_edit_startpos_full(struct connection *pc, const struct packet_edit_startpos_full *packet)
int dsend_packet_edit_startpos(struct connection *pc, int id, bool removal, int tag)
int send_packet_edit_player(struct connection *pc, const struct packet_edit_player *packet)
int dsend_packet_edit_player_create(struct connection *pc, int tag)
int send_packet_edit_unit(struct connection *pc, const struct packet_edit_unit *packet)
int send_packet_edit_scenario_desc(struct connection *pc, const struct packet_edit_scenario_desc *packet)
int dsend_packet_edit_unit_remove_by_id(struct connection *pc, int id)
int dsend_packet_edit_unit_create(struct connection *pc, int owner, int tile, Unit_type_id type, int count, int tag)
int dsend_packet_edit_player_remove(struct connection *pc, int id)
int send_packet_edit_tile(struct connection *pc, const struct packet_edit_tile *packet)
int dsend_packet_edit_city_remove(struct connection *pc, int id)
bool player_slot_is_used(const struct player_slot *pslot)
Definition player.c:448
struct player * player_by_number(const int player_id)
Definition player.c:849
int player_number(const struct player *pplayer)
Definition player.c:837
const char * player_name(const struct player *pplayer)
Definition player.c:895
int player_slot_index(const struct player_slot *pslot)
Definition player.c:426
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1990
int player_index(const struct player *pplayer)
Definition player.c:829
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
struct player * player_slot_get_player(const struct player_slot *pslot)
Definition player.c:437
#define players_iterate_end
Definition player.h:537
#define players_iterate(_pplayer)
Definition player.h:532
#define player_slots_iterate(_pslot)
Definition player.h:523
#define player_slots_iterate_end
Definition player.h:527
struct research * research_get(const struct player *pplayer)
Definition research.c:128
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:619
Road_type_id road_count(void)
Definition road.c:50
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
#define ARRAY_SIZE(x)
Definition shared.h:85
int step
Definition specpq.h:92
size_t size
Definition specvec.h:72
int turn
Definition city.h:246
cairo_surface_t * surface
Definition canvas.h:23
Definition city.h:320
int food_stock
Definition city.h:367
struct built_status built[B_LAST]
Definition city.h:394
int history
Definition city.h:410
int id
Definition city.h:326
char * name
Definition city.h:321
int shield_stock
Definition city.h:368
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
GtkWidget * view_widget
Definition editprop.c:522
GtkWidget * panel_button
Definition editprop.c:519
GtkWidget * view_label
Definition editprop.c:523
GtkWidget * panel_image
Definition editprop.c:520
GtkTextBuffer * textbuf
Definition editprop.c:526
struct objprop * objprop
Definition editprop.c:514
GtkWidget * panel_label
Definition editprop.c:518
struct propval * pv_cached
Definition editprop.c:515
GtkListStore * store
Definition editprop.c:525
GtkWidget * panel_widget
Definition editprop.c:517
bool(* player_tile_vision_get)(const struct tile *ptile, const struct player *pplayer, enum vision_layer vision)
int object_id
Definition editprop.c:459
struct propstate_hash * propstate_table
Definition editprop.c:461
struct property_page * parent_property_page
Definition editprop.c:460
GtkTreeRowReference * rowref
Definition editprop.c:462
enum editor_object_type objtype
Definition editprop.c:458
const char * name
Definition editprop.c:392
const char * tooltip
Definition editprop.c:393
GtkWidget * widget
Definition editprop.c:398
struct property_page * parent_page
Definition editprop.c:400
enum object_property_flags flags
Definition editprop.c:394
struct extviewer * extviewer
Definition editprop.c:399
int id
Definition editprop.c:391
enum value_types valtype
Definition editprop.c:395
int column_id
Definition editprop.c:396
GtkTreeViewColumn * view_column
Definition editprop.c:397
int built[B_LAST]
char name[MAX_LEN_CITYNAME]
char scenario_name[256]
char scenario_authors[MAX_LEN_PACKET/3]
Nation_type_id nation
char name[MAX_LEN_NAME]
Government_type_id government
bool inventions[A_LAST+1]
bv_startpos_nations nations
char label[MAX_LEN_NAME]
struct pf_pattern conjunction[PF_MAX_CLAUSES]
Definition editprop.c:128
char * text
Definition editprop.c:124
bool negate
Definition editprop.c:123
int autoselect_weight
Definition player.h:297
struct government * government
Definition player.h:256
int turns_alive
Definition player.h:264
struct player_economic economic
Definition player.h:282
char name[MAX_LEN_NAME]
Definition player.h:249
struct nation_type * nation
Definition player.h:258
GtkWidget * notebook
Definition editprop.c:648
struct property_page * property_pages[NUM_OBJTYPES]
Definition editprop.c:650
GtkWidget * widget
Definition editprop.c:647
struct pf_conjunction disjunction[PF_MAX_CLAUSES]
Definition editprop.c:133
GtkListStore * object_store
Definition editprop.c:552
struct property_editor * pe_parent
Definition editprop.c:556
GtkWidget * extviewer_notebook
Definition editprop.c:554
GtkWidget * widget
Definition editprop.c:551
struct objbind_hash * objbind_table
Definition editprop.c:559
GtkWidget * object_view
Definition editprop.c:553
struct objbind * focused_objbind
Definition editprop.c:562
struct stored_tag_hash * tag_table
Definition editprop.c:560
enum editor_object_type objtype
Definition editprop.c:549
struct objprop_hash * objprop_table
Definition editprop.c:558
struct propval * property_value
Definition editprop.c:256
int property_id
Definition editprop.c:255
union propval_data data
Definition editprop.c:244
enum value_types valtype
Definition editprop.c:245
bool must_free
Definition editprop.c:246
Definition map.c:41
bv_player tile_known
Definition editprop.c:114
bv_player tile_seen[V_COUNT]
Definition editprop.c:114
Definition tile.h:50
char * label
Definition tile.h:65
Continent_id continent
Definition tile.h:54
Definition unit.h:138
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
bool moved
Definition unit.h:173
int hp
Definition unit.h:151
int fuel
Definition unit.h:153
bool stay
Definition unit.h:205
bool done_moving
Definition unit.h:181
int veteran
Definition unit.h:152
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:791
char * fc_strcasestr(const char *haystack, const char *needle)
Definition support.c:440
#define sz_strlcpy(dest, src)
Definition support.h:189
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define sz_strlcat(dest, src)
Definition support.h:190
const char * advance_name_translation(const struct advance *padvance)
Definition tech.c:290
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
#define advance_index_iterate_end
Definition tech.h:248
static Tech_type_id advance_count(void)
Definition tech.h:170
#define A_FIRST
Definition tech.h:44
#define advance_iterate(_p)
Definition tech.h:275
#define advance_iterate_end
Definition tech.h:276
#define advance_index_iterate(_start, _index)
Definition tech.h:244
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:238
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:88
#define tile_resource(_tile)
Definition tile.h:102
#define tile_list_iterate(tile_list, ptile)
Definition tile.h:73
#define tile_terrain(_tile)
Definition tile.h:110
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_list_iterate_end
Definition tile.h:75
static const bv_extras * tile_extras(const struct tile *ptile)
Definition tile.h:120
#define tile_has_extra(ptile, pextra)
Definition tile.h:147
struct sprite * get_government_sprite(const struct tileset *t, const struct government *gov)
Definition tilespec.c:6797
int tileset_full_tile_height(const struct tileset *t)
Definition tilespec.c:789
bool tileset_layer_in_category(enum mapview_layer layer, enum layer_category cat)
Definition tilespec.c:7332
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:765
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:776
#define mapview_layer_iterate(layer)
Definition tilespec.h:175
#define mapview_layer_iterate_end
Definition tilespec.h:183
layer_category
Definition tilespec.h:189
@ LAYER_CATEGORY_TILE
Definition tilespec.h:191
@ LAYER_CATEGORY_CITY
Definition tilespec.h:190
@ LAYER_CATEGORY_UNIT
Definition tilespec.h:192
gpointer v_pointer2
Definition editprop.c:99
struct packet_edit_tile * tile
Definition editprop.c:101
gpointer v_pointer1
Definition editprop.c:98
struct packet_edit_unit * unit
Definition editprop.c:104
struct packetdata::@147 pointers
struct packet_edit_player * player
Definition editprop.c:105
struct packet_edit_scenario_desc * desc
Definition editprop.c:108
struct packet_edit_city * city
Definition editprop.c:103
struct packet_edit_game * game
Definition editprop.c:107
struct packet_edit_startpos_full * startpos
Definition editprop.c:102
struct government * v_gov
Definition editprop.c:238
bv_techs v_bv_inventions
Definition editprop.c:239
bv_max_extras v_bv_special
Definition editprop.c:233
struct tile_vision_data * v_tile_vision
Definition editprop.c:240
char * v_string
Definition editprop.c:229
struct built_status * v_built
Definition editprop.c:232
bv_max_extras v_bv_roads
Definition editprop.c:234
gpointer v_pointer
Definition editprop.c:226
struct nation_type * v_nation
Definition editprop.c:236
struct nation_hash * v_nation_hash
Definition editprop.c:237
bv_max_extras v_bv_bases
Definition editprop.c:235
GdkPixbuf * v_pixbuf
Definition editprop.c:231
const char * v_const_string
Definition editprop.c:230
#define unit_tile(_pu)
Definition unit.h:390
static bool is_enemy_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:413
#define unit_owner(_pu)
Definition unit.h:389
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:425
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2613
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
#define utype_fuel(ptype)
Definition unittype.h:836
#define vision_layer_iterate(v)
Definition vision.h:77
#define vision_layer_iterate_end
Definition vision.h:80