Freeciv-3.3
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 */
371
383
390
403
404static struct objprop *objprop_new(int id,
405 const char *name,
406 const char *tooltip,
408 enum value_types valtype,
409 struct property_page *parent);
410static int objprop_get_id(const struct objprop *op);
411static const char *objprop_get_name(const struct objprop *op);
412static const char *objprop_get_tooltip(const struct objprop *op);
413static enum value_types objprop_get_valtype(const struct objprop *op);
414static struct property_page *
416
417static bool objprop_show_in_listview(const struct objprop *op);
418static bool objprop_is_sortable(const struct objprop *op);
419static bool objprop_is_readonly(const struct objprop *op);
420static bool objprop_has_widget(const struct objprop *op);
421
422static GType objprop_get_gtype(const struct objprop *op);
423static const char *objprop_get_attribute_type_string(const struct objprop *op);
424static void objprop_set_column_id(struct objprop *op, int col_id);
425static int objprop_get_column_id(const struct objprop *op);
426static void objprop_set_treeview_column(struct objprop *op,
430
431static void objprop_setup_widget(struct objprop *op);
432static GtkWidget *objprop_get_widget(struct objprop *op);
433static void objprop_set_child_widget(struct objprop *op,
434 const char *widget_name,
437 const char *widget_name);
438static void objprop_set_extviewer(struct objprop *op,
439 struct extviewer *ev);
440static struct extviewer *objprop_get_extviewer(struct objprop *op);
441static void objprop_refresh_widget(struct objprop *op,
442 struct objbind *ob);
448
449#define SPECHASH_TAG objprop
450#define SPECHASH_INT_KEY_TYPE
451#define SPECHASH_IDATA_TYPE struct objprop *
452#include "spechash.h"
453
454
455/****************************************************************************
456 Objbind declarations.
457****************************************************************************/
465
467 gpointer object);
468static void objbind_destroy(struct objbind *ob);
469static enum editor_object_type objbind_get_objtype(const struct objbind *ob);
470static void objbind_bind_properties(struct objbind *ob,
471 struct property_page *pp);
472static gpointer objbind_get_object(struct objbind *ob);
473static int objbind_get_object_id(struct objbind *ob);
474static void objbind_request_destroy_object(struct objbind *ob);
475static struct propval *objbind_get_value_from_object(struct objbind *ob,
476 struct objprop *op);
477static bool objbind_get_allowed_value_span(struct objbind *ob,
478 struct objprop *op,
479 double *pmin,
480 double *pmax,
481 double *pstep,
482 double *pbig_step);
483static bool objbind_set_modified_value(struct objbind *ob,
484 struct objprop *op,
485 struct propval *pv);
486static struct propval *objbind_get_modified_value(struct objbind *ob,
487 struct objprop *op);
488static void objbind_clear_modified_value(struct objbind *ob,
489 struct objprop *op);
490static bool objbind_property_is_modified(struct objbind *ob,
491 struct objprop *op);
492static bool objbind_has_modified_properties(struct objbind *ob);
493static void objbind_clear_all_modified_values(struct objbind *ob);
494static void objbind_pack_current_values(struct objbind *ob,
495 union packetdata packet);
496static void objbind_pack_modified_value(struct objbind *ob,
497 struct objprop *op,
498 union packetdata packet);
499static void objbind_set_rowref(struct objbind *ob,
502
503#define SPECHASH_TAG objbind
504#define SPECHASH_INT_KEY_TYPE
505#define SPECHASH_IDATA_TYPE struct objbind *
506#define SPECHASH_IDATA_FREE objbind_destroy
507#include "spechash.h"
508
509
510/****************************************************************************
511 Extended property viewer declarations. This is a set of widgets used
512 for viewing and/or editing properties with complex values (e.g. arrays).
513****************************************************************************/
529
530static struct extviewer *extviewer_new(struct objprop *op);
531static struct objprop *extviewer_get_objprop(struct extviewer *ev);
534static void extviewer_refresh_widgets(struct extviewer *ev,
535 struct propval *pv);
536static void extviewer_clear_widgets(struct extviewer *ev);
537static void extviewer_panel_button_clicked(GtkButton *button,
540 gchar *path,
542static void extviewer_textbuf_changed(GtkTextBuffer *textbuf,
544
545
546/****************************************************************************
547 Property page declarations.
548****************************************************************************/
565
566static struct property_page *
568 struct property_editor *parent);
570static const char *property_page_get_name(const struct property_page *pp);
571static enum editor_object_type
573static void property_page_load_tiles(struct property_page *pp,
574 const struct tile_list *tiles);
576 const struct tile *ptile);
577static int property_page_get_num_objbinds(const struct property_page *pp);
579static void property_page_add_objbind(struct property_page *pp,
581static void property_page_fill_widgets(struct property_page *pp);
582static struct objbind *
585 struct objbind *ob);
587 int object_id);
591 GtkTreeModel *model,
592 GtkTreePath *path,
594 gpointer data);
598 struct objprop *op,
599 struct propval *pv);
600static void property_page_send_values(struct property_page *pp);
604 struct tile_list *hint_tiles);
606static void property_page_send_packet(struct property_page *pp,
607 union packetdata packet);
608static void property_page_free_packet(struct property_page *pp,
609 union packetdata packet);
611 int object_id,
612 bool remove);
614 int tag, int object_id);
616 struct extviewer *ev);
618 struct extviewer *ev);
620 int tag, int count);
622 int tag);
623static bool property_page_tag_is_known(struct property_page *pp, int tag);
624static void property_page_clear_tags(struct property_page *pp);
633
634
635#define property_page_objprop_iterate(ARG_pp, NAME_op) \
636 TYPED_HASH_DATA_ITERATE(struct objprop *, (ARG_pp)->objprop_table, NAME_op)
637#define property_page_objprop_iterate_end HASH_DATA_ITERATE_END
638
639#define property_page_objbind_iterate(ARG_pp, NAME_ob) \
640 TYPED_HASH_DATA_ITERATE(struct objbind *, (ARG_pp)->objbind_table, NAME_ob)
641#define property_page_objbind_iterate_end HASH_DATA_ITERATE_END
642
643
644/****************************************************************************
645 Property editor declarations.
646****************************************************************************/
653
654static struct property_editor *property_editor_new(void);
657static struct property_page *
660
662
663
664/************************************************************************/
668{
669 switch (objtype) {
670 case OBJTYPE_TILE:
671 return _("Tile");
672 case OBJTYPE_STARTPOS:
673 return _("Start Position");
674 case OBJTYPE_UNIT:
675 return _("Unit");
676 case OBJTYPE_CITY:
677 return _("City");
678 case OBJTYPE_PLAYER:
679 return _("Player");
680 case OBJTYPE_GAME:
681 return Q_("?play:Game");
682 case NUM_OBJTYPES:
683 break;
684 }
685
686 log_error("%s() Unhandled request to get name of object type %d.",
688 return "Unknown";
689}
690
691/************************************************************************/
697 gpointer object)
698{
699 switch (objtype) {
700 case OBJTYPE_TILE:
701 return tile_index((struct tile *) object);
702 case OBJTYPE_STARTPOS:
703 return startpos_number((struct startpos *) object);
704 case OBJTYPE_UNIT:
705 return ((struct unit *) object)->id;
706 case OBJTYPE_CITY:
707 return ((struct city *) object)->id;
708 case OBJTYPE_PLAYER:
709 return player_number((struct player *) object);
710 case OBJTYPE_GAME:
711 return 1;
712 case NUM_OBJTYPES:
713 break;
714 }
715
716 log_error("%s(): Unhandled request to get object ID from object %p of "
717 "type %d (%s).", __FUNCTION__, object, objtype,
719 return -1;
720}
721
722/************************************************************************/
726 int id)
727{
728 switch (objtype) {
729 case OBJTYPE_TILE:
730 return index_to_tile(&(wld.map), id);
731 case OBJTYPE_STARTPOS:
732 return map_startpos_by_number(id);
733 case OBJTYPE_UNIT:
734 return game_unit_by_number(id);
735 case OBJTYPE_CITY:
736 return game_city_by_number(id);
737 case OBJTYPE_PLAYER:
738 return player_by_number(id);
739 case OBJTYPE_GAME:
740 return &game;
741 case NUM_OBJTYPES:
742 break;
743 }
744
745 log_error("%s(): Unhandled request to get object of type %d (%s) "
746 "with ID %d.", __FUNCTION__, objtype,
748 return NULL;
749}
750
751/************************************************************************/
757{
758 switch (objtype) {
759 case OBJTYPE_TILE:
760 case OBJTYPE_GAME:
761 return TRUE;
762 case OBJTYPE_STARTPOS:
763 case OBJTYPE_UNIT:
764 case OBJTYPE_CITY:
765 case OBJTYPE_PLAYER:
766 return FALSE;
767 case NUM_OBJTYPES:
768 break;
769 }
770
771 log_error("%s(): Unhandled request for object type %d (%s)).",
773 return TRUE;
774}
775
776/************************************************************************/
779static const char *valtype_get_name(enum value_types valtype)
780{
781 switch (valtype) {
782 case VALTYPE_NONE:
783 return "none";
784 case VALTYPE_STRING:
785 return "string";
786 case VALTYPE_INT:
787 return "int";
788 case VALTYPE_BOOL:
789 return "bool";
790 case VALTYPE_PIXBUF:
791 return "pixbuf";
793 return "struct built_status[B_LAST]";
795 return "bool[A_LAST]";
797 return "bv_special";
798 case VALTYPE_BV_ROADS:
799 return "bv_roads";
800 case VALTYPE_BV_BASES:
801 return "bv_bases";
802 case VALTYPE_NATION:
803 return "nation";
805 return "struct nation_hash";
806 case VALTYPE_GOV:
807 return "government";
809 return "struct tile_vision_data";
810 }
811
812 log_error("%s(): unhandled value type %d.", __FUNCTION__, valtype);
813 return "void";
814}
815
816/************************************************************************/
821 int col_id,
822 const char *name,
823 GType gtype,
824 bool editable,
825 bool is_radio,
828{
831 const char *attr = NULL;
832
833 if (gtype == G_TYPE_BOOLEAN) {
836 is_radio);
837 if (editable) {
839 }
840 attr = "active";
841 } else if (gtype == GDK_TYPE_PIXBUF) {
843 attr = "pixbuf";
844 } else {
846 if (editable) {
847 g_object_set(cell, "editable", TRUE, NULL);
849 }
850 attr = "text";
851 }
852
854 attr, col_id, NULL);
856}
857
858/************************************************************************/
863{
864 int count = 0;
865
867
868 switch (pv->valtype) {
869 case VALTYPE_NONE:
870 return g_strdup("");
871
872 case VALTYPE_INT:
873 return g_strdup_printf("%d", pv->data.v_int);
874
875 case VALTYPE_BOOL:
876 return g_strdup_printf("%s", pv->data.v_bool ? _("TRUE") : _("FALSE"));
877
878 case VALTYPE_NATION:
879 return g_strdup_printf("%s", nation_adjective_translation(pv->data.v_nation));
880
881 case VALTYPE_GOV:
882 if (pv->data.v_gov != NULL) {
883 return g_strdup_printf("%s", government_name_translation(pv->data.v_gov));
884 } else {
886 }
887
889 {
890 int great_wonder_count = 0, small_wonder_count = 0, building_count = 0;
891 int id;
892
893 improvement_iterate(pimprove) {
894 id = improvement_index(pimprove);
895 if (pv->data.v_built[id].turn < 0) {
896 continue;
897 }
898 if (is_great_wonder(pimprove)) {
900 } else if (is_small_wonder(pimprove)) {
902 } else {
903 building_count++;
904 }
906 /* TRANS: "Number of buildings, number of small
907 * wonders (e.g. palace), number of great wonders." */
908 return g_strdup_printf(_("%db %ds %dW"),
909 building_count, small_wonder_count,
911 }
912
915 if (BV_ISSET(pv->data.v_bv_inventions, tech)) {
916 count++;
917 }
919 /* TRANS: "Number of technologies known". */
920 return g_strdup_printf(_("%d known"), count);
921
924 if (BV_ISSET(pv->data.v_bv_special, spe->data.special_idx)) {
925 count++;
926 }
928 /* TRANS: "The number of terrain specials (e.g. hut,
929 * river, pollution, etc.) present on a tile." */
930 return g_strdup_printf(_("%d present"), count);
931
932 case VALTYPE_BV_ROADS:
934 struct road_type *proad = extra_road_get(pextra);
935
936 if (BV_ISSET(pv->data.v_bv_roads, road_number(proad))) {
937 count++;
938 }
940 return g_strdup_printf(_("%d present"), count);
941
942 case VALTYPE_BV_BASES:
944 struct base_type *pbase = extra_base_get(pextra);
945
946 if (BV_ISSET(pv->data.v_bv_bases, base_number(pbase))) {
947 count++;
948 }
950 return g_strdup_printf(_("%d present"), count);
951
953 count = nation_hash_size(pv->data.v_nation_hash);
954 if (0 == count) {
955 return g_strdup(_("All nations"));
956 } else {
957 return g_strdup_printf(PL_("%d nation", "%d nations",
958 count), count);
959 }
960
961 case VALTYPE_STRING:
962 /* Assume it is a very long string. */
963 count = strlen(pv->data.v_const_string);
964 return g_strdup_printf(PL_("%d byte", "%d bytes", count),
965 count);
966
967 case VALTYPE_PIXBUF:
969 break;
970 }
971
972 log_error("%s(): Unhandled value type %d for property value %p.",
973 __FUNCTION__, pv->valtype, pv);
974 return g_strdup("");
975}
976
977/************************************************************************/
982{
983 int turn_built;
984
985 turn_built = bs->turn;
986
987 if (turn_built == I_NEVER) {
988 /* TRANS: Improvement never built. */
989 return g_strdup(_("(never)"));
990 } else if (turn_built == I_DESTROYED) {
991 /* TRANS: Improvement was destroyed. */
992 return g_strdup(_("(destroyed)"));
993 } else {
994 return g_strdup_printf("%d", turn_built);
995 }
996}
997
998/************************************************************************/
1002static bool can_create_unit_at_tile(struct tile *ptile)
1003{
1004 struct unit *vunit;
1005 struct city *pcity;
1006 struct player *pplayer;
1007 bool ret;
1008
1009 if (!ptile) {
1010 return FALSE;
1011 }
1012
1014 if (vunit == NULL) {
1015 return FALSE;
1016 }
1017
1018 pcity = tile_city(ptile);
1019 pplayer = unit_owner(vunit);
1020
1021 ret = (can_unit_exist_at_tile(&(wld.map), vunit, ptile)
1022 && !is_non_allied_unit_tile(ptile, pplayer,
1024 && (pcity == NULL
1026 unit_owner(vunit))));
1027 free(vunit);
1028
1029 return ret;
1030}
1031
1032/************************************************************************/
1035static int get_next_unique_tag(void)
1036{
1037 static int tag_series = 0;
1038
1039 tag_series++;
1040 return tag_series;
1041}
1042
1043/************************************************************************/
1046static struct propval *propval_copy(struct propval *pv)
1047{
1048 struct propval *pv_copy;
1049 size_t size;
1050
1051 if (!pv) {
1052 return NULL;
1053 }
1054
1055 pv_copy = fc_calloc(1, sizeof(*pv));
1056 pv_copy->valtype = pv->valtype;
1057
1058 switch (pv->valtype) {
1059 case VALTYPE_NONE:
1060 return pv_copy;
1061 case VALTYPE_INT:
1062 pv_copy->data.v_int = pv->data.v_int;
1063 return pv_copy;
1064 case VALTYPE_BOOL:
1065 pv_copy->data.v_bool = pv->data.v_bool;
1066 return pv_copy;
1067 case VALTYPE_STRING:
1068 pv_copy->data.v_string = fc_strdup(pv->data.v_string);
1069 pv_copy->must_free = TRUE;
1070 return pv_copy;
1071 case VALTYPE_PIXBUF:
1072 g_object_ref(pv->data.v_pixbuf);
1073 pv_copy->data.v_pixbuf = pv->data.v_pixbuf;
1074 pv_copy->must_free = TRUE;
1075 return pv_copy;
1077 size = B_LAST * sizeof(struct built_status);
1078 pv_copy->data.v_pointer = fc_malloc(size);
1079 memcpy(pv_copy->data.v_pointer, pv->data.v_pointer, size);
1080 pv_copy->must_free = TRUE;
1081 return pv_copy;
1082 case VALTYPE_BV_SPECIAL:
1083 pv_copy->data.v_bv_special = pv->data.v_bv_special;
1084 return pv_copy;
1085 case VALTYPE_BV_ROADS:
1086 pv_copy->data.v_bv_roads = pv->data.v_bv_roads;
1087 return pv_copy;
1088 case VALTYPE_BV_BASES:
1089 pv_copy->data.v_bv_bases = pv->data.v_bv_bases;
1090 return pv_copy;
1091 case VALTYPE_NATION:
1092 pv_copy->data.v_nation = pv->data.v_nation;
1093 return pv_copy;
1094 case VALTYPE_GOV:
1095 pv_copy->data.v_gov = pv->data.v_gov;
1096 return pv_copy;
1098 pv_copy->data.v_nation_hash
1099 = nation_hash_copy(pv->data.v_nation_hash);
1100 pv_copy->must_free = TRUE;
1101 return pv_copy;
1103 pv_copy->data.v_bv_inventions = pv->data.v_bv_inventions;
1104 return pv_copy;
1106 size = sizeof(struct tile_vision_data);
1107 pv_copy->data.v_tile_vision = fc_malloc(size);
1108 pv_copy->data.v_tile_vision->tile_known
1109 = pv->data.v_tile_vision->tile_known;
1111 pv_copy->data.v_tile_vision->tile_seen[v]
1112 = pv->data.v_tile_vision->tile_seen[v];
1114 pv_copy->must_free = TRUE;
1115 return pv_copy;
1116 }
1117
1118 log_error("%s(): Unhandled value type %d for property value %p.",
1119 __FUNCTION__, pv->valtype, pv);
1120 pv_copy->data = pv->data;
1121 return pv_copy;
1122}
1123
1124/************************************************************************/
1128static void propval_free(struct propval *pv)
1129{
1130 if (!pv) {
1131 return;
1132 }
1133
1135 free(pv);
1136}
1137
1138/************************************************************************/
1142static void propval_free_data(struct propval *pv)
1143{
1144 if (!pv || !pv->must_free) {
1145 return;
1146 }
1147
1148 switch (pv->valtype) {
1149 case VALTYPE_NONE:
1150 case VALTYPE_INT:
1151 case VALTYPE_BOOL:
1152 case VALTYPE_BV_SPECIAL:
1153 case VALTYPE_BV_ROADS:
1154 case VALTYPE_BV_BASES:
1155 case VALTYPE_NATION:
1156 case VALTYPE_GOV:
1157 return;
1158 case VALTYPE_PIXBUF:
1159 g_object_unref(pv->data.v_pixbuf);
1160 return;
1161 case VALTYPE_STRING:
1165 free(pv->data.v_pointer);
1166 return;
1168 nation_hash_destroy(pv->data.v_nation_hash);
1169 return;
1170 }
1171
1172 log_error("%s(): Unhandled request to free data %p (type %s).",
1173 __FUNCTION__, pv->data.v_pointer, valtype_get_name(pv->valtype));
1174}
1175
1176/************************************************************************/
1179static bool propval_equal(struct propval *pva,
1180 struct propval *pvb)
1181{
1182 if (!pva || !pvb) {
1183 return pva == pvb;
1184 }
1185
1186 if (pva->valtype != pvb->valtype) {
1187 return FALSE;
1188 }
1189
1190 switch (pva->valtype) {
1191 case VALTYPE_NONE:
1192 return TRUE;
1193 case VALTYPE_INT:
1194 return pva->data.v_int == pvb->data.v_int;
1195 case VALTYPE_BOOL:
1196 return pva->data.v_bool == pvb->data.v_bool;
1197 case VALTYPE_STRING:
1198 if (pva->data.v_const_string != NULL
1199 && pvb->data.v_const_string != NULL) {
1200 return !strcmp(pva->data.v_const_string,
1201 pvb->data.v_const_string);
1202 }
1203 return pva->data.v_const_string == pvb->data.v_const_string;
1204 case VALTYPE_PIXBUF:
1205 return pva->data.v_pixbuf == pvb->data.v_pixbuf;
1207 if (pva->data.v_pointer == pvb->data.v_pointer) {
1208 return TRUE;
1209 } else if (!pva->data.v_pointer || !pvb->data.v_pointer) {
1210 return FALSE;
1211 }
1212
1213 improvement_iterate(pimprove) {
1214 int id, vatb, vbtb;
1215 id = improvement_index(pimprove);
1216 vatb = pva->data.v_built[id].turn;
1217 vbtb = pvb->data.v_built[id].turn;
1218 if (vatb < 0 && vbtb < 0) {
1219 continue;
1220 }
1221 if (vatb != vbtb) {
1222 return FALSE;
1223 }
1225 return TRUE;
1227 return BV_ARE_EQUAL(pva->data.v_bv_inventions, pvb->data.v_bv_inventions);
1228 case VALTYPE_BV_SPECIAL:
1229 return BV_ARE_EQUAL(pva->data.v_bv_special, pvb->data.v_bv_special);
1230 case VALTYPE_BV_ROADS:
1231 return BV_ARE_EQUAL(pva->data.v_bv_roads, pvb->data.v_bv_roads);
1232 case VALTYPE_BV_BASES:
1233 return BV_ARE_EQUAL(pva->data.v_bv_bases, pvb->data.v_bv_bases);
1234 case VALTYPE_NATION:
1235 return pva->data.v_nation == pvb->data.v_nation;
1237 return nation_hashes_are_equal(pva->data.v_nation_hash,
1238 pvb->data.v_nation_hash);
1239 case VALTYPE_GOV:
1240 return pva->data.v_gov == pvb->data.v_gov;
1242 if (!BV_ARE_EQUAL(pva->data.v_tile_vision->tile_known,
1243 pvb->data.v_tile_vision->tile_known)) {
1244 return FALSE;
1245 }
1247 if (!BV_ARE_EQUAL(pva->data.v_tile_vision->tile_seen[v],
1248 pvb->data.v_tile_vision->tile_seen[v])) {
1249 return FALSE;
1250 }
1252 return TRUE;
1253 }
1254
1255 log_error("%s(): Unhandled value type %d for property values %p and %p.",
1256 __FUNCTION__, pva->valtype, pva, pvb);
1257 return pva->data.v_pointer == pvb->data.v_pointer;
1258}
1259
1260/************************************************************************/
1266static struct propstate *propstate_new(struct objprop *op,
1267 struct propval *pv)
1268{
1269 struct propstate *ps;
1270
1271 if (!op) {
1272 return NULL;
1273 }
1274
1275 ps = fc_calloc(1, sizeof(*ps));
1276 ps->property_id = objprop_get_id(op);
1277 ps->property_value = pv;
1278
1279 return ps;
1280}
1281
1282/************************************************************************/
1286{
1287 if (!ps) {
1288 return;
1289 }
1290
1291 propval_free(ps->property_value);
1292 ps->property_value = NULL;
1293}
1294
1295/************************************************************************/
1298static void propstate_destroy(struct propstate *ps)
1299{
1300 if (!ps) {
1301 return;
1302 }
1304 free(ps);
1305}
1306
1307/************************************************************************/
1314 struct propval *pv)
1315{
1316 if (!ps) {
1317 return;
1318 }
1320 ps->property_value = pv;
1321}
1322
1323/************************************************************************/
1329{
1330 if (!ps) {
1331 return NULL;
1332 }
1333 return ps->property_value;
1334}
1335
1336/************************************************************************/
1341 gpointer object)
1342{
1343 struct objbind *ob;
1344 int id;
1345
1346 if (object == NULL) {
1347 return NULL;
1348 }
1349
1350 id = objtype_get_id_from_object(objtype, object);
1351 if (id < 0) {
1352 return NULL;
1353 }
1354
1355 ob = fc_calloc(1, sizeof(*ob));
1356 ob->object_id = id;
1357 ob->objtype = objtype;
1358 ob->propstate_table = propstate_hash_new();
1359
1360 return ob;
1361}
1362
1363/************************************************************************/
1367{
1368 int id;
1369
1370 if (!ob) {
1371 return NULL;
1372 }
1373
1375
1376 return objtype_get_object_from_id(ob->objtype, id);
1377}
1378
1379/************************************************************************/
1383{
1384 if (NULL == ob) {
1385 return -1;
1386 }
1387 return ob->object_id;
1388}
1389
1390/************************************************************************/
1396{
1397 struct connection *my_conn = &client.conn;
1399 int id;
1400
1401 if (!ob) {
1402 return;
1403 }
1404
1407 return;
1408 }
1409
1411
1412 switch (objtype) {
1413 case OBJTYPE_STARTPOS:
1415 return;
1416 case OBJTYPE_UNIT:
1418 return;
1419 case OBJTYPE_CITY:
1421 return;
1422 case OBJTYPE_PLAYER:
1424 return;
1425 case OBJTYPE_TILE:
1426 case OBJTYPE_GAME:
1427 case NUM_OBJTYPES:
1428 break;
1429 }
1430
1431 log_error("%s(): Unhandled request to destroy object %p (ID %d) of type "
1432 "%d (%s).", __FUNCTION__, objbind_get_object(ob), id, objtype,
1434}
1435
1436/************************************************************************/
1444 struct objprop *op)
1445{
1448 struct propval *pv;
1449
1450 if (!ob || !op) {
1451 return NULL;
1452 }
1453
1456
1457 pv = fc_calloc(1, sizeof(*pv));
1458 pv->valtype = objprop_get_valtype(op);
1459
1460 switch (objtype) {
1461 case OBJTYPE_TILE:
1462 {
1463 const struct tile *ptile = objbind_get_object(ob);
1464 int tile_x, tile_y, nat_x, nat_y;
1465
1466 if (NULL == ptile) {
1467 goto FAILED;
1468 }
1469
1472
1473 switch (propid) {
1474 case OPID_TILE_IMAGE:
1475 pv->data.v_pixbuf = create_tile_pixbuf(ptile);
1476 pv->must_free = TRUE;
1477 break;
1478#ifdef FREECIV_DEBUG
1479 case OPID_TILE_ADDRESS:
1480 pv->data.v_string = g_strdup_printf("%p", ptile);
1481 pv->must_free = TRUE;
1482 break;
1483#endif /* FREECIV_DEBUG */
1484 case OPID_TILE_TERRAIN:
1485 {
1486 const struct terrain *pterrain = tile_terrain(ptile);
1487
1488 if (NULL != pterrain) {
1489 pv->data.v_const_string = terrain_name_translation(pterrain);
1490 } else {
1491 pv->data.v_const_string = "";
1492 }
1493 }
1494 break;
1495 case OPID_TILE_RESOURCE:
1496 {
1497 const struct extra_type *presource = tile_resource(ptile);
1498
1499 if (NULL != presource) {
1500 pv->data.v_const_string = extra_name_translation(presource);
1501 } else {
1502 pv->data.v_const_string = "";
1503 }
1504 }
1505 break;
1506 case OPID_TILE_XY:
1507 pv->data.v_string = g_strdup_printf("(%d, %d)", tile_x, tile_y);
1508 pv->must_free = TRUE;
1509 break;
1510 case OPID_TILE_INDEX:
1511 pv->data.v_int = tile_index(ptile);
1512 break;
1513 case OPID_TILE_X:
1514 pv->data.v_int = tile_x;
1515 break;
1516 case OPID_TILE_Y:
1517 pv->data.v_int = tile_y;
1518 break;
1519 case OPID_TILE_NAT_X:
1520 pv->data.v_int = nat_x;
1521 break;
1522 case OPID_TILE_NAT_Y:
1523 pv->data.v_int = nat_y;
1524 break;
1526 pv->data.v_int = ptile->continent;
1527 break;
1528 case OPID_TILE_SPECIALS:
1529 BV_CLR_ALL(pv->data.v_bv_special);
1531 if (tile_has_extra(ptile, pextra)) {
1532 BV_SET(pv->data.v_bv_special, pextra->data.special_idx);
1533 }
1535 break;
1536 case OPID_TILE_ROADS:
1537 BV_CLR_ALL(pv->data.v_bv_roads);
1539 if (tile_has_extra(ptile, pextra)) {
1540 BV_SET(pv->data.v_bv_roads, road_number(extra_road_get(pextra)));
1541 }
1543 break;
1544 case OPID_TILE_BASES:
1545 BV_CLR_ALL(pv->data.v_bv_bases);
1547 if (tile_has_extra(ptile, pextra)) {
1548 BV_SET(pv->data.v_bv_bases, base_number(extra_base_get(pextra)));
1549 }
1551 break;
1552 case OPID_TILE_VISION:
1553 pv->data.v_tile_vision = fc_malloc(sizeof(struct tile_vision_data));
1554
1555 /* The server saves the known tiles and the player vision in special
1556 * bitvectors with the number of tiles as index. Here we want the
1557 * information for one tile. Thus, the data is transformed to
1558 * bitvectors with the number of player slots as index. */
1559 BV_CLR_ALL(pv->data.v_tile_vision->tile_known);
1560 players_iterate(pplayer) {
1561 if (dbv_isset(&pplayer->tile_known, tile_index(ptile))) {
1562 BV_SET(pv->data.v_tile_vision->tile_known,
1563 player_index(pplayer));
1564 }
1566
1568 BV_CLR_ALL(pv->data.v_tile_vision->tile_seen[v]);
1569 players_iterate(pplayer) {
1570 if (fc_funcs->player_tile_vision_get(ptile, pplayer, v)) {
1571 BV_SET(pv->data.v_tile_vision->tile_seen[v],
1572 player_index(pplayer));
1573 }
1576 pv->must_free = TRUE;
1577 break;
1578 case OPID_TILE_LABEL:
1579 if (ptile->label != NULL) {
1580 pv->data.v_const_string = ptile->label;
1581 } else {
1582 pv->data.v_const_string = "";
1583 }
1584 break;
1585 default:
1586 log_error("%s(): Unhandled request for value of property %d "
1587 "(%s) from object of type \"%s\".", __FUNCTION__,
1589 goto FAILED;
1590 }
1591 }
1592 return pv;
1593
1594 case OBJTYPE_STARTPOS:
1595 {
1596 const struct startpos *psp = objbind_get_object(ob);
1597 const struct tile *ptile;
1598
1599 if (NULL == psp) {
1600 goto FAILED;
1601 }
1602
1603 switch (propid) {
1605 ptile = startpos_tile(psp);
1606 pv->data.v_pixbuf = create_tile_pixbuf(ptile);
1607 pv->must_free = TRUE;
1608 break;
1609 case OPID_STARTPOS_XY:
1610 ptile = startpos_tile(psp);
1611 pv->data.v_string = g_strdup_printf("(%d, %d)", TILE_XY(ptile));
1612 pv->must_free = TRUE;
1613 break;
1615 pv->data.v_bool = startpos_is_excluding(psp);
1616 break;
1618 pv->data.v_nation_hash = nation_hash_copy(startpos_raw_nations(psp));
1619 pv->must_free = TRUE;
1620 break;
1621 default:
1622 log_error("%s(): Unhandled request for value of property %d "
1623 "(%s) from object of type \"%s\".", __FUNCTION__,
1625 goto FAILED;
1626 }
1627 }
1628 return pv;
1629
1630 case OBJTYPE_UNIT:
1631 {
1632 struct unit *punit = objbind_get_object(ob);
1633
1634 if (NULL == punit) {
1635 goto FAILED;
1636 }
1637
1638 switch (propid) {
1639 case OPID_UNIT_IMAGE:
1640 pv->data.v_pixbuf = create_unit_pixbuf(punit);
1641 pv->must_free = TRUE;
1642 break;
1643#ifdef FREECIV_DEBUG
1644 case OPID_UNIT_ADDRESS:
1645 pv->data.v_string = g_strdup_printf("%p", punit);
1646 pv->must_free = TRUE;
1647 break;
1648#endif /* FREECIV_DEBUG */
1649 case OPID_UNIT_XY:
1650 {
1651 const struct tile *ptile = unit_tile(punit);
1652
1653 pv->data.v_string = g_strdup_printf("(%d, %d)", TILE_XY(ptile));
1654 pv->must_free = TRUE;
1655 }
1656 break;
1657 case OPID_UNIT_ID:
1658 pv->data.v_int = punit->id;
1659 break;
1660 case OPID_UNIT_TYPE:
1661 {
1662 const struct unit_type *putype = unit_type_get(punit);
1663
1664 pv->data.v_const_string = utype_name_translation(putype);
1665 }
1666 break;
1668 pv->data.v_int = punit->moves_left;
1669 break;
1670 case OPID_UNIT_FUEL:
1671 pv->data.v_int = punit->fuel;
1672 break;
1673 case OPID_UNIT_MOVED:
1674 pv->data.v_bool = punit->moved;
1675 break;
1677 pv->data.v_bool = punit->done_moving;
1678 break;
1679 case OPID_UNIT_HP:
1680 pv->data.v_int = punit->hp;
1681 break;
1682 case OPID_UNIT_VETERAN:
1683 pv->data.v_int = punit->veteran;
1684 break;
1685 case OPID_UNIT_STAY:
1686 pv->data.v_bool = punit->stay;
1687 break;
1688 default:
1689 log_error("%s(): Unhandled request for value of property %d "
1690 "(%s) from object of type \"%s\".", __FUNCTION__,
1692 goto FAILED;
1693 }
1694 }
1695 return pv;
1696
1697 case OBJTYPE_CITY:
1698 {
1699 const struct city *pcity = objbind_get_object(ob);
1700
1701 if (NULL == pcity) {
1702 goto FAILED;
1703 }
1704
1705 switch (propid) {
1706 case OPID_CITY_IMAGE:
1707 pv->data.v_pixbuf = create_city_pixbuf(pcity);
1708 pv->must_free = TRUE;
1709 break;
1710#ifdef FREECIV_DEBUG
1711 case OPID_CITY_ADDRESS:
1712 pv->data.v_string = g_strdup_printf("%p", pcity);
1713 pv->must_free = TRUE;
1714 break;
1715#endif /* FREECIV_DEBUG */
1716 case OPID_CITY_XY:
1717 {
1718 const struct tile *ptile = city_tile(pcity);
1719
1720 pv->data.v_string = g_strdup_printf("(%d, %d)", TILE_XY(ptile));
1721 pv->must_free = TRUE;
1722 }
1723 break;
1724 case OPID_CITY_ID:
1725 pv->data.v_int = pcity->id;
1726 break;
1727 case OPID_CITY_NAME:
1728 pv->data.v_const_string = pcity->name;
1729 break;
1730 case OPID_CITY_SIZE:
1731 pv->data.v_int = city_size_get(pcity);
1732 break;
1733 case OPID_CITY_HISTORY:
1734 pv->data.v_int = pcity->history;
1735 break;
1737 pv->data.v_built = fc_malloc(sizeof(pcity->built));
1738 memcpy(pv->data.v_built, pcity->built, sizeof(pcity->built));
1739 pv->must_free = TRUE;
1740 break;
1742 pv->data.v_int = pcity->food_stock;
1743 break;
1745 pv->data.v_int = pcity->shield_stock;
1746 break;
1747 default:
1748 log_error("%s(): Unhandled request for value of property %d "
1749 "(%s) from object of type \"%s\".", __FUNCTION__,
1751 goto FAILED;
1752 }
1753 }
1754 return pv;
1755
1756 case OBJTYPE_PLAYER:
1757 {
1758 const struct player *pplayer = objbind_get_object(ob);
1759 const struct research *presearch;
1760
1761 if (NULL == pplayer) {
1762 goto FAILED;
1763 }
1764
1765 switch (propid) {
1766 case OPID_PLAYER_NAME:
1767 pv->data.v_const_string = pplayer->name;
1768 break;
1769 case OPID_PLAYER_NATION:
1770 pv->data.v_nation = nation_of_player(pplayer);
1771 break;
1772 case OPID_PLAYER_GOV:
1773 pv->data.v_gov = pplayer->government;
1774 break;
1775 case OPID_PLAYER_AGE:
1776 pv->data.v_int = pplayer->turns_alive;
1777 break;
1778#ifdef FREECIV_DEBUG
1780 pv->data.v_string = g_strdup_printf("%p", pplayer);
1781 pv->must_free = TRUE;
1782 break;
1783#endif /* FREECIV_DEBUG */
1785 presearch = research_get(pplayer);
1786 BV_CLR_ALL(pv->data.v_bv_inventions);
1789 BV_SET(pv->data.v_bv_inventions, tech);
1790 }
1792 break;
1794 pv->data.v_bool = player_has_flag(pplayer, PLRF_SCENARIO_RESERVED);
1795 break;
1797 pv->data.v_int = pplayer->autoselect_weight;
1798 break;
1800 presearch = research_get(pplayer);
1801 pv->data.v_int = presearch->bulbs_researched;
1802 break;
1803 case OPID_PLAYER_GOLD:
1804 pv->data.v_int = pplayer->economic.gold;
1805 break;
1807 pv->data.v_int = pplayer->economic.infra_points;
1808 break;
1809 default:
1810 log_error("%s(): Unhandled request for value of property %d "
1811 "(%s) from object of type \"%s\".", __FUNCTION__,
1813 goto FAILED;
1814 }
1815 }
1816 return pv;
1817
1818 case OBJTYPE_GAME:
1819 {
1820 const struct civ_game *pgame = objbind_get_object(ob);
1821
1822 if (NULL == pgame) {
1823 goto FAILED;
1824 }
1825
1826 switch (propid) {
1827 case OPID_GAME_SCENARIO:
1828 pv->data.v_bool = pgame->scenario.is_scenario;
1829 break;
1831 pv->data.v_const_string = pgame->scenario.name;
1832 break;
1834 pv->data.v_const_string = pgame->scenario.authors;
1835 break;
1837 pv->data.v_const_string = pgame->scenario_desc.description;
1838 break;
1840 pv->data.v_bool = pgame->scenario.save_random;
1841 break;
1843 pv->data.v_bool = pgame->scenario.players;
1844 break;
1846 pv->data.v_bool = pgame->scenario.startpos_nations;
1847 break;
1849 pv->data.v_bool = pgame->scenario.prevent_new_cities;
1850 break;
1852 pv->data.v_bool = pgame->scenario.lake_flooding;
1853 break;
1855 pv->data.v_bool = pgame->scenario.ruleset_locked;
1856 break;
1857 default:
1858 log_error("%s(): Unhandled request for value of property %d "
1859 "(%s) from object of type \"%s\".", __FUNCTION__,
1861 goto FAILED;
1862 }
1863 }
1864 return pv;
1865
1866 case NUM_OBJTYPES:
1867 break;
1868 }
1869
1870 log_error("%s(): Unhandled request for object type \"%s\" (nb %d).",
1872
1873FAILED:
1874 if (NULL != pv) {
1875 free(pv);
1876 }
1877 return NULL;
1878}
1879
1880/************************************************************************/
1885 struct objprop *op,
1886 double *pmin,
1887 double *pmax,
1888 double *pstep,
1889 double *pbig_step)
1890{
1893 double dummy;
1894
1895 /* Fill the values with something. */
1896 if (NULL != pmin) {
1897 *pmin = 0;
1898 } else {
1899 pmin = &dummy;
1900 }
1901 if (NULL != pmax) {
1902 *pmax = 1;
1903 } else {
1904 pmax = &dummy;
1905 }
1906 if (NULL != pstep) {
1907 *pstep = 1;
1908 } else {
1909 pstep = &dummy;
1910 }
1911 if (NULL != pbig_step) {
1912 *pbig_step = 1;
1913 } else {
1914 pbig_step = &dummy;
1915 }
1916
1917 if (!ob || !op) {
1918 return FALSE;
1919 }
1920
1923
1924 switch (objtype) {
1925 case OBJTYPE_TILE:
1926 case OBJTYPE_STARTPOS:
1927 log_error("%s(): Unhandled request for value range of property %d (%s) "
1928 "from object of type \"%s\".", __FUNCTION__,
1930 return FALSE;
1931
1932 case OBJTYPE_UNIT:
1933 {
1934 const struct unit *punit = objbind_get_object(ob);
1935 const struct unit_type *putype;
1936
1937 if (NULL == punit) {
1938 return FALSE;
1939 }
1940
1942
1943 switch (propid) {
1945 *pmin = 0;
1947 *pstep = 1;
1948 *pbig_step = 5;
1949 return TRUE;
1950 case OPID_UNIT_FUEL:
1951 *pmin = 0;
1953 *pstep = 1;
1954 *pbig_step = 5;
1955 return TRUE;
1956 case OPID_UNIT_HP:
1957 *pmin = 1;
1958 *pmax = putype->hp;
1959 *pstep = 1;
1960 *pbig_step = 10;
1961 return TRUE;
1962 case OPID_UNIT_VETERAN:
1963 *pmin = 0;
1965 *pstep = 1;
1966 *pbig_step = 3;
1967 return TRUE;
1968 default:
1969 break;
1970 }
1971 }
1972 log_error("%s(): Unhandled request for value range of property %d (%s) "
1973 "from object of type \"%s\".", __FUNCTION__,
1975 return FALSE;
1976
1977 case OBJTYPE_CITY:
1978 {
1979 const struct city *pcity = objbind_get_object(ob);
1980
1981 if (NULL == pcity) {
1982 return FALSE;
1983 }
1984
1985 switch (propid) {
1986 case OPID_CITY_SIZE:
1987 *pmin = 1;
1989 *pstep = 1;
1990 *pbig_step = 5;
1991 return TRUE;
1992 case OPID_CITY_HISTORY:
1993 *pmin = 0;
1994 *pmax = USHRT_MAX;
1995 *pstep = 1;
1996 *pbig_step = 10;
1997 return TRUE;
1999 *pmin = 0;
2001 *pstep = 1;
2002 *pbig_step = 5;
2003 return TRUE;
2005 *pmin = 0;
2006 *pmax = USHRT_MAX; /* Limited to uint16 by city info packet. */
2007 *pstep = 1;
2008 *pbig_step = 10;
2009 return TRUE;
2010 default:
2011 break;
2012 }
2013 }
2014 log_error("%s(): Unhandled request for value range of property %d (%s) "
2015 "from object of type \"%s\".", __FUNCTION__,
2017 return FALSE;
2018
2019 case OBJTYPE_PLAYER:
2020 switch (propid) {
2022 *pmin = 0;
2023 *pmax = 1000000; /* Arbitrary. */
2024 *pstep = 1;
2025 *pbig_step = 100;
2026 return TRUE;
2027 case OPID_PLAYER_GOLD:
2028 *pmin = 0;
2029 *pmax = 1000000; /* Arbitrary. */
2030 *pstep = 1;
2031 *pbig_step = 100;
2032 return TRUE;
2034 *pmin = 0;
2035 *pmax = 1000000; /* Arbitrary. */
2036 *pstep = 1;
2037 *pbig_step = 100;
2038 return TRUE;
2040 *pmin = -1;
2041 *pmax = 10000; /* Keep it under SINT16 */
2042 *pstep = 1;
2043 *pbig_step = 10;
2044 return TRUE;
2045 default:
2046 break;
2047 }
2048 log_error("%s(): Unhandled request for value range of property %d (%s) "
2049 "from object of type \"%s\".", __FUNCTION__,
2051 return FALSE;
2052
2053 case OBJTYPE_GAME:
2054 log_error("%s(): Unhandled request for value range of property %d (%s) "
2055 "from object of type \"%s\".", __FUNCTION__,
2057 return FALSE;
2058
2059 case NUM_OBJTYPES:
2060 break;
2061 }
2062
2063 log_error("%s(): Unhandled request for object type \"%s\" (nb %d).",
2065 return FALSE;
2066}
2067
2068/************************************************************************/
2072 struct objprop *op)
2073{
2074 if (!ob || !op || !ob->propstate_table) {
2075 return;
2076 }
2077
2078 propstate_hash_remove(ob->propstate_table, objprop_get_id(op));
2079}
2080
2081/************************************************************************/
2086 struct objprop *op)
2087{
2088 if (!ob || !op) {
2089 return FALSE;
2090 }
2091
2092 if (objprop_is_readonly(op)) {
2093 return FALSE;
2094 }
2095
2096 return propstate_hash_lookup(ob->propstate_table,
2098}
2099
2100/************************************************************************/
2105{
2106 if (!ob) {
2107 return FALSE;
2108 }
2109
2110 return (0 < propstate_hash_size(ob->propstate_table));
2111}
2112
2113/************************************************************************/
2117{
2118 if (!ob) {
2119 return;
2120 }
2121 propstate_hash_clear(ob->propstate_table);
2122}
2123
2124/************************************************************************/
2131 struct objprop *op,
2132 struct propval *pv)
2133{
2134 struct propstate *ps;
2135 bool equal;
2136 struct propval *pv_old, *pv_copy;
2138
2139 if (!ob || !op) {
2140 return FALSE;
2141 }
2142
2144
2146 if (!pv_old) {
2147 return FALSE;
2148 }
2149
2152
2153 if (equal) {
2155 return FALSE;
2156 }
2157
2159
2160 if (propstate_hash_lookup(ob->propstate_table, propid, &ps)) {
2162 } else {
2164 propstate_hash_insert(ob->propstate_table, propid, ps);
2165 }
2166
2167 return TRUE;
2168}
2169
2170/************************************************************************/
2177 struct objprop *op)
2178{
2179 struct propstate *ps;
2180
2181 if (!ob || !op) {
2182 return NULL;
2183 }
2184
2185 if (propstate_hash_lookup(ob->propstate_table, objprop_get_id(op), &ps)) {
2186 return propstate_get_value(ps);
2187 } else {
2188 return NULL;
2189 }
2190}
2191
2192/************************************************************************/
2195static void objbind_destroy(struct objbind *ob)
2196{
2197 if (!ob) {
2198 return;
2199 }
2200 if (ob->propstate_table) {
2201 propstate_hash_destroy(ob->propstate_table);
2202 ob->propstate_table = NULL;
2203 }
2204 if (ob->rowref) {
2206 ob->rowref = NULL;
2207 }
2208 free(ob);
2209}
2210
2211/************************************************************************/
2215{
2216 if (!ob) {
2217 return NUM_OBJTYPES;
2218 }
2219 return ob->objtype;
2220}
2221
2222/************************************************************************/
2226 struct property_page *pp)
2227{
2228 if (!ob) {
2229 return;
2230 }
2231 ob->parent_property_page = pp;
2232}
2233
2234/************************************************************************/
2240 union packetdata pd)
2241{
2243
2244 if (!ob || !pd.pointers.v_pointer1) {
2245 return;
2246 }
2247
2249
2250 switch (objtype) {
2251 case OBJTYPE_TILE:
2252 {
2253 struct packet_edit_tile *packet = pd.tile;
2254 const struct tile *ptile = objbind_get_object(ob);
2255
2256 if (NULL == ptile) {
2257 return;
2258 }
2259
2260 packet->tile = tile_index(ptile);
2261 packet->extras = *tile_extras(ptile);
2262 /* TODO: Set more packet fields. */
2263 }
2264 return;
2265
2266 case OBJTYPE_STARTPOS:
2267 {
2268 struct packet_edit_startpos_full *packet = pd.startpos;
2269 const struct startpos *psp = objbind_get_object(ob);
2270
2271 if (NULL != psp) {
2272 startpos_pack(psp, packet);
2273 }
2274 }
2275 return;
2276
2277 case OBJTYPE_UNIT:
2278 {
2279 struct packet_edit_unit *packet = pd.unit;
2280 const struct unit *punit = objbind_get_object(ob);
2281
2282 if (NULL == punit) {
2283 return;
2284 }
2285
2286 packet->id = punit->id;
2287 packet->moves_left = punit->moves_left;
2288 packet->fuel = punit->fuel;
2289 packet->moved = punit->moved;
2290 packet->done_moving = punit->done_moving;
2291 packet->hp = punit->hp;
2292 packet->veteran = punit->veteran;
2293 packet->stay = punit->stay;
2294 /* TODO: Set more packet fields. */
2295 }
2296 return;
2297
2298 case OBJTYPE_CITY:
2299 {
2300 struct packet_edit_city *packet = pd.city;
2301 const struct city *pcity = objbind_get_object(ob);
2302 int i;
2303
2304 if (NULL == pcity) {
2305 return;
2306 }
2307
2308 packet->id = pcity->id;
2309 sz_strlcpy(packet->name, pcity->name);
2310 packet->size = city_size_get(pcity);
2311 packet->history = pcity->history;
2312 for (i = 0; i < B_LAST; i++) {
2313 packet->built[i] = pcity->built[i].turn;
2314 }
2315 packet->food_stock = pcity->food_stock;
2316 packet->shield_stock = pcity->shield_stock;
2317 /* TODO: Set more packet fields. */
2318 }
2319 return;
2320
2321 case OBJTYPE_PLAYER:
2322 {
2323 struct packet_edit_player *packet = pd.player;
2324 const struct player *pplayer = objbind_get_object(ob);
2325 const struct nation_type *pnation;
2326 const struct research *presearch;
2327
2328 if (NULL == pplayer) {
2329 return;
2330 }
2331
2332 packet->id = player_number(pplayer);
2333 sz_strlcpy(packet->name, pplayer->name);
2334 pnation = nation_of_player(pplayer);
2335 packet->nation = nation_index(pnation);
2336 presearch = research_get(pplayer);
2338 packet->inventions[tech]
2341 packet->autoselect_weight = pplayer->autoselect_weight;
2342 packet->gold = pplayer->economic.gold;
2343 packet->infrapoints = pplayer->economic.infra_points;
2344 packet->government = government_index(pplayer->government);
2346 /* TODO: Set more packet fields. */
2347 }
2348 return;
2349
2350 case OBJTYPE_GAME:
2351 {
2352 struct packet_edit_game *packet = pd.game.game;
2353 const struct civ_game *pgame = objbind_get_object(ob);
2354
2355 if (NULL == pgame) {
2356 return;
2357 }
2358
2359 packet->scenario = pgame->scenario.is_scenario;
2360 sz_strlcpy(packet->scenario_name, pgame->scenario.name);
2361 sz_strlcpy(packet->scenario_authors, pgame->scenario.authors);
2362 sz_strlcpy(pd.game.desc->scenario_desc, pgame->scenario_desc.description);
2363 packet->scenario_random = pgame->scenario.save_random;
2364 packet->scenario_players = pgame->scenario.players;
2365 packet->startpos_nations = pgame->scenario.startpos_nations;
2366 packet->prevent_new_cities = pgame->scenario.prevent_new_cities;
2367 packet->lake_flooding = pgame->scenario.lake_flooding;
2368 }
2369 return;
2370
2371 case NUM_OBJTYPES:
2372 break;
2373 }
2374
2375 log_error("%s(): Unhandled object type %s (nb %d).", __FUNCTION__,
2377}
2378
2379/************************************************************************/
2383 struct objprop *op,
2384 union packetdata pd)
2385{
2386 struct propval *pv;
2389
2390 if (!op || !ob || !pd.pointers.v_pointer1) {
2391 return;
2392 }
2393
2394 if (NULL == objbind_get_object(ob)) {
2395 return;
2396 }
2397
2399 return;
2400 }
2401
2403 if (!pv) {
2404 return;
2405 }
2406
2409
2410 switch (objtype) {
2411 case OBJTYPE_TILE:
2412 {
2413 struct packet_edit_tile *packet = pd.tile;
2414
2415 switch (propid) {
2416 case OPID_TILE_SPECIALS:
2418 if (BV_ISSET(pv->data.v_bv_special, pextra->data.special_idx)) {
2419 BV_SET(packet->extras, pextra->data.special_idx);
2420 } else {
2421 BV_CLR(packet->extras, pextra->data.special_idx);
2422 }
2424 return;
2425 case OPID_TILE_ROADS:
2427 int ridx = road_number(extra_road_get(pextra));
2428
2429 if (BV_ISSET(pv->data.v_bv_roads, ridx)) {
2430 BV_SET(packet->extras, extra_index(pextra));
2431 } else {
2432 BV_CLR(packet->extras, extra_index(pextra));
2433 }
2435 return;
2436 case OPID_TILE_BASES:
2438 int bidx = base_number(extra_base_get(pextra));
2439
2440 if (BV_ISSET(pv->data.v_bv_bases, bidx)) {
2441 BV_SET(packet->extras, extra_index(pextra));
2442 } else {
2443 BV_CLR(packet->extras, extra_index(pextra));
2444 }
2446 return;
2447 case OPID_TILE_LABEL:
2448 sz_strlcpy(packet->label, pv->data.v_string);
2449 return;
2450 default:
2451 break;
2452 }
2453 }
2454 log_error("%s(): Unhandled request to pack value of property "
2455 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2457 return;
2458
2459 case OBJTYPE_STARTPOS:
2460 {
2461 struct packet_edit_startpos_full *packet = pd.startpos;
2462
2463 switch (propid) {
2465 packet->exclude = pv->data.v_bool;
2466 return;
2468 BV_CLR_ALL(packet->nations);
2469 nation_hash_iterate(pv->data.v_nation_hash, pnation) {
2470 BV_SET(packet->nations, nation_number(pnation));
2472 return;
2473 default:
2474 break;
2475 }
2476 }
2477 log_error("%s(): Unhandled request to pack value of property "
2478 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2480 return;
2481
2482 case OBJTYPE_UNIT:
2483 {
2484 struct packet_edit_unit *packet = pd.unit;
2485
2486 switch (propid) {
2488 packet->moves_left = pv->data.v_int;
2489 return;
2490 case OPID_UNIT_FUEL:
2491 packet->fuel = pv->data.v_int;
2492 return;
2493 case OPID_UNIT_MOVED:
2494 packet->moved = pv->data.v_bool;
2495 return;
2497 packet->done_moving = pv->data.v_bool;
2498 return;
2499 case OPID_UNIT_HP:
2500 packet->hp = pv->data.v_int;
2501 return;
2502 case OPID_UNIT_VETERAN:
2503 packet->veteran = pv->data.v_int;
2504 return;
2505 case OPID_UNIT_STAY:
2506 packet->stay = pv->data.v_bool;
2507 return;
2508 default:
2509 break;
2510 }
2511 }
2512 log_error("%s(): Unhandled request to pack value of property "
2513 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2515 return;
2516
2517 case OBJTYPE_CITY:
2518 {
2519 struct packet_edit_city *packet = pd.city;
2520
2521 switch (propid) {
2522 case OPID_CITY_NAME:
2523 sz_strlcpy(packet->name, pv->data.v_string);
2524 return;
2525 case OPID_CITY_SIZE:
2526 packet->size = pv->data.v_int;
2527 return;
2528 case OPID_CITY_HISTORY:
2529 packet->history = pv->data.v_int;
2530 return;
2532 packet->food_stock = pv->data.v_int;
2533 return;
2535 packet->shield_stock = pv->data.v_int;
2536 return;
2538 {
2539 int i;
2540
2541 for (i = 0; i < B_LAST; i++) {
2542 packet->built[i] = pv->data.v_built[i].turn;
2543 }
2544 }
2545 return;
2546 default:
2547 break;
2548 }
2549 }
2550 log_error("%s(): Unhandled request to pack value of property "
2551 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2553 return;
2554
2555 case OBJTYPE_PLAYER:
2556 {
2557 struct packet_edit_player *packet = pd.player;
2558
2559 switch (propid) {
2560 case OPID_PLAYER_NAME:
2561 sz_strlcpy(packet->name, pv->data.v_string);
2562 return;
2563 case OPID_PLAYER_NATION:
2564 packet->nation = nation_index(pv->data.v_nation);
2565 return;
2566 case OPID_PLAYER_GOV:
2567 packet->government = government_index(pv->data.v_gov);
2568 return;
2571 packet->inventions[tech] = BV_ISSET(pv->data.v_bv_inventions, tech);
2573 return;
2575 packet->scenario_reserved = pv->data.v_bool;
2576 return;
2578 packet->autoselect_weight = pv->data.v_int;
2579 return;
2581 packet->bulbs_researched = pv->data.v_int;
2582 return;
2583 case OPID_PLAYER_GOLD:
2584 packet->gold = pv->data.v_int;
2585 return;
2587 packet->infrapoints = pv->data.v_int;
2588 return;
2589 default:
2590 break;
2591 }
2592 }
2593 log_error("%s(): Unhandled request to pack value of property "
2594 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2596 return;
2597
2598 case OBJTYPE_GAME:
2599 {
2600 struct packet_edit_game *packet = pd.game.game;
2601
2602 switch (propid) {
2603 case OPID_GAME_SCENARIO:
2604 packet->scenario = pv->data.v_bool;
2605 return;
2607 sz_strlcpy(packet->scenario_name, pv->data.v_const_string);
2608 return;
2610 sz_strlcpy(packet->scenario_authors, pv->data.v_const_string);
2611 return;
2613 sz_strlcpy(pd.game.desc->scenario_desc, pv->data.v_const_string);
2614 return;
2616 packet->scenario_random = pv->data.v_bool;
2617 return;
2619 packet->scenario_players = pv->data.v_bool;
2620 return;
2622 packet->startpos_nations = pv->data.v_bool;
2623 return;
2625 packet->prevent_new_cities = pv->data.v_bool;
2626 return;
2628 packet->lake_flooding = pv->data.v_bool;
2629 return;
2631 packet->ruleset_locked = pv->data.v_bool;
2632 return;
2633 default:
2634 break;
2635 }
2636 }
2637 log_error("%s(): Unhandled request to pack value of property "
2638 "%d (%s) from object of type \"%s\".", __FUNCTION__,
2640 return;
2641
2642 case NUM_OBJTYPES:
2643 break;
2644 }
2645
2646 log_error("%s(): Unhandled request for object type \"%s\" (nb %d).",
2648
2649}
2650
2651/************************************************************************/
2654static void objbind_set_rowref(struct objbind *ob,
2656{
2657 if (!ob) {
2658 return;
2659 }
2660 ob->rowref = rr;
2661}
2662
2663/************************************************************************/
2667{
2668 if (!ob) {
2669 return NULL;
2670 }
2671 return ob->rowref;
2672}
2673
2674/************************************************************************/
2677static int objprop_get_id(const struct objprop *op)
2678{
2679 if (!op) {
2680 return -1;
2681 }
2682 return op->id;
2683}
2684
2685/************************************************************************/
2692static GType objprop_get_gtype(const struct objprop *op)
2693{
2695
2696 switch (op->valtype) {
2697 case VALTYPE_NONE:
2699 return G_TYPE_NONE;
2700 case VALTYPE_INT:
2701 return G_TYPE_INT;
2702 case VALTYPE_BOOL:
2703 /* We want to show it as translated string, not as untranslated G_TYPE_BOOLEAN */
2704 return G_TYPE_STRING;
2705 case VALTYPE_STRING:
2708 case VALTYPE_BV_SPECIAL:
2709 case VALTYPE_BV_ROADS:
2710 case VALTYPE_BV_BASES:
2712 return G_TYPE_STRING;
2713 case VALTYPE_PIXBUF:
2714 case VALTYPE_NATION:
2715 case VALTYPE_GOV:
2716 return GDK_TYPE_PIXBUF;
2717 }
2718 log_error("%s(): Unhandled value type %d.", __FUNCTION__, op->valtype);
2719 return G_TYPE_NONE;
2720}
2721
2722/************************************************************************/
2725static enum value_types objprop_get_valtype(const struct objprop *op)
2726{
2727 if (!op) {
2728 return VALTYPE_NONE;
2729 }
2730 return op->valtype;
2731}
2732
2733/************************************************************************/
2736static bool objprop_show_in_listview(const struct objprop *op)
2737{
2738 if (!op) {
2739 return FALSE;
2740 }
2741 return op->flags & OPF_IN_LISTVIEW;
2742}
2743
2744/************************************************************************/
2747static bool objprop_has_widget(const struct objprop *op)
2748{
2749 if (!op) {
2750 return FALSE;
2751 }
2752 return op->flags & OPF_HAS_WIDGET;
2753}
2754
2755/************************************************************************/
2761static const char *objprop_get_attribute_type_string(const struct objprop *op)
2762{
2763 GType gtype;
2764
2765 if (!op) {
2766 return NULL;
2767 }
2768
2770 if (gtype == G_TYPE_INT || gtype == G_TYPE_STRING
2771 || gtype == G_TYPE_BOOLEAN) {
2772 return "text";
2773 } else if (gtype == GDK_TYPE_PIXBUF) {
2774 return "pixbuf";
2775 }
2776
2777 return NULL;
2778}
2779
2780/************************************************************************/
2786static void objprop_set_column_id(struct objprop *op, int col_id)
2787{
2788 if (!op) {
2789 return;
2790 }
2791 op->column_id = col_id;
2792}
2793
2794/************************************************************************/
2799static int objprop_get_column_id(const struct objprop *op)
2800{
2801 if (!op) {
2802 return -1;
2803 }
2804 return op->column_id;
2805}
2806
2807/************************************************************************/
2812{
2813 if (!op) {
2814 return;
2815 }
2816 op->view_column = col;
2817}
2818
2819/************************************************************************/
2824{
2825 if (!op) {
2826 return NULL;
2827 }
2828 return op->view_column;
2829}
2830
2831/************************************************************************/
2834static const char *objprop_get_name(const struct objprop *op)
2835{
2836 if (!op) {
2837 return NULL;
2838 }
2839 return op->name;
2840}
2841
2842/************************************************************************/
2845static const char *objprop_get_tooltip(const struct objprop *op)
2846{
2847 if (!op) {
2848 return NULL;
2849 }
2850 return op->tooltip;
2851}
2852
2853/************************************************************************/
2859{
2861 GType gtype;
2862
2864
2865 if (gtype == G_TYPE_INT || gtype == G_TYPE_STRING
2866 || gtype == G_TYPE_BOOLEAN) {
2868 } else if (gtype == GDK_TYPE_PIXBUF) {
2870 }
2871
2872 return cell;
2873}
2874
2875/************************************************************************/
2879static bool objprop_is_sortable(const struct objprop *op)
2880{
2881 GType gtype;
2882 if (!op) {
2883 return FALSE;
2884 }
2886 return gtype == G_TYPE_INT || gtype == G_TYPE_STRING;
2887}
2888
2889/************************************************************************/
2893static bool objprop_is_readonly(const struct objprop *op)
2894{
2895 if (!op) {
2896 return TRUE;
2897 }
2898 return !(op->flags & OPF_EDITABLE);
2899}
2900
2901/************************************************************************/
2905{
2906 struct objprop *op;
2907 struct property_page *pp;
2908 struct propval value = {{0,}, VALTYPE_STRING, FALSE};
2909
2910 op = userdata;
2913
2914 property_page_change_value(pp, op, &value);
2915}
2916
2917/************************************************************************/
2922{
2923 struct objprop *op;
2924 struct property_page *pp;
2925 struct propval value = {{0,}, VALTYPE_INT, FALSE};
2926
2927 op = userdata;
2930
2931 property_page_change_value(pp, op, &value);
2932}
2933
2934/************************************************************************/
2939{
2940 struct objprop *op;
2941 struct property_page *pp;
2942 struct propval value = {{0,}, VALTYPE_BOOL, FALSE};
2943
2944 op = userdata;
2947
2949}
2950
2951/************************************************************************/
2954static void objprop_setup_widget(struct objprop *op)
2955{
2956 GtkWidget *ebox, *hbox, *hbox2, *label, *image, *entry, *spin, *button;
2957 struct extviewer *ev = NULL;
2959
2960 if (!op) {
2961 return;
2962 }
2963
2964 if (!objprop_has_widget(op)) {
2965 return;
2966 }
2967
2968 ebox = gtk_event_box_new();
2969 op->widget = ebox;
2970
2971 hbox = gtk_grid_new();
2973
2975
2980 objprop_set_child_widget(op, "name-label", label);
2981
2983
2984 switch (propid) {
2985 case OPID_TILE_INDEX:
2986 case OPID_TILE_X:
2987 case OPID_TILE_Y:
2988 case OPID_TILE_NAT_X:
2989 case OPID_TILE_NAT_Y:
2991 case OPID_TILE_TERRAIN:
2992 case OPID_TILE_RESOURCE:
2993 case OPID_TILE_XY:
2994 case OPID_STARTPOS_XY:
2995 case OPID_UNIT_ID:
2996 case OPID_UNIT_XY:
2997 case OPID_UNIT_TYPE:
2998 case OPID_CITY_ID:
2999 case OPID_CITY_XY:
3000 case OPID_PLAYER_AGE:
3001#ifdef FREECIV_DEBUG
3002 case OPID_TILE_ADDRESS:
3003 case OPID_UNIT_ADDRESS:
3004 case OPID_CITY_ADDRESS:
3006#endif /* FREECIV_DEBUG */
3007 label = gtk_label_new(NULL);
3012 objprop_set_child_widget(op, "value-label", label);
3013 return;
3014
3015 case OPID_TILE_IMAGE:
3017 case OPID_UNIT_IMAGE:
3018 case OPID_CITY_IMAGE:
3019 image = gtk_image_new();
3025 return;
3026
3027 case OPID_CITY_NAME:
3028 case OPID_PLAYER_NAME:
3030 case OPID_TILE_LABEL:
3031 entry = gtk_entry_new();
3035 g_signal_connect(entry, "changed",
3039 return;
3040
3042 case OPID_CITY_SIZE:
3043 case OPID_CITY_HISTORY:
3047 case OPID_PLAYER_GOLD:
3049 spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0);
3052 g_signal_connect(spin, "value-changed",
3056 return;
3057
3058 case OPID_UNIT_FUEL:
3059 case OPID_UNIT_HP:
3060 case OPID_UNIT_VETERAN:
3062 hbox2 = gtk_grid_new();
3067 spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0);
3068 g_signal_connect(spin, "value-changed",
3072 label = gtk_label_new(NULL);
3076 objprop_set_child_widget(op, "max-value-label", label);
3077 return;
3078
3079 case OPID_TILE_SPECIALS:
3080 case OPID_TILE_ROADS:
3081 case OPID_TILE_BASES:
3082 case OPID_TILE_VISION:
3085 case OPID_PLAYER_NATION:
3086 case OPID_PLAYER_GOV:
3090 ev = extviewer_new(op);
3096 return;
3097
3099 case OPID_UNIT_MOVED:
3101 case OPID_UNIT_STAY:
3102 case OPID_GAME_SCENARIO:
3110 button = gtk_check_button_new();
3113 g_signal_connect(button, "toggled",
3116 objprop_set_child_widget(op, "checkbutton", button);
3117 return;
3118 }
3119
3120 log_error("%s(): Unhandled request to create widget for property %d (%s).",
3122}
3123
3124/************************************************************************/
3133 struct objbind *ob)
3134{
3135 GtkWidget *w, *label, *image, *entry, *spin, *button;
3136 struct extviewer *ev;
3137 struct propval *pv;
3138 bool modified;
3140 double min, max, step, big_step;
3141 char buf[256];
3142
3143 if (!op || !objprop_has_widget(op)) {
3144 return;
3145 }
3146
3148 if (!w) {
3149 return;
3150 }
3151
3153
3154 /* NB: We must take care to propval_free the return value of
3155 * objbind_get_value_from_object(), since it always makes a
3156 * copy, but to NOT free the result of objbind_get_modified_value()
3157 * since it returns its own stored value. */
3160
3161 if (pv && modified) {
3162 struct propval *pv_mod;
3163
3165 if (pv_mod) {
3166 if (propval_equal(pv, pv_mod)) {
3168 modified = FALSE;
3169 } else {
3171 pv = pv_mod;
3172 modified = TRUE;
3173 }
3174 } else {
3175 modified = FALSE;
3176 }
3177 }
3178
3179 switch (propid) {
3180 case OPID_TILE_IMAGE:
3182 case OPID_UNIT_IMAGE:
3183 case OPID_CITY_IMAGE:
3184 image = objprop_get_child_widget(op, "image");
3185 if (pv) {
3186 gtk_image_set_from_pixbuf(GTK_IMAGE(image), pv->data.v_pixbuf);
3187 } else {
3189 }
3190 break;
3191
3192 case OPID_TILE_XY:
3193 case OPID_TILE_TERRAIN:
3194 case OPID_TILE_RESOURCE:
3195 case OPID_STARTPOS_XY:
3196 case OPID_UNIT_XY:
3197 case OPID_UNIT_TYPE:
3198 case OPID_CITY_XY:
3199#ifdef FREECIV_DEBUG
3200 case OPID_TILE_ADDRESS:
3201 case OPID_UNIT_ADDRESS:
3202 case OPID_CITY_ADDRESS:
3204#endif /* FREECIV_DEBUG */
3205 label = objprop_get_child_widget(op, "value-label");
3206 if (pv) {
3207 gtk_label_set_text(GTK_LABEL(label), pv->data.v_string);
3208 } else {
3210 }
3211 break;
3212
3213 case OPID_TILE_INDEX:
3214 case OPID_TILE_X:
3215 case OPID_TILE_Y:
3216 case OPID_TILE_NAT_X:
3217 case OPID_TILE_NAT_Y:
3219 case OPID_UNIT_ID:
3220 case OPID_CITY_ID:
3221 case OPID_PLAYER_AGE:
3222 label = objprop_get_child_widget(op, "value-label");
3223 if (pv) {
3224 char agebuf[16];
3225
3226 fc_snprintf(agebuf, sizeof(agebuf), "%d", pv->data.v_int);
3228 } else {
3230 }
3231 break;
3232
3233 case OPID_CITY_NAME:
3234 case OPID_PLAYER_NAME:
3236 case OPID_TILE_LABEL:
3237 entry = objprop_get_child_widget(op, "entry");
3238 if (pv) {
3239 gtk_entry_set_text(GTK_ENTRY(entry), pv->data.v_string);
3240 } else {
3242 }
3244 break;
3245
3247 case OPID_CITY_SIZE:
3248 case OPID_CITY_HISTORY:
3252 case OPID_PLAYER_GOLD:
3254 spin = objprop_get_child_widget(op, "spin");
3255 if (pv) {
3258 if (objbind_get_allowed_value_span(ob, op, &min, &max,
3259 &step, &big_step)) {
3262 step, big_step);
3263 }
3267 }
3269 break;
3270
3271 case OPID_UNIT_FUEL:
3272 case OPID_UNIT_HP:
3273 case OPID_UNIT_VETERAN:
3275 spin = objprop_get_child_widget(op, "spin");
3276 label = objprop_get_child_widget(op, "max-value-label");
3277 if (pv) {
3280 if (objbind_get_allowed_value_span(ob, op, &min, &max,
3281 &step, &big_step)) {
3284 step, big_step);
3285 fc_snprintf(buf, sizeof(buf), "/%d", (int) max);
3287 } else {
3289 }
3293 } else {
3295 }
3297 break;
3298
3299 case OPID_TILE_SPECIALS:
3300 case OPID_TILE_ROADS:
3301 case OPID_TILE_BASES:
3302 case OPID_TILE_VISION:
3305 case OPID_PLAYER_NATION:
3306 case OPID_PLAYER_GOV:
3311 if (pv) {
3313 } else {
3315 }
3316 break;
3317
3319 case OPID_UNIT_MOVED:
3321 case OPID_UNIT_STAY:
3322 case OPID_GAME_SCENARIO:
3330 button = objprop_get_child_widget(op, "checkbutton");
3333 if (pv) {
3335 pv->data.v_bool);
3336 } else {
3338 }
3341 gtk_widget_set_sensitive(button, pv != NULL);
3342 break;
3343 }
3344
3345 if (!modified) {
3347 }
3348
3349 label = objprop_get_child_widget(op, "name-label");
3350 if (label) {
3351 const char *name = objprop_get_name(op);
3352 if (modified) {
3353 char namebuf[128];
3354
3355 fc_snprintf(namebuf, sizeof(namebuf),
3356 "<span foreground=\"red\">%s</span>", name);
3358 } else {
3360 }
3361 }
3362}
3363
3364/************************************************************************/
3369{
3370 if (!op) {
3371 return NULL;
3372 }
3373 if (!op->widget) {
3375 }
3376 return op->widget;
3377}
3378
3379/************************************************************************/
3384 const char *widget_name,
3386{
3387 GtkWidget *w;
3388
3389 if (!op || !widget_name || !widget) {
3390 return;
3391 }
3392
3394 if (!w) {
3395 log_error("Cannot store child widget %p under name "
3396 "\"%s\" using objprop_set_child_widget for object "
3397 "property %d (%s) because objprop_get_widget does "
3398 "not return a valid widget.",
3400 return;
3401 }
3402
3404}
3405
3406/************************************************************************/
3411 const char *widget_name)
3412{
3413 GtkWidget *w, *child;
3414
3415 if (!op || !widget_name) {
3416 return NULL;
3417 }
3418
3420 if (!w) {
3421 log_error("Cannot retrieve child widget under name "
3422 "\"%s\" using objprop_get_child_widget for object "
3423 "property %d (%s) because objprop_get_widget does "
3424 "not return a valid widget.",
3426 return NULL;
3427 }
3428
3430 if (!child) {
3431 log_error("Child widget \"%s\" not found for object "
3432 "property %d (%s) via objprop_get_child_widget.",
3434 return NULL;
3435 }
3436
3437 return child;
3438}
3439
3440/************************************************************************/
3444 struct extviewer *ev)
3445{
3446 if (!op) {
3447 return;
3448 }
3449 op->extviewer = ev;
3450}
3451
3452/************************************************************************/
3456{
3457 if (!op) {
3458 return NULL;
3459 }
3460 return op->extviewer;
3461}
3462
3463/************************************************************************/
3467{
3468 if (!op) {
3469 return NULL;
3470 }
3471 return op->parent_page;
3472}
3473
3474/************************************************************************/
3477static struct objprop *objprop_new(int id,
3478 const char *name,
3479 const char *tooltip,
3481 enum value_types valtype,
3482 struct property_page *parent)
3483{
3484 struct objprop *op;
3485
3486 op = fc_calloc(1, sizeof(*op));
3487 op->id = id;
3488 op->name = name;
3489 op->tooltip = tooltip;
3490 op->flags = flags;
3491 op->valtype = valtype;
3492 op->column_id = -1;
3493 op->parent_page = parent;
3494
3495 return op;
3496}
3497
3498/************************************************************************/
3502static struct extviewer *extviewer_new(struct objprop *op)
3503{
3504 struct extviewer *ev;
3505 GtkWidget *hbox, *vbox, *label, *button, *scrollwin, *image;
3506 GtkWidget *view = NULL;
3510 GType *gtypes;
3512 int num_cols;
3513
3514 if (!op) {
3515 return NULL;
3516 }
3517
3518 ev = fc_calloc(1, sizeof(*ev));
3519 ev->objprop = op;
3520
3522
3523
3524 /* Create the panel widget. */
3525
3526 switch (propid) {
3527 case OPID_TILE_SPECIALS:
3528 case OPID_TILE_ROADS:
3529 case OPID_TILE_BASES:
3535 hbox = gtk_grid_new();
3537 ev->panel_widget = hbox;
3538
3539 label = gtk_label_new(NULL);
3543 ev->panel_label = label;
3544 break;
3545
3546 case OPID_PLAYER_NATION:
3547 case OPID_PLAYER_GOV:
3548 vbox = gtk_grid_new();
3552 ev->panel_widget = vbox;
3553
3554 label = gtk_label_new(NULL);
3557 gtk_container_add(GTK_CONTAINER(vbox), label);
3558 ev->panel_label = label;
3559
3560 hbox = gtk_grid_new();
3563
3564 image = gtk_image_new();
3568 ev->panel_image = image;
3569 break;
3570
3571 case OPID_TILE_VISION:
3572 hbox = gtk_grid_new();
3574 ev->panel_widget = hbox;
3575 break;
3576
3577 default:
3578 log_error("Unhandled request to create panel widget "
3579 "for property %d (%s) in extviewer_new().",
3581 hbox = gtk_grid_new();
3583 ev->panel_widget = hbox;
3584 break;
3585 }
3586
3587 if (objprop_is_readonly(op)) {
3588 button = gtk_button_new_with_label(Q_("?verb:View"));
3589 } else {
3590 button = gtk_button_new_with_label(_("Edit"));
3591 }
3592 g_signal_connect(button, "clicked",
3595 ev->panel_button = button;
3596
3597
3598 /* Create the data store. */
3599
3600 switch (propid) {
3601 case OPID_TILE_SPECIALS:
3602 case OPID_TILE_ROADS:
3603 case OPID_TILE_BASES:
3607 break;
3608 case OPID_TILE_VISION:
3609 num_cols = 3 + 1 + V_COUNT;
3610 gtypes = fc_malloc(num_cols * sizeof(GType));
3611 gtypes[0] = G_TYPE_INT; /* player number */
3612 gtypes[1] = GDK_TYPE_PIXBUF; /* player flag */
3613 gtypes[2] = G_TYPE_STRING; /* player name */
3614 gtypes[3] = G_TYPE_BOOLEAN; /* tile_known */
3616 gtypes[4 + v] = G_TYPE_BOOLEAN; /* tile_seen[v] */
3619 free(gtypes);
3620 break;
3624 break;
3626 case OPID_PLAYER_NATION:
3627 case OPID_PLAYER_GOV:
3630 break;
3634 break;
3635 default:
3636 log_error("Unhandled request to create data store "
3637 "for property %d (%s) in extviewer_new().",
3639 break;
3640 }
3641
3642 ev->store = store;
3643 ev->textbuf = textbuf;
3644
3645 /* Create the view widget. */
3646
3647 vbox = gtk_grid_new();
3652 ev->view_widget = vbox;
3653
3657 gtk_container_add(GTK_CONTAINER(vbox), label);
3658 ev->view_label = label;
3659
3660 if (store || textbuf) {
3668
3669 if (store) {
3673 } else {
3674 const bool editable = !objprop_is_readonly(op);
3678 }
3681
3683 }
3684
3685 switch (propid) {
3686
3687 case OPID_TILE_SPECIALS:
3688 case OPID_TILE_ROADS:
3689 case OPID_TILE_BASES:
3690 /* TRANS: As in "this tile special is present". */
3691 add_column(view, 0, _("Present"), G_TYPE_BOOLEAN, TRUE, FALSE,
3693 add_column(view, 1, _("ID"), G_TYPE_INT,
3694 FALSE, FALSE, NULL, NULL);
3695 add_column(view, 2, _("Name"), G_TYPE_STRING,
3696 FALSE, FALSE, NULL, NULL);
3697 break;
3698
3699 case OPID_TILE_VISION:
3700 add_column(view, 0, _("ID"), G_TYPE_INT,
3701 FALSE, FALSE, NULL, NULL);
3702 add_column(view, 1, _("Nation"), GDK_TYPE_PIXBUF,
3703 FALSE, FALSE, NULL, NULL);
3704 add_column(view, 2, _("Name"), G_TYPE_STRING,
3705 FALSE, FALSE, NULL, NULL);
3706 add_column(view, 3, _("Known"), G_TYPE_BOOLEAN,
3707 FALSE, FALSE, NULL, NULL);
3712 break;
3713
3715 /* TRANS: As in "this building is present". */
3716 add_column(view, 0, _("Present"), G_TYPE_BOOLEAN, TRUE, FALSE,
3718 add_column(view, 1, _("ID"), G_TYPE_INT,
3719 FALSE, FALSE, NULL, NULL);
3720 add_column(view, 2, _("Name"), G_TYPE_STRING,
3721 FALSE, FALSE, NULL, NULL);
3722 /* TRANS: As in "the turn when this building was built". */
3723 add_column(view, 3, _("Turn Built"), G_TYPE_STRING,
3724 FALSE, FALSE, NULL, NULL);
3725 break;
3726
3728 /* TRANS: As in "the player has set this nation". */
3729 add_column(view, 0, _("Set"), G_TYPE_BOOLEAN, TRUE, FALSE,
3731 add_column(view, 1, _("ID"), G_TYPE_INT,
3732 FALSE, FALSE, NULL, NULL);
3733 add_column(view, 2, _("Flag"), GDK_TYPE_PIXBUF,
3734 FALSE, FALSE, NULL, NULL);
3735 add_column(view, 3, _("Name"), G_TYPE_STRING,
3736 FALSE, FALSE, NULL, NULL);
3737 break;
3738
3739 case OPID_PLAYER_NATION:
3740 case OPID_PLAYER_GOV:
3741 /* TRANS: As in "the player has set this nation". */
3742 add_column(view, 0, _("Set"), G_TYPE_BOOLEAN, TRUE, TRUE,
3744 add_column(view, 1, _("ID"), G_TYPE_INT,
3745 FALSE, FALSE, NULL, NULL);
3746 add_column(view, 2,
3747 propid == OPID_PLAYER_GOV ? _("Icon") : _("Flag"),
3749 FALSE, FALSE, NULL, NULL);
3750 add_column(view, 3, _("Name"), G_TYPE_STRING,
3751 FALSE, FALSE, NULL, NULL);
3752 break;
3753
3755 /* TRANS: As in "this invention is known". */
3756 add_column(view, 0, _("Known"), G_TYPE_BOOLEAN, TRUE, FALSE,
3758 add_column(view, 1, _("ID"), G_TYPE_INT,
3759 FALSE, FALSE, NULL, NULL);
3760 add_column(view, 2, _("Name"), G_TYPE_STRING,
3761 FALSE, FALSE, NULL, NULL);
3762 break;
3763
3766 g_signal_connect(textbuf, "changed",
3768 break;
3769
3770 default:
3771 log_error("Unhandled request to configure view widget "
3772 "for property %d (%s) in extviewer_new().",
3774 break;
3775 }
3776
3777 gtk_widget_show_all(ev->panel_widget);
3778 gtk_widget_show_all(ev->view_widget);
3779
3780 return ev;
3781}
3782
3783/************************************************************************/
3787{
3788 if (!ev) {
3789 return NULL;
3790 }
3791 return ev->objprop;
3792}
3793
3794/************************************************************************/
3799{
3800 if (!ev) {
3801 return NULL;
3802 }
3803 return ev->panel_widget;
3804}
3805
3806/************************************************************************/
3811{
3812 if (!ev) {
3813 return NULL;
3814 }
3815 return ev->view_widget;
3816}
3817
3818/************************************************************************/
3822 struct propval *pv)
3823{
3824 struct objprop *op;
3826 int id, turn_built;
3827 bool present, all;
3828 const char *name;
3830 GtkListStore *store;
3831 GtkTextBuffer *textbuf;
3833 gchar *buf;
3834
3835 if (!ev) {
3836 return;
3837 }
3838
3841
3842 if (propval_equal(pv, ev->pv_cached)) {
3843 return;
3844 }
3845 propval_free(ev->pv_cached);
3846 ev->pv_cached = propval_copy(pv);
3847 store = ev->store;
3848 textbuf = ev->textbuf;
3849
3850
3851 /* NB: Remember to have -1 as the last argument to
3852 * gtk_list_store_set() and to use the correct column
3853 * number when inserting data. :) */
3854 switch (propid) {
3855
3856 case OPID_TILE_SPECIALS:
3857 gtk_list_store_clear(store);
3859 id = spe->data.special_idx;
3861 present = BV_ISSET(pv->data.v_bv_special, id);
3862 gtk_list_store_append(store, &iter);
3863 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
3866 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3867 g_free(buf);
3868 break;
3869
3870 case OPID_TILE_ROADS:
3871 gtk_list_store_clear(store);
3873 struct road_type *proad = extra_road_get(pextra);
3874
3875 id = road_number(proad);
3876 name = extra_name_translation(pextra);
3877 present = BV_ISSET(pv->data.v_bv_roads, id);
3878 gtk_list_store_append(store, &iter);
3879 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
3882 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3883 g_free(buf);
3884 break;
3885
3886 case OPID_TILE_BASES:
3887 gtk_list_store_clear(store);
3889 struct base_type *pbase = extra_base_get(pextra);
3890
3891 id = base_number(pbase);
3892 name = extra_name_translation(pextra);
3893 present = BV_ISSET(pv->data.v_bv_bases, id);
3894 gtk_list_store_append(store, &iter);
3895 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
3898 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3899 g_free(buf);
3900 break;
3901
3902 case OPID_TILE_VISION:
3903 gtk_list_store_clear(store);
3904 player_slots_iterate(pslot) {
3905 id = player_slot_index(pslot);
3906 if (player_slot_is_used(pslot)) {
3907 struct player *pplayer = player_slot_get_player(pslot);
3908 name = player_name(pplayer);
3909 pixbuf = get_flag(pplayer->nation);
3910 } else {
3911 name = "";
3912 pixbuf = NULL;
3913 }
3914 gtk_list_store_append(store, &iter);
3915 gtk_list_store_set(store, &iter, 0, id, 2, name, -1);
3916 if (pixbuf) {
3917 gtk_list_store_set(store, &iter, 1, pixbuf, -1);
3919 pixbuf = NULL;
3920 }
3921 present = BV_ISSET(pv->data.v_tile_vision->tile_known, id);
3922 gtk_list_store_set(store, &iter, 3, present, -1);
3924 present = BV_ISSET(pv->data.v_tile_vision->tile_seen[v], id);
3925 gtk_list_store_set(store, &iter, 4 + v, present, -1);
3928 break;
3929
3931 gtk_list_store_clear(store);
3932 gtk_list_store_append(store, &iter);
3933 all = (0 == nation_hash_size(pv->data.v_nation_hash));
3934 gtk_list_store_set(store, &iter, 0, all, 1, -1, 3,
3935 _("All nations"), -1);
3936 nations_iterate(pnation) {
3938 && is_nation_playable(pnation)) {
3939 present = (!all && nation_hash_lookup(pv->data.v_nation_hash,
3940 pnation, NULL));
3941 id = nation_number(pnation);
3942 pixbuf = get_flag(pnation);
3944 gtk_list_store_append(store, &iter);
3945 gtk_list_store_set(store, &iter, 0, present, 1, id,
3946 2, pixbuf, 3, name, -1);
3947 if (pixbuf) {
3949 }
3950 }
3953 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3954 g_free(buf);
3955 break;
3956
3958 gtk_list_store_clear(store);
3959 improvement_iterate(pimprove) {
3960 if (is_special_improvement(pimprove)) {
3961 continue;
3962 }
3963 id = improvement_index(pimprove);
3965 turn_built = pv->data.v_built[id].turn;
3966 present = turn_built >= 0;
3967 buf = built_status_to_string(&pv->data.v_built[id]);
3968 gtk_list_store_append(store, &iter);
3969 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name,
3970 3, buf, -1);
3971 g_free(buf);
3974 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
3975 g_free(buf);
3976 break;
3977
3978 case OPID_PLAYER_NATION:
3979 {
3980 enum barbarian_type barbarian_type =
3981 nation_barbarian_type(pv->data.v_nation);
3982
3983 gtk_list_store_clear(store);
3984 nations_iterate(pnation) {
3986 && nation_barbarian_type(pnation) == barbarian_type
3987 && (barbarian_type != NOT_A_BARBARIAN
3988 || is_nation_playable(pnation))) {
3989 present = (pnation == pv->data.v_nation);
3990 id = nation_index(pnation);
3991 pixbuf = get_flag(pnation);
3993 gtk_list_store_append(store, &iter);
3994 gtk_list_store_set(store, &iter, 0, present, 1, id,
3995 2, pixbuf, 3, name, -1);
3996 if (pixbuf) {
3998 }
3999 }
4001 gtk_label_set_text(GTK_LABEL(ev->panel_label),
4002 nation_adjective_translation(pv->data.v_nation));
4003 pixbuf = get_flag(pv->data.v_nation);
4005 if (pixbuf) {
4007 }
4008 }
4009 break;
4010
4011 case OPID_PLAYER_GOV:
4012 {
4013 gtk_list_store_clear(store);
4015 present = (pgov == pv->data.v_gov);
4016 id = government_index(pgov);
4019 gtk_list_store_append(store, &iter);
4020 gtk_list_store_set(store, &iter, 0, present, 1, id,
4021 2, pixbuf, 3, name, -1);
4022 if (pixbuf) {
4024 }
4026 if (pv->data.v_gov != NULL) {
4027 gtk_label_set_text(GTK_LABEL(ev->panel_label),
4028 government_name_translation(pv->data.v_gov));
4030 } else {
4031 gtk_label_set_text(GTK_LABEL(ev->panel_label), "?");
4034 }
4035
4037 if (pixbuf) {
4039 }
4040 }
4041 break;
4042
4044 gtk_list_store_clear(store);
4046 id = advance_index(padvance);
4047 present = BV_ISSET(pv->data.v_bv_inventions, id);
4049 gtk_list_store_append(store, &iter);
4050 gtk_list_store_set(store, &iter, 0, present, 1, id, 2, name, -1);
4053 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4054 g_free(buf);
4055 break;
4056
4061 {
4062 GtkTextIter start, end;
4063 char *oldtext;
4064
4065 /* Don't re-set content if unchanged, to avoid moving cursor */
4066 gtk_text_buffer_get_bounds(textbuf, &start, &end);
4067 oldtext = gtk_text_buffer_get_text(textbuf, &start, &end, TRUE);
4068 if (strcmp(oldtext, pv->data.v_const_string) != 0) {
4069 gtk_text_buffer_set_text(textbuf, pv->data.v_const_string, -1);
4070 }
4071 }
4074 gtk_widget_set_sensitive(ev->view_widget, TRUE);
4076 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4077 g_free(buf);
4078 break;
4079
4080 default:
4081 log_error("Unhandled request to refresh widgets "
4082 "extviewer_refresh_widgets() for objprop id=%d "
4083 "name \"%s\".", propid, objprop_get_name(op));
4084 break;
4085 }
4086}
4087
4088/************************************************************************/
4092{
4093 struct objprop *op;
4095
4096 if (!ev) {
4097 return;
4098 }
4099
4102
4103 propval_free(ev->pv_cached);
4104 ev->pv_cached = NULL;
4105
4106 if (ev->panel_label != NULL) {
4107 gtk_label_set_text(GTK_LABEL(ev->panel_label), NULL);
4108 }
4109
4110 switch (propid) {
4111 case OPID_TILE_SPECIALS:
4112 case OPID_TILE_ROADS:
4113 case OPID_TILE_BASES:
4114 case OPID_TILE_VISION:
4118 gtk_list_store_clear(ev->store);
4119 break;
4120 case OPID_PLAYER_NATION:
4121 case OPID_PLAYER_GOV:
4122 gtk_list_store_clear(ev->store);
4124 break;
4129 gtk_text_buffer_set_text(ev->textbuf, "", -1);
4132 gtk_widget_set_sensitive(ev->view_widget, FALSE);
4133 break;
4134 default:
4135 log_error("Unhandled request to clear widgets "
4136 "in extviewer_clear_widgets() for objprop id=%d "
4137 "name \"%s\".", propid, objprop_get_name(op));
4138 break;
4139 }
4140}
4141
4142/************************************************************************/
4148{
4149 struct extviewer *ev;
4150 struct property_page *pp;
4151 struct objprop *op;
4152
4153 ev = userdata;
4154 if (!ev) {
4155 return;
4156 }
4157
4161}
4162
4163/************************************************************************/
4167 gchar *path,
4169{
4170 struct extviewer *ev;
4171 struct objprop *op;
4172 struct property_page *pp;
4174 GtkTreeModel *model;
4176 int id, old_id, turn_built;
4177 struct propval *pv;
4178 bool active, present;
4179 gchar *buf;
4181
4182 ev = userdata;
4183 if (!ev) {
4184 return;
4185 }
4186
4187 pv = ev->pv_cached;
4188 if (!pv) {
4189 return;
4190 }
4191
4196
4197 model = GTK_TREE_MODEL(ev->store);
4198 if (!gtk_tree_model_get_iter_from_string(model, &iter, path)) {
4199 return;
4200 }
4201 present = !active;
4202
4203
4204 switch (propid) {
4205
4206 case OPID_TILE_SPECIALS:
4207 gtk_tree_model_get(model, &iter, 1, &id, -1);
4209 return;
4210 }
4211 if (present) {
4212 BV_SET(pv->data.v_bv_special, id);
4213 } else {
4214 BV_CLR(pv->data.v_bv_special, id);
4215 }
4216 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4218 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4219 g_free(buf);
4220 break;
4221
4222 case OPID_TILE_ROADS:
4223 gtk_tree_model_get(model, &iter, 1, &id, -1);
4224 if (!(0 <= id && id < road_count())) {
4225 return;
4226 }
4227 if (present) {
4228 BV_SET(pv->data.v_bv_roads, id);
4229 } else {
4230 BV_CLR(pv->data.v_bv_roads, id);
4231 }
4232 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4234 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4235 g_free(buf);
4236 break;
4237
4238 case OPID_TILE_BASES:
4239 gtk_tree_model_get(model, &iter, 1, &id, -1);
4240 if (!(0 <= id && id < base_count())) {
4241 return;
4242 }
4243 if (present) {
4244 BV_SET(pv->data.v_bv_bases, id);
4245 } else {
4246 BV_CLR(pv->data.v_bv_bases, id);
4247 }
4248 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4250 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4251 g_free(buf);
4252 break;
4253
4255 gtk_tree_model_get(model, &iter, 1, &id, -1);
4256 if (-1 > id && id >= nation_count()) {
4257 return;
4258 }
4259
4260 if (-1 == id) {
4261 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4263 if (present) {
4264 while (gtk_tree_model_iter_next(model, &iter)) {
4265 gtk_list_store_set(ev->store, &iter, 0, FALSE, -1);
4266 }
4267 nation_hash_clear(pv->data.v_nation_hash);
4268 } else {
4269 const struct nation_type *pnation;
4270 int id2;
4271
4273 gtk_tree_model_get(model, &iter, 0, &id2, -1);
4274 gtk_list_store_set(ev->store, &iter, 0, TRUE, -1);
4275 pnation = nation_by_number(id2);
4276 nation_hash_insert(pv->data.v_nation_hash, pnation, NULL);
4277 }
4278 } else {
4279 const struct nation_type *pnation;
4280 bool all;
4281
4282 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4283 pnation = nation_by_number(id);
4284 if (present) {
4285 nation_hash_insert(pv->data.v_nation_hash, pnation, NULL);
4286 } else {
4287 nation_hash_remove(pv->data.v_nation_hash, pnation);
4288 }
4290 all = (0 == nation_hash_size(pv->data.v_nation_hash));
4291 gtk_list_store_set(ev->store, &iter, 0, all, -1);
4292 }
4294 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4295 g_free(buf);
4296 break;
4297
4299 gtk_tree_model_get(model, &iter, 1, &id, -1);
4300 if (!(0 <= id && id < B_LAST)) {
4301 return;
4302 }
4303 turn_built = present ? game.info.turn : I_NEVER;
4304 pv->data.v_built[id].turn = turn_built;
4305 buf = built_status_to_string(&pv->data.v_built[id]);
4306 gtk_list_store_set(ev->store, &iter, 0, present, 3, buf, -1);
4307 g_free(buf);
4309 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4310 g_free(buf);
4311 break;
4312
4313 case OPID_PLAYER_NATION:
4314 gtk_tree_model_get(model, &iter, 1, &id, -1);
4315 if (!(0 <= id && id < nation_count()) || !present) {
4316 return;
4317 }
4318 old_id = nation_index(pv->data.v_nation);
4319 pv->data.v_nation = nation_by_number(id);
4320 gtk_list_store_set(ev->store, &iter, 0, TRUE, -1);
4322 gtk_list_store_set(ev->store, &iter, 0, FALSE, -1);
4323 gtk_label_set_text(GTK_LABEL(ev->panel_label),
4324 nation_adjective_translation(pv->data.v_nation));
4325 pixbuf = get_flag(pv->data.v_nation);
4327 if (pixbuf) {
4329 }
4330 break;
4331
4332 case OPID_PLAYER_GOV:
4333 gtk_tree_model_get(model, &iter, 1, &id, -1);
4334 if (!(0 <= id && id < government_count()) || !present) {
4335 return;
4336 }
4337 if (pv->data.v_gov != NULL) {
4338 old_id = government_index(pv->data.v_gov);
4339 pv->data.v_gov = government_by_number(id);
4340 gtk_list_store_set(ev->store, &iter, 0, TRUE, -1);
4342 gtk_list_store_set(ev->store, &iter, 0, FALSE, -1);
4343 } else {
4344 pv->data.v_gov = government_by_number(id);
4345 gtk_list_store_set(ev->store, &iter, 0, TRUE, -1);
4346 }
4347
4348 gtk_label_set_text(GTK_LABEL(ev->panel_label),
4349 government_name_translation(pv->data.v_gov));
4352 if (pixbuf) {
4354 }
4355 break;
4356
4358 gtk_tree_model_get(model, &iter, 1, &id, -1);
4359 if (!(A_FIRST <= id && id < advance_count())) {
4360 return;
4361 }
4362 if (present) {
4363 BV_SET(pv->data.v_bv_inventions, id);
4364 } else {
4365 BV_CLR(pv->data.v_bv_inventions, id);
4366 }
4367 gtk_list_store_set(ev->store, &iter, 0, present, -1);
4369 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4370 g_free(buf);
4371 break;
4372
4373 default:
4374 log_error("Unhandled widget toggled signal in "
4375 "extviewer_view_cell_toggled() for objprop id=%d "
4376 "name \"%s\".", propid, objprop_get_name(op));
4377 return;
4378 break;
4379 }
4380
4382}
4383
4384/************************************************************************/
4389{
4390 struct extviewer *ev;
4391 struct objprop *op;
4392 struct property_page *pp;
4394 struct propval value = {{0,}, VALTYPE_STRING, FALSE}, *pv;
4395 GtkTextIter start, end;
4396 char *text;
4397 gchar *buf;
4398
4399 ev = userdata;
4400 if (!ev) {
4401 return;
4402 }
4403
4407
4408 gtk_text_buffer_get_start_iter(textbuf, &start);
4409 gtk_text_buffer_get_end_iter(textbuf, &end);
4410 text = gtk_text_buffer_get_text(textbuf, &start, &end, FALSE);
4411 value.data.v_const_string = text;
4412 pv = &value;
4413
4414 switch (propid) {
4418 gtk_label_set_text(GTK_LABEL(ev->panel_label), buf);
4419 g_free(buf);
4420 break;
4421 default:
4422 log_error("Unhandled widget modified signal in "
4423 "extviewer_textbuf_changed() for objprop id=%d "
4424 "name \"%s\".", propid, objprop_get_name(op));
4425 return;
4426 break;
4427 }
4428
4430 g_free(text);
4431}
4432
4433/************************************************************************/
4437{
4438#define ADDPROP(ARG_id, ARG_name, ARG_tooltip, ARG_flags, ARG_valtype) do { \
4439 struct objprop *MY_op = objprop_new(ARG_id, ARG_name, ARG_tooltip, \
4440 ARG_flags, ARG_valtype, pp); \
4441 objprop_hash_insert(pp->objprop_table, MY_op->id, MY_op); \
4442} while (FALSE)
4443
4444 switch (property_page_get_objtype(pp)) {
4445 case OBJTYPE_TILE:
4446 ADDPROP(OPID_TILE_IMAGE, _("Image"), NULL,
4448 ADDPROP(OPID_TILE_TERRAIN, _("Terrain"), NULL,
4450 ADDPROP(OPID_TILE_RESOURCE, _("Resource"), NULL,
4452 ADDPROP(OPID_TILE_INDEX, _("Index"), NULL,
4454 ADDPROP(OPID_TILE_X, Q_("?coordinate:X"), NULL,
4456 ADDPROP(OPID_TILE_Y, Q_("?coordinate:Y"), NULL,
4458 /* TRANS: The coordinate X in native coordinates.
4459 * The freeciv coordinate system is described in doc/HACKING. */
4460 ADDPROP(OPID_TILE_NAT_X, _("NAT X"), NULL,
4462 /* TRANS: The coordinate Y in native coordinates.
4463 * The freeciv coordinate system is described in doc/HACKING. */
4464 ADDPROP(OPID_TILE_NAT_Y, _("NAT Y"), NULL,
4466 ADDPROP(OPID_TILE_CONTINENT, _("Continent"), NULL,
4468 ADDPROP(OPID_TILE_XY, Q_("?coordinates:X,Y"), NULL,
4470 ADDPROP(OPID_TILE_SPECIALS, _("Specials"), NULL,
4473 ADDPROP(OPID_TILE_ROADS, _("Roads"), NULL,
4476 ADDPROP(OPID_TILE_BASES, _("Bases"), NULL,
4479#ifdef FREECIV_DEBUG
4480 ADDPROP(OPID_TILE_ADDRESS, _("Address"), NULL,
4482#endif /* FREECIV_DEBUG */
4483#if 0
4484 /* Disabled entirely for now as server is not sending other
4485 * players' vision information anyway. */
4486 ADDPROP(OPID_TILE_VISION, _("Vision"), NULL,
4488#endif
4489 /* TRANS: Tile property "Label" label in editor */
4490 ADDPROP(OPID_TILE_LABEL, Q_("?property:Label"), NULL,
4492 return;
4493
4494 case OBJTYPE_STARTPOS:
4495 ADDPROP(OPID_STARTPOS_IMAGE, _("Image"), NULL,
4497 ADDPROP(OPID_STARTPOS_XY, Q_("?coordinates:X,Y"), NULL,
4499 ADDPROP(OPID_STARTPOS_EXCLUDE, _("Exclude Nations"), NULL,
4501 ADDPROP(OPID_STARTPOS_NATIONS, _("Nations"), NULL,
4504 return;
4505
4506 case OBJTYPE_UNIT:
4507 ADDPROP(OPID_UNIT_IMAGE, _("Image"), NULL,
4509#ifdef FREECIV_DEBUG
4510 ADDPROP(OPID_UNIT_ADDRESS, _("Address"), NULL,
4512#endif /* FREECIV_DEBUG */
4513 ADDPROP(OPID_UNIT_TYPE, _("Type"), NULL,
4515 ADDPROP(OPID_UNIT_ID, _("ID"), NULL,
4517 ADDPROP(OPID_UNIT_XY, Q_("?coordinates:X,Y"), NULL,
4519 ADDPROP(OPID_UNIT_MOVES_LEFT, _("Moves Left"), NULL,
4521 ADDPROP(OPID_UNIT_FUEL, _("Fuel"), NULL,
4523 ADDPROP(OPID_UNIT_MOVED, _("Moved"), NULL,
4525 ADDPROP(OPID_UNIT_DONE_MOVING, _("Done Moving"), NULL,
4527 /* TRANS: HP = Hit Points of a unit. */
4528 ADDPROP(OPID_UNIT_HP, _("HP"), NULL,
4530 ADDPROP(OPID_UNIT_VETERAN, _("Veteran"), NULL,
4532 ADDPROP(OPID_UNIT_STAY, _("Stay put"), NULL,
4534 return;
4535
4536 case OBJTYPE_CITY:
4537 ADDPROP(OPID_CITY_IMAGE, _("Image"), NULL,
4539 ADDPROP(OPID_CITY_NAME, _("Name"), NULL,
4541#ifdef FREECIV_DEBUG
4542 ADDPROP(OPID_CITY_ADDRESS, _("Address"), NULL,
4544#endif /* FREECIV_DEBUG */
4545 ADDPROP(OPID_CITY_ID, _("ID"), NULL,
4547 ADDPROP(OPID_CITY_XY, Q_("?coordinates:X,Y"), NULL,
4549 ADDPROP(OPID_CITY_SIZE, _("Size"), NULL,
4551 ADDPROP(OPID_CITY_HISTORY, _("History"), NULL,
4553 ADDPROP(OPID_CITY_BUILDINGS, _("Buildings"), NULL,
4556 ADDPROP(OPID_CITY_FOOD_STOCK, _("Food Stock"), NULL,
4558 ADDPROP(OPID_CITY_SHIELD_STOCK, _("Shield Stock"), NULL,
4560 return;
4561
4562 case OBJTYPE_PLAYER:
4563 ADDPROP(OPID_PLAYER_NAME, _("Name"), NULL,
4566#ifdef FREECIV_DEBUG
4567 ADDPROP(OPID_PLAYER_ADDRESS, _("Address"), NULL,
4569#endif /* FREECIV_DEBUG */
4570 ADDPROP(OPID_PLAYER_NATION, _("Nation"), NULL,
4573 ADDPROP(OPID_PLAYER_GOV, _("Government"), NULL,
4575 VALTYPE_GOV);
4576 ADDPROP(OPID_PLAYER_AGE, _("Age"), NULL,
4578 ADDPROP(OPID_PLAYER_INVENTIONS, _("Inventions"), NULL,
4583 ADDPROP(OPID_PLAYER_SELECT_WEIGHT, _("Select Weight"),
4584 _("How likely user is to get this player by autoselect. '-1' for default behavior."),
4586 VALTYPE_INT);
4587 ADDPROP(OPID_PLAYER_SCIENCE, _("Science"), NULL,
4589 ADDPROP(OPID_PLAYER_GOLD, _("Gold"), NULL,
4591 VALTYPE_INT);
4592 ADDPROP(OPID_PLAYER_INFRAPOINTS, _("Infrapoints"), NULL,
4594 VALTYPE_INT);
4595 return;
4596
4597 case OBJTYPE_GAME:
4598 ADDPROP(OPID_GAME_SCENARIO, _("Scenario"), NULL,
4600 VALTYPE_BOOL);
4602 _("Scenario Name"), NULL,
4606 _("Scenario Authors"), NULL,
4610 _("Scenario Description"), NULL,
4614 _("Save Random Number State"), NULL,
4617 _("Save Players"), NULL,
4620 _("Nation Start Positions"), NULL,
4623 _("Prevent New Cities"), NULL,
4626 _("Saltwater Flooding Lakes"), NULL,
4629 _("Lock to current Ruleset"), NULL,
4631 return;
4632
4633 case NUM_OBJTYPES:
4634 break;
4635 }
4636
4637 log_error("%s(): Unhandled page object type %s (nb %d).", __FUNCTION__,
4640#undef ADDPROP
4641}
4642
4643/************************************************************************/
4666
4667/************************************************************************/
4672 GtkTreeModel *model,
4675 gpointer data)
4676{
4677 struct property_page *pp;
4678 struct objbind *ob = NULL, *old_ob;
4680
4681 pp = data;
4682 if (!pp || !sel_path) {
4683 return TRUE;
4684 }
4685
4686 if (!gtk_tree_model_get_iter(model, &iter, sel_path)) {
4687 return TRUE;
4688 }
4689
4691 gtk_tree_model_get(model, &iter, 0, &ob, -1);
4692 if (currently_selected) {
4693 if (ob == old_ob) {
4694 GList *rows, *p;
4695 GtkTreePath *path;
4696 struct objbind *new_ob = NULL;
4697
4699 for (p = rows; p != NULL; p = p->next) {
4700 path = p->data;
4701 if (gtk_tree_model_get_iter(model, &iter, path)) {
4702 struct objbind *test_ob = NULL;
4703 gtk_tree_model_get(model, &iter, 0, &test_ob, -1);
4704 if (test_ob == ob) {
4705 continue;
4706 }
4707 new_ob = test_ob;
4708 break;
4709 }
4710 }
4713
4715 }
4716 } else {
4718 }
4719
4720 return TRUE;
4721}
4722
4723/************************************************************************/
4728{
4729 struct property_page *pp;
4730 const gchar *text;
4731 GtkWidget *w;
4733 struct property_filter *pf;
4734 bool matched;
4735
4736 pp = userdata;
4738 pf = property_filter_new(text);
4739
4743 continue;
4744 }
4747 if (objprop_has_widget(op) && w != NULL) {
4748 if (matched) {
4749 gtk_widget_show(w);
4750 } else {
4751 gtk_widget_hide(w);
4752 }
4753 }
4755 if (objprop_show_in_listview(op) && col != NULL) {
4757 }
4759
4761}
4762
4763/************************************************************************/
4767static struct property_page *
4769 struct property_editor *pe)
4770{
4771 struct property_page *pp;
4772 GtkWidget *vbox, *vbox2, *hbox, *hbox2, *paned, *frame, *w;
4773 GtkWidget *scrollwin, *view, *label, *entry, *notebook;
4774 GtkWidget *button, *hsep, *image;
4779 int num_columns = 0;
4781 int col_id = 1;
4782 const char *attr_type_str, *name, *tooltip;
4783 gchar *title;
4784
4785 if (!(objtype < NUM_OBJTYPES)) {
4786 return NULL;
4787 }
4788
4789 pp = fc_calloc(1, sizeof(struct property_page));
4790 pp->objtype = objtype;
4791 pp->pe_parent = pe;
4792
4794
4795 pp->objprop_table = objprop_hash_new();
4797
4798 pp->objbind_table = objbind_hash_new();
4799
4800 pp->tag_table = stored_tag_hash_new();
4801
4804 num_columns++;
4805 }
4807
4808 /* Column zero in the store holds an objbind
4809 * pointer and is never displayed. */
4810 num_columns++;
4813
4818 col_id++;
4819 }
4821
4824
4827 pp->widget = paned;
4828
4829 /* Left side object list view. */
4830
4831 vbox = gtk_grid_new();
4837
4845
4849
4852 continue;
4853 }
4854
4856 if (!attr_type_str) {
4857 continue;
4858 }
4860 if (col_id < 0) {
4861 continue;
4862 }
4864 if (!name) {
4865 continue;
4866 }
4868 if (!cell) {
4869 continue;
4870 }
4871
4874 NULL);
4875
4879 if (objprop_is_sortable(op)) {
4882 } else {
4884 }
4887
4889
4892 g_signal_connect(sel, "changed",
4896
4898 pp->object_view = view;
4899
4901 hbox = gtk_grid_new();
4904
4905 button = gtk_button_new();
4908 gtk_button_set_label(GTK_BUTTON(button), _("Create"));
4911 _("Pressing this button will create a new object of the "
4912 "same type as the current property page and add it to "
4913 "the page. The specific type and count of the objects "
4914 "is taken from the editor tool state. So for example, "
4915 "the \"tool value\" of the unit tool and its \"count\" "
4916 "parameter affect unit creation."));
4917 g_signal_connect(button, "clicked",
4920
4921 button = gtk_button_new();
4922 image = gtk_image_new_from_icon_name("list-remove",
4925 gtk_button_set_label(GTK_BUTTON(button), _("Destroy"));
4928 _("Pressing this button will send a request to the server "
4929 "to destroy (i.e. erase) the objects selected in the object "
4930 "list."));
4931 g_signal_connect(button, "clicked",
4934 }
4935
4936 /* Right side properties panel. */
4937
4938 hbox = gtk_grid_new();
4941
4942 vbox = gtk_grid_new();
4948
4949 /* Extended property viewer to the right of the properties panel.
4950 * This needs to be created before property widgets, since some
4951 * might try to append themselves to this notebook. */
4952
4953 vbox2 = gtk_grid_new();
4960
4961 notebook = gtk_notebook_new();
4962 gtk_widget_set_vexpand(notebook, TRUE);
4963 gtk_widget_set_size_request(notebook, 256, -1);
4967 pp->extviewer_notebook = notebook;
4968
4971
4972 hbox2 = gtk_grid_new();
4975
4976 button = gtk_button_new_with_mnemonic(_("_Close"));
4978 g_signal_connect_swapped(button, "clicked",
4981
4982 /* Now create the properties panel. */
4983
4984 /* TRANS: %s is a type of object that can be edited, such as "Tile",
4985 * "Unit", "Start Position", etc. */
4986 title = g_strdup_printf(_("%s Properties"),
4988 frame = gtk_frame_new(title);
4989 g_free(title);
4990 gtk_widget_set_size_request(frame, 256, -1);
4991 gtk_container_add(GTK_CONTAINER(vbox), frame);
4992
5000
5001 vbox2 = gtk_grid_new();
5008
5010 if (!objprop_has_widget(op)) {
5011 continue;
5012 }
5014 if (!w) {
5015 continue;
5016 }
5019 if (NULL != tooltip) {
5021 }
5023
5024 hbox2 = gtk_grid_new();
5029
5030 label = gtk_label_new(_("Filter:"));
5032
5033 entry = gtk_entry_new();
5035 _("Enter a filter string to limit which properties are shown. "
5036 "The filter is one or more text patterns separated by | "
5037 "(\"or\") or & (\"and\"). The symbol & has higher precedence "
5038 "than |. A pattern may also be negated by prefixing it with !."));
5039 g_signal_connect(entry, "changed",
5042
5043 hbox2 = gtk_grid_new();
5046
5047 button = gtk_button_new_with_mnemonic(_("_Refresh"));
5050 _("Pressing this button will reset all modified properties of "
5051 "the selected objects to their current values (the values "
5052 "they have on the server)."));
5053 g_signal_connect(button, "clicked",
5056
5057 button = gtk_button_new_with_mnemonic(_("_Apply"));
5060 _("Pressing this button will send all modified properties of "
5061 "the objects selected in the object list to the server. "
5062 "Modified properties' names are shown in red in the properties "
5063 "panel."));
5064 g_signal_connect(button, "clicked",
5067
5068 return pp;
5069}
5070
5071/************************************************************************/
5074static const char *property_page_get_name(const struct property_page *pp)
5075{
5076 if (!pp) {
5077 return "";
5078 }
5080}
5081
5082/************************************************************************/
5085static enum editor_object_type
5087{
5088 if (!pp) {
5089 return -1;
5090 }
5091 return pp->objtype;
5092}
5093
5094/************************************************************************/
5102static GdkPixbuf *create_tile_pixbuf(const struct tile *ptile)
5103{
5105}
5106
5107/************************************************************************/
5118
5119/************************************************************************/
5131
5132/************************************************************************/
5140static GdkPixbuf *create_pixbuf_from_layers(const struct tile *ptile,
5141 const struct unit *punit,
5142 const struct city *pcity,
5143 enum layer_category category)
5144{
5146 int h, fh, fw, canvas_x, canvas_y;
5148 cairo_t *cr;
5149
5153
5155
5158 cairo_paint(cr);
5159 cairo_destroy(cr);
5160
5161 canvas_x = 0;
5162 canvas_y = 0;
5163
5164 canvas_y += (fh - h);
5165
5166 mapview_layer_iterate(layer) {
5167 if (tileset_layer_in_category(layer, category)) {
5168 put_one_element(&canvas, 1.0, layer,
5169 ptile, NULL, NULL, punit, pcity,
5171 }
5175
5176 return pixbuf;
5177}
5178
5179/************************************************************************/
5183{
5184 if (!pp) {
5185 return;
5186 }
5187
5188 gtk_list_store_clear(pp->object_store);
5189 objbind_hash_clear(pp->objbind_table);
5191}
5192
5193/************************************************************************/
5199{
5200 struct objbind *ob;
5202 int id;
5203
5204 if (!pp) {
5205 return;
5206 }
5207
5210 if (id < 0) {
5211 return;
5212 }
5213
5214 if (objbind_hash_lookup(pp->objbind_table, id, NULL)) {
5215 /* Object already exists. */
5216 return;
5217 }
5218
5220 if (!ob) {
5221 return;
5222 }
5223
5225
5226 objbind_hash_insert(pp->objbind_table, ob->object_id, ob);
5227}
5228
5229/************************************************************************/
5234 const struct tile *ptile)
5235{
5236
5237 if (!pp || !ptile) {
5238 return;
5239 }
5240
5241 switch (property_page_get_objtype(pp)) {
5242 case OBJTYPE_TILE:
5244 return;
5245
5246 case OBJTYPE_STARTPOS:
5247 {
5248 struct startpos *psp = map_startpos_get(ptile);
5249
5250 if (NULL != psp) {
5252 }
5253 }
5254 return;
5255
5256 case OBJTYPE_UNIT:
5257 unit_list_iterate(ptile->units, punit) {
5260 return;
5261
5262 case OBJTYPE_CITY:
5263 if (tile_city(ptile)) {
5265 }
5266 return;
5267
5268 case OBJTYPE_PLAYER:
5269 case OBJTYPE_GAME:
5270 return;
5271
5272 case NUM_OBJTYPES:
5273 break;
5274 }
5275
5276 log_error("%s(): Unhandled page object type %s (nb %d).", __FUNCTION__,
5279}
5280
5281/************************************************************************/
5288 struct objprop *op,
5289 struct objbind *ob,
5291{
5292 int col_id;
5293 struct propval *pv;
5294 enum value_types valtype;
5295 char buf[128], *p;
5297 GtkListStore *store;
5298 gchar *buf2;
5299
5300 if (!pp || !pp->object_store || !op || !ob) {
5301 return FALSE;
5302 }
5303
5305 return FALSE;
5306 }
5307
5309 if (col_id < 0) {
5310 return FALSE;
5311 }
5312
5314 if (!pv) {
5315 return FALSE;
5316 }
5317
5319 store = pp->object_store;
5320
5321 switch (valtype) {
5322 case VALTYPE_NONE:
5323 break;
5324 case VALTYPE_INT:
5325 gtk_list_store_set(store, iter, col_id, pv->data.v_int, -1);
5326 break;
5327 case VALTYPE_BOOL:
5328 /* Set as translated string, not as untranslated G_TYPE_BOOLEAN */
5330 break;
5331 case VALTYPE_STRING:
5332 if (fc_strlcpy(buf, pv->data.v_string, 28) >= 28) {
5333 sz_strlcat(buf, "...");
5334 }
5335 for (p = buf; *p; p++) {
5336 if (*p == '\n' || *p == '\t' || *p == '\r') {
5337 *p = ' ';
5338 }
5339 }
5340 gtk_list_store_set(store, iter, col_id, buf, -1);
5341 break;
5342 case VALTYPE_PIXBUF:
5343 gtk_list_store_set(store, iter, col_id, pv->data.v_pixbuf, -1);
5344 break;
5347 case VALTYPE_BV_SPECIAL:
5348 case VALTYPE_BV_ROADS:
5349 case VALTYPE_BV_BASES:
5352 gtk_list_store_set(store, iter, col_id, buf2, -1);
5353 g_free(buf2);
5354 break;
5355 case VALTYPE_NATION:
5356 pixbuf = get_flag(pv->data.v_nation);
5357 gtk_list_store_set(store, iter, col_id, pixbuf, -1);
5358 if (pixbuf) {
5360 }
5361 break;
5362 case VALTYPE_GOV:
5363 if (pv->data.v_gov != NULL) {
5365 } else {
5368 }
5369 gtk_list_store_set(store, iter, col_id, pixbuf, -1);
5370 if (pixbuf) {
5372 }
5373 break;
5375 break;
5376 }
5377
5379
5380 return TRUE;
5381}
5382
5383/************************************************************************/
5388{
5389 struct objbind *focused;
5390
5391 if (!pp || !pp->objbind_table) {
5392 return;
5393 }
5394
5395 if (pp->object_store) {
5398 GtkTreeModel *model;
5399 GtkTreePath *path;
5400
5401 model = GTK_TREE_MODEL(pp->object_store);
5402
5404 if (objbind_get_rowref(ob)) {
5405 continue;
5406 }
5407 gtk_list_store_append(pp->object_store, &iter);
5408 gtk_list_store_set(pp->object_store, &iter, 0, ob, -1);
5409 path = gtk_tree_model_get_path(model, &iter);
5410 rr = gtk_tree_row_reference_new(model, path);
5411 gtk_tree_path_free(path);
5413
5418
5419 if (gtk_tree_model_get_iter_first(model, &iter)) {
5423 }
5424 }
5425
5430}
5431
5432/************************************************************************/
5437{
5438 if (!pp) {
5439 return NULL;
5440 }
5441 return pp->focused_objbind;
5442}
5443
5444/************************************************************************/
5449 struct objbind *ob)
5450{
5451 if (!pp) {
5452 return;
5453 }
5454 pp->focused_objbind = ob;
5455}
5456
5457/************************************************************************/
5462 int object_id)
5463{
5464 struct objbind *ob;
5465
5466 if (!pp || !pp->objbind_table) {
5467 return NULL;
5468 }
5469
5470 objbind_hash_lookup(pp->objbind_table, object_id, &ob);
5471 return ob;
5472}
5473
5474/************************************************************************/
5479 const struct tile_list *tiles)
5480{
5481 if (!pp || !tiles) {
5482 return;
5483 }
5484
5485 tile_list_iterate(tiles, ptile) {
5488
5490}
5491
5492/************************************************************************/
5496{
5497 if (!pp || !pp->objbind_table) {
5498 return 0;
5499 }
5500 return objbind_hash_size(pp->objbind_table);
5501}
5502
5503/************************************************************************/
5508 struct objprop *op,
5509 struct propval *pv)
5510{
5512 GtkTreeModel *model;
5513 GList *rows, *p;
5514 GtkTreePath *path;
5516 struct objbind *ob;
5517 bool changed = FALSE;
5518
5519 if (!pp || !op || !pp->object_view) {
5520 return;
5521 }
5522
5523 if (objprop_is_readonly(op)) {
5524 return;
5525 }
5526
5529
5530 for (p = rows; p != NULL; p = p->next) {
5531 path = p->data;
5532 if (gtk_tree_model_get_iter(model, &iter, path)) {
5533 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5534 changed |= objbind_set_modified_value(ob, op, pv);
5535 }
5536 gtk_tree_path_free(path);
5537 }
5539
5540 if (changed) {
5543 }
5544}
5545
5546/************************************************************************/
5550{
5552 GtkTreeModel *model;
5553 GList *rows, *p;
5554 GtkTreePath *path;
5556 struct objbind *ob;
5557 union packetdata packet;
5558 struct connection *my_conn = &client.conn;
5559
5560 if (!pp || !pp->object_view) {
5561 return;
5562 }
5563
5566 return;
5567 }
5568
5569 packet = property_page_new_packet(pp);
5570 if (!packet.pointers.v_pointer1) {
5571 return;
5572 }
5573
5576 for (p = rows; p != NULL; p = p->next) {
5577 path = p->data;
5578 if (gtk_tree_model_get_iter(model, &iter, path)) {
5579 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5583 if (objprop_is_readonly(op)) {
5584 continue;
5585 }
5589 }
5590 }
5591 gtk_tree_path_free(path);
5592 }
5595
5597}
5598
5599/************************************************************************/
5604{
5605 union packetdata packet;
5606
5607 packet.pointers.v_pointer2 = NULL;
5608
5609 if (!pp) {
5610 packet.pointers.v_pointer1 = NULL;
5611 return packet;
5612 }
5613
5614 switch (property_page_get_objtype(pp)) {
5615 case OBJTYPE_TILE:
5616 packet.tile = fc_calloc(1, sizeof(*packet.tile));
5617 break;
5618 case OBJTYPE_STARTPOS:
5619 packet.startpos = fc_calloc(1, sizeof(*packet.startpos));
5620 break;
5621 case OBJTYPE_UNIT:
5622 packet.unit = fc_calloc(1, sizeof(*packet.unit));
5623 break;
5624 case OBJTYPE_CITY:
5625 packet.city = fc_calloc(1, sizeof(*packet.city));
5626 break;
5627 case OBJTYPE_PLAYER:
5628 packet.player = fc_calloc(1, sizeof(*packet.player));
5629 break;
5630 case OBJTYPE_GAME:
5631 packet.game.game = fc_calloc(1, sizeof(*packet.game.game));
5632 packet.game.desc = fc_calloc(1, sizeof(*packet.game.desc));
5633 break;
5634 case NUM_OBJTYPES:
5635 break;
5636 }
5637
5638 return packet;
5639}
5640
5641/************************************************************************/
5645 union packetdata packet)
5646{
5647 struct connection *my_conn = &client.conn;
5648
5649 if (!pp || !packet.pointers.v_pointer1) {
5650 return;
5651 }
5652
5653 switch (property_page_get_objtype(pp)) {
5654 case OBJTYPE_TILE:
5656 return;
5657 case OBJTYPE_STARTPOS:
5659 return;
5660 case OBJTYPE_UNIT:
5662 return;
5663 case OBJTYPE_CITY:
5665 return;
5666 case OBJTYPE_PLAYER:
5668 return;
5669 case OBJTYPE_GAME:
5670 send_packet_edit_game(my_conn, packet.game.game);
5672 return;
5673 case NUM_OBJTYPES:
5674 break;
5675 }
5676
5677 log_error("%s(): Unhandled object type %s (nb %d).",
5680}
5681
5682/************************************************************************/
5686 union packetdata packet)
5687{
5688 if (!packet.pointers.v_pointer1) {
5689 return;
5690 }
5691
5692 free(packet.pointers.v_pointer1);
5693 packet.pointers.v_pointer1 = NULL;
5694
5695 if (packet.pointers.v_pointer2 != NULL) {
5696 free(packet.pointers.v_pointer2);
5697 packet.pointers.v_pointer2 = NULL;
5698 }
5699}
5700
5701/************************************************************************/
5706{
5708 GtkTreeModel *model;
5710 GtkTreePath *path;
5711 GList *rows, *p;
5712 struct objbind *ob;
5713
5714 if (!pp || !pp->object_view) {
5715 return;
5716 }
5717
5720 return;
5721 }
5722
5724 for (p = rows; p != NULL; p = p->next) {
5725 path = p->data;
5726 if (gtk_tree_model_get_iter(model, &iter, path)) {
5727 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5732 }
5733 gtk_tree_path_free(path);
5734 }
5736
5741}
5742
5743/************************************************************************/
5747{
5749 GtkTreeModel *model;
5751 GtkTreePath *path;
5752 GList *rows, *p;
5753 struct objbind *ob;
5754 struct connection *my_conn = &client.conn;
5755
5756 if (!pp || !pp->object_view) {
5757 return;
5758 }
5759
5762 return;
5763 }
5764
5767 for (p = rows; p != NULL; p = p->next) {
5768 path = p->data;
5769 if (gtk_tree_model_get_iter(model, &iter, path)) {
5770 gtk_tree_model_get(model, &iter, 0, &ob, -1);
5772 }
5773 gtk_tree_path_free(path);
5774 }
5777}
5778
5779/************************************************************************/
5786 struct tile_list *hint_tiles)
5787{
5789 int apno, value, count, size;
5790 int tag;
5791 struct connection *my_conn = &client.conn;
5792 struct tile *ptile = NULL;
5793 struct player *pplayer;
5794
5795 if (!pp) {
5796 return;
5797 }
5798
5801 return;
5802 }
5803
5804 tag = get_next_unique_tag();
5805 count = 1;
5806
5807 switch (objtype) {
5808 case OBJTYPE_STARTPOS:
5809 if (hint_tiles) {
5811 if (NULL == map_startpos_get(atile)) {
5812 ptile = atile;
5813 break;
5814 }
5816 }
5817
5818 if (NULL == ptile) {
5819 ptile = get_center_tile_mapcanvas();
5820 }
5821
5822 if (NULL == ptile) {
5823 break;
5824 }
5825
5827 break;
5828
5829 case OBJTYPE_UNIT:
5830 if (hint_tiles) {
5833 ptile = atile;
5834 break;
5835 }
5837 }
5838
5839 if (!ptile) {
5840 struct unit *punit;
5844 ptile = unit_tile(punit);
5845 break;
5846 }
5848 }
5849
5850 if (!ptile) {
5851 ptile = get_center_tile_mapcanvas();
5852 }
5853
5854 if (!ptile) {
5855 break;
5856 }
5857
5862 value, count, tag);
5863 break;
5864
5865 case OBJTYPE_CITY:
5867 pplayer = player_by_number(apno);
5868 if (pplayer && hint_tiles) {
5870 if (!is_enemy_unit_tile(atile, pplayer)
5872 ptile = atile;
5873 break;
5874 }
5876 }
5877
5878 if (!ptile) {
5879 ptile = get_center_tile_mapcanvas();
5880 }
5881
5882 if (!ptile) {
5883 break;
5884 }
5885
5888 size, tag);
5889 break;
5890
5891 case OBJTYPE_PLAYER:
5893 break;
5894
5895 case OBJTYPE_TILE:
5896 case OBJTYPE_GAME:
5897 case NUM_OBJTYPES:
5898 break;
5899 }
5900
5902}
5903
5904/************************************************************************/
5910 int object_id,
5911 bool removed)
5912{
5913 struct objbind *ob;
5915
5917 if (!ob) {
5918 return;
5919 }
5920
5923 GtkTreePath *path;
5925 GtkTreeModel *model;
5926
5927 model = GTK_TREE_MODEL(pp->object_store);
5929
5930 if (gtk_tree_model_get_iter(model, &iter, path)) {
5931 if (removed) {
5932 gtk_list_store_remove(pp->object_store, &iter);
5933 } else {
5937 }
5938 }
5939
5940 gtk_tree_path_free(path);
5941 }
5942
5943 if (removed) {
5944 objbind_hash_remove(pp->objbind_table, object_id);
5945 return;
5946 }
5947
5952 }
5953}
5954
5955/************************************************************************/
5962 int tag, int object_id)
5963{
5966
5967 if (!property_page_tag_is_known(pp, tag)) {
5968 return;
5969 }
5971
5974
5975 if (!object) {
5976 return;
5977 }
5978
5981}
5982
5983/************************************************************************/
5988 struct extviewer *ev)
5989{
5990 GtkWidget *w;
5991
5992 if (!pp || !ev) {
5993 return;
5994 }
5995
5997 if (!w) {
5998 return;
5999 }
6000 gtk_notebook_append_page(GTK_NOTEBOOK(pp->extviewer_notebook), w, NULL);
6001}
6002
6003/************************************************************************/
6008 struct extviewer *ev)
6009{
6010 GtkWidget *w;
6011 GtkNotebook *notebook;
6012 int page;
6013
6014 if (!pp || !ev) {
6015 return;
6016 }
6017
6019 if (!w) {
6020 return;
6021 }
6022
6023 notebook = GTK_NOTEBOOK(pp->extviewer_notebook);
6024 page = gtk_notebook_page_num(notebook, w);
6025 gtk_notebook_set_current_page(notebook, page);
6026}
6027
6028/************************************************************************/
6033 int tag, int count)
6034{
6035 if (!pp || !pp->tag_table) {
6036 return;
6037 }
6038
6039 if (stored_tag_hash_lookup(pp->tag_table, tag, NULL)) {
6040 log_error("Attempted to insert object creation tag %d "
6041 "twice into tag table for property page %p (%d %s).",
6044 return;
6045 }
6046
6047 stored_tag_hash_insert(pp->tag_table, tag, count);
6048}
6049
6050/************************************************************************/
6055 int tag)
6056{
6057 int count;
6058
6059 if (!pp || !pp->tag_table) {
6060 return;
6061 }
6062
6063 if (stored_tag_hash_lookup(pp->tag_table, tag, &count)) {
6064 if (0 >= --count) {
6065 stored_tag_hash_remove(pp->tag_table, tag);
6066 }
6067 }
6068}
6069
6070/************************************************************************/
6073static bool property_page_tag_is_known(struct property_page *pp, int tag)
6074{
6075 if (!pp || !pp->tag_table) {
6076 return FALSE;
6077 }
6078 return stored_tag_hash_lookup(pp->tag_table, tag, NULL);
6079}
6080
6081/************************************************************************/
6085{
6086 if (!pp || !pp->tag_table) {
6087 return;
6088 }
6089 stored_tag_hash_clear(pp->tag_table);
6090}
6091
6092/************************************************************************/
6101
6102/************************************************************************/
6112
6113/************************************************************************/
6118{
6119 struct property_page *pp = userdata, *tile_pp;
6120 struct tile_list *tiles = NULL;
6121 struct tile *ptile;
6122
6123 if (!pp) {
6124 return;
6125 }
6126
6128 tiles = tile_list_new();
6129
6131 ptile = objbind_get_object(ob);
6132 if (ptile) {
6133 tile_list_append(tiles, ptile);
6134 }
6136
6138 tile_list_destroy(tiles);
6139}
6140
6141/************************************************************************/
6150
6151/************************************************************************/
6157{
6158 struct property_page *pp;
6159 GtkWidget *label;
6160 const char *name;
6161
6162 if (!pe || !pe->notebook) {
6163 return FALSE;
6164 }
6165
6166 if (!(objtype < NUM_OBJTYPES)) {
6167 return FALSE;
6168 }
6169
6171 if (!pp) {
6172 return FALSE;
6173 }
6174
6176 label = gtk_label_new(name);
6178 pp->widget, label);
6179
6180 pe->property_pages[objtype] = pp;
6181
6182 return TRUE;
6183}
6184
6185/************************************************************************/
6188static struct property_page *
6191{
6192 if (!pe || !(objtype < NUM_OBJTYPES)) {
6193 return NULL;
6194 }
6195
6196 return pe->property_pages[objtype];
6197}
6198
6199/************************************************************************/
6203{
6204 struct property_editor *pe;
6205 GtkWidget *win, *notebook, *vbox;
6207
6208 pe = fc_calloc(1, sizeof(*pe));
6209
6210 /* The property editor dialog window. */
6211
6213 gtk_window_set_title(GTK_WINDOW(win), _("Property Editor"));
6221 g_signal_connect(win, "delete-event",
6223 pe->widget = win;
6224
6225 vbox = gtk_grid_new();
6226 gtk_container_add(GTK_CONTAINER(win), vbox);
6227
6228 /* Property pages. */
6229
6233 pe->notebook = notebook;
6234
6235 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6237 }
6238
6239 return pe;
6240}
6241
6242/************************************************************************/
6252
6253/************************************************************************/
6257 const struct tile_list *tiles)
6258{
6259 struct property_page *pp;
6261 int i;
6262 const enum editor_object_type preferred[] = {
6267 };
6268
6269 if (!pe || !tiles) {
6270 return;
6271 }
6272
6273 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6276 }
6277
6278 for (i = 0; i < ARRAY_SIZE(preferred) - 1; i++) {
6281 break;
6282 }
6283 }
6284 objtype = preferred[i];
6286}
6287
6288/************************************************************************/
6294{
6295 if (!pe || !pe->widget) {
6296 return;
6297 }
6298
6299 gtk_widget_show_all(pe->widget);
6300
6302 if (objtype < NUM_OBJTYPES) {
6304 }
6305}
6306
6307/************************************************************************/
6311{
6312 if (!pe || !pe->widget) {
6313 return;
6314 }
6315 gtk_widget_hide(pe->widget);
6316}
6317
6318/************************************************************************/
6324 int object_id,
6325 bool remove)
6326{
6327 struct property_page *pp;
6328
6329 if (!pe) {
6330 return;
6331 }
6332
6333 if (!(objtype < NUM_OBJTYPES)) {
6334 return;
6335 }
6336
6339}
6340
6341/************************************************************************/
6345 int tag, int object_id)
6346{
6348 struct property_page *pp;
6349
6350 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6352 continue;
6353 }
6355 property_page_object_created(pp, tag, object_id);
6356 }
6357}
6358
6359/************************************************************************/
6363{
6365 struct property_page *pp;
6366
6367 if (!pe) {
6368 return;
6369 }
6370
6371 for (objtype = 0; objtype < NUM_OBJTYPES; objtype++) {
6375 }
6376}
6377
6378/************************************************************************/
6384{
6385 struct property_page *pp;
6386
6387 if (!pe) {
6388 return;
6389 }
6390
6392 if (!pp) {
6393 return;
6394 }
6395
6397
6398 switch (objtype) {
6399 case OBJTYPE_PLAYER:
6400 players_iterate(pplayer) {
6401 property_page_add_objbind(pp, pplayer);
6403 break;
6404 case OBJTYPE_GAME:
6406 break;
6407 case OBJTYPE_TILE:
6408 case OBJTYPE_STARTPOS:
6409 case OBJTYPE_UNIT:
6410 case OBJTYPE_CITY:
6411 case NUM_OBJTYPES:
6412 break;
6413 }
6414
6417}
6418
6419/************************************************************************/
6430static struct property_filter *property_filter_new(const char *filter)
6431{
6432 struct property_filter *pf;
6433 struct pf_conjunction *pfc;
6434 struct pf_pattern *pfp;
6437 const char *pattern;
6438 int i, j;
6439
6440 pf = fc_calloc(1, sizeof(*pf));
6441
6442 if (!filter || filter[0] == '\0') {
6443 return pf;
6444 }
6445
6449
6450 for (i = 0; i < or_clause_count; i++) {
6451 if (or_clauses[i][0] == '\0') {
6452 continue;
6453 }
6454 pfc = &pf->disjunction[pf->count];
6455
6459
6460 for (j = 0; j < and_clause_count; j++) {
6461 if (and_clauses[j][0] == '\0') {
6462 continue;
6463 }
6464 pfp = &pfc->conjunction[pfc->count];
6465 pattern = and_clauses[j];
6466
6467 switch (pattern[0]) {
6468 case '!':
6469 pfp->negate = TRUE;
6470 pfp->text = fc_strdup(pattern + 1);
6471 break;
6472 default:
6473 pfp->text = fc_strdup(pattern);
6474 break;
6475 }
6476 pfc->count++;
6477 }
6479 pf->count++;
6480 }
6481
6483
6484 return pf;
6485}
6486
6487/************************************************************************/
6505 const struct objprop *op)
6506{
6507 struct pf_pattern *pfp;
6508 struct pf_conjunction *pfc;
6509 const char *name;
6510 bool match, or_result, and_result;
6511 int i, j;
6512
6513 if (!pf) {
6514 return TRUE;
6515 }
6516 if (!op) {
6517 return FALSE;
6518 }
6519
6521 if (!name) {
6522 return FALSE;
6523 }
6524
6525 if (pf->count < 1) {
6526 return TRUE;
6527 }
6528
6529 or_result = FALSE;
6530
6531 for (i = 0; i < pf->count; i++) {
6532 pfc = &pf->disjunction[i];
6533 and_result = TRUE;
6534 for (j = 0; j < pfc->count; j++) {
6535 pfp = &pfc->conjunction[j];
6536 match = (pfp->text[0] == '\0'
6537 || fc_strcasestr(name, pfp->text));
6538 if (pfp->negate) {
6539 match = !match;
6540 }
6541 and_result = and_result && match;
6542 if (!and_result) {
6543 break;
6544 }
6545 }
6547 if (or_result) {
6548 break;
6549 }
6550 }
6551
6552 return or_result;
6553}
6554
6555/************************************************************************/
6559{
6560 struct pf_pattern *pfp;
6561 struct pf_conjunction *pfc;
6562 int i, j;
6563
6564 if (!pf) {
6565 return;
6566 }
6567
6568 for (i = 0; i < pf->count; i++) {
6569 pfc = &pf->disjunction[i];
6570 for (j = 0; j < pfc->count; j++) {
6571 pfp = &pfc->conjunction[j];
6572 if (pfp->text != NULL) {
6573 free(pfp->text);
6574 pfp->text = NULL;
6575 }
6576 }
6577 pfc->count = 0;
6578 }
6579 pf->count = 0;
6580 free(pf);
6581}
6582
6583/************************************************************************/
6587{
6588 switch (vl) {
6589 case V_MAIN:
6590 /* TRANS: Vision layer name. Feel free to leave untranslated. */
6591 return _("Seen (Main)");
6592 case V_INVIS:
6593 /* TRANS: Vision layer name. Feel free to leave untranslated. */
6594 return _("Seen (Invis)");
6595 case V_SUBSURFACE:
6596 /* TRANS: Vision layer name. Feel free to leave untranslated. */
6597 return _("Seen (Subsurface)");
6598 case V_COUNT:
6599 break;
6600 }
6601
6602 log_error("%s(): Unrecognized vision layer %d.", __FUNCTION__, vl);
6603 return _("Unknown");
6604}
Base_type_id base_number(const struct base_type *pbase)
Definition base.c:96
Base_type_id base_count(void)
Definition base.c:113
bool dbv_isset(const struct dbv *pdbv, int bit)
Definition bitvector.c:120
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
#define BV_ARE_EQUAL(vec1, vec2)
Definition bitvector.h:121
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
#define BV_CLR(bv, bit)
Definition bitvector.h:94
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:2132
bool city_can_be_built_here(const struct civ_map *nmap, const struct tile *ptile, const struct unit *punit, bool hut_test)
Definition city.c:1487
#define city_tile(_pcity_)
Definition city.h:561
static citizens city_size_get(const struct city *pcity)
Definition city.h:566
#define city_owner(_pcity_)
Definition city.h:560
#define MAX_CITY_SIZE
Definition city.h:103
#define I_DESTROYED
Definition city.h:245
#define I_NEVER
Definition city.h:244
struct civclient client
bool client_nation_is_in_current_set(const struct nation_type *pnation)
Definition climisc.c:1509
char * incite_cost
Definition comments.c:76
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
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 int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
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:822
#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:61
struct world wld
Definition game.c:62
struct unit * game_unit_by_number(int id)
Definition game.c:115
struct city * game_city_by_number(int id)
Definition game.c:106
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:124
#define governments_iterate_end
Definition government.h:127
#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:820
static void property_page_reset_objbinds(struct property_page *pp)
Definition editprop.c:5705
static void property_page_send_values(struct property_page *pp)
Definition editprop.c:5549
static void objprop_setup_widget(struct objprop *op)
Definition editprop.c:2954
static void property_page_store_creation_tag(struct property_page *pp, int tag, int count)
Definition editprop.c:6032
static gchar * propval_as_string(struct propval *pv)
Definition editprop.c:862
static struct property_page * objprop_get_property_page(const struct objprop *op)
Definition editprop.c:3466
static const char * objprop_get_name(const struct objprop *op)
Definition editprop.c:2834
const char * vision_layer_get_name(enum vision_layer)
Definition editprop.c:6586
static int objbind_get_object_id(struct objbind *ob)
Definition editprop.c:1382
static void objprop_set_extviewer(struct objprop *op, struct extviewer *ev)
Definition editprop.c:3443
static GtkWidget * extviewer_get_panel_widget(struct extviewer *ev)
Definition editprop.c:3798
static gpointer objtype_get_object_from_id(enum editor_object_type objtype, int id)
Definition editprop.c:725
void property_editor_handle_object_changed(struct property_editor *pe, enum editor_object_type objtype, int object_id, bool remove)
Definition editprop.c:6322
static struct propstate * propstate_new(struct objprop *op, struct propval *pv)
Definition editprop.c:1266
static const char * valtype_get_name(enum value_types valtype)
Definition editprop.c:779
static void propstate_destroy(struct propstate *ps)
Definition editprop.c:1298
static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv)
Definition editprop.c:2130
static GtkCellRenderer * objprop_create_cell_renderer(const struct objprop *op)
Definition editprop.c:2858
static void extviewer_clear_widgets(struct extviewer *ev)
Definition editprop.c:4091
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:3383
static bool property_editor_add_page(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6155
static void propstate_clear_value(struct propstate *ps)
Definition editprop.c:1285
static void objbind_pack_modified_value(struct objbind *ob, struct objprop *op, union packetdata packet)
Definition editprop.c:2382
static struct objbind * property_page_get_focused_objbind(struct property_page *pp)
Definition editprop.c:5436
static bool objprop_has_widget(const struct objprop *op)
Definition editprop.c:2747
static int objtype_get_id_from_object(enum editor_object_type objtype, gpointer object)
Definition editprop.c:696
static enum editor_object_type objbind_get_objtype(const struct objbind *ob)
Definition editprop.c:2214
static struct extviewer * objprop_get_extviewer(struct objprop *op)
Definition editprop.c:3455
static void extviewer_refresh_widgets(struct extviewer *ev, struct propval *pv)
Definition editprop.c:3821
static enum editor_object_type property_page_get_objtype(const struct property_page *pp)
Definition editprop.c:5086
#define property_page_objbind_iterate_end
Definition editprop.c:641
static void property_page_show_extviewer(struct property_page *pp, struct extviewer *ev)
Definition editprop.c:6007
static gpointer objbind_get_object(struct objbind *ob)
Definition editprop.c:1366
static const char * property_page_get_name(const struct property_page *pp)
Definition editprop.c:5074
void property_editor_handle_object_created(struct property_editor *pe, int tag, int object_id)
Definition editprop.c:6344
static bool objbind_property_is_modified(struct objbind *ob, struct objprop *op)
Definition editprop.c:2085
static struct propval * propstate_get_value(struct propstate *ps)
Definition editprop.c:1328
static void property_page_clear_tags(struct property_page *pp)
Definition editprop.c:6084
static void property_page_object_created(struct property_page *pp, int tag, int object_id)
Definition editprop.c:5961
static bool property_page_tag_is_known(struct property_page *pp, int tag)
Definition editprop.c:6073
static void property_page_remove_creation_tag(struct property_page *pp, int tag)
Definition editprop.c:6054
static void property_page_load_tiles(struct property_page *pp, const struct tile_list *tiles)
Definition editprop.c:5478
static void property_page_create_objects(struct property_page *pp, struct tile_list *hint_tiles)
Definition editprop.c:5785
static void property_page_add_extviewer(struct property_page *pp, struct extviewer *ev)
Definition editprop.c:5987
static void property_page_refresh_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6106
static void property_page_set_focused_objbind(struct property_page *pp, struct objbind *ob)
Definition editprop.c:5448
static void property_page_setup_objprops(struct property_page *pp)
Definition editprop.c:4436
static void objbind_set_rowref(struct objbind *ob, GtkTreeRowReference *rr)
Definition editprop.c:2654
object_property_flags
Definition editprop.c:384
@ OPF_IN_LISTVIEW
Definition editprop.c:387
@ OPF_EDITABLE
Definition editprop.c:386
@ OPF_HAS_WIDGET
Definition editprop.c:388
@ OPF_NO_FLAGS
Definition editprop.c:385
static void objbind_clear_modified_value(struct objbind *ob, struct objprop *op)
Definition editprop.c:2071
static struct propval * objbind_get_value_from_object(struct objbind *ob, struct objprop *op)
Definition editprop.c:1443
static void propval_free(struct propval *pv)
Definition editprop.c:1128
static struct property_filter * property_filter_new(const char *filter)
Definition editprop.c:6430
static bool property_page_set_store_value(struct property_page *pp, struct objprop *op, struct objbind *ob, GtkTreeIter *iter)
Definition editprop.c:5287
static const char * objtype_get_name(enum editor_object_type objtype)
Definition editprop.c:667
static void objprop_widget_entry_changed(GtkEntry *entry, gpointer userdata)
Definition editprop.c:2904
static void objbind_clear_all_modified_values(struct objbind *ob)
Definition editprop.c:2116
static bool property_filter_match(struct property_filter *pf, const struct objprop *op)
Definition editprop.c:6504
void property_editor_popup(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6292
static void property_page_destroy_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6144
static struct objbind * objbind_new(enum editor_object_type objtype, gpointer object)
Definition editprop.c:1340
static gboolean property_page_selection_func(GtkTreeSelection *sel, GtkTreeModel *model, GtkTreePath *path, gboolean currently_selected, gpointer data)
Definition editprop.c:4671
static int property_page_get_num_objbinds(const struct property_page *pp)
Definition editprop.c:5495
static bool objprop_show_in_listview(const struct objprop *op)
Definition editprop.c:2736
static GType objprop_get_gtype(const struct objprop *op)
Definition editprop.c:2692
static void objprop_set_treeview_column(struct objprop *op, GtkTreeViewColumn *col)
Definition editprop.c:2810
static void objbind_pack_current_values(struct objbind *ob, union packetdata packet)
Definition editprop.c:2239
static const char * objprop_get_attribute_type_string(const struct objprop *op)
Definition editprop.c:2761
static struct propval * propval_copy(struct propval *pv)
Definition editprop.c:1046
struct property_editor * editprop_get_property_editor(void)
Definition editprop.c:6245
void property_editor_reload(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6382
static GdkPixbuf * create_unit_pixbuf(const struct unit *punit)
Definition editprop.c:5114
static void extviewer_view_cell_toggled(GtkCellRendererToggle *cell, gchar *path, gpointer userdata)
Definition editprop.c:4166
static struct property_editor * property_editor_new(void)
Definition editprop.c:6202
static void property_page_send_packet(struct property_page *pp, union packetdata packet)
Definition editprop.c:5644
static gchar * built_status_to_string(struct built_status *bs)
Definition editprop.c:981
static int objprop_get_id(const struct objprop *op)
Definition editprop.c:2677
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:380
@ 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:373
@ 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:374
@ 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:379
@ 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:375
@ OPID_GAME_STARTPOS_NATIONS
Definition editprop.c:378
@ 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:376
@ OPID_PLAYER_INFRAPOINTS
Definition editprop.c:370
@ OPID_GAME_SCENARIO_PLAYERS
Definition editprop.c:377
@ 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:372
@ OPID_GAME_RULESET_LOCKED
Definition editprop.c:381
@ 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:2725
static int get_next_unique_tag(void)
Definition editprop.c:1035
static bool objprop_is_sortable(const struct objprop *op)
Definition editprop.c:2879
static void property_page_add_objbinds_from_tile(struct property_page *pp, const struct tile *ptile)
Definition editprop.c:5233
static const char * objprop_get_tooltip(const struct objprop *op)
Definition editprop.c:2845
static GtkTreeRowReference * objbind_get_rowref(struct objbind *ob)
Definition editprop.c:2666
static void property_filter_free(struct property_filter *pf)
Definition editprop.c:6558
static void objprop_widget_spin_button_changed(GtkSpinButton *spin, gpointer userdata)
Definition editprop.c:2920
#define PF_DISJUNCTION_SEPARATOR
Definition editprop.c:119
static GtkWidget * objprop_get_child_widget(struct objprop *op, const char *widget_name)
Definition editprop.c:3410
static void property_page_selection_changed(GtkTreeSelection *sel, gpointer userdata)
Definition editprop.c:4646
static bool objtype_is_conserved(enum editor_object_type objtype)
Definition editprop.c:756
static struct extviewer * extviewer_new(struct objprop *op)
Definition editprop.c:3502
static bool propval_equal(struct propval *pva, struct propval *pvb)
Definition editprop.c:1179
static void property_page_quick_find_entry_changed(GtkWidget *entry, gpointer userdata)
Definition editprop.c:4726
static void objprop_refresh_widget(struct objprop *op, struct objbind *ob)
Definition editprop.c:3132
#define PF_MAX_CLAUSES
Definition editprop.c:118
void property_editor_popdown(struct property_editor *pe)
Definition editprop.c:6310
static void objbind_destroy(struct objbind *ob)
Definition editprop.c:2195
static void property_page_add_objbind(struct property_page *pp, gpointer object_data)
Definition editprop.c:5197
static void objbind_request_destroy_object(struct objbind *ob)
Definition editprop.c:1395
static void property_page_create_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6116
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:5140
static union packetdata property_page_new_packet(struct property_page *pp)
Definition editprop.c:5603
static void propstate_set_value(struct propstate *ps, struct propval *pv)
Definition editprop.c:1313
static int objprop_get_column_id(const struct objprop *op)
Definition editprop.c:2799
static GdkPixbuf * create_tile_pixbuf(const struct tile *ptile)
Definition editprop.c:5102
static struct objprop * extviewer_get_objprop(struct extviewer *ev)
Definition editprop.c:3786
static bool can_create_unit_at_tile(struct tile *ptile)
Definition editprop.c:1002
static struct objbind * property_page_get_objbind(struct property_page *pp, int object_id)
Definition editprop.c:5461
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:1884
static void property_page_free_packet(struct property_page *pp, union packetdata packet)
Definition editprop.c:5685
static GdkPixbuf * create_city_pixbuf(const struct city *pcity)
Definition editprop.c:5126
#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:4146
static void property_page_destroy_objects(struct property_page *pp)
Definition editprop.c:5746
void property_editor_load_tiles(struct property_editor *pe, const struct tile_list *tiles)
Definition editprop.c:6256
static struct property_page * property_page_new(enum editor_object_type objtype, struct property_editor *parent)
Definition editprop.c:4768
#define property_page_objprop_iterate_end
Definition editprop.c:637
static void property_page_clear_objbinds(struct property_page *pp)
Definition editprop.c:5182
void property_editor_clear(struct property_editor *pe)
Definition editprop.c:6362
#define property_page_objprop_iterate(ARG_pp, NAME_op)
Definition editprop.c:635
static void objprop_set_column_id(struct objprop *op, int col_id)
Definition editprop.c:2786
static void objbind_bind_properties(struct objbind *ob, struct property_page *pp)
Definition editprop.c:2225
static void property_page_fill_widgets(struct property_page *pp)
Definition editprop.c:5387
static bool objbind_has_modified_properties(struct objbind *ob)
Definition editprop.c:2104
static void property_page_change_value(struct property_page *pp, struct objprop *op, struct propval *pv)
Definition editprop.c:5507
static void objprop_widget_toggle_button_changed(GtkToggleButton *button, gpointer userdata)
Definition editprop.c:2937
#define PF_CONJUNCTION_SEPARATOR
Definition editprop.c:120
static void property_page_apply_button_clicked(GtkButton *button, gpointer userdata)
Definition editprop.c:6095
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:3477
static GtkWidget * extviewer_get_view_widget(struct extviewer *ev)
Definition editprop.c:3810
static GtkWidget * objprop_get_widget(struct objprop *op)
Definition editprop.c:3368
static void propval_free_data(struct propval *pv)
Definition editprop.c:1142
static void extviewer_textbuf_changed(GtkTextBuffer *textbuf, gpointer userdata)
Definition editprop.c:4387
static struct property_editor * the_property_editor
Definition editprop.c:661
static void property_page_object_changed(struct property_page *pp, int object_id, bool remove)
Definition editprop.c:5909
static bool objprop_is_readonly(const struct objprop *op)
Definition editprop.c:2893
#define property_page_objbind_iterate(ARG_pp, NAME_ob)
Definition editprop.c:639
static GtkTreeViewColumn * objprop_get_treeview_column(const struct objprop *op)
Definition editprop.c:2823
static struct property_page * property_editor_get_page(struct property_editor *pe, enum editor_object_type objtype)
Definition editprop.c:6189
static struct propval * objbind_get_modified_value(struct objbind *ob, struct objprop *op)
Definition editprop.c:2176
GtkWidget * toplevel
Definition gui_main.c:126
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:384
#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:195
#define log_error(message,...)
Definition log.h:104
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:2038
int startpos_number(const struct startpos *psp)
Definition map.c:1776
#define nat_x
#define nat_y
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1820
const struct nation_hash * startpos_raw_nations(const struct startpos *psp)
Definition map.c:1916
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1854
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:471
bool startpos_is_excluding(const struct startpos *psp)
Definition map.c:1903
struct startpos * map_startpos_by_number(int id)
Definition map.c:1767
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:161
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:229
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:318
#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:1996
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:1409
struct player * player_slot_get_player(const struct player_slot *pslot)
Definition player.c:437
#define players_iterate_end
Definition player.h:542
#define players_iterate(_pplayer)
Definition player.h:537
#define player_slots_iterate(_pslot)
Definition player.h:528
#define player_slots_iterate_end
Definition player.h:532
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
cairo_surface_t * surface
Definition canvas.h:23
Definition city.h:317
struct packet_game_info info
Definition game.h:89
struct government * government_during_revolution
Definition game.h:94
struct connection conn
Definition client_main.h:96
GtkWidget * view_widget
Definition editprop.c:523
GtkWidget * panel_button
Definition editprop.c:520
GtkWidget * view_label
Definition editprop.c:524
GtkWidget * panel_image
Definition editprop.c:521
GtkTextBuffer * textbuf
Definition editprop.c:527
struct objprop * objprop
Definition editprop.c:515
GtkWidget * panel_label
Definition editprop.c:519
struct propval * pv_cached
Definition editprop.c:516
GtkListStore * store
Definition editprop.c:526
GtkWidget * panel_widget
Definition editprop.c:518
bool(* player_tile_vision_get)(const struct tile *ptile, const struct player *pplayer, enum vision_layer vision)
int object_id
Definition editprop.c:460
struct propstate_hash * propstate_table
Definition editprop.c:462
struct property_page * parent_property_page
Definition editprop.c:461
GtkTreeRowReference * rowref
Definition editprop.c:463
enum editor_object_type objtype
Definition editprop.c:459
const char * name
Definition editprop.c:393
const char * tooltip
Definition editprop.c:394
GtkWidget * widget
Definition editprop.c:399
struct property_page * parent_page
Definition editprop.c:401
enum object_property_flags flags
Definition editprop.c:395
struct extviewer * extviewer
Definition editprop.c:400
int id
Definition editprop.c:392
enum value_types valtype
Definition editprop.c:396
int column_id
Definition editprop.c:397
GtkTreeViewColumn * view_column
Definition editprop.c:398
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 infra_points
Definition player.h:67
int autoselect_weight
Definition player.h:299
struct government * government
Definition player.h:258
int turns_alive
Definition player.h:266
struct player_economic economic
Definition player.h:284
char name[MAX_LEN_NAME]
Definition player.h:251
struct nation_type * nation
Definition player.h:260
GtkWidget * notebook
Definition editprop.c:649
struct property_page * property_pages[NUM_OBJTYPES]
Definition editprop.c:651
GtkWidget * widget
Definition editprop.c:648
struct pf_conjunction disjunction[PF_MAX_CLAUSES]
Definition editprop.c:133
GtkListStore * object_store
Definition editprop.c:553
struct property_editor * pe_parent
Definition editprop.c:557
GtkWidget * extviewer_notebook
Definition editprop.c:555
GtkWidget * widget
Definition editprop.c:552
struct objbind_hash * objbind_table
Definition editprop.c:560
GtkWidget * object_view
Definition editprop.c:554
struct objbind * focused_objbind
Definition editprop.c:563
struct stored_tag_hash * tag_table
Definition editprop.c:561
enum editor_object_type objtype
Definition editprop.c:550
struct objprop_hash * objprop_table
Definition editprop.c:559
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:40
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:66
Continent_id continent
Definition tile.h:54
Definition unit.h:140
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
bool moved
Definition unit.h:176
int hp
Definition unit.h:153
int fuel
Definition unit.h:155
bool stay
Definition unit.h:208
bool done_moving
Definition unit.h:184
int veteran
Definition unit.h:154
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:777
char * fc_strcasestr(const char *haystack, const char *needle)
Definition support.c:437
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define sz_strlcat(dest, src)
Definition support.h:196
const char * advance_name_translation(const struct advance *padvance)
Definition tech.c:300
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
#define advance_index_iterate_end
Definition tech.h:244
static Tech_type_id advance_count(void)
Definition tech.h:165
#define A_FIRST
Definition tech.h:44
#define advance_iterate(_p)
Definition tech.h:271
#define advance_iterate_end
Definition tech.h:272
#define advance_index_iterate(_start, _index)
Definition tech.h:240
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:89
#define tile_resource(_tile)
Definition tile.h:103
#define tile_list_iterate(tile_list, ptile)
Definition tile.h:74
#define tile_terrain(_tile)
Definition tile.h:111
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_list_iterate_end
Definition tile.h:76
static const bv_extras * tile_extras(const struct tile *ptile)
Definition tile.h:121
#define tile_has_extra(ptile, pextra)
Definition tile.h:148
struct sprite * get_government_sprite(const struct tileset *t, const struct government *gov)
Definition tilespec.c:7017
int tileset_full_tile_height(const struct tileset *t)
Definition tilespec.c:815
bool tileset_layer_in_category(enum mapview_layer layer, enum layer_category cat)
Definition tilespec.c:7557
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:791
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:802
#define mapview_layer_iterate(layer)
Definition tilespec.h:177
#define mapview_layer_iterate_end
Definition tilespec.h:185
layer_category
Definition tilespec.h:191
@ LAYER_CATEGORY_TILE
Definition tilespec.h:193
@ LAYER_CATEGORY_CITY
Definition tilespec.h:192
@ LAYER_CATEGORY_UNIT
Definition tilespec.h:194
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 packet_edit_player * player
Definition editprop.c:105
struct packetdata::@152 pointers
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:404
static bool is_enemy_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:427
#define unit_owner(_pu)
Definition unit.h:403
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:440
#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:2631
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:196
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1566
#define utype_fuel(ptype)
Definition unittype.h:846
#define vision_layer_iterate(v)
Definition vision.h:77
#define vision_layer_iterate_end
Definition vision.h:80