Freeciv-3.4
Loading...
Searching...
No Matches
citydlg.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <gtk/gtk.h>
23#include <gdk/gdkkeysyms.h>
24
25/* utility */
26#include "bitvector.h"
27#include "fcintl.h"
28#include "log.h"
29#include "mem.h"
30#include "shared.h"
31#include "support.h"
32
33/* common */
34#include "city.h"
35#include "counters.h"
36#include "game.h"
37#include "map.h"
38#include "movement.h"
39#include "packets.h"
40#include "player.h"
41#include "unitlist.h"
42
43/* client */
44#include "chatline_common.h"
45#include "client_main.h"
46#include "colors.h"
47#include "control.h"
48#include "climap.h"
49#include "options.h"
50#include "text.h"
51#include "tilespec.h"
52
53/* client/agents */
54#include "cma_fec.h"
55
56/* client/gui-gtk-3.22 */
57#include "choice_dialog.h"
58#include "citizensinfo.h"
59#include "cityrep.h"
60#include "cma_fe.h"
61#include "dialogs.h"
62#include "graphics.h"
63#include "gui_main.h"
64#include "gui_stuff.h"
65#include "happiness.h"
66#include "helpdlg.h"
67#include "inputdlg.h"
68#include "mapview.h"
69#include "update_queue.h"
70#include "wldlg.h"
71
72#include "citydlg.h"
73
74#define CITYMAP_WIDTH MIN(512, canvas_width)
75#define CITYMAP_HEIGHT (CITYMAP_WIDTH * canvas_height / canvas_width)
76#define CITYMAP_SCALE ((double)CITYMAP_WIDTH / (double)canvas_width)
77
78#define TINYSCREEN_MAX_HEIGHT (500 - 1)
79
80/* Only CDLGR_UNITS button currently uses these, others have
81 * direct callback. */
83
84struct city_dialog;
85
86/* get 'struct dialog_list' and related function */
87#define SPECLIST_TAG dialog
88#define SPECLIST_TYPE struct city_dialog
89#include "speclist.h"
90
91#define dialog_list_iterate(dialoglist, pdialog) \
92 TYPED_LIST_ITERATE(struct city_dialog, dialoglist, pdialog)
93#define dialog_list_iterate_end LIST_ITERATE_END
94
100
101/* get 'struct unit_node' and related function */
102#define SPECVEC_TAG unit_node
103#define SPECVEC_TYPE struct unit_node
104#include "specvec.h"
105
106#define unit_node_vector_iterate(list, elt) \
107 TYPED_VECTOR_ITERATE(struct unit_node, list, elt)
108#define unit_node_vector_iterate_end VECTOR_ITERATE_END
109
110#define NUM_CITIZENS_SHOWN 30
111
114 NUM_PAGES /* the number of pages in city dialog notebook
115 * must match the entries in misc_whichtab_label[] */
117
118enum {
123 NUM_INFO_FIELDS /* number of fields in city_info panel
124 * must match entries in output_label[] */
126
127/* minimal size for the city map scrolling windows*/
128#define CITY_MAP_MIN_SIZE_X 200
129#define CITY_MAP_MIN_SIZE_Y 150
130
136
138 struct city *pcity;
139
144
148
149 struct {
151
156
159
162
163 struct unit_node_vector supported_units;
164 struct unit_node_vector present_units;
165
168
171
172 struct {
174 GtkWidget *production_bar;
175 GtkWidget *buy_command;
178
179 struct {
181
187
188 struct {
192
194
195 struct {
197 GtkWidget *new_citizens_radio[3];
199 GtkWidget *whichtab_radio[NUM_PAGES];
202
206
210
212
214};
215
221
223
224static struct
225{
226 struct city *owner;
227 struct tile *loc;
229
230static bool low_citydlg;
231
232/****************************************/
233
234static void initialize_city_dialogs(void);
235static void city_dialog_map_create(struct city_dialog *pdialog,
238
239static struct city_dialog *get_city_dialog(struct city *pcity);
241 struct city_dialog *pdialog);
242
243static GtkWidget *create_city_info_table(struct city_dialog *pdialog,
246static void create_and_append_overview_page(struct city_dialog *pdialog);
247static void create_and_append_map_page(struct city_dialog *pdialog);
248static void create_and_append_buildings_page(struct city_dialog *pdialog);
249static void create_and_append_worklist_page(struct city_dialog *pdialog);
250static void create_and_append_happiness_page(struct city_dialog *pdialog);
251static void create_and_append_cma_page(struct city_dialog *pdialog);
252static void create_and_append_settings_page(struct city_dialog *pdialog);
253
254static struct city_dialog *create_city_dialog(struct city *pcity);
255
256static void city_dialog_update_title(struct city_dialog *pdialog);
257static void city_dialog_update_citizens(struct city_dialog *pdialog);
258static void city_dialog_update_counters(struct city_dialog *pdialog);
261 struct city_dialog *pdialog);
262static void city_dialog_update_map(struct city_dialog *pdialog);
263static void city_dialog_update_building(struct city_dialog *pdialog);
265 *pdialog);
267 *pdialog);
268static void city_dialog_update_present_units(struct city_dialog *pdialog);
269static void city_dialog_update_prev_next(void);
270
271static void show_units_response(void *data);
272
274 gpointer data);
276 gpointer data);
279 gpointer data);
282 gpointer data);
283
284static void unit_center_callback(GtkWidget * w, gpointer data);
285static void unit_activate_callback(GtkWidget * w, gpointer data);
287 gpointer data);
289 gpointer data);
290static void unit_load_callback(GtkWidget * w, gpointer data);
291static void unit_unload_callback(GtkWidget * w, gpointer data);
292static void unit_sentry_callback(GtkWidget * w, gpointer data);
293static void unit_fortify_callback(GtkWidget * w, gpointer data);
294static void unit_disband_callback(GtkWidget * w, gpointer data);
295static void unit_homecity_callback(GtkWidget * w, gpointer data);
296static void unit_upgrade_callback(GtkWidget * w, gpointer data);
297
299 gpointer data);
301 gpointer data);
302static void draw_map_canvas(struct city_dialog *pdialog);
303
304static void buy_callback(GtkWidget * w, gpointer data);
305static void change_production_callback(GtkComboBox *combo,
306 struct city_dialog *pdialog);
307
308static void sell_callback(struct impr_type *pimprove, gpointer data);
309static void sell_callback_response(GtkWidget *w, gint response, gpointer data);
310
311static void impr_callback(GtkTreeView *view, GtkTreePath *path,
313
314static void rename_callback(GtkWidget * w, gpointer data);
315static void rename_popup_callback(gpointer data, gint response,
316 const char *input);
317static void set_cityopt_values(struct city_dialog *pdialog);
318static void cityopt_callback(GtkWidget * w, gpointer data);
319static void misc_whichtab_callback(GtkWidget * w, gpointer data);
320
321static void city_destroy_callback(GtkWidget *w, gpointer data);
322static void close_city_dialog(struct city_dialog *pdialog);
323static void citydlg_response_callback(GtkDialog *dlg, gint response,
324 void *data);
325static void close_callback(GtkWidget *w, gpointer data);
326static void switch_city_callback(GtkWidget *w, gpointer data);
327
328/**********************************************************************/
337
338/**********************************************************************/
341static void initialize_city_dialogs(void)
342{
343 int height;
344
346
350
351 /* Use default layout when height cannot be determined
352 * (when height == 0) */
353 if (height > 0 && height <= TINYSCREEN_MAX_HEIGHT) {
355 } else {
357 }
358
360}
361
362/**********************************************************************/
366{
368 return;
369 }
370
372
374 /* There's no reasonable way to resize a GtkImage, so we don't try.
375 Instead we just redraw the overview within the existing area. The
376 player has to close and reopen the dialog to fix this. */
377 city_dialog_update_map(pdialog);
379
381}
382
383/**********************************************************************/
387static struct city_dialog *get_city_dialog(struct city *pcity)
388{
391 }
392
394 if (pdialog->pcity == pcity)
395 return pdialog;
396 }
398 return NULL;
399}
400
401/**********************************************************************/
405 gpointer data)
406{
407 struct city_dialog *pdialog = data;
408
411 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
412 cairo_paint_with_alpha(cr, 0.5);
413 } else {
414 cairo_paint(cr);
415 }
416
417 return TRUE;
418}
419
420/**********************************************************************/
458
459/**********************************************************************/
483
484/**********************************************************************/
488{
489 struct city_dialog *pdialog = get_city_dialog(pcity);
490
491 log_debug("CITYMAP_WIDTH: %d", CITYMAP_WIDTH);
492 log_debug("CITYMAP_HEIGHT: %d", CITYMAP_HEIGHT);
493 log_debug("CITYMAP_SCALE: %.3f", CITYMAP_SCALE);
494
498 }
499
500 if (!pdialog) {
501 return;
502 }
503
507 pdialog->overview.info_label, pdialog);
508 city_dialog_update_map(pdialog);
514
517
519
520 if (!low_citydlg) {
522 pdialog->happiness.info_label, pdialog);
523 }
527 }
528
529 if (!client_is_observer()) {
531 }
532
536 } else {
537 /* Set the buttons we do not want live while a Diplomat investigates */
539 }
540}
541
542/**********************************************************************/
547{
548 struct city *pcity_sup, *pcity_pre;
549 struct city_dialog *pdialog;
550
553
554 if (pcity_sup && (pdialog = get_city_dialog(pcity_sup))) {
556 }
557
558 if (pcity_pre && (pdialog = get_city_dialog(pcity_pre))) {
560 }
561}
562
563/**********************************************************************/
567{
568 struct city_dialog *pdialog;
569
570 if (!(pdialog = get_city_dialog(pcity))) {
571 pdialog = create_city_dialog(pcity);
572 }
573
575
576 /* center the city map(s); this must be *after* the city dialog was drawn
577 * else the size information is missing! */
579 if (pdialog->happiness.map_canvas.sw) {
581 }
582}
583
584/**********************************************************************/
588{
589 return get_city_dialog(pcity) != NULL;
590}
591
592/**********************************************************************/
596{
597 struct city_dialog *pdialog = get_city_dialog(pcity);
598
599 if (pdialog) {
600 close_city_dialog(pdialog);
601 }
602}
603
604/**********************************************************************/
620
621/**********************************************************************/
625 struct city_dialog *pdialog)
626{
627 if (event->state & GDK_CONTROL_MASK) {
628 switch (event->keyval) {
629 case GDK_KEY_Left:
631 return TRUE;
632
633 case GDK_KEY_Right:
635 return TRUE;
636
637 default:
638 break;
639 }
640 }
641
642 return FALSE;
643}
644
645/**********************************************************************/
657
658/**********************************************************************/
662 gpointer data)
663{
664 struct city_dialog *pdialog = g_object_get_data(G_OBJECT(w), "pdialog");
665
666 if (ev->button == 1) {
667 GtkWidget *p, *label, *frame;
668 char buf[1024];
669
670 switch (GPOINTER_TO_UINT(data)) {
671 case INFO_SIZE:
672 fc_snprintf(buf, sizeof(buf), _("Population: %d, Specialists: %d"),
673 pdialog->pcity->size, city_specialists(pdialog->pcity));
674 break;
675 case INFO_FOOD:
676 get_city_dialog_output_text(pdialog->pcity, O_FOOD, buf, sizeof(buf));
677 break;
678 case INFO_SHIELD:
680 buf, sizeof(buf));
681 break;
682 case INFO_TRADE:
683 get_city_dialog_output_text(pdialog->pcity, O_TRADE, buf, sizeof(buf));
684 break;
685 case INFO_GOLD:
686 get_city_dialog_output_text(pdialog->pcity, O_GOLD, buf, sizeof(buf));
687 break;
688 case INFO_SCIENCE:
690 buf, sizeof(buf));
691 break;
692 case INFO_LUXURY:
694 buf, sizeof(buf));
695 break;
696 case INFO_CULTURE:
697 get_city_dialog_culture_text(pdialog->pcity, buf, sizeof(buf));
698 break;
699 case INFO_POLLUTION:
700 get_city_dialog_pollution_text(pdialog->pcity, buf, sizeof(buf));
701 break;
702 case INFO_ILLNESS:
703 get_city_dialog_illness_text(pdialog->pcity, buf, sizeof(buf));
704 break;
705 case INFO_AIRLIFT:
706 get_city_dialog_airlift_text(pdialog->pcity, buf, sizeof(buf));
707 break;
708 default:
709 return TRUE;
710 }
711
713 gtk_widget_set_name(p, "Freeciv");
717
718 frame = gtk_frame_new(NULL);
720
721 label = gtk_label_new(buf);
722 gtk_widget_set_name(label, "city_label");
727 gtk_container_add(GTK_CONTAINER(frame), label);
729
732 TRUE, NULL, (GdkEvent *)ev, NULL, NULL);
733 gtk_grab_add(p);
734
735 g_signal_connect_after(p, "button_release_event",
737 }
738 return TRUE;
739}
740
741/**********************************************************************/
748{
749 int i;
750 GtkWidget *table, *label, *ebox;
751
752 static const char *output_label[NUM_INFO_FIELDS] = {
753 N_("Size:"),
754 N_("Food:"),
755 N_("Prod:"),
756 N_("Trade:"),
757 N_("Gold:"),
758 N_("Luxury:"),
759 N_("Science:"),
760 N_("Granary:"),
761 N_("Change in:"),
762 N_("Corruption:"),
763 N_("Waste:"),
764 N_("Culture:"),
765 N_("Pollution:"),
766 N_("Plague risk:"),
767 N_("Tech Stolen:"),
768 N_("Airlift:"),
769 };
770 static bool output_label_done;
771
773 g_object_set(table, "margin", 4, NULL);
774
776
777 for (i = 0; i < NUM_INFO_FIELDS; i++) {
778 label = gtk_label_new(output_label[i]);
779 switch (i) {
780 case INFO_SIZE:
781 case INFO_TRADE:
782 case INFO_SCIENCE:
783 case INFO_GROWTH:
785 break;
786
787 case INFO_FOOD:
788 case INFO_GOLD:
789 case INFO_GRANARY:
790 case INFO_CORRUPTION:
792 break;
793 default:
794 break;
795 }
797 gtk_widget_set_name(label, "city_label"); /* for font style? */
800 gtk_grid_attach(GTK_GRID(table), label, 0, i, 1, 1);
801
802 ebox = gtk_event_box_new();
803 switch (i) {
804 case INFO_TRADE:
805 case INFO_SCIENCE:
806 case INFO_GROWTH:
808 break;
809
810 case INFO_GOLD:
811 case INFO_GRANARY:
812 case INFO_CORRUPTION:
814 break;
815 default:
816 break;
817 }
819 g_object_set_data(G_OBJECT(ebox), "pdialog", pdialog);
820 g_signal_connect(ebox, "button_press_event",
822 info_ebox[i] = ebox;
823
824 label = gtk_label_new("");
825 info_label[i] = label;
826 gtk_widget_set_name(label, "city_label"); /* ditto */
829
830 gtk_container_add(GTK_CONTAINER(ebox), label);
831
832 gtk_grid_attach(GTK_GRID(table), ebox, 1, i, 1, 1);
833 }
834
835 /*
836 * Allow special highlighting of emergencies for granary etc by
837 * city_dialog_update_information().
838 */
839 {
840 /* This will persist, and can be shared between overview and happiness
841 * pages. */
843
844 if (emergency_provider == NULL) {
846
848 ".emergency {\n"
849 " color: rgba(255, 0.0, 0.0, 255);\n"
850 "}",
851 -1, NULL);
852 }
853
854 /* GRANARY */
858 /* GROWTH */
862 /* POLLUTION */
866 /* ILLNESS */
870 }
871
873
874 return table;
875}
876
877/**********************************************************************/
880static void create_citydlg_main_map(struct city_dialog *pdialog,
882{
883 GtkWidget *frame;
884
885 frame = gtk_frame_new(_("City map"));
889
890 city_dialog_map_create(pdialog, &pdialog->overview.map_canvas);
892}
893
894/**********************************************************************/
898 GtkWidget *vbox)
899{
901 GtkListStore *store;
903
904 /* improvements */
905 /* gtk list store columns: 0 - sell value, 1 - sprite,
906 2 - description, 3 - upkeep, 4 - is redundant, 5 - tooltip */
910
914 g_object_unref(store);
916 gtk_widget_set_name(view, "small_font");
917 pdialog->overview.improvement_list = view;
918
921 rend, "pixbuf", 1, NULL);
924 rend, "text", 2,
925 "strikethrough", 4, NULL);
927 g_object_set(rend, "xalign", 1.0, NULL);
929 rend, "text", 3,
930 "strikethrough", 4, NULL);
931
933
935 pdialog);
936
937 return view;
938}
939
940/**********************************************************************/
957{
959 GtkWidget *hbox, *right, *vbox, *frame, *table;
960 GtkWidget *label, *sw, *view, *bar, *production_combo;
963 /* TRANS: Overview tab in city dialog */
964 const char *tab_title = _("_Overview");
966
967 /* main page */
968 page = gtk_grid_new();
974
975 if (!low_citydlg) {
976 GtkWidget *middle;
977
978 /* middle: city map, improvements */
979 middle = gtk_grid_new();
982
983 /* city map */
984 create_citydlg_main_map(pdialog, middle);
985
986 /* improvements */
987 vbox = gtk_grid_new();
990 gtk_container_add(GTK_CONTAINER(middle), vbox);
991
992 view = create_citydlg_improvement_list(pdialog, middle);
993
994 label = g_object_new(GTK_TYPE_LABEL, "label", _("Production:"),
995 "xalign", 0.0, "yalign", 0.5, NULL);
996 gtk_container_add(GTK_CONTAINER(vbox), label);
997
998 hbox = gtk_grid_new();
1001
1005
1014
1019 rend, "pixbuf", 0, NULL);
1020 g_object_set(rend, "xalign", 0.0, NULL);
1021
1025 rend, "text", 1, "strikethrough", 3, NULL);
1026
1027 bar = gtk_progress_bar_new();
1029 pdialog->overview.production_bar = bar;
1032
1033 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(bar), _("%d/%d %d turns"));
1034
1035 pdialog->overview.buy_command
1036 = icon_label_button_new("system-run", _("_Buy"));
1038 g_signal_connect(pdialog->overview.buy_command, "clicked",
1039 G_CALLBACK(buy_callback), pdialog);
1040
1041 label = g_object_new(GTK_TYPE_LABEL, "use-underline", TRUE,
1042 "mnemonic-widget", view,
1043 "label", _("I_mprovements:"),
1044 "xalign", 0.0, "yalign", 0.5, NULL);
1045 gtk_container_add(GTK_CONTAINER(vbox), label);
1046
1053
1055 } else {
1056 pdialog->overview.buy_command = NULL;
1057 pdialog->overview.production_bar = NULL;
1058 pdialog->overview.production_combo = NULL;
1060 }
1061
1062 /* bottom: info, units */
1063 bottom = gtk_grid_new();
1066
1067 /* info */
1068 frame = gtk_frame_new(_("Info"));
1070
1071 table = create_city_info_table(pdialog,
1072 pdialog->overview.info_ebox,
1073 pdialog->overview.info_label);
1077
1078 /* right: present and supported units (overview page) */
1079 right = gtk_grid_new();
1083
1089 pdialog->overview.present_units_frame);
1090
1091 /* supported units */
1099 sw);
1100
1101
1102 table = gtk_grid_new();
1106
1111
1114
1115 /* present units */
1123
1124 table = gtk_grid_new();
1128
1133
1136
1137 /* show page */
1139}
1140
1141/**********************************************************************/
1144static void create_and_append_map_page(struct city_dialog *pdialog)
1145{
1146 if (low_citydlg) {
1147 GtkWidget *page;
1148 GtkWidget *label;
1149 const char *tab_title = _("Citymap");
1150
1151 page = gtk_grid_new();
1157
1158 create_citydlg_main_map(pdialog, page);
1159
1161 }
1162}
1163
1164/**********************************************************************/
1169 gint x, gint y,
1170 GtkSelectionData *data,
1171 guint info, guint time,
1172 gpointer user_data)
1173{
1174 struct city_dialog *pdialog = (struct city_dialog *) user_data;
1175 GtkTreeModel *model;
1176 GtkTreePath *path;
1177
1178 if (NULL != client.conn.playing
1179 && city_owner(pdialog->pcity) != client.conn.playing) {
1181 }
1182
1183 if (gtk_tree_get_row_drag_data(data, &model, &path)) {
1184 GtkTreeIter it;
1185
1186 if (gtk_tree_model_get_iter(model, &it, path)) {
1187 cid id;
1188 struct universal univ;
1189
1190 gtk_tree_model_get(model, &it, 0, &id, -1);
1191 univ = cid_production(id);
1192 city_change_production(pdialog->pcity, &univ);
1194 }
1195 gtk_tree_path_free(path);
1196 }
1197
1199}
1200
1201/**********************************************************************/
1206{
1207 GtkWidget *hbox, *bar;
1208
1209 hbox = gtk_grid_new();
1210 g_object_set(hbox, "margin", 2, NULL);
1213
1214 /* The label is set in city_dialog_update_building() */
1215 bar = gtk_progress_bar_new();
1218 pdialog->production.production_bar = bar;
1220 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(bar), _("%d/%d %d turns"));
1221
1223
1224 g_signal_connect(bar, "drag_data_received",
1226
1227 pdialog->production.buy_command
1228 = icon_label_button_new("system-run", _("_Buy"));
1230
1231 g_signal_connect(pdialog->production.buy_command, "clicked",
1232 G_CALLBACK(buy_callback), pdialog);
1233}
1234
1235/**********************************************************************/
1239{
1240 if (low_citydlg) {
1241 GtkWidget *page;
1242 GtkWidget *label;
1243 GtkWidget *vbox;
1244 GtkWidget *view;
1245 const char *tab_title = _("Buildings");
1246
1247 page = gtk_grid_new();
1252
1254 gtk_notebook_append_page(GTK_NOTEBOOK(pdialog->notebook), page, label);
1255
1256 vbox = gtk_grid_new();
1259 gtk_container_add(GTK_CONTAINER(page), vbox);
1260
1261 view = create_citydlg_improvement_list(pdialog, vbox);
1262
1264
1265 gtk_widget_show_all(page);
1266 }
1267}
1268
1269/**********************************************************************/
1273{
1274 const char *tab_title = _("P_roduction");
1276 GtkWidget *page, *editor;
1277
1278 page = gtk_grid_new();
1282 gtk_notebook_append_page(GTK_NOTEBOOK(pdialog->notebook), page, label);
1283
1284 /* stuff that's being currently built */
1285 if (!low_citydlg) {
1287 "label", _("Production:"),
1288 "xalign", 0.0, "yalign", 0.5, NULL);
1289 pdialog->production.production_label = label;
1290 gtk_container_add(GTK_CONTAINER(page), label);
1291
1293 } else {
1294 pdialog->production.production_label = NULL;
1295 }
1296
1298 g_object_set(editor, "margin", 6, NULL);
1299 reset_city_worklist(editor, pdialog->pcity);
1301 pdialog->production.worklist = editor;
1302
1303 gtk_widget_show_all(page);
1304}
1305
1306/**********************************************************************/
1317{
1318 GtkWidget *page, *label, *table, *right, *left, *frame;
1319 const char *tab_title = _("Happ_iness");
1320
1321 /* main page */
1322 page = gtk_grid_new();
1326 gtk_notebook_append_page(GTK_NOTEBOOK(pdialog->notebook), page, label);
1327
1328 /* left: info, citizens */
1329 left = gtk_grid_new();
1332 gtk_container_add(GTK_CONTAINER(page), left);
1333
1334 if (!low_citydlg) {
1335 /* upper left: info */
1336 frame = gtk_frame_new(_("Info"));
1337 gtk_container_add(GTK_CONTAINER(left), frame);
1338
1339 table = create_city_info_table(pdialog,
1340 pdialog->happiness.info_ebox,
1341 pdialog->happiness.info_label);
1344 }
1345
1346 /* lower left: citizens */
1348 pdialog->happiness.citizens = gtk_grid_new();
1354 citizens_dialog_display(pdialog->pcity));
1355 }
1356
1357 /* right: city map, happiness */
1358 right = gtk_grid_new();
1361 gtk_container_add(GTK_CONTAINER(page), right);
1362
1363 if (!low_citydlg) {
1364 /* upper right: city map */
1365 frame = gtk_frame_new(_("City map"));
1368 gtk_container_add(GTK_CONTAINER(right), frame);
1369
1370 city_dialog_map_create(pdialog, &pdialog->happiness.map_canvas);
1372 }
1373
1374 /* lower right: happiness */
1375 pdialog->happiness.widget = gtk_grid_new();
1380 get_top_happiness_display(pdialog->pcity, low_citydlg, pdialog->shell));
1381
1382 /* show page */
1383 gtk_widget_show_all(page);
1384}
1385
1386/**********************************************************************/
1389/**********************************************************************/
1394{
1396 GtkLabel *label = GTK_LABEL(gtk_label_new(_("Counters")));
1397
1398 pdialog->counters.container = NULL;
1399 pdialog->counters.widget = NULL;
1400
1402
1404
1406
1407 gtk_widget_show_all(page);
1408}
1409
1410/**********************************************************************/
1413static void city_dialog_update_counters(struct city_dialog *pdialog)
1414{
1419 char int_val[101];
1420 char *text;
1421 int text_size;
1422
1423 if (NULL != pdialog->counters.widget) {
1425 }
1426
1427 if (NULL == pdialog->counters.container) {
1429 }
1430
1434
1438 counterValue = GTK_LABEL(gtk_label_new(_("Current value is: ")));
1440 fc_snprintf(int_val, sizeof(int_val), "%d", pdialog->pcity->counter_values[counter_index(pcount)]);
1444
1446 counterValue = GTK_LABEL(gtk_label_new(_("Activated once value equal or higher than: ")));
1448 fc_snprintf(int_val, sizeof(int_val), "%d", pcount->checkpoint);
1452
1453 text_size = 0;
1454 if (NULL != pcount->helptext) {
1455 strvec_iterate(pcount->helptext, text_) {
1458 }
1459 if (0 < text_size) {
1460 text = malloc(text_size+1);
1461 text_size = 0;
1462 strvec_iterate(pcount->helptext, text_) {
1463 strcpy(&text[text_size], text_);
1467 free(text);
1469 }
1472
1475}
1476
1477/**********************************************************************/
1480static void create_and_append_cma_page(struct city_dialog *pdialog)
1481{
1482 GtkWidget *page, *label;
1483 const char *tab_title = _("_Governor");
1484
1485 page = gtk_grid_new();
1486
1488
1489 gtk_notebook_append_page(GTK_NOTEBOOK(pdialog->notebook), page, label);
1490
1491 pdialog->cma_editor = create_cma_dialog(pdialog->pcity, low_citydlg);
1493
1494 gtk_widget_show(page);
1495}
1496
1497/**********************************************************************/
1501{
1502 int i;
1503 GtkWidget *vbox2, *page, *frame, *label, *button;
1505 GSList *group;
1506 const char *tab_title = _("_Settings");
1507
1508 static const char *new_citizens_output_label[] = {
1509 N_("Luxury"),
1510 N_("Science"),
1511 N_("Gold")
1512 };
1513
1514 static const char *disband_label
1515 = N_("Allow unit production to disband city");
1516
1517 static const char *misc_whichtab_label[NUM_PAGES] = {
1518 N_("Overview page"),
1519 N_("Production page"),
1520 N_("Happiness page"),
1521 N_("Governor page"),
1522 N_("This Settings page"),
1523 N_("Last active page")
1524 };
1525
1526 static bool new_citizens_label_done;
1527 static bool misc_whichtab_label_done;
1528
1529 /* initialize signal_blocker */
1530 pdialog->misc.block_signal = 0;
1531
1532
1533 page = gtk_grid_new();
1536
1538
1540
1541 gtk_notebook_append_page(GTK_NOTEBOOK(pdialog->notebook), page, label);
1542
1543 /* new_citizens radio */
1544 frame = gtk_frame_new(_("New citizens produce"));
1545 gtk_grid_attach(GTK_GRID(page), frame, 0, 0, 1, 1);
1547
1548 vbox2 = gtk_grid_new();
1552
1555
1556 group = NULL;
1557 for (i = 0; i < ARRAY_SIZE(new_citizens_output_label); i++) {
1559 pdialog->misc.new_citizens_radio[i] = button;
1561 g_signal_connect(button, "toggled",
1562 G_CALLBACK(cityopt_callback), pdialog);
1564 }
1565
1566 /* next is the next-time-open radio group in the right column */
1567 frame = gtk_frame_new(_("Next time open"));
1568 gtk_grid_attach(GTK_GRID(page), frame, 1, 0, 1, 1);
1570
1571 vbox2 = gtk_grid_new();
1575
1578
1579 group = NULL;
1580 for (i = 0; i < ARRAY_SIZE(misc_whichtab_label); i++) {
1582 pdialog->misc.whichtab_radio[i] = button;
1584 g_signal_connect(button, "toggled",
1587 }
1588
1589 /* now we go back and fill the hbox rename */
1590 frame = gtk_frame_new(_("City"));
1591 gtk_widget_set_margin_top(frame, 12);
1593 gtk_grid_attach(GTK_GRID(page), frame, 0, 1, 1, 1);
1594
1595 vbox2 = gtk_grid_new();
1599
1600 button = gtk_button_new_with_mnemonic(_("R_ename..."));
1601 pdialog->misc.rename_command = button;
1603 g_signal_connect(button, "clicked",
1604 G_CALLBACK(rename_callback), pdialog);
1605
1607
1608 /* the disband-city-on-unit-production button */
1610 pdialog->misc.disband_on_settler = button;
1612 g_signal_connect(button, "toggled",
1613 G_CALLBACK(cityopt_callback), pdialog);
1614
1615 /* we choose which page to popup by default */
1617 (pdialog->
1619 TRUE);
1620
1621 set_cityopt_values(pdialog);
1622
1623 gtk_widget_show_all(page);
1624
1625 if (new_dialog_def_page == (NUM_PAGES - 1)) {
1627 last_page);
1628 } else {
1631 }
1632}
1633
1634/**********************************************************************/
1643{
1644 struct city_dialog *pdialog;
1646 GtkWidget *vbox, *hbox, *cbox, *ebox;
1649 struct player *owner;
1650
1653 }
1654
1655 pdialog = fc_malloc(sizeof(struct city_dialog));
1656 pdialog->pcity = pcity;
1657 pdialog->sell_shell = NULL;
1658 pdialog->rename_shell = NULL;
1659 pdialog->happiness.map_canvas.sw = NULL; /* make sure NULL if spy */
1660 pdialog->happiness.map_canvas.ebox = NULL; /* ditto */
1661 pdialog->happiness.map_canvas.darea = NULL; /* ditto */
1662 pdialog->happiness.citizens = NULL; /* ditto */
1663 pdialog->production.buy_command = NULL;
1664 pdialog->production.production_label = NULL;
1665 pdialog->production.production_bar = NULL;
1666 pdialog->cma_editor = NULL;
1670
1671 pdialog->shell = gtk_dialog_new();
1674 setup_dialog(pdialog->shell, toplevel);
1675 gtk_window_set_role(GTK_WINDOW(pdialog->shell), "city");
1676
1677 g_signal_connect(pdialog->shell, "destroy",
1680 gtk_widget_set_name(pdialog->shell, "Freeciv");
1681
1682 gtk_widget_realize(pdialog->shell);
1683
1684 /* keep the icon of the executable on Windows (see PR#36491) */
1685#ifndef FREECIV_MSWINDOWS
1686 {
1688
1689 /* Only call this after tileset_load_tiles is called. */
1692 }
1693#endif /* FREECIV_MSWINDOWS */
1694
1695 /* Restore size of the city dialog. */
1699
1700 pdialog->popup_menu = gtk_menu_new();
1701
1703 hbox = gtk_grid_new();
1706
1707 /**** Citizens bar here ****/
1708 cbox = gtk_grid_new();
1710
1711 ebox = gtk_event_box_new();
1713 gtk_container_add(GTK_CONTAINER(cbox), ebox);
1714
1717
1721
1730 g_signal_connect(G_OBJECT(ebox), "button-press-event",
1731 G_CALLBACK(citizens_callback), pdialog);
1732
1733 /**** City name label here ****/
1734 pdialog->name_label = gtk_label_new(NULL);
1739
1740 /**** -Start of Notebook- ****/
1741
1742 pdialog->notebook = gtk_notebook_new();
1745 gtk_container_add(GTK_CONTAINER(vbox), pdialog->notebook);
1746
1750
1752
1753 /* Only create these tabs if not a spy */
1757 }
1758
1760
1761 if (owner == client_player()
1762 && !client_is_observer()) {
1765 } else {
1768 }
1769
1770 /**** End of Notebook ****/
1771
1772 /* bottom buttons */
1773
1774 pdialog->show_units_command =
1775 gtk_dialog_add_button(GTK_DIALOG(pdialog->shell), _("_List present units..."), CDLGR_UNITS);
1776
1777 g_signal_connect(GTK_DIALOG(pdialog->shell), "response",
1779
1780 pdialog->prev_command = gtk_button_new_from_icon_name("go-previous", 0);
1782 GTK_WIDGET(pdialog->prev_command), 1);
1783
1784 pdialog->next_command = gtk_button_new_from_icon_name("go-next", 0);
1786 GTK_WIDGET(pdialog->next_command), 2);
1787
1788 if (owner != client_player()) {
1791 }
1792
1794 _("_Close"), GTK_RESPONSE_CLOSE);
1795
1798
1800 G_CALLBACK(close_callback), pdialog);
1801
1802 g_signal_connect(pdialog->prev_command, "clicked",
1804
1805 g_signal_connect(pdialog->next_command, "clicked",
1807
1808 /* some other things we gotta do */
1809
1810 g_signal_connect(pdialog->shell, "key_press_event",
1811 G_CALLBACK(keyboard_handler), pdialog);
1812
1814
1816
1817 /* need to do this every time a new dialog is opened. */
1819
1820 gtk_widget_show_all(pdialog->shell);
1821
1823
1824 return pdialog;
1825}
1826
1827/**************** Functions to update parts of the dialog ****************/
1828/**********************************************************************/
1831static void city_dialog_update_title(struct city_dialog *pdialog)
1832{
1833 gchar *buf;
1834 const gchar *now;
1835
1836 if (city_unhappy(pdialog->pcity)) {
1837 /* TRANS: city dialog title */
1838 buf = g_strdup_printf(_("<b>%s</b> - %s citizens - DISORDER"),
1839 city_name_getx(pdialog->pcity),
1841 } else if (city_celebrating(pdialog->pcity)) {
1842 /* TRANS: city dialog title */
1843 buf = g_strdup_printf(_("<b>%s</b> - %s citizens - celebrating"),
1844 city_name_getx(pdialog->pcity),
1846 } else if (city_happy(pdialog->pcity)) {
1847 /* TRANS: city dialog title */
1848 buf = g_strdup_printf(_("<b>%s</b> - %s citizens - happy"),
1849 city_name_getx(pdialog->pcity),
1851 } else {
1852 /* TRANS: city dialog title */
1853 buf = g_strdup_printf(_("<b>%s</b> - %s citizens"),
1854 city_name_getx(pdialog->pcity),
1856 }
1857
1859 if (strcmp(now, buf) != 0) {
1862 }
1863
1864 g_free(buf);
1865}
1866
1867/**********************************************************************/
1870static void city_dialog_update_citizens(struct city_dialog *pdialog)
1871{
1872 enum citizen_category categories[MAX_CITY_SIZE];
1875 struct city *pcity = pdialog->pcity;
1877 int num_supers
1879 ARRAY_SIZE(categories) - num_citizens,
1880 &categories[num_citizens]);
1881 cairo_t *cr;
1882
1883 if (num_supers >= 0) {
1884 /* Just draw superspecialists in the common roster */
1886 } else {
1887 /* FIXME: show them in some compact way */
1888 num_citizens = ARRAY_SIZE(categories);
1889 }
1890 /* If there is not enough space we stack the icons. We draw from left to */
1891 /* right. width is how far we go to the right for each drawn pixmap. The */
1892 /* last icon is always drawn in full, and so has reserved */
1893 /* tileset_small_sprite_width(tileset) pixels. */
1894
1896 if (num_citizens > 1) {
1898 / (num_citizens - 1));
1899 } else {
1900 width = full_width;
1901 }
1902 pdialog->cwidth = width;
1903
1904 /* overview page */
1905 /* keep these values in sync with create_city_dialog */
1908
1909 cr = cairo_create(pdialog->citizen_surface);
1910
1911 for (i = 0; i < num_citizens; i++) {
1913 get_citizen_sprite(tileset, categories[i], i, pcity)->surface,
1914 i * width, 0);
1915 cairo_rectangle(cr, i * width, 0,
1916 /* Always draw last citizen in full */
1917 i + 1 < num_citizens ? width : full_width,
1919 cairo_fill(cr);
1920 }
1921
1922 total_used_width = (i - 1) * width + full_width;
1923
1925 /* Clear the rest of the area.
1926 * Note that this might still be necessary even in cases where
1927 * num_citizens > NUM_CITIZENS_SHOWN, if the available width cannot be
1928 * divided perfectly. */
1933 cairo_fill(cr);
1934 }
1935
1936 cairo_destroy(cr);
1937
1939}
1940
1941/**********************************************************************/
1946 struct city_dialog *pdialog)
1947{
1948 int i, illness = 0;
1949 char buf[NUM_INFO_FIELDS][512];
1950 struct city *pcity = pdialog->pcity;
1951 int granaryturns;
1954
1955 /* fill the buffers with the necessary info */
1956 if (supers) {
1957 fc_snprintf(buf[INFO_SIZE], sizeof(buf[INFO_SIZE]), "%3d (%3d+%d)",
1958 pcity->size, non_workers, supers);
1959 } else if (non_workers) {
1960 fc_snprintf(buf[INFO_SIZE], sizeof(buf[INFO_SIZE]), "%3d (%3d)",
1961 pcity->size, non_workers);
1962 } else {
1963 fc_snprintf(buf[INFO_SIZE], sizeof(buf[INFO_SIZE]), "%3d", pcity->size);
1964 }
1965 fc_snprintf(buf[INFO_FOOD], sizeof(buf[INFO_FOOD]), "%3d (%+4d)",
1966 pcity->prod[O_FOOD], pcity->surplus[O_FOOD]);
1967 fc_snprintf(buf[INFO_SHIELD], sizeof(buf[INFO_SHIELD]), "%3d (%+4d)",
1968 pcity->prod[O_SHIELD] + pcity->waste[O_SHIELD],
1969 pcity->surplus[O_SHIELD]);
1970 fc_snprintf(buf[INFO_TRADE], sizeof(buf[INFO_TRADE]), "%3d (%+4d)",
1971 pcity->surplus[O_TRADE] + pcity->waste[O_TRADE],
1972 pcity->surplus[O_TRADE]);
1973 fc_snprintf(buf[INFO_GOLD], sizeof(buf[INFO_GOLD]), "%3d (%+4d)",
1974 pcity->prod[O_GOLD], pcity->surplus[O_GOLD]);
1975 fc_snprintf(buf[INFO_LUXURY], sizeof(buf[INFO_LUXURY]), "%3d",
1976 pcity->prod[O_LUXURY]);
1977 fc_snprintf(buf[INFO_SCIENCE], sizeof(buf[INFO_SCIENCE]), "%3d",
1978 pcity->prod[O_SCIENCE]);
1979 fc_snprintf(buf[INFO_GRANARY], sizeof(buf[INFO_GRANARY]), "%4d/%-4d",
1981
1983 if (granaryturns == 0) {
1984 /* TRANS: city growth is blocked. Keep short. */
1985 fc_snprintf(buf[INFO_GROWTH], sizeof(buf[INFO_GROWTH]), _("blocked"));
1986 } else if (granaryturns == FC_INFINITY) {
1987 /* TRANS: city is not growing. Keep short. */
1988 fc_snprintf(buf[INFO_GROWTH], sizeof(buf[INFO_GROWTH]), _("never"));
1989 } else {
1990 /* A negative value means we'll have famine in that many turns.
1991 But that's handled down below. */
1992 /* TRANS: city growth turns. Keep short. */
1994 PL_("%d turn", "%d turns", abs(granaryturns)),
1995 abs(granaryturns));
1996 }
1998 pcity->waste[O_TRADE]);
1999 fc_snprintf(buf[INFO_WASTE], sizeof(buf[INFO_WASTE]), "%4d",
2000 pcity->waste[O_SHIELD]);
2001 fc_snprintf(buf[INFO_CULTURE], sizeof(buf[INFO_CULTURE]), "%4d",
2002 pcity->client.culture);
2004 pcity->pollution);
2005 if (!game.info.illness_on) {
2006 fc_snprintf(buf[INFO_ILLNESS], sizeof(buf[INFO_ILLNESS]), " -.-");
2007 } else {
2009 /* illness is in tenth of percent */
2010 fc_snprintf(buf[INFO_ILLNESS], sizeof(buf[INFO_ILLNESS]), "%5.1f%%",
2011 (float)illness / 10.0);
2012 }
2013 if (pcity->steal) {
2014 fc_snprintf(buf[INFO_STEAL], sizeof(buf[INFO_STEAL]), PL_("%d time", "%d times", pcity->steal),
2015 pcity->steal);
2016 } else {
2017 fc_snprintf(buf[INFO_STEAL], sizeof(buf[INFO_STEAL]), _("Not stolen"));
2018 }
2019
2021
2022 /* stick 'em in the labels */
2023 for (i = 0; i < NUM_INFO_FIELDS; i++) {
2025 }
2026
2027 /*
2028 * Make use of the emergency-indicating styles set up for certain labels
2029 * in create_city_info_table().
2030 */
2031 /* For starvation, the "4" below is arbitrary. 3 turns should be enough
2032 * of a warning. */
2033 if (granaryturns > -4 && granaryturns < 0) {
2035 } else {
2037 }
2038
2039 if (granaryturns == 0 || pcity->surplus[O_FOOD] < 0) {
2041 } else {
2043 }
2044
2045 /* someone could add the color &orange for better granularity here */
2046 if (pcity->pollution >= 10) {
2048 } else {
2050 }
2051
2052 /* illness is in tenth of percent, i.e 100 == 10.0% */
2053 if (illness >= 100) {
2055 } else {
2057 }
2058}
2059
2060/**********************************************************************/
2063static void city_dialog_update_map(struct city_dialog *pdialog)
2064{
2065 struct canvas store = FC_STATIC_CANVAS_INIT;
2066
2067 store.surface = pdialog->map_canvas_store_unscaled;
2068
2069 /* The drawing is done in three steps.
2070 * 1. First we render to a pixmap with the appropriate canvas size.
2071 * 2. Then the pixmap is rendered into a pixbuf of equal size.
2072 * 3. Finally this pixbuf is composited and scaled onto the GtkImage's
2073 * target pixbuf.
2074 */
2075
2076 city_dialog_redraw_map(pdialog->pcity, &store);
2077
2078 /* draw to real window */
2079 draw_map_canvas(pdialog);
2080}
2081
2082/**********************************************************************/
2085static void city_dialog_update_building(struct city_dialog *pdialog)
2086{
2087 char buf[32], buf2[200];
2088 gdouble pct;
2089
2090 GtkListStore* store;
2092 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
2093 struct item items[MAX_NUM_PRODUCTION_TARGETS];
2094 int targets_used, item;
2095 struct city *pcity = pdialog->pcity;
2097 const char *descr = city_production_name_translation(pcity);
2099
2100 if (pdialog->overview.buy_command != NULL) {
2102 }
2103 if (pdialog->production.buy_command != NULL) {
2105 }
2106
2107 /* Make sure build slots info is up to date */
2108 if (pdialog->production.production_label != NULL) {
2110
2111 /* Only display extra info if more than one slot is available */
2112 if (build_slots > 1) {
2113 fc_snprintf(buf2, sizeof(buf2),
2114 /* TRANS: never actually used with built_slots <= 1 */
2115 PL_("Production (up to %d unit per turn):",
2116 "Production (up to %d units per turn):", build_slots),
2117 build_slots);
2120 } else {
2122 GTK_LABEL(pdialog->production.production_label), _("Production:"));
2123 }
2124 }
2125
2126 /* Update what the city is working on */
2128
2129 if (cost > 0) {
2130 pct = (gdouble) pcity->shield_stock / (gdouble) cost;
2131 pct = CLAMP(pct, 0.0, 1.0);
2132 } else {
2133 pct = 1.0;
2134 }
2135
2136 if (pdialog->overview.production_bar != NULL) {
2137 fc_snprintf(buf2, sizeof(buf2), "%s%s\n%s", descr,
2138 worklist_is_empty(&pcity->worklist) ? "" : " (+)", buf);
2143 }
2144
2145 if (pdialog->production.production_bar != NULL) {
2146 fc_snprintf(buf2, sizeof(buf2), "%s%s: %s", descr,
2147 worklist_is_empty(&pcity->worklist) ? "" : " (+)", buf);
2152 }
2153
2154 if (pdialog->overview.production_combo != NULL) {
2156 -1);
2157 }
2158
2159 store = pdialog->overview.change_production_store;
2160 if (store != NULL) {
2162
2164 = collect_eventually_buildable_targets(targets, pdialog->pcity, FALSE);
2165 name_and_sort_items(targets, targets_used, items, FALSE, pcity);
2166
2167 for (item = 0; item < targets_used; item++) {
2168 if (can_city_build_now(&(wld.map), pcity, &items[item].item,
2169 RPT_CERTAIN)) {
2170 const char *name;
2171 struct sprite* sprite;
2172 GdkPixbuf *pix;
2173 struct universal target = items[item].item;
2174 bool useless;
2175
2176 if (VUT_UTYPE == target.kind) {
2181 useless = FALSE;
2182 } else {
2185 useless = is_improvement_redundant(pcity, target.value.building);
2186 }
2188 gtk_list_store_append(store, &iter);
2189 gtk_list_store_set(store, &iter, 0, pix,
2190 1, name, 3, useless,
2191 2, (gint)cid_encode(items[item].item), -1);
2193 }
2194 }
2195 }
2196
2197 /* work around GTK+ refresh bug. */
2198 if (pdialog->overview.production_bar != NULL) {
2200 }
2201 if (pdialog->production.production_bar != NULL) {
2203 }
2204}
2205
2206/**********************************************************************/
2210{
2211 int item, targets_used;
2212 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
2213 struct item items[MAX_NUM_PRODUCTION_TARGETS];
2214 GtkTreeModel *model;
2215 GtkListStore *store;
2216
2217 const char *tooltip_sellable = _("Press <b>ENTER</b> or double-click to "
2218 "sell an improvement.");
2219 const char *tooltip_great_wonder = _("Great Wonder - cannot be sold.");
2220 const char *tooltip_small_wonder = _("Small Wonder - cannot be sold.");
2221
2222 model =
2224 store = GTK_LIST_STORE(model);
2225
2227 name_and_sort_items(targets, targets_used, items, FALSE, pdialog->pcity);
2228
2229 gtk_list_store_clear(store);
2230
2231 for (item = 0; item < targets_used; item++) {
2232 GdkPixbuf *pix;
2233 GtkTreeIter it;
2234 int upkeep;
2235 struct sprite *sprite;
2236 struct universal target = items[item].item;
2237
2238 fc_assert_action(VUT_IMPROVEMENT == target.kind, continue);
2239 /* This takes effects (like Adam Smith's) into account. */
2240 upkeep = city_improvement_upkeep(pdialog->pcity, target.value.building);
2242
2244 gtk_list_store_append(store, &it);
2245 gtk_list_store_set(store, &it,
2246 0, target.value.building,
2247 1, pix,
2248 2, items[item].descr,
2249 3, upkeep,
2250 4,
2252 target.value.building),
2253 5,
2256 (is_small_wonder(target.value.building) ?
2258 -1);
2260 }
2261}
2262
2263/**********************************************************************/
2267{
2268 struct unit_list *units;
2269 struct unit_node_vector *nodes;
2270 int n, m, i;
2271 gchar *buf;
2273 const struct civ_map *nmap = &(wld.map);
2274
2275 if (NULL != client.conn.playing
2276 && city_owner(pdialog->pcity) != client.conn.playing) {
2277 units = pdialog->pcity->client.info_units_supported;
2278 } else {
2279 units = pdialog->pcity->units_supported;
2280 }
2281
2282 nodes = &pdialog->overview.supported_units;
2283
2284 n = unit_list_size(units);
2285 m = unit_node_vector_size(nodes);
2286
2287 if (m > n) {
2288 i = 0;
2290 if (i++ >= n) {
2291 gtk_widget_destroy(elt->cmd);
2292 }
2294
2296 } else {
2297 for (i = m; i < n; i++) {
2298 GtkWidget *cmd, *pix;
2299 struct unit_node node;
2300
2301 cmd = gtk_button_new();
2302 node.cmd = cmd;
2303
2307
2308 pix = gtk_image_new();
2309 node.pix = pix;
2311
2313
2315 cmd, i, 0, 1, 1);
2316 unit_node_vector_append(nodes, node);
2317 }
2318 }
2319
2320 i = 0;
2321 unit_list_iterate(units, punit) {
2322 struct unit_node *pnode;
2323 int happy_cost = city_unit_unhappiness(nmap, punit, &free_unhappy);
2324
2325 pnode = unit_node_vector_get(nodes, i);
2326 if (pnode) {
2327 GtkWidget *cmd, *pix;
2328
2329 cmd = pnode->cmd;
2330 pix = pnode->pix;
2331
2333 punit->upkeep, happy_cost);
2334
2338
2342
2344
2345 g_signal_connect(cmd, "button_press_event",
2348
2349 g_signal_connect(cmd, "button_release_event",
2352
2353 if (city_owner(pdialog->pcity) != client.conn.playing) {
2355 } else {
2357 }
2358
2361 }
2362 i++;
2364
2365 buf = g_strdup_printf(_("Supported units %d"), n);
2367 g_free(buf);
2368}
2369
2370/**********************************************************************/
2374{
2375 struct unit_list *units;
2376 struct unit_node_vector *nodes;
2377 int n, m, i;
2378 gchar *buf;
2379
2380 if (NULL != client.conn.playing
2381 && city_owner(pdialog->pcity) != client.conn.playing) {
2382 units = pdialog->pcity->client.info_units_present;
2383 } else {
2384 units = pdialog->pcity->tile->units;
2385 }
2386
2387 nodes = &pdialog->overview.present_units;
2388
2389 n = unit_list_size(units);
2390 m = unit_node_vector_size(nodes);
2391
2392 if (m > n) {
2393 i = 0;
2395 if (i++ >= n) {
2396 gtk_widget_destroy(elt->cmd);
2397 }
2399
2401 } else {
2402 for (i = m; i < n; i++) {
2403 GtkWidget *cmd, *pix;
2404 struct unit_node node;
2405
2406 cmd = gtk_button_new();
2407 node.cmd = cmd;
2408
2412
2413 pix = gtk_image_new();
2414 node.pix = pix;
2416
2418
2420 cmd, i, 0, 1, 1);
2421 unit_node_vector_append(nodes, node);
2422 }
2423 }
2424
2425 i = 0;
2426 unit_list_iterate(units, punit) {
2427 struct unit_node *pnode;
2428
2429 pnode = unit_node_vector_get(nodes, i);
2430 if (pnode) {
2431 GtkWidget *cmd, *pix;
2432
2433 cmd = pnode->cmd;
2434 pix = pnode->pix;
2435
2437
2441
2445
2447
2448 g_signal_connect(cmd, "button_press_event",
2451
2452 g_signal_connect(cmd, "button_release_event",
2455
2456 if (city_owner(pdialog->pcity) != client.conn.playing) {
2458 } else {
2460 }
2461
2464 }
2465 i++;
2467
2468 buf = g_strdup_printf(_("Present units %d"), n);
2470 g_free(buf);
2471}
2472
2473/**********************************************************************/
2481{
2482 int count = 0;
2483 int city_number;
2484
2485 if (NULL != client.conn.playing) {
2487 } else {
2488 city_number = FC_INFINITY; /* ? */
2489 }
2490
2491 /* the first time, we see if all the city dialogs are open */
2492
2494 if (city_owner(pdialog->pcity) == client.conn.playing)
2495 count++;
2496 }
2498
2499 if (count == city_number) { /* all are open, shouldn't prev/next */
2501 gtk_widget_set_sensitive(GTK_WIDGET(pdialog->prev_command), FALSE);
2502 gtk_widget_set_sensitive(GTK_WIDGET(pdialog->next_command), FALSE);
2503 }
2505 } else {
2507 if (city_owner(pdialog->pcity) == client.conn.playing) {
2508 gtk_widget_set_sensitive(GTK_WIDGET(pdialog->prev_command), TRUE);
2509 gtk_widget_set_sensitive(GTK_WIDGET(pdialog->next_command), TRUE);
2510 }
2511 }
2513 }
2514}
2515
2516/**********************************************************************/
2519static void citydlg_response_callback(GtkDialog *dlg, gint response,
2520 void *data)
2521{
2522 switch (response) {
2523 case CDLGR_UNITS:
2524 show_units_response(data);
2525 break;
2526 }
2527}
2528
2529/**********************************************************************/
2532static void show_units_response(void *data)
2533{
2534 struct city_dialog *pdialog = (struct city_dialog *) data;
2535 struct tile *ptile = pdialog->pcity->tile;
2536
2537 if (unit_list_size(ptile->units)) {
2539 }
2540}
2541
2542/**********************************************************************/
2545static void destroy_func(GtkWidget *w, gpointer data)
2546{
2548}
2549
2550/**********************************************************************/
2554 gpointer data)
2555{
2556 GtkWidget *menu, *item;
2557 struct city_dialog *pdialog;
2558 struct city *pcity;
2559 struct unit *punit =
2560 player_unit_by_number(client_player(), (size_t) data);
2561
2562 if (NULL != punit
2564 && NULL != (pdialog = get_city_dialog(pcity))) {
2565
2566 if (ev->type != GDK_BUTTON_PRESS || ev->button == 2 || ev->button == 3
2568 return FALSE;
2569 }
2570
2571 menu = pdialog->popup_menu;
2572
2575
2577 g_signal_connect(item, "activate",
2581
2582 item = gtk_menu_item_new_with_mnemonic(_("_Activate unit"));
2583 g_signal_connect(item, "activate",
2587
2588 item = gtk_menu_item_new_with_mnemonic(_("Activate unit, _close dialog"));
2589 g_signal_connect(item, "activate",
2593
2594 item = gtk_menu_item_new_with_mnemonic(_("_Disband unit"));
2595 g_signal_connect(item, "activate",
2599
2602 }
2603
2604 gtk_widget_show_all(menu);
2605
2607 }
2608
2609 return TRUE;
2610}
2611
2612/**********************************************************************/
2616 gpointer data)
2617{
2618 GtkWidget *menu, *item;
2619 struct city_dialog *pdialog;
2620 struct city *pcity;
2621 struct unit *punit =
2622 player_unit_by_number(client_player(), (size_t) data);
2623
2624 if (NULL != punit
2625 && NULL != (pcity = tile_city(unit_tile(punit)))
2626 && NULL != (pdialog = get_city_dialog(pcity))) {
2627
2628 if (ev->type != GDK_BUTTON_PRESS || ev->button == 2 || ev->button == 3
2630 return FALSE;
2631 }
2632
2633 menu = pdialog->popup_menu;
2634
2637
2638 item = gtk_menu_item_new_with_mnemonic(_("_Activate unit"));
2639 g_signal_connect(item, "activate",
2643
2644 item = gtk_menu_item_new_with_mnemonic(_("Activate unit, _close dialog"));
2645 g_signal_connect(item, "activate",
2649
2650 item = gtk_menu_item_new_with_mnemonic(_("_Load unit"));
2651 g_signal_connect(item, "activate",
2655
2656 if (!unit_can_load(punit)) {
2658 }
2659
2660 item = gtk_menu_item_new_with_mnemonic(_("_Unload unit"));
2661 g_signal_connect(item, "activate",
2665
2669 }
2670
2671 item = gtk_menu_item_new_with_mnemonic(_("_Sentry unit"));
2672 g_signal_connect(item, "activate",
2676
2680 }
2681
2682 item = gtk_menu_item_new_with_mnemonic(_("_Fortify unit"));
2683 g_signal_connect(item, "activate",
2687
2691 }
2692
2693 item = gtk_menu_item_new_with_mnemonic(_("_Disband unit"));
2694 g_signal_connect(item, "activate",
2698
2701 }
2702
2705 g_signal_connect(item, "activate",
2710 punit, pcity));
2711
2712 item = gtk_menu_item_new_with_mnemonic(_("U_pgrade unit"));
2714 g_signal_connect(item, "activate",
2718
2721 unit_type_get(punit))) {
2723 }
2724
2725 gtk_widget_show_all(menu);
2726
2728 }
2729
2730 return TRUE;
2731}
2732
2733/**********************************************************************/
2738 gpointer data)
2739{
2740 struct city_dialog *pdialog;
2741 struct city *pcity;
2742 struct unit *punit =
2743 player_unit_by_number(client_player(), (size_t) data);
2744
2745 if (NULL != punit
2746 && NULL != (pcity = tile_city(unit_tile(punit)))
2747 && NULL != (pdialog = get_city_dialog(pcity))
2749
2750 if (ev->button == 3) {
2752 } else if (ev->button == 2) {
2754 close_city_dialog(pdialog);
2755 }
2756 }
2757
2758 return TRUE;
2759}
2760
2761/**********************************************************************/
2766 gpointer data)
2767{
2768 struct city_dialog *pdialog;
2769 struct city *pcity;
2770 struct unit *punit =
2771 player_unit_by_number(client_player(), (size_t) data);
2772
2773 if (NULL != punit
2775 && NULL != (pdialog = get_city_dialog(pcity))
2777
2778 if (ev->button == 3) {
2780 } else if (ev->button == 2) {
2782 close_city_dialog(pdialog);
2783 }
2784 }
2785
2786 return TRUE;
2787}
2788
2789/**********************************************************************/
2793{
2794 struct unit *punit =
2795 player_unit_by_number(client_player(), (size_t)data);
2796
2797 if (NULL != punit) {
2799 }
2800}
2801
2802/**********************************************************************/
2806{
2807 struct unit *punit =
2808 player_unit_by_number(client_player(), (size_t)data);
2809
2810 if (NULL != punit) {
2812 }
2813}
2814
2815/**********************************************************************/
2820 gpointer data)
2821{
2822 struct unit *punit =
2823 player_unit_by_number(client_player(), (size_t)data);
2824
2825 if (NULL != punit) {
2826 struct city *pcity =
2828
2830 if (NULL != pcity) {
2831 struct city_dialog *pdialog = get_city_dialog(pcity);
2832
2833 if (NULL != pdialog) {
2834 close_city_dialog(pdialog);
2835 }
2836 }
2837 }
2838}
2839
2840/**********************************************************************/
2845 gpointer data)
2846{
2847 struct unit *punit =
2848 player_unit_by_number(client_player(), (size_t)data);
2849
2850 if (NULL != punit) {
2851 struct city *pcity = tile_city(unit_tile(punit));
2852
2854 if (NULL != pcity) {
2855 struct city_dialog *pdialog = get_city_dialog(pcity);
2856
2857 if (NULL != pdialog) {
2858 close_city_dialog(pdialog);
2859 }
2860 }
2861 }
2862}
2863
2864/**********************************************************************/
2868{
2869 struct unit *punit =
2870 player_unit_by_number(client_player(), (size_t)data);
2871
2872 if (NULL != punit) {
2874 }
2875}
2876
2877/**********************************************************************/
2881{
2882 struct unit *punit =
2883 player_unit_by_number(client_player(), (size_t)data);
2884
2885 if (NULL != punit) {
2887 }
2888}
2889
2890/**********************************************************************/
2894{
2895 struct unit *punit =
2896 player_unit_by_number(client_player(), (size_t)data);
2897
2898 if (NULL != punit) {
2900 }
2901}
2902
2903/**********************************************************************/
2907{
2908 struct unit *punit =
2909 player_unit_by_number(client_player(), (size_t)data);
2910
2911 if (NULL != punit) {
2913 }
2914}
2915
2916/**********************************************************************/
2920{
2921 struct unit_list *punits;
2922 struct unit *punit =
2923 player_unit_by_number(client_player(), (size_t)data);
2924
2925 if (NULL == punit) {
2926 return;
2927 }
2928
2933}
2934
2935/**********************************************************************/
2940{
2941 struct unit *punit =
2942 player_unit_by_number(client_player(), (size_t)data);
2943
2944 if (NULL != punit) {
2946 }
2947}
2948
2949/**********************************************************************/
2953{
2954 struct unit_list *punits;
2955 struct unit *punit =
2956 player_unit_by_number(client_player(), (size_t)data);
2957
2958 if (NULL == punit) {
2959 return;
2960 }
2961
2966}
2967
2968/******** Callbacks for citizen bar, map funcs that are not update *******/
2969/**********************************************************************/
2974 gpointer data)
2975{
2976 struct city_dialog *pdialog = data;
2977 struct city *pcity = pdialog->pcity;
2978 int citnum, tlen, len;
2979
2980 if (!can_client_issue_orders()) {
2981 return FALSE;
2982 }
2983
2985 len = (city_size_get(pcity) - 1) * pdialog->cwidth + tlen;
2986 if (ev->x > len) {
2987 /* no citizen that far to the right */
2988 return FALSE;
2989 }
2990 citnum = MIN(city_size_get(pcity) - 1, ev->x / pdialog->cwidth);
2991
2993
2994 return TRUE;
2995}
2996
2997/**********************************************************************/
3001{
3002 enum unit_activity act = (enum unit_activity)GPOINTER_TO_INT(data);
3003 struct city *pcity = workertask_req.owner;
3004 struct tile *ptile = workertask_req.loc;
3005 struct packet_worker_task task;
3006
3007 task.city_id = pcity->id;
3008
3009 if (act == ACTIVITY_LAST) {
3010 task.tgt = -1;
3011 task.want = 0;
3012 } else {
3013 enum extra_cause cause = activity_to_extra_cause(act);
3015 struct extra_type *tgt;
3016
3017 if (cause != EC_NONE) {
3018 tgt = next_extra_for_tile(ptile, cause, city_owner(pcity), NULL);
3019 } else if (rmcause != ERM_NONE) {
3021 } else {
3022 tgt = NULL;
3023 }
3024
3025 if (tgt == NULL) {
3026 struct terrain *pterr = tile_terrain(ptile);
3027
3028 if ((act != ACTIVITY_TRANSFORM
3029 || pterr->transform_result == NULL || pterr->transform_result == pterr)
3030 && (act != ACTIVITY_CULTIVATE || pterr->cultivate_result == NULL)
3031 && (act != ACTIVITY_PLANT || pterr->plant_result == NULL)) {
3032 /* No extra to order */
3033 output_window_append(ftc_client, _("There's no suitable extra to order."));
3034
3035 return;
3036 }
3037
3038 task.tgt = -1;
3039 } else {
3040 task.tgt = extra_index(tgt);
3041 }
3042
3043 task.want = 100;
3044 }
3045
3046 task.tile_id = ptile->index;
3047 task.activity = act;
3048
3050}
3051
3052/**********************************************************************/
3059
3060/**********************************************************************/
3063static void popup_workertask_dlg(struct city *pcity, struct tile *ptile)
3064{
3066 GtkWidget *shl;
3067 struct terrain *pterr = tile_terrain(ptile);
3068 struct universal for_terr = { .kind = VUT_TERRAIN,
3069 .value = { .terrain = pterr }};
3070 struct worker_task *ptask;
3071
3073 workertask_req.owner = pcity;
3074 workertask_req.loc = ptile;
3075
3077 _("What Action to Request"),
3078 _("Select autoworker activity:"));
3079
3080 ptask = worker_task_list_get(pcity->task_reqs, 0);
3081 if (ptask != NULL) {
3082 choice_dialog_add(shl, _("Clear request"),
3085 }
3086
3088 choice_dialog_add(shl, Q_("?act:Mine"),
3091 }
3092 if (pterr->plant_result != NULL
3094 NULL, &for_terr)) {
3095 choice_dialog_add(shl, _("Plant"),
3098 }
3100 choice_dialog_add(shl, _("Irrigate"),
3103 }
3104 if (pterr->cultivate_result != NULL
3106 NULL, &for_terr)) {
3107 choice_dialog_add(shl, _("Cultivate"),
3110 }
3112 choice_dialog_add(shl, _("Road"),
3115 }
3116 if (pterr->transform_result != pterr && pterr->transform_result != NULL
3118 NULL, &for_terr)) {
3119 choice_dialog_add(shl, _("Transform"),
3122 }
3124 city_owner(pcity), NULL) != NULL) {
3125 choice_dialog_add(shl, _("Clean"),
3128 }
3129
3130 choice_dialog_add(shl, _("_Cancel"), 0, 0, FALSE, NULL);
3132
3134 NULL);
3135 }
3136}
3137
3138/**********************************************************************/
3142 gpointer data)
3143{
3144 struct city_dialog *pdialog = data;
3146
3147 if (!can_client_issue_orders()) {
3148 return FALSE;
3149 }
3150
3151 if (ev->button == 1 && cma_is_city_under_agent(pdialog->pcity, NULL)) {
3152 return FALSE;
3153 }
3154
3155 canvas_x = ev->x * (double)canvas_width / (double)CITYMAP_WIDTH;
3156 canvas_y = ev->y * (double)canvas_height / (double)CITYMAP_HEIGHT;
3157
3159 city_map_radius_sq_get(pdialog->pcity),
3160 canvas_x, canvas_y)) {
3161 if (ev->button == 1) {
3163 } else if (ev->button == 3) {
3164 struct city *pcity = pdialog->pcity;
3165
3166 popup_workertask_dlg(pdialog->pcity,
3169 city_x, city_y));
3170 }
3171 }
3172
3173 return TRUE;
3174}
3175
3176/**********************************************************************/
3179static void draw_map_canvas(struct city_dialog *pdialog)
3180{
3182 if (pdialog->happiness.map_canvas.darea) { /* in case of spy */
3184 }
3185}
3186
3187/************** Callbacks for Buy, Change, Sell, Worklist ****************/
3188/**********************************************************************/
3191static void buy_callback_response(GtkWidget *w, gint response, gpointer data)
3192{
3193 struct city_dialog *pdialog = data;
3194
3195 if (response == GTK_RESPONSE_YES) {
3196 city_buy_production(pdialog->pcity);
3197 }
3199}
3200
3201/**********************************************************************/
3204static void buy_callback(GtkWidget *w, gpointer data)
3205{
3207 struct city_dialog *pdialog = data;
3208 const char *name = city_production_name_translation(pdialog->pcity);
3209 int value = pdialog->pcity->client.buy_cost;
3210 char buf[1024];
3211
3212 if (!can_client_issue_orders()) {
3213 return;
3214 }
3215
3216 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Treasury contains %d gold.",
3217 "Treasury contains %d gold.",
3218 client_player()->economic.gold),
3219 client_player()->economic.gold);
3220
3221 if (value <= client_player()->economic.gold) {
3225 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
3226 PL_("Buy %s for %d gold?\n%s",
3227 "Buy %s for %d gold?\n%s", value),
3228 name, value, buf);
3229 setup_dialog(shell, pdialog->shell);
3230 gtk_window_set_title(GTK_WINDOW(shell), _("Buy It!"));
3233 pdialog);
3235 } else {
3239 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
3240 PL_("%s costs %d gold.\n%s",
3241 "%s costs %d gold.\n%s", value),
3242 name, value, buf);
3243 setup_dialog(shell, pdialog->shell);
3244 gtk_window_set_title(GTK_WINDOW(shell), _("Buy It!"));
3246 NULL);
3248 }
3249}
3250
3251/**********************************************************************/
3255 struct city_dialog *pdialog)
3256{
3258
3260 && gtk_combo_box_get_active_iter(combo, &iter)) {
3261 cid id;
3262 struct universal univ;
3263
3264 gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter, 2, &id, -1);
3265 univ = cid_production(id);
3266 city_change_production(pdialog->pcity, &univ);
3267 }
3268}
3269
3270/**********************************************************************/
3273static void sell_callback(struct impr_type *pimprove, gpointer data)
3274{
3275 GtkWidget *shl;
3276 struct city_dialog *pdialog = (struct city_dialog *) data;
3277 pdialog->sell_id = improvement_number(pimprove);
3278 int price;
3279
3280 if (!can_client_issue_orders()) {
3281 return;
3282 }
3283
3285 pimprove) != TR_SUCCESS) {
3286 return;
3287 }
3288
3289 price = impr_sell_gold(pimprove);
3294 PL_("Sell %s for %d gold?",
3295 "Sell %s for %d gold?", price),
3296 city_improvement_name_translation(pdialog->pcity, pimprove), price);
3297 setup_dialog(shl, pdialog->shell);
3298 pdialog->sell_shell = shl;
3299
3300 gtk_window_set_title(GTK_WINDOW(shl), _("Sell It!"));
3302
3303 g_signal_connect(shl, "response",
3305
3307}
3308
3309/**********************************************************************/
3312static void sell_callback_response(GtkWidget *w, gint response, gpointer data)
3313{
3314 struct city_dialog *pdialog = data;
3315
3316 if (response == GTK_RESPONSE_YES) {
3317 city_sell_improvement(pdialog->pcity, pdialog->sell_id);
3318 }
3320
3321 pdialog->sell_shell = NULL;
3322}
3323
3324/**********************************************************************/
3329{
3330 GtkTreeModel *model;
3331 GtkTreeIter it;
3332 GdkWindow *win;
3333 GdkSeat *seat;
3335 struct impr_type *pimprove;
3336
3338
3339 if (!gtk_tree_model_get_iter(model, &it, path)) {
3340 return;
3341 }
3342
3343 gtk_tree_model_get(model, &it, 0, &pimprove, -1);
3344
3347
3349 NULL, NULL, &mask);
3350
3351 if (!(mask & GDK_CONTROL_MASK)) {
3352 sell_callback(pimprove, data);
3353 } else {
3354 if (is_great_wonder(pimprove)) {
3356 } else {
3358 }
3359 }
3360}
3361
3362/************ Callbacks for stuff on the Misc. Settings page *************/
3363/**********************************************************************/
3367{
3368 struct city_dialog *pdialog;
3369
3370 pdialog = (struct city_dialog *) data;
3371
3372 pdialog->rename_shell = input_dialog_create(GTK_WINDOW(pdialog->shell),
3373 /* "shellrenamecity" */
3374 _("Rename City"),
3375 _("What should we rename the city to?"),
3376 city_name_get(pdialog->pcity),
3377 rename_popup_callback, pdialog);
3378}
3379
3380/**********************************************************************/
3383static void rename_popup_callback(gpointer data, gint response,
3384 const char *input)
3385{
3386 struct city_dialog *pdialog = data;
3387
3388 if (pdialog) {
3389 if (response == GTK_RESPONSE_OK) {
3390 city_rename(pdialog->pcity, input);
3391 } /* else CANCEL or DELETE_EVENT */
3392
3393 pdialog->rename_shell = NULL;
3394 }
3395}
3396
3397/**********************************************************************/
3401{
3403}
3404
3405/**********************************************************************/
3409{
3410 struct city_dialog *pdialog = (struct city_dialog *) data;
3411
3412 if (!can_client_issue_orders()) {
3413 return;
3414 }
3415
3416 if (!pdialog->misc.block_signal) {
3417 struct city *pcity = pdialog->pcity;
3419
3420 fc_assert(CITYO_LAST == 3);
3421
3425 }
3428 }
3431 }
3432
3434 pcity->wlcb);
3435 }
3436}
3437
3438/**********************************************************************/
3463
3464/******************** Callbacks for: Close, Prev, Next. ******************/
3465/**********************************************************************/
3468static void close_callback(GtkWidget *w, gpointer data)
3469{
3470 close_city_dialog((struct city_dialog *) data);
3471}
3472
3473/**********************************************************************/
3477{
3478 struct city_dialog *pdialog;
3479 int width, height;
3481
3482 pdialog = (struct city_dialog *) data;
3483
3487
3488 gtk_widget_hide(pdialog->shell);
3489
3491 citizens_dialog_close(pdialog->pcity);
3492 }
3493 close_happiness_dialog(pdialog->pcity);
3494 close_cma_dialog(pdialog->pcity);
3495
3496 /* Save size of the city dialog. */
3499 width,
3503 height,
3505
3506 last_page
3508
3509 if (pdialog->popup_menu) {
3511 }
3512
3514
3517
3518 if (pdialog->sell_shell) {
3520 }
3521 if (pdialog->rename_shell) {
3523 }
3524
3527
3528 free(pdialog);
3529
3530 /* need to do this every time a new dialog is closed. */
3532}
3533
3534/**********************************************************************/
3537static void close_city_dialog(struct city_dialog *pdialog)
3538{
3539 gtk_widget_destroy(pdialog->shell);
3540}
3541
3542/**********************************************************************/
3547{
3548 struct city_dialog *pdialog = (struct city_dialog *) data;
3549 int i, j, dir, size;
3550 struct city *new_pcity = NULL;
3551
3553 return;
3554 }
3555
3557
3559 fc_assert_ret(size >= 1);
3561
3562 if (size == 1) {
3563 return;
3564 }
3565
3566 /* dir = 1 will advance to the city, dir = -1 will get previous */
3567 if (w == GTK_WIDGET(pdialog->next_command)) {
3568 dir = 1;
3569 } else if (w == GTK_WIDGET(pdialog->prev_command)) {
3570 dir = -1;
3571 } else {
3572 /* Always fails. */
3574 || w == GTK_WIDGET(pdialog->prev_command));
3575 dir = 1;
3576 }
3577
3578 for (i = 0; i < size; i++) {
3579 if (pdialog->pcity == city_list_get(client.conn.playing->cities, i)) {
3580 break;
3581 }
3582 }
3583
3584 fc_assert_ret(i < size);
3585
3586 for (j = 1; j < size; j++) {
3588 (i + dir * j + size) % size);
3590
3591 fc_assert_ret(other_pdialog != pdialog);
3592 if (!other_pdialog) {
3594 break;
3595 }
3596 }
3597
3598 if (!new_pcity) {
3599 /* Every other city has an open city dialog. */
3600 return;
3601 }
3602
3603 /* cleanup happiness dialog */
3605 citizens_dialog_close(pdialog->pcity);
3606 }
3607 close_happiness_dialog(pdialog->pcity);
3608
3609 pdialog->pcity = new_pcity;
3610
3611 /* reinitialize happiness, and cma dialogs */
3614 citizens_dialog_display(pdialog->pcity));
3615 }
3617 get_top_happiness_display(pdialog->pcity, low_citydlg, pdialog->shell));
3618 if (!client_is_observer()) {
3619 fc_assert(pdialog->cma_editor != NULL);
3620 pdialog->cma_editor->pcity = new_pcity;
3621 }
3622
3623 reset_city_worklist(pdialog->production.worklist, pdialog->pcity);
3624
3625 can_slide = FALSE;
3626 center_tile_mapcanvas(pdialog->pcity->tile);
3627 can_slide = TRUE;
3628 if (!client_is_observer()) {
3629 set_cityopt_values(pdialog); /* need not be in real_city_dialog_refresh */
3630 }
3631
3633
3634 /* recenter the city map(s) */
3636 if (pdialog->happiness.map_canvas.sw) {
3638 }
3639}
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1271
bool action_ever_possible(action_id action)
Definition actions.c:7500
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:740
#define n
Definition astring.c:77
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
#define BV_SET(bv, bit)
Definition bitvector.h:89
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int canvas_y
Definition canvas_g.h:43
struct canvas int canvas_x
Definition canvas_g.h:43
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
void output_window_append(const struct ft_color color, const char *featured_text)
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:666
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:740
const char * city_name_getx(const struct city *pcity)
Definition city.c:1166
int city_granary_size(int city_size)
Definition city.c:2189
int city_build_slots(const struct city *pcity)
Definition city.c:2990
struct tile * city_map_to_tile(const struct civ_map *nmap, const struct tile *city_center, int city_radius_sq, int city_map_x, int city_map_y)
Definition city.c:305
int city_superspecialists(const struct city *pcity)
Definition city.c:3416
const char * city_name_get(const struct city *pcity)
Definition city.c:1157
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Definition city.c:1312
bool is_city_option_set(const struct city *pcity, enum city_options option)
Definition city.c:3486
int city_population(const struct city *pcity)
Definition city.c:1247
int city_unit_unhappiness(const struct civ_map *nmap, struct unit *punit, int *free_unhappy)
Definition city.c:3107
bool city_unhappy(const struct city *pcity)
Definition city.c:1683
bool city_celebrating(const struct city *pcity)
Definition city.c:1702
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2928
bool city_happy(const struct city *pcity)
Definition city.c:1671
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
bool can_city_build_now(const struct civ_map *nmap, const struct city *pcity, const struct universal *target, const enum req_problem_type prob_type)
Definition city.c:1028
citizens city_specialists(const struct city *pcity)
Definition city.c:3401
int city_turns_to_grow(const struct city *pcity)
Definition city.c:2053
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:703
static citizens city_size_get(const struct city *pcity)
Definition city.h:570
citizen_category
Definition city.h:265
#define city_owner(_pcity_)
Definition city.h:564
#define MAX_CITY_SIZE
Definition city.h:104
@ FEELING_FINAL
Definition city.h:282
void get_city_dialog_output_text(const struct city *pcity, Output_type_id otype, char *buf, size_t bufsz)
void get_city_dialog_production(struct city *pcity, char *buffer, size_t buffer_len)
int city_rename(struct city *pcity, const char *name)
int get_city_citizen_types(struct city *pcity, enum citizen_feeling idx, enum citizen_category *categories)
int city_buy_production(struct city *pcity)
int city_toggle_worker(struct city *pcity, int city_x, int city_y)
void get_city_dialog_airlift_text(const struct city *pcity, char *buf, size_t bufsz)
int city_change_production(struct city *pcity, struct universal *target)
void city_rotate_specialist(struct city *pcity, int citizen_index)
int get_citydlg_canvas_width(void)
bool canvas_to_city_pos(int *city_x, int *city_y, int city_radius_sq, int canvas_x, int canvas_y)
int city_try_fill_superspecialists(struct city *pcity, int cat_len, enum citizen_category *categories)
void get_city_dialog_airlift_value(const struct city *pcity, char *buf, size_t bufsz)
void city_dialog_redraw_map(struct city *pcity, struct canvas *pcanvas)
int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
void get_city_dialog_pollution_text(const struct city *pcity, char *buf, size_t bufsz)
void get_city_dialog_culture_text(const struct city *pcity, char *buf, size_t bufsz)
bool city_can_buy(const struct city *pcity)
int get_citydlg_canvas_height(void)
void get_city_dialog_illness_text(const struct city *pcity, char *buf, size_t bufsz)
void city_report_dialog_update_city(struct city *pcity)
bool client_is_global_observer(void)
bool client_is_observer(void)
struct civclient client
bool can_client_issue_orders(void)
bool client_has_player(void)
#define client_player()
int collect_eventually_buildable_targets(struct universal *targets, struct city *pcity, bool advanced_tech)
Definition climisc.c:821
void name_and_sort_items(struct universal *targets, int num_targets, struct item *items, bool show_cost, struct city *pcity)
Definition climisc.c:650
cid cid_encode(struct universal target)
Definition climisc.c:483
int collect_already_built_targets(struct universal *targets, struct city *pcity)
Definition climisc.c:918
#define MAX_NUM_PRODUCTION_TARGETS
Definition climisc.h:89
#define cid_production
Definition climisc.h:71
int cid
Definition climisc.h:31
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:552
char * incite_cost
Definition comments.c:77
void request_unit_fortify(struct unit *punit)
Definition control.c:2365
void unit_focus_set(struct unit *punit)
Definition control.c:518
void request_unit_change_homecity(struct unit *punit)
Definition control.c:2106
void request_unit_unload(struct unit *pcargo)
Definition control.c:2206
void request_unit_sentry(struct unit *punit)
Definition control.c:2354
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:41
int counter_index(const struct counter *pcount)
Definition counters.c:176
#define city_counters_iterate_end
Definition counters.h:64
#define city_counters_iterate(pcount)
Definition counters.h:57
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
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 cost
Definition dialogs_g.h:74
int int id
Definition editgui_g.h:28
static struct editor_state * editor
Definition editor.c:100
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
enum event_type event
Definition events.c:82
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:779
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:804
enum extra_cause activity_to_extra_cause(enum unit_activity act)
Definition extras.c:1090
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
Definition extras.c:1111
#define extra_index(_e_)
Definition extras.h:183
int Impr_type_id
Definition fc_types.h:237
@ RPT_CERTAIN
Definition fc_types.h:516
#define EC_NONE
Definition fc_types.h:808
@ TR_SUCCESS
Definition fc_types.h:941
#define ERM_NONE
Definition fc_types.h:831
@ O_SHIELD
Definition fc_types.h:103
@ O_FOOD
Definition fc_types.h:103
@ O_TRADE
Definition fc_types.h:103
@ O_SCIENCE
Definition fc_types.h:103
@ O_LUXURY
Definition fc_types.h:103
@ O_GOLD
Definition fc_types.h:103
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
#define N_(String)
Definition fcintl.h:69
const struct ft_color ftc_client
const char * population_to_text(int thousand_citizen)
Definition game.c:743
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct city * game_city_by_number(int id)
Definition game.c:106
#define FC_STATIC_CANVAS_INIT
Definition canvas.h:28
GtkWidget * choice_dialog_start(GtkWindow *parent, const gchar *name, const gchar *text)
void choice_dialog_end(GtkWidget *dshell)
void choice_dialog_add(GtkWidget *dshell, const gchar *label, GCallback handler, gpointer data, bool meta, const gchar *tool_tip)
GtkWidget * citizens_dialog_display(const struct city *pcity)
void citizens_dialog_refresh(const struct city *pcity)
void citizens_dialog_close(const struct city *pcity)
static void unit_sentry_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2893
citydlg_response
Definition citydlg.c:82
@ CDLGR_UNITS
Definition citydlg.c:82
@ CDLGR_PREV
Definition citydlg.c:82
@ CDLGR_NEXT
Definition citydlg.c:82
static int new_dialog_def_page
Definition citydlg.c:219
static void create_and_append_buildings_page(struct city_dialog *pdialog)
Definition citydlg.c:1238
static void unit_upgrade_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2952
static void popup_workertask_dlg(struct city *pcity, struct tile *ptile)
Definition citydlg.c:3063
static void city_dialog_update_citizens(struct city_dialog *pdialog)
Definition citydlg.c:1870
static void city_destroy_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:3476
static void city_dialog_update_title(struct city_dialog *pdialog)
Definition citydlg.c:1831
static int last_page
Definition citydlg.c:220
static void init_citydlg_dimensions(void)
Definition citydlg.c:332
static void create_and_append_worklist_page(struct city_dialog *pdialog)
Definition citydlg.c:1272
struct tile * loc
Definition citydlg.c:227
static gboolean canvas_exposed_cb(GtkWidget *w, cairo_t *cr, gpointer data)
Definition citydlg.c:404
#define CITY_MAP_MIN_SIZE_X
Definition citydlg.c:128
void real_city_dialog_popup(struct city *pcity)
Definition citydlg.c:566
static void misc_whichtab_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:3400
static bool low_citydlg
Definition citydlg.c:230
bool city_dialog_is_open(struct city *pcity)
Definition citydlg.c:587
static void city_dialog_update_building(struct city_dialog *pdialog)
Definition citydlg.c:2085
static void citydlg_response_callback(GtkDialog *dlg, gint response, void *data)
Definition citydlg.c:2519
static void buy_callback_response(GtkWidget *w, gint response, gpointer data)
Definition citydlg.c:3191
static gboolean present_unit_middle_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:2736
void real_city_dialog_refresh(struct city *pcity)
Definition citydlg.c:487
static void unit_center_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2792
static struct city_dialog * get_city_dialog(struct city *pcity)
Definition citydlg.c:387
@ INFO_LUXURY
Definition citydlg.c:120
@ INFO_STEAL
Definition citydlg.c:122
@ INFO_CORRUPTION
Definition citydlg.c:121
@ NUM_INFO_FIELDS
Definition citydlg.c:123
@ INFO_ILLNESS
Definition citydlg.c:122
@ INFO_WASTE
Definition citydlg.c:121
@ INFO_SIZE
Definition citydlg.c:119
@ INFO_GROWTH
Definition citydlg.c:120
@ INFO_SHIELD
Definition citydlg.c:119
@ INFO_CULTURE
Definition citydlg.c:121
@ INFO_GOLD
Definition citydlg.c:119
@ INFO_SCIENCE
Definition citydlg.c:120
@ INFO_POLLUTION
Definition citydlg.c:121
@ INFO_TRADE
Definition citydlg.c:119
@ INFO_AIRLIFT
Definition citydlg.c:122
@ INFO_GRANARY
Definition citydlg.c:120
@ INFO_FOOD
Definition citydlg.c:119
#define CITY_MAP_MIN_SIZE_Y
Definition citydlg.c:129
static void city_dialog_update_information(GtkWidget **info_ebox, GtkWidget **info_label, struct city_dialog *pdialog)
Definition citydlg.c:1944
static GtkWidget * create_citydlg_improvement_list(struct city_dialog *pdialog, GtkWidget *vbox)
Definition citydlg.c:897
static void create_production_header(struct city_dialog *pdialog, GtkContainer *contain)
Definition citydlg.c:1205
static void workertask_dlg_destroy(GtkWidget *w, gpointer data)
Definition citydlg.c:3055
static void city_dialog_update_present_units(struct city_dialog *pdialog)
Definition citydlg.c:2373
#define CITYMAP_SCALE
Definition citydlg.c:76
static gboolean keyboard_handler(GtkWidget *widget, GdkEventKey *event, struct city_dialog *pdialog)
Definition citydlg.c:624
static gboolean citizens_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:2973
static void change_production_callback(GtkComboBox *combo, struct city_dialog *pdialog)
Definition citydlg.c:3254
static void unit_load_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2867
static void set_cityopt_values(struct city_dialog *pdialog)
Definition citydlg.c:3442
static void close_city_dialog(struct city_dialog *pdialog)
Definition citydlg.c:3537
static gboolean show_info_popup(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:661
static void create_and_append_overview_page(struct city_dialog *pdialog)
Definition citydlg.c:956
static void create_and_append_happiness_page(struct city_dialog *pdialog)
Definition citydlg.c:1316
void popdown_all_city_dialogs(void)
Definition citydlg.c:607
static void buy_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:3204
#define dialog_list_iterate_end
Definition citydlg.c:93
static void impr_callback(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
Definition citydlg.c:3327
static void create_and_append_map_page(struct city_dialog *pdialog)
Definition citydlg.c:1144
static void city_dialog_map_create(struct city_dialog *pdialog, struct city_map_canvas *cmap_canvas)
Definition citydlg.c:423
void refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.c:546
void reset_city_dialogs(void)
Definition citydlg.c:365
static gboolean show_info_button_release(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:648
static void cityopt_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:3408
static void city_dialog_map_recenter(GtkWidget *map_canvas_sw)
Definition citydlg.c:462
@ WORKLIST_PAGE
Definition citydlg.c:112
@ CMA_PAGE
Definition citydlg.c:112
@ HAPPINESS_PAGE
Definition citydlg.c:112
@ SETTINGS_PAGE
Definition citydlg.c:113
@ STICKY_PAGE
Definition citydlg.c:113
@ NUM_PAGES
Definition citydlg.c:114
@ OVERVIEW_PAGE
Definition citydlg.c:112
static void draw_map_canvas(struct city_dialog *pdialog)
Definition citydlg.c:3179
static struct @145 workertask_req
static bool is_showing_workertask_dialog
Definition citydlg.c:222
#define unit_node_vector_iterate_end
Definition citydlg.c:108
static void sell_callback(struct impr_type *pimprove, gpointer data)
Definition citydlg.c:3273
#define dialog_list_iterate(dialoglist, pdialog)
Definition citydlg.c:91
static void supported_unit_activate_close_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2819
static void city_dialog_update_prev_next(void)
Definition citydlg.c:2480
static void create_and_append_settings_page(struct city_dialog *pdialog)
Definition citydlg.c:1500
static bool city_dialogs_have_been_initialised
Definition citydlg.c:217
static void close_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:3468
static struct dialog_list * dialog_list
Definition citydlg.c:216
static void sell_callback_response(GtkWidget *w, gint response, gpointer data)
Definition citydlg.c:3312
static void create_citydlg_main_map(struct city_dialog *pdialog, GtkWidget *container)
Definition citydlg.c:880
#define NUM_CITIZENS_SHOWN
Definition citydlg.c:110
#define CITYMAP_HEIGHT
Definition citydlg.c:75
static void destroy_func(GtkWidget *w, gpointer data)
Definition citydlg.c:2545
static void unit_homecity_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2939
static void unit_fortify_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2906
static gboolean supported_unit_middle_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:2764
static void city_dialog_update_counters(struct city_dialog *pdialog)
Definition citydlg.c:1413
static gboolean present_unit_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:2615
struct city * owner
Definition citydlg.c:226
static GtkWidget * create_city_info_table(struct city_dialog *pdialog, GtkWidget **info_ebox, GtkWidget **info_label)
Definition citydlg.c:745
static struct city_dialog * create_city_dialog(struct city *pcity)
Definition citydlg.c:1642
static void target_drag_data_received(GtkWidget *w, GdkDragContext *context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data)
Definition citydlg.c:1167
static void unit_disband_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2919
#define unit_node_vector_iterate(list, elt)
Definition citydlg.c:106
static void rename_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:3366
static void switch_city_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:3546
static gboolean button_down_citymap(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:3141
#define CITYMAP_WIDTH
Definition citydlg.c:74
static void city_dialog_update_map(struct city_dialog *pdialog)
Definition citydlg.c:2063
static void create_and_append_counters_page(struct city_dialog *pdialog)
Definition citydlg.c:1393
static void unit_unload_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2880
static void show_units_response(void *data)
Definition citydlg.c:2532
static void initialize_city_dialogs(void)
Definition citydlg.c:341
static int canvas_height
Definition citydlg.c:218
static int canvas_width
Definition citydlg.c:218
#define TINYSCREEN_MAX_HEIGHT
Definition citydlg.c:78
static void city_dialog_update_supported_units(struct city_dialog *pdialog)
Definition citydlg.c:2266
static void unit_activate_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2805
static void present_unit_activate_close_callback(GtkWidget *w, gpointer data)
Definition citydlg.c:2844
static void set_city_workertask(GtkWidget *w, gpointer data)
Definition citydlg.c:3000
static void rename_popup_callback(gpointer data, gint response, const char *input)
Definition citydlg.c:3383
static void city_dialog_update_improvement_list(struct city_dialog *pdialog)
Definition citydlg.c:2209
static void create_and_append_cma_page(struct city_dialog *pdialog)
Definition citydlg.c:1480
void popdown_city_dialog(struct city *pcity)
Definition citydlg.c:595
static gboolean supported_unit_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition citydlg.c:2553
void close_cma_dialog(struct city *pcity)
Definition cma_fe.c:104
struct cma_dialog * create_cma_dialog(struct city *pcity, bool tiny)
Definition cma_fe.c:214
void refresh_cma_dialog(struct city *pcity, enum cma_refresh refresh)
Definition cma_fe.c:471
@ REFRESH_ALL
Definition cma_fe.h:26
void unit_select_dialog_popup(struct tile *ptile)
Definition dialogs.c:377
void popup_upgrade_dialog(struct unit_list *punits)
Definition dialogs.c:1435
void popup_disband_dialog(struct unit_list *punits)
Definition dialogs.c:1473
GtkWidget * toplevel
Definition gui_main.c:126
GtkWidget * map_canvas
Definition gui_main.c:108
int screen_height(void)
Definition gui_main.c:2591
#define GUI_GTK_OPTION(optname)
Definition gui_main.h:32
GtkWidget * icon_label_button_new(const gchar *icon_name, const gchar *label_text)
Definition gui_stuff.c:76
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
void intl_slist(int n, const char **s, bool *done)
Definition gui_stuff.c:111
void close_happiness_dialog(struct city *pcity)
Definition happiness.c:330
void refresh_happiness_dialog(struct city *pcity)
Definition happiness.c:317
GtkWidget * get_top_happiness_display(struct city *pcity, bool low_dlg, GtkWidget *win)
Definition happiness.c:356
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:196
GtkWidget * input_dialog_create(GtkWindow *parent, const char *dialogname, const char *text, const char *postinputtest, input_dialog_callback_t response_callback, gpointer response_cli_data)
Definition inputdlg.c:66
void put_unit_image_city_overlays(struct unit *punit, GtkImage *p, int height, int *upkeep_cost, int happy_cost)
Definition mapview.c:521
void put_unit_image(struct unit *punit, GtkImage *p, int height)
Definition mapview.c:496
static struct gui_dialog * shell
Definition messagedlg.c:39
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
bool request_transport(struct unit *cargo, struct tile *ptile)
void refresh_worklist(GtkWidget *editor)
Definition wldlg.c:1327
void add_worklist_dnd_target(GtkWidget *w)
Definition wldlg.c:339
void reset_city_worklist(GtkWidget *editor, struct city *pcity)
Definition wldlg.c:1279
GtkWidget * create_worklist(void)
Definition wldlg.c:1054
static SDL_Surface * info_label
Definition widget.c:57
@ HELP_IMPROVEMENT
Definition helpdlg_g.h:20
@ HELP_WONDER
Definition helpdlg_g.h:21
int impr_sell_gold(const struct impr_type *pimprove)
enum test_result test_player_sell_building_now(struct player *pplayer, struct city *pcity, const struct impr_type *pimprove)
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
Impr_type_id improvement_number(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)
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_action(condition, action)
Definition log.h:188
#define log_debug(message,...)
Definition log.h:116
int send_packet_worker_task(struct connection *pc, const struct packet_worker_task *packet)
int dsend_packet_city_options_req(struct connection *pc, int city_id, bv_city_options options, enum city_wl_cancel_behavior wl_cb)
void center_tile_mapcanvas(const struct tile *ptile)
bool can_slide
#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:350
bool unit_can_load(const struct unit *punit)
Definition movement.c:934
static const char * name_translation_get(const struct name_translation *ptrans)
#define GUI_GTK3_22_CITYDLG_MIN_YSIZE
Definition options.h:675
#define GUI_GTK3_22_CITYDLG_MAX_XSIZE
Definition options.h:672
#define GUI_GTK3_22_CITYDLG_MIN_XSIZE
Definition options.h:671
#define GUI_GTK3_22_CITYDLG_MAX_YSIZE
Definition options.h:676
int len
Definition packhand.c:128
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1217
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1191
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MIN(x, y)
Definition shared.h:55
#define FC_INFINITY
Definition shared.h:36
size_t size
Definition specvec.h:72
struct sprite int int int int struct sprite * mask
Definition sprite_g.h:32
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
#define strvec_iterate(psv, str)
#define strvec_iterate_end
cairo_surface_t * surface
Definition canvas.h:23
GtkWidget * prev_command
Definition citydlg.c:208
GtkWidget * name_label
Definition citydlg.c:141
GtkWidget * citizen_images
Definition citydlg.c:146
GtkWidget * rename_shell
Definition citydlg.c:205
GtkWidget * info_ebox[NUM_INFO_FIELDS]
Definition citydlg.c:166
GtkWidget * rename_command
Definition citydlg.c:196
GtkWidget * production_bar
Definition citydlg.c:152
GtkWidget * supported_units_frame
Definition citydlg.c:157
GtkWidget * sell_shell
Definition citydlg.c:203
GtkWidget * production_label
Definition citydlg.c:173
GtkWidget * widget
Definition citydlg.c:182
GtkWidget * supported_unit_table
Definition citydlg.c:158
GtkWidget * disband_on_settler
Definition citydlg.c:198
struct city_map_canvas map_canvas
Definition citydlg.c:150
enum city_dialog::@217 page
GtkWidget * improvement_list
Definition citydlg.c:155
GtkWidget * container
Definition citydlg.c:189
GtkWidget * buy_command
Definition citydlg.c:154
short block_signal
Definition citydlg.c:200
GtkWidget * whichtab_radio[NUM_PAGES]
Definition citydlg.c:199
struct unit_node_vector supported_units
Definition citydlg.c:163
cairo_surface_t * map_canvas_store_unscaled
Definition citydlg.c:142
struct city * pcity
Definition citydlg.c:138
struct city_dialog::@148 happiness
struct unit_node_vector present_units
Definition citydlg.c:164
city_map * view
Definition citydlg.h:446
GtkWidget * citizens
Definition citydlg.c:185
GtkWidget * popup_menu
Definition citydlg.c:145
GtkWidget * show_units_command
Definition citydlg.c:207
Impr_type_id sell_id
Definition citydlg.c:211
GtkWidget * production_combo
Definition citydlg.c:153
struct city_dialog::@150 misc
struct cma_dialog * cma_editor
Definition citydlg.c:193
cairo_surface_t * citizen_surface
Definition citydlg.c:147
GtkWidget * shell
Definition citydlg.c:140
GtkWidget * worklist
Definition citydlg.c:176
GtkWidget * present_units_frame
Definition citydlg.c:160
GtkWidget * info_label[NUM_INFO_FIELDS]
Definition citydlg.c:167
GtkWidget * new_citizens_radio[3]
Definition citydlg.c:197
GtkListStore * change_production_store
Definition citydlg.c:169
GtkWidget * present_unit_table
Definition citydlg.c:161
struct city_dialog::@149 counters
GtkWidget * notebook
Definition citydlg.c:143
struct city_dialog::@146 overview
GtkWidget * next_command
Definition citydlg.c:209
GtkTreeSelection * change_selection
Definition citydlg.c:204
struct city_dialog::@147 production
GtkWidget * darea
Definition citydlg.c:134
GtkWidget * sw
Definition citydlg.c:132
GtkWidget * ebox
Definition citydlg.c:133
Definition city.h:318
int * counter_values
Definition city.h:406
struct unit_list * info_units_present
Definition city.h:474
struct unit_list * info_units_supported
Definition city.h:473
citizens size
Definition city.h:330
int illness
Definition city.h:432
int buy_cost
Definition city.h:466
struct city::@18::@21 client
struct tile * tile
Definition city.h:320
struct unit_list * units_supported
Definition city.h:404
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
GtkWidget * shell
Definition cma_fe.h:33
struct city * pcity
Definition cma_fe.h:32
struct player * playing
Definition connection.h:151
Definition climisc.h:82
struct universal item
Definition climisc.h:83
char descr[MAX_LEN_NAME+40]
Definition climisc.h:84
enum unit_activity activity
struct city_list * cities
Definition player.h:281
Definition tile.h:50
int index
Definition tile.h:51
struct unit_list * units
Definition tile.h:58
int height
Definition citydlg.c:98
GtkWidget * cmd
Definition citydlg.c:96
GtkWidget * pix
Definition citydlg.c:97
Definition unit.h:140
int upkeep[O_LAST]
Definition unit.h:150
enum unit_activity activity
Definition unit.h:159
int id
Definition unit.h:147
struct tile * tile
Definition unit.h:142
struct unit::@84::@86 client
int homecity
Definition unit.h:148
struct player * owner
Definition unit.h:145
enum universals_n kind
Definition fc_types.h:595
universals_u value
Definition fc_types.h:594
struct tile * ptile
Definition workertask.h:22
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char * unit_description(struct unit *punit)
Definition text.c:528
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_terrain(_tile)
Definition tile.h:115
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:7033
int tileset_small_sprite_width(const struct tileset *t)
Definition tilespec.c:927
int tileset_full_tile_height(const struct tileset *t)
Definition tilespec.c:815
int tileset_small_sprite_height(const struct tileset *t)
Definition tilespec.c:963
struct sprite * get_icon_sprite(const struct tileset *t, enum icon_type icon)
Definition tilespec.c:7237
int tileset_unit_with_upkeep_height(const struct tileset *t)
Definition tilespec.c:885
struct sprite * get_citizen_sprite(const struct tileset *t, enum citizen_category type, int citizen_index, const struct city *pcity)
Definition tilespec.c:6972
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:7055
@ ICON_CITYDLG
Definition tilespec.h:317
const struct unit_type * utype
Definition fc_types.h:536
const struct impr_type * building
Definition fc_types.h:529
bool can_unit_change_homecity_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pcity)
Definition unit.c:508
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2525
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:402
bool can_unit_unload(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:793
#define unit_tile(_pu)
Definition unit.h:408
#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:126
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1729
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1586
void economy_report_dialog_update(void)
bool worklist_is_empty(const struct worklist *pwl)
Definition worklist.c:66