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 <stdlib.h>
19 
20 #include <gtk/gtk.h>
21 
22 /* utility */
23 #include "fcintl.h"
24 #include "log.h"
25 #include "shared.h"
26 #include "support.h"
27 
28 /* common */
29 #include "game.h"
30 #include "government.h"
31 #include "road.h"
32 #include "unit.h"
33 
34 /* client */
35 #include "client_main.h"
36 #include "clinet.h"
37 #include "connectdlg_common.h"
38 #include "control.h"
39 #include "mapview_common.h"
40 #include "options.h"
41 #include "tilespec.h"
42 
43 /* client/gui-gtk-3.22 */
44 #include "chatline.h"
45 #include "cityrep.h"
46 #include "dialogs.h"
47 #include "editgui.h"
48 #include "editprop.h"
49 #include "finddlg.h"
50 #include "gamedlgs.h"
51 #include "gotodlg.h"
52 #include "gui_main.h"
53 #include "gui_stuff.h"
54 #include "helpdlg.h"
55 #include "luaconsole.h"
56 #include "mapctrl.h"            /* center_on_unit(). */
57 #include "messagedlg.h"
58 #include "messagewin.h"
59 #include "optiondlg.h"
60 #include "pages.h"
61 #include "plrdlg.h"
62 #include "ratesdlg.h"
63 #include "repodlgs.h"
64 #include "sprite.h"
65 #include "spaceshipdlg.h"
66 #include "transportdlg.h"
67 #include "unitselect.h"
68 #include "wldlg.h"
69 
70 #include "menu.h"
71 
72 #ifndef GTK_STOCK_EDIT
73 #define GTK_STOCK_EDIT NULL
74 #endif
75 
76 static GtkBuilder *ui_builder = NULL;
77 
78 static void menu_entry_set_active(const char *key,
79                                   gboolean is_active);
80 static void menu_entry_set_sensitive(const char *key,
81                                      gboolean is_sensitive);
82 #ifndef DEBUG
83 static void menu_entry_set_visible(const char *key,
84                                    gboolean is_visible,
85                                    gboolean is_sensitive);
86 #endif /* DEBUG */
87 
88 static void view_menu_update_sensitivity(void);
89 
90 enum menu_entry_grouping { MGROUP_SAFE, MGROUP_EDIT, MGROUP_PLAYING,
91                            MGROUP_UNIT, MGROUP_PLAYER, MGROUP_ALL };
92 
93 static void menu_entry_group_set_sensitive(enum menu_entry_grouping group,
94                                            gboolean is_sensitive);
95 
96 struct menu_entry_info {
97   const char *key;
98   const char *name;
99   guint accel;
100   GdkModifierType accel_mod;
101   GCallback cb;
102   enum menu_entry_grouping grouping;
103 };
104 
105 static void clear_chat_logs_callback(GtkMenuItem *item, gpointer data);
106 static void save_chat_logs_callback(GtkMenuItem *item, gpointer data);
107 static void local_options_callback(GtkMenuItem *item, gpointer data);
108 static void message_options_callback(GtkMenuItem *item, gpointer data);
109 static void server_options_callback(GtkMenuItem *item, gpointer data);
110 static void save_options_callback(GtkMenuItem *item, gpointer data);
111 static void reload_tileset_callback(GtkMenuItem *item, gpointer data);
112 static void save_game_callback(GtkMenuItem *item, gpointer data);
113 static void save_game_as_callback(GtkMenuItem *item, gpointer data);
114 static void save_mapimg_callback(GtkMenuItem *item, gpointer data);
115 static void save_mapimg_as_callback(GtkMenuItem *item, gpointer data);
116 static void find_city_callback(GtkMenuItem *item, gpointer data);
117 static void worklists_callback(GtkMenuItem *item, gpointer data);
118 static void client_lua_script_callback(GtkMenuItem *item, gpointer data);
119 static void leave_callback(GtkMenuItem *item, gpointer data);
120 static void quit_callback(GtkMenuItem *item, gpointer data);
121 static void map_view_callback(GtkMenuItem *item, gpointer data);
122 static void report_units_callback(GtkMenuItem *item, gpointer data);
123 static void report_nations_callback(GtkMenuItem *item, gpointer data);
124 static void report_cities_callback(GtkMenuItem *item, gpointer data);
125 static void report_wow_callback(GtkMenuItem *item, gpointer data);
126 static void report_top_cities_callback(GtkMenuItem *item, gpointer data);
127 static void report_messages_callback(GtkMenuItem *item, gpointer data);
128 static void report_demographic_callback(GtkMenuItem *item, gpointer data);
129 static void help_overview_callback(GtkMenuItem *item, gpointer data);
130 static void help_playing_callback(GtkMenuItem *item, gpointer data);
131 static void help_policies_callback(GtkMenuItem *item, gpointer data);
132 static void help_terrain_callback(GtkMenuItem *item, gpointer data);
133 static void help_economy_callback(GtkMenuItem *item, gpointer data);
134 static void help_cities_callback(GtkMenuItem *item, gpointer data);
135 static void help_improvements_callback(GtkMenuItem *item, gpointer data);
136 static void help_wonders_callback(GtkMenuItem *item, gpointer data);
137 static void help_units_callback(GtkMenuItem *item, gpointer data);
138 static void help_combat_callback(GtkMenuItem *item, gpointer data);
139 static void help_zoc_callback(GtkMenuItem *item, gpointer data);
140 static void help_government_callback(GtkMenuItem *item, gpointer data);
141 static void help_diplomacy_callback(GtkMenuItem *item, gpointer data);
142 static void help_tech_callback(GtkMenuItem *item, gpointer data);
143 static void help_space_race_callback(GtkMenuItem *item, gpointer data);
144 static void help_ruleset_callback(GtkMenuItem *item, gpointer data);
145 static void help_tileset_callback(GtkMenuItem *item, gpointer data);
146 static void help_nations_callback(GtkMenuItem *item, gpointer data);
147 static void help_connecting_callback(GtkMenuItem *item, gpointer data);
148 static void help_controls_callback(GtkMenuItem *item, gpointer data);
149 static void help_cma_callback(GtkMenuItem *item, gpointer data);
150 static void help_chatline_callback(GtkMenuItem *item, gpointer data);
151 static void help_worklist_editor_callback(GtkMenuItem *item, gpointer data);
152 static void help_language_callback(GtkMenuItem *item, gpointer data);
153 static void help_copying_callback(GtkMenuItem *item, gpointer data);
154 static void help_about_callback(GtkMenuItem *item, gpointer data);
155 static void save_options_on_exit_callback(GtkCheckMenuItem *item,
156                                           gpointer data);
157 static void edit_mode_callback(GtkCheckMenuItem *item, gpointer data);
158 static void show_city_outlines_callback(GtkCheckMenuItem *item,
159                                         gpointer data);
160 static void show_city_output_callback(GtkCheckMenuItem *item, gpointer data);
161 static void show_map_grid_callback(GtkCheckMenuItem *item, gpointer data);
162 static void show_national_borders_callback(GtkCheckMenuItem *item,
163                                            gpointer data);
164 static void show_native_tiles_callback(GtkCheckMenuItem *item,
165                                        gpointer data);
166 static void show_city_full_bar_callback(GtkCheckMenuItem *item,
167                                         gpointer data);
168 static void show_city_names_callback(GtkCheckMenuItem *item, gpointer data);
169 static void show_city_growth_callback(GtkCheckMenuItem *item, gpointer data);
170 static void show_city_productions_callback(GtkCheckMenuItem *item,
171                                            gpointer data);
172 static void show_city_buy_cost_callback(GtkCheckMenuItem *item,
173                                         gpointer data);
174 static void show_city_trade_routes_callback(GtkCheckMenuItem *item,
175                                             gpointer data);
176 static void show_terrain_callback(GtkCheckMenuItem *item, gpointer data);
177 static void show_coastline_callback(GtkCheckMenuItem *item, gpointer data);
178 static void show_road_rails_callback(GtkCheckMenuItem *item, gpointer data);
179 static void show_irrigation_callback(GtkCheckMenuItem *item, gpointer data);
180 static void show_mine_callback(GtkCheckMenuItem *item, gpointer data);
181 static void show_bases_callback(GtkCheckMenuItem *item, gpointer data);
182 static void show_resources_callback(GtkCheckMenuItem *item, gpointer data);
183 static void show_huts_callback(GtkCheckMenuItem *item, gpointer data);
184 static void show_pollution_callback(GtkCheckMenuItem *item, gpointer data);
185 static void show_cities_callback(GtkCheckMenuItem *item, gpointer data);
186 static void show_units_callback(GtkCheckMenuItem *item, gpointer data);
187 static void show_unit_solid_bg_callback(GtkCheckMenuItem *item,
188                                         gpointer data);
189 static void show_unit_shields_callback(GtkCheckMenuItem *item,
190                                        gpointer data);
191 static void show_focus_unit_callback(GtkCheckMenuItem *item, gpointer data);
192 static void show_fog_of_war_callback(GtkCheckMenuItem *item, gpointer data);
193 static void full_screen_callback(GtkCheckMenuItem *item, gpointer data);
194 static void recalc_borders_callback(GtkMenuItem *item, gpointer data);
195 static void toggle_fog_callback(GtkMenuItem *item, gpointer data);
196 static void scenario_properties_callback(GtkMenuItem *item, gpointer data);
197 static void save_scenario_callback(GtkMenuItem *item, gpointer data);
198 static void center_view_callback(GtkMenuItem *item, gpointer data);
199 static void report_economy_callback(GtkMenuItem *item, gpointer data);
200 static void report_research_callback(GtkMenuItem *item, gpointer data);
201 static void multiplier_callback(GtkMenuItem *item, gpointer data);
202 static void report_spaceship_callback(GtkMenuItem *item, gpointer data);
203 static void report_achievements_callback(GtkMenuItem *item, gpointer data);
204 static void government_callback(GtkMenuItem *item, gpointer data);
205 static void tax_rate_callback(GtkMenuItem *item, gpointer data);
206 static void select_single_callback(GtkMenuItem *item, gpointer data);
207 static void select_all_on_tile_callback(GtkMenuItem *item, gpointer data);
208 static void select_same_type_tile_callback(GtkMenuItem *item, gpointer data);
209 static void select_same_type_cont_callback(GtkMenuItem *item, gpointer data);
210 static void select_same_type_callback(GtkMenuItem *item, gpointer data);
211 static void select_dialog_callback(GtkMenuItem *item, gpointer data);
212 static void unit_wait_callback(GtkMenuItem *item, gpointer data);
213 static void unit_done_callback(GtkMenuItem *item, gpointer data);
214 static void unit_goto_callback(GtkMenuItem *item, gpointer data);
215 static void unit_goto_city_callback(GtkMenuItem *item, gpointer data);
216 static void unit_return_callback(GtkMenuItem *item, gpointer data);
217 static void unit_explore_callback(GtkMenuItem *item, gpointer data);
218 static void unit_patrol_callback(GtkMenuItem *item, gpointer data);
219 static void unit_sentry_callback(GtkMenuItem *item, gpointer data);
220 static void unit_unsentry_callback(GtkMenuItem *item, gpointer data);
221 static void unit_load_callback(GtkMenuItem *item, gpointer data);
222 static void unit_unload_callback(GtkMenuItem *item, gpointer data);
223 static void unit_unload_transporter_callback(GtkMenuItem *item,
224                                              gpointer data);
225 static void unit_homecity_callback(GtkMenuItem *item, gpointer data);
226 static void unit_upgrade_callback(GtkMenuItem *item, gpointer data);
227 static void unit_convert_callback(GtkMenuItem *item, gpointer data);
228 static void unit_disband_callback(GtkMenuItem *item, gpointer data);
229 static void build_city_callback(GtkMenuItem *item, gpointer data);
230 static void go_build_city_callback(GtkMenuItem *item, gpointer data);
231 static void auto_settle_callback(GtkMenuItem *item, gpointer data);
232 static void build_road_callback(GtkMenuItem *item, gpointer data);
233 static void build_irrigation_callback(GtkMenuItem *item, gpointer data);
234 static void build_mine_callback(GtkMenuItem *item, gpointer data);
235 static void connect_road_callback(GtkMenuItem *item, gpointer data);
236 static void connect_rail_callback(GtkMenuItem *item, gpointer data);
237 static void connect_irrigation_callback(GtkMenuItem *item, gpointer data);
238 static void transform_terrain_callback(GtkMenuItem *item, gpointer data);
239 static void clean_pollution_callback(GtkMenuItem *item, gpointer data);
240 static void clean_fallout_callback(GtkMenuItem *item, gpointer data);
241 static void fortify_callback(GtkMenuItem *item, gpointer data);
242 static void build_fortress_callback(GtkMenuItem *item, gpointer data);
243 static void build_airbase_callback(GtkMenuItem *item, gpointer data);
244 static void do_pillage_callback(GtkMenuItem *item, gpointer data);
245 static void diplomat_action_callback(GtkMenuItem *item, gpointer data);
246 static void explode_nuke_callback(GtkMenuItem *item, gpointer data);
247 
248 static struct menu_entry_info menu_entries[] =
249 {
250   { "MENU_GAME", N_("_Game"), 0, 0, NULL, MGROUP_SAFE },
251   { "MENU_OPTIONS", N_("_Options"), 0, 0, NULL, MGROUP_SAFE },
252   { "MENU_EDIT", N_("_Edit"), 0, 0, NULL, MGROUP_SAFE },
253   { "MENU_VIEW", N_("?verb:_View"), 0, 0, NULL, MGROUP_SAFE },
254   { "MENU_IMPROVEMENTS", N_("_Improvements"), 0, 0,
255     NULL, MGROUP_SAFE },
256   { "MENU_CIVILIZATION", N_("C_ivilization"), 0, 0,
257     NULL, MGROUP_SAFE },
258   { "MENU_HELP", N_("_Help"), 0, 0, NULL, MGROUP_SAFE },
259   { "CLEAR_CHAT_LOGS", N_("_Clear Chat Log"), 0, 0,
260     G_CALLBACK(clear_chat_logs_callback), MGROUP_SAFE },
261   { "SAVE_CHAT_LOGS", N_("Save Chat _Log"), 0, 0,
262     G_CALLBACK(save_chat_logs_callback), MGROUP_SAFE },
263   { "LOCAL_OPTIONS", N_("_Local Client"), 0, 0,
264     G_CALLBACK(local_options_callback), MGROUP_SAFE },
265   { "MESSAGE_OPTIONS", N_("_Message"), 0, 0,
266     G_CALLBACK(message_options_callback), MGROUP_SAFE },
267   { "SERVER_OPTIONS", N_("_Remote Server"), 0, 0,
268     G_CALLBACK(server_options_callback), MGROUP_SAFE },
269   { "SAVE_OPTIONS", N_("Save Options _Now"), 0, 0,
270     G_CALLBACK(save_options_callback), MGROUP_SAFE },
271   { "RELOAD_TILESET", N_("_Reload Tileset"),
272     GDK_KEY_r, GDK_MOD1_MASK | GDK_CONTROL_MASK,
273     G_CALLBACK(reload_tileset_callback), MGROUP_SAFE },
274   { "GAME_SAVE", N_("_Save Game"), GDK_KEY_s, GDK_CONTROL_MASK,
275     G_CALLBACK(save_game_callback), MGROUP_SAFE },
276   { "GAME_SAVE_AS", N_("Save Game _As..."), 0, 0,
277     G_CALLBACK(save_game_as_callback), MGROUP_SAFE },
278   { "MAPIMG_SAVE", N_("Save Map _Image"), 0, 0,
279     G_CALLBACK(save_mapimg_callback), MGROUP_SAFE },
280   { "MAPIMG_SAVE_AS", N_("Save _Map Image As..."), 0, 0,
281     G_CALLBACK(save_mapimg_as_callback), MGROUP_SAFE },
282   { "LEAVE", N_("_Leave"), 0, 0, G_CALLBACK(leave_callback), MGROUP_SAFE },
283   { "QUIT", N_("_Quit"), GDK_KEY_q, GDK_CONTROL_MASK,
284     G_CALLBACK(quit_callback), MGROUP_SAFE },
285   { "FIND_CITY", N_("_Find City"), GDK_KEY_f, GDK_CONTROL_MASK,
286     G_CALLBACK(find_city_callback), MGROUP_SAFE },
287   { "WORKLISTS", N_("Work_lists"), GDK_KEY_l, GDK_CONTROL_MASK,
288     G_CALLBACK(worklists_callback), MGROUP_SAFE },
289   { "CLIENT_LUA_SCRIPT", N_("Client _Lua Script"), 0, 0,
290     G_CALLBACK(client_lua_script_callback), MGROUP_SAFE },
291   { "MAP_VIEW", N_("?noun:_View"), GDK_KEY_F1, 0,
292     G_CALLBACK(map_view_callback), MGROUP_SAFE },
293   { "REPORT_UNITS", N_("_Units"), GDK_KEY_F2, 0,
294     G_CALLBACK(report_units_callback), MGROUP_SAFE },
295   { "REPORT_NATIONS", N_("_Nations"), GDK_KEY_F3, 0,
296     G_CALLBACK(report_nations_callback), MGROUP_SAFE },
297   { "REPORT_CITIES", N_("_Cities"), GDK_KEY_F4, 0,
298     G_CALLBACK(report_cities_callback), MGROUP_SAFE },
299   { "REPORT_WOW", N_("_Wonders of the World"), GDK_KEY_F7, 0,
300     G_CALLBACK(report_wow_callback), MGROUP_SAFE },
301   { "REPORT_TOP_CITIES", N_("Top _Five Cities"), GDK_KEY_F8, 0,
302     G_CALLBACK(report_top_cities_callback), MGROUP_SAFE },
303   { "REPORT_MESSAGES", N_("_Messages"), GDK_KEY_F9, 0,
304     G_CALLBACK(report_messages_callback), MGROUP_SAFE },
305   { "REPORT_DEMOGRAPHIC", N_("_Demographics"), GDK_KEY_F11, 0,
306     G_CALLBACK(report_demographic_callback), MGROUP_SAFE },
307   { "HELP_OVERVIEW", N_("?help:Overview"), 0, 0,
308     G_CALLBACK(help_overview_callback), MGROUP_SAFE },
309   { "HELP_PLAYING", N_("Strategy and Tactics"), 0, 0,
310     G_CALLBACK(help_playing_callback), MGROUP_SAFE },
311   { "HELP_POLICIES", N_("Policies"), 0, 0,
312     G_CALLBACK(help_policies_callback), MGROUP_SAFE },
313   { "HELP_TERRAIN", N_("Terrain"), 0, 0,
314     G_CALLBACK(help_terrain_callback), MGROUP_SAFE },
315   { "HELP_ECONOMY", N_("Economy"), 0, 0,
316     G_CALLBACK(help_economy_callback), MGROUP_SAFE },
317   { "HELP_CITIES", N_("Cities"), 0, 0,
318     G_CALLBACK(help_cities_callback), MGROUP_SAFE },
319   { "HELP_IMPROVEMENTS", N_("City Improvements"), 0, 0,
320     G_CALLBACK(help_improvements_callback), MGROUP_SAFE },
321   { "HELP_WONDERS", N_("Wonders of the World"), 0, 0,
322     G_CALLBACK(help_wonders_callback), MGROUP_SAFE },
323   { "HELP_UNITS", N_("Units"), 0, 0,
324     G_CALLBACK(help_units_callback), MGROUP_SAFE },
325   { "HELP_COMBAT", N_("Combat"), 0, 0,
326     G_CALLBACK(help_combat_callback), MGROUP_SAFE },
327   { "HELP_ZOC", N_("Zones of Control"), 0, 0,
328     G_CALLBACK(help_zoc_callback), MGROUP_SAFE },
329   { "HELP_GOVERNMENT", N_("Government"), 0, 0,
330     G_CALLBACK(help_government_callback), MGROUP_SAFE },
331   { "HELP_DIPLOMACY", N_("Diplomacy"), 0, 0,
332     G_CALLBACK(help_diplomacy_callback), MGROUP_SAFE },
333   { "HELP_TECH", N_("Technology"), 0, 0,
334     G_CALLBACK(help_tech_callback), MGROUP_SAFE },
335   { "HELP_SPACE_RACE", N_("Space Race"), 0, 0,
336     G_CALLBACK(help_space_race_callback), MGROUP_SAFE },
337   { "HELP_RULESET", N_("About Current Ruleset"), 0, 0,
338     G_CALLBACK(help_ruleset_callback), MGROUP_SAFE },
339   { "HELP_TILESET", N_("About Current Tileset"), 0, 0,
340     G_CALLBACK(help_tileset_callback), MGROUP_SAFE },
341   { "HELP_NATIONS", N_("About Nations"), 0, 0,
342     G_CALLBACK(help_nations_callback), MGROUP_SAFE },
343   { "HELP_CONNECTING", N_("Connecting"), 0, 0,
344     G_CALLBACK(help_connecting_callback), MGROUP_SAFE },
345   { "HELP_CONTROLS", N_("Controls"), 0, 0,
346     G_CALLBACK(help_controls_callback), MGROUP_SAFE },
347   { "HELP_CMA", N_("Citizen Governor"), 0, 0,
348     G_CALLBACK(help_cma_callback), MGROUP_SAFE },
349   { "HELP_CHATLINE", N_("Chatline"), 0, 0,
350     G_CALLBACK(help_chatline_callback), MGROUP_SAFE },
351   { "HELP_WORKLIST_EDITOR", N_("Worklist Editor"), 0, 0,
352     G_CALLBACK(help_worklist_editor_callback), MGROUP_SAFE },
353   { "HELP_LANGUAGES", N_("Languages"), 0, 0,
354     G_CALLBACK(help_language_callback), MGROUP_SAFE },
355   { "HELP_COPYING", N_("Copying"), 0, 0,
356     G_CALLBACK(help_copying_callback), MGROUP_SAFE },
357   { "HELP_ABOUT", N_("About Freeciv"), 0, 0,
358     G_CALLBACK(help_about_callback), MGROUP_SAFE },
359   { "SAVE_OPTIONS_ON_EXIT", N_("Save Options on _Exit"), 0, 0,
360     G_CALLBACK(save_options_on_exit_callback), MGROUP_SAFE },
361   { "EDIT_MODE", N_("_Editing Mode"), GDK_KEY_e, GDK_CONTROL_MASK,
362     G_CALLBACK(edit_mode_callback), MGROUP_SAFE },
363   { "SHOW_CITY_OUTLINES", N_("Cit_y Outlines"), GDK_KEY_y, GDK_CONTROL_MASK,
364     G_CALLBACK(show_city_outlines_callback), MGROUP_SAFE },
365   { "SHOW_CITY_OUTPUT", N_("City Output"), GDK_KEY_w, GDK_CONTROL_MASK,
366     G_CALLBACK(show_city_output_callback), MGROUP_SAFE },
367   { "SHOW_MAP_GRID", N_("Map _Grid"), GDK_KEY_g, GDK_CONTROL_MASK,
368     G_CALLBACK(show_map_grid_callback), MGROUP_SAFE },
369   { "SHOW_NATIONAL_BORDERS", N_("National _Borders"), GDK_KEY_b, GDK_CONTROL_MASK,
370     G_CALLBACK(show_national_borders_callback), MGROUP_SAFE },
371   { "SHOW_NATIVE_TILES", N_("Native Tiles"), GDK_KEY_n, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
372     G_CALLBACK(show_native_tiles_callback), MGROUP_SAFE },
373   { "SHOW_CITY_FULL_BAR", N_("City Full Bar"), 0, 0,
374     G_CALLBACK(show_city_full_bar_callback), MGROUP_SAFE },
375   { "SHOW_CITY_NAMES", N_("City _Names"), GDK_KEY_n, GDK_CONTROL_MASK,
376     G_CALLBACK(show_city_names_callback), MGROUP_SAFE },
377   { "SHOW_CITY_GROWTH", N_("City G_rowth"), GDK_KEY_r, GDK_CONTROL_MASK,
378     G_CALLBACK(show_city_growth_callback), MGROUP_SAFE },
379   { "SHOW_CITY_PRODUCTIONS", N_("City _Production Levels"), GDK_KEY_p, GDK_CONTROL_MASK,
380     G_CALLBACK(show_city_productions_callback), MGROUP_SAFE },
381   { "SHOW_CITY_BUY_COST", N_("City Buy Cost"), 0, 0,
382     G_CALLBACK(show_city_buy_cost_callback), MGROUP_SAFE },
383   { "SHOW_CITY_TRADE_ROUTES", N_("City Tra_deroutes"), GDK_KEY_d, GDK_CONTROL_MASK,
384     G_CALLBACK(show_city_trade_routes_callback), MGROUP_SAFE },
385   { "SHOW_TERRAIN", N_("_Terrain"), 0, 0,
386     G_CALLBACK(show_terrain_callback), MGROUP_SAFE },
387   { "SHOW_COASTLINE", N_("C_oastline"), 0, 0,
388     G_CALLBACK(show_coastline_callback), MGROUP_SAFE },
389   { "SHOW_PATHS", N_("_Paths"), 0, 0,
390     G_CALLBACK(show_road_rails_callback), MGROUP_SAFE },
391   { "SHOW_IRRIGATION", N_("_Irrigation"), 0, 0,
392     G_CALLBACK(show_irrigation_callback), MGROUP_SAFE },
393   { "SHOW_MINES", N_("_Mines"), 0, 0,
394     G_CALLBACK(show_mine_callback), MGROUP_SAFE },
395   { "SHOW_BASES", N_("_Bases"), 0, 0,
396     G_CALLBACK(show_bases_callback), MGROUP_SAFE },
397   { "SHOW_RESOURCES", N_("_Resources"), 0, 0,
398     G_CALLBACK(show_resources_callback), MGROUP_SAFE },
399   { "SHOW_HUTS", N_("_Huts"), 0, 0,
400     G_CALLBACK(show_huts_callback), MGROUP_SAFE },
401   { "SHOW_POLLUTION", N_("Po_llution & Fallout"), 0, 0,
402     G_CALLBACK(show_pollution_callback), MGROUP_SAFE },
403   { "SHOW_CITIES", N_("Citi_es"), 0, 0,
404     G_CALLBACK(show_cities_callback), MGROUP_SAFE },
405   { "SHOW_UNITS", N_("_Units"), 0, 0,
406     G_CALLBACK(show_units_callback), MGROUP_SAFE },
407   { "SHOW_UNIT_SOLID_BG", N_("Unit Solid Background"), 0, 0,
408     G_CALLBACK(show_unit_solid_bg_callback), MGROUP_SAFE },
409   { "SHOW_UNIT_SHIELDS", N_("Unit shields"), 0, 0,
410     G_CALLBACK(show_unit_shields_callback), MGROUP_SAFE },
411   { "SHOW_FOCUS_UNIT", N_("Focu_s Unit"), 0, 0,
412     G_CALLBACK(show_focus_unit_callback), MGROUP_SAFE },
413   { "SHOW_FOG_OF_WAR", N_("Fog of _War"), 0, 0,
414     G_CALLBACK(show_fog_of_war_callback), MGROUP_SAFE },
415   { "FULL_SCREEN", N_("_Fullscreen"), GDK_KEY_Return, GDK_MOD1_MASK,
416     G_CALLBACK(full_screen_callback), MGROUP_SAFE },
417 
418   { "RECALC_BORDERS", N_("Recalculate _Borders"), 0, 0,
419     G_CALLBACK(recalc_borders_callback), MGROUP_EDIT },
420   { "TOGGLE_FOG", N_("Toggle Fog of _War"), GDK_KEY_m, GDK_CONTROL_MASK,
421     G_CALLBACK(toggle_fog_callback), MGROUP_EDIT },
422   { "SCENARIO_PROPERTIES", N_("Game/Scenario Properties"), 0, 0,
423     G_CALLBACK(scenario_properties_callback), MGROUP_EDIT },
424   { "SAVE_SCENARIO", N_("Save Scenario"), 0, 0,
425     G_CALLBACK(save_scenario_callback), MGROUP_EDIT },
426 
427   { "CENTER_VIEW", N_("_Center View"), GDK_KEY_c, 0,
428     G_CALLBACK(center_view_callback), MGROUP_PLAYER },
429   { "REPORT_ECONOMY", N_("_Economy"), GDK_KEY_F5, 0,
430     G_CALLBACK(report_economy_callback), MGROUP_PLAYER },
431   { "REPORT_RESEARCH", N_("_Research"), GDK_KEY_F6, 0,
432     G_CALLBACK(report_research_callback), MGROUP_PLAYER },
433   { "POLICIES", N_("_Policies..."),
434     GDK_KEY_p, GDK_SHIFT_MASK | GDK_CONTROL_MASK,
435     G_CALLBACK(multiplier_callback), MGROUP_PLAYER },
436   { "REPORT_SPACESHIP", N_("_Spaceship"), GDK_KEY_F12, 0,
437     G_CALLBACK(report_spaceship_callback), MGROUP_PLAYER },
438   { "REPORT_ACHIEVEMENTS", N_("_Achievements"), GDK_KEY_asterisk, 0,
439     G_CALLBACK(report_achievements_callback), MGROUP_PLAYER },
440 
441   { "MENU_SELECT", N_("_Select"), 0, 0, NULL, MGROUP_UNIT },
442   { "MENU_UNIT", N_("_Unit"), 0, 0, NULL, MGROUP_UNIT },
443   { "MENU_WORK", N_("_Work"), 0, 0, NULL, MGROUP_UNIT },
444   { "MENU_COMBAT", N_("_Combat"), 0, 0, NULL, MGROUP_UNIT },
445   { "MENU_BUILD_BASE", N_("Build _Base"), 0, 0, NULL, MGROUP_UNIT },
446   { "MENU_BUILD_PATH", N_("Build _Path"), 0, 0, NULL, MGROUP_UNIT },
447   { "SELECT_SINGLE", N_("_Single Unit (Unselect Others)"), GDK_KEY_z, 0,
448     G_CALLBACK(select_single_callback), MGROUP_UNIT },
449   { "SELECT_ALL_ON_TILE", N_("_All On Tile"), GDK_KEY_v, 0,
450     G_CALLBACK(select_all_on_tile_callback), MGROUP_UNIT },
451   { "SELECT_SAME_TYPE_TILE", N_("Same Type on _Tile"),
452     GDK_KEY_v, GDK_SHIFT_MASK,
453     G_CALLBACK(select_same_type_tile_callback), MGROUP_UNIT },
454   { "SELECT_SAME_TYPE_CONT", N_("Same Type on _Continent"),
455     GDK_KEY_c, GDK_SHIFT_MASK,
456     G_CALLBACK(select_same_type_cont_callback), MGROUP_UNIT },
457   { "SELECT_SAME_TYPE", N_("Same Type _Everywhere"), GDK_KEY_x, GDK_SHIFT_MASK,
458     G_CALLBACK(select_same_type_callback), MGROUP_UNIT },
459   { "SELECT_DLG", N_("Unit Selection Dialog"), 0, 0,
460     G_CALLBACK(select_dialog_callback), MGROUP_UNIT },
461   { "UNIT_WAIT", N_("_Wait"), GDK_KEY_w, 0,
462     G_CALLBACK(unit_wait_callback), MGROUP_UNIT },
463   { "UNIT_DONE", N_("_Done"), GDK_KEY_space, 0,
464     G_CALLBACK(unit_done_callback), MGROUP_UNIT },
465   { "UNIT_GOTO", N_("_Go to"), GDK_KEY_g, 0,
466     G_CALLBACK(unit_goto_callback), MGROUP_UNIT },
467   { "UNIT_GOTO_CITY", N_("Go _to/Airlift to City..."), GDK_KEY_t, 0,
468     G_CALLBACK(unit_goto_city_callback), MGROUP_UNIT },
469   { "UNIT_RETURN", N_("_Return to Nearest City"), GDK_KEY_g, GDK_SHIFT_MASK,
470     G_CALLBACK(unit_return_callback), MGROUP_UNIT },
471   { "UNIT_EXPLORE", N_("Auto E_xplore"), GDK_KEY_x, 0,
472     G_CALLBACK(unit_explore_callback), MGROUP_UNIT },
473   { "UNIT_PATROL", N_("_Patrol"), GDK_KEY_q, 0,
474     G_CALLBACK(unit_patrol_callback), MGROUP_UNIT },
475   { "UNIT_SENTRY", N_("_Sentry"), GDK_KEY_s, 0,
476     G_CALLBACK(unit_sentry_callback), MGROUP_UNIT },
477   { "UNIT_UNSENTRY", N_("Uns_entry All On Tile"), GDK_KEY_s, GDK_SHIFT_MASK,
478     G_CALLBACK(unit_unsentry_callback), MGROUP_UNIT },
479   { "UNIT_LOAD", N_("_Load"), GDK_KEY_l, 0,
480     G_CALLBACK(unit_load_callback), MGROUP_UNIT },
481   { "UNIT_UNLOAD", N_("_Unload"), GDK_KEY_u, 0,
482     G_CALLBACK(unit_unload_callback), MGROUP_UNIT },
483   { "UNIT_UNLOAD_TRANSPORTER", N_("U_nload All From Transporter"),
484     GDK_KEY_t, GDK_SHIFT_MASK,
485     G_CALLBACK(unit_unload_transporter_callback), MGROUP_UNIT },
486   { "UNIT_HOMECITY", N_("Set _Home City"), GDK_KEY_h, 0,
487     G_CALLBACK(unit_homecity_callback), MGROUP_UNIT },
488   { "UNIT_UPGRADE", N_("Upgr_ade"), GDK_KEY_u, GDK_SHIFT_MASK,
489     G_CALLBACK(unit_upgrade_callback), MGROUP_UNIT },
490   { "UNIT_CONVERT", N_("C_onvert"), GDK_KEY_o, GDK_SHIFT_MASK,
491     G_CALLBACK(unit_convert_callback), MGROUP_UNIT },
492   { "UNIT_DISBAND", N_("_Disband"), GDK_KEY_d, GDK_SHIFT_MASK,
493     G_CALLBACK(unit_disband_callback), MGROUP_UNIT },
494   { "BUILD_CITY", N_("_Build City"), GDK_KEY_b, 0,
495     G_CALLBACK(build_city_callback), MGROUP_UNIT },
496   { "GO_BUILD_CITY", N_("Go _to and Build city"), GDK_KEY_b, GDK_SHIFT_MASK,
497     G_CALLBACK(go_build_city_callback), MGROUP_UNIT },
498   { "AUTO_SETTLER", N_("_Auto Settler"), GDK_KEY_a, 0,
499     G_CALLBACK(auto_settle_callback), MGROUP_UNIT },
500   { "BUILD_ROAD", N_("Build _Road"), GDK_KEY_r, 0,
501     G_CALLBACK(build_road_callback), MGROUP_UNIT },
502   { "BUILD_IRRIGATION", N_("Build _Irrigation"), GDK_KEY_i, 0,
503     G_CALLBACK(build_irrigation_callback), MGROUP_UNIT },
504   { "BUILD_MINE", N_("Build _Mine"), GDK_KEY_m, 0,
505     G_CALLBACK(build_mine_callback), MGROUP_UNIT },
506   { "CONNECT_ROAD", N_("Connect With Roa_d"), GDK_KEY_r, GDK_SHIFT_MASK,
507     G_CALLBACK(connect_road_callback), MGROUP_UNIT },
508   { "CONNECT_RAIL", N_("Connect With Rai_l"), GDK_KEY_l, GDK_SHIFT_MASK,
509     G_CALLBACK(connect_rail_callback), MGROUP_UNIT },
510   { "CONNECT_IRRIGATION", N_("Connect With Irri_gation"),
511     GDK_KEY_i, GDK_SHIFT_MASK,
512     G_CALLBACK(connect_irrigation_callback), MGROUP_UNIT },
513   { "TRANSFORM_TERRAIN", N_("Transf_orm Terrain"), GDK_KEY_o, 0,
514     G_CALLBACK(transform_terrain_callback), MGROUP_UNIT },
515   { "CLEAN_POLLUTION", N_("Clean _Pollution"), GDK_KEY_p, 0,
516     G_CALLBACK(clean_pollution_callback), MGROUP_UNIT },
517   { "CLEAN_FALLOUT", N_("Clean _Nuclear Fallout"), GDK_KEY_n, 0,
518     G_CALLBACK(clean_fallout_callback), MGROUP_UNIT },
519   { "FORTIFY", N_("Fortify"), GDK_KEY_f, 0,
520     G_CALLBACK(fortify_callback), MGROUP_UNIT },
521   { "BUILD_FORTRESS", N_("Build Fortress"), GDK_KEY_f, GDK_SHIFT_MASK,
522     G_CALLBACK(build_fortress_callback), MGROUP_UNIT },
523   { "BUILD_AIRBASE", N_("Build Airbase"), GDK_KEY_e, GDK_SHIFT_MASK,
524     G_CALLBACK(build_airbase_callback), MGROUP_UNIT },
525   { "DO_PILLAGE", N_("_Pillage"), GDK_KEY_p, GDK_SHIFT_MASK,
526     G_CALLBACK(do_pillage_callback), MGROUP_UNIT },
527   { "DIPLOMAT_ACTION", N_("_Do..."), GDK_KEY_d, 0,
528     G_CALLBACK(diplomat_action_callback), MGROUP_UNIT },
529   { "EXPLODE_NUKE", N_("Explode _Nuclear"), GDK_KEY_n, GDK_SHIFT_MASK,
530     G_CALLBACK(explode_nuke_callback), MGROUP_UNIT },
531 
532   { "MENU_GOVERNMENT", N_("_Government"), 0, 0,
533     NULL, MGROUP_PLAYING },
534   { "TAX_RATE", N_("_Tax Rates..."), GDK_KEY_t, GDK_CONTROL_MASK,
535     G_CALLBACK(tax_rate_callback), MGROUP_PLAYING },
536   { "START_REVOLUTION", N_("_Revolution..."),
537     GDK_KEY_r, GDK_SHIFT_MASK | GDK_CONTROL_MASK,
538     G_CALLBACK(government_callback), MGROUP_PLAYING },
539   { NULL }
540 };
541 
542 static struct menu_entry_info *menu_entry_info_find(const char *key);
543 
544 /****************************************************************
545   Item "CLEAR_CHAT_LOGS" callback.
546 *****************************************************************/
clear_chat_logs_callback(GtkMenuItem * item,gpointer data)547 static void clear_chat_logs_callback(GtkMenuItem *item, gpointer data)
548 {
549   clear_output_window();
550 }
551 
552 /****************************************************************
553   Item "SAVE_CHAT_LOGS" callback.
554 *****************************************************************/
save_chat_logs_callback(GtkMenuItem * item,gpointer data)555 static void save_chat_logs_callback(GtkMenuItem *item, gpointer data)
556 {
557   log_output_window();
558 }
559 
560 /****************************************************************
561   Item "LOCAL_OPTIONS" callback.
562 *****************************************************************/
local_options_callback(GtkMenuItem * item,gpointer data)563 static void local_options_callback(GtkMenuItem *item, gpointer data)
564 {
565   option_dialog_popup(_("Set local options"), client_optset);
566 }
567 
568 /****************************************************************
569   Item "MESSAGE_OPTIONS" callback.
570 *****************************************************************/
message_options_callback(GtkMenuItem * item,gpointer data)571 static void message_options_callback(GtkMenuItem *item, gpointer data)
572 {
573   popup_messageopt_dialog();
574 }
575 
576 /****************************************************************
577   Item "SERVER_OPTIONS" callback.
578 *****************************************************************/
server_options_callback(GtkMenuItem * item,gpointer data)579 static void server_options_callback(GtkMenuItem *item, gpointer data)
580 {
581   option_dialog_popup(_("Game Settings"), server_optset);
582 }
583 
584 /****************************************************************
585   Item "SAVE_OPTIONS" callback.
586 *****************************************************************/
save_options_callback(GtkMenuItem * item,gpointer data)587 static void save_options_callback(GtkMenuItem *item, gpointer data)
588 {
589   options_save(NULL);
590 }
591 
592 /****************************************************************
593   Item "RELOAD_TILESET" callback.
594 *****************************************************************/
reload_tileset_callback(GtkMenuItem * item,gpointer data)595 static void reload_tileset_callback(GtkMenuItem *item, gpointer data)
596 {
597   tilespec_reread(NULL, TRUE, 1.0);
598 }
599 
600 /****************************************************************
601   Item "SAVE_GAME" callback.
602 *****************************************************************/
save_game_callback(GtkMenuItem * item,gpointer data)603 static void save_game_callback(GtkMenuItem *item, gpointer data)
604 {
605   send_save_game(NULL);
606 }
607 
608 /****************************************************************
609   Item "SAVE_GAME_AS" callback.
610 *****************************************************************/
save_game_as_callback(GtkMenuItem * item,gpointer data)611 static void save_game_as_callback(GtkMenuItem *item, gpointer data)
612 {
613   save_game_dialog_popup();
614 }
615 
616 /****************************************************************************
617   Item "SAVE_MAPIMG" callback.
618 ****************************************************************************/
save_mapimg_callback(GtkMenuItem * item,gpointer data)619 static void save_mapimg_callback(GtkMenuItem *item, gpointer data)
620 {
621   mapimg_client_save(NULL);
622 }
623 
624 /****************************************************************************
625   Item "SAVE_MAPIMG_AS" callback.
626 ****************************************************************************/
save_mapimg_as_callback(GtkMenuItem * item,gpointer data)627 static void save_mapimg_as_callback(GtkMenuItem *item, gpointer data)
628 {
629   save_mapimg_dialog_popup();
630 }
631 
632 /****************************************************************
633   This is the response callback for the dialog with the message:
634   Leaving a local game will end it!
635 ****************************************************************/
leave_local_game_response(GtkWidget * dialog,gint response)636 static void leave_local_game_response(GtkWidget *dialog, gint response)
637 {
638   gtk_widget_destroy(dialog);
639   if (response == GTK_RESPONSE_OK) {
640     /* It might be killed already */
641     if (client.conn.used) {
642       /* It will also kill the server */
643       disconnect_from_server();
644     }
645   }
646 }
647 
648 /****************************************************************
649   Item "LEAVE" callback.
650 *****************************************************************/
leave_callback(GtkMenuItem * item,gpointer data)651 static void leave_callback(GtkMenuItem *item, gpointer data)
652 {
653   if (is_server_running()) {
654     GtkWidget* dialog =
655         gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_WARNING,
656                                GTK_BUTTONS_OK_CANCEL,
657                                _("Leaving a local game will end it!"));
658     setup_dialog(dialog, toplevel);
659     gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
660     g_signal_connect(dialog, "response",
661                      G_CALLBACK(leave_local_game_response), NULL);
662     gtk_window_present(GTK_WINDOW(dialog));
663   } else {
664     disconnect_from_server();
665   }
666 }
667 
668 /****************************************************************
669   Item "QUIT" callback.
670 *****************************************************************/
quit_callback(GtkMenuItem * item,gpointer data)671 static void quit_callback(GtkMenuItem *item, gpointer data)
672 {
673   popup_quit_dialog();
674 }
675 
676 /****************************************************************
677   Item "FIND_CITY" callback.
678 *****************************************************************/
find_city_callback(GtkMenuItem * item,gpointer data)679 static void find_city_callback(GtkMenuItem *item, gpointer data)
680 {
681   popup_find_dialog();
682 }
683 
684 /****************************************************************
685   Item "WORKLISTS" callback.
686 *****************************************************************/
worklists_callback(GtkMenuItem * item,gpointer data)687 static void worklists_callback(GtkMenuItem *item, gpointer data)
688 {
689   popup_worklists_report();
690 }
691 
692 /****************************************************************
693   Item "MAP_VIEW" callback.
694 *****************************************************************/
map_view_callback(GtkMenuItem * item,gpointer data)695 static void map_view_callback(GtkMenuItem *item, gpointer data)
696 {
697   map_canvas_focus();
698 }
699 
700 /****************************************************************
701   Item "REPORT_NATIONS" callback.
702 *****************************************************************/
report_nations_callback(GtkMenuItem * item,gpointer data)703 static void report_nations_callback(GtkMenuItem *item, gpointer data)
704 {
705   popup_players_dialog(TRUE);
706 }
707 
708 /****************************************************************
709   Item "REPORT_WOW" callback.
710 *****************************************************************/
report_wow_callback(GtkMenuItem * item,gpointer data)711 static void report_wow_callback(GtkMenuItem *item, gpointer data)
712 {
713   send_report_request(REPORT_WONDERS_OF_THE_WORLD);
714 }
715 
716 /****************************************************************
717   Item "REPORT_TOP_CITIES" callback.
718 *****************************************************************/
report_top_cities_callback(GtkMenuItem * item,gpointer data)719 static void report_top_cities_callback(GtkMenuItem *item, gpointer data)
720 {
721   send_report_request(REPORT_TOP_5_CITIES);
722 }
723 
724 /****************************************************************
725   Item "REPORT_MESSAGES" callback.
726 *****************************************************************/
report_messages_callback(GtkMenuItem * item,gpointer data)727 static void report_messages_callback(GtkMenuItem *item, gpointer data)
728 {
729   meswin_dialog_popup(TRUE);
730 }
731 
732 /****************************************************************
733   Item "CLIENT_LUA_SCRIPT" callback.
734 *****************************************************************/
client_lua_script_callback(GtkMenuItem * item,gpointer data)735 static void client_lua_script_callback(GtkMenuItem *item, gpointer data)
736 {
737   luaconsole_dialog_popup(TRUE);
738 }
739 
740 /****************************************************************
741   Item "REPORT_DEMOGRAPHIC" callback.
742 *****************************************************************/
report_demographic_callback(GtkMenuItem * item,gpointer data)743 static void report_demographic_callback(GtkMenuItem *item, gpointer data)
744 {
745   send_report_request(REPORT_DEMOGRAPHIC);
746 }
747 
748 /****************************************************************
749   Item "REPORT_ACHIEVEMENTS" callback.
750 *****************************************************************/
report_achievements_callback(GtkMenuItem * item,gpointer data)751 static void report_achievements_callback(GtkMenuItem *item, gpointer data)
752 {
753   send_report_request(REPORT_ACHIEVEMENTS);
754 }
755 
756 /****************************************************************
757   Item "HELP_LANGUAGE" callback.
758 *****************************************************************/
help_language_callback(GtkMenuItem * item,gpointer data)759 static void help_language_callback(GtkMenuItem *item, gpointer data)
760 {
761   popup_help_dialog_string(HELP_LANGUAGES_ITEM);
762 }
763 
764 /****************************************************************
765   Item "HELP_POLICIES" callback.
766 *****************************************************************/
help_policies_callback(GtkMenuItem * item,gpointer data)767 static void help_policies_callback(GtkMenuItem *item, gpointer data)
768 {
769   popup_help_dialog_string(HELP_MULTIPLIER_ITEM);
770 }
771 
772 /****************************************************************
773   Item "HELP_CONNECTING" callback.
774 *****************************************************************/
help_connecting_callback(GtkMenuItem * item,gpointer data)775 static void help_connecting_callback(GtkMenuItem *item, gpointer data)
776 {
777   popup_help_dialog_string(HELP_CONNECTING_ITEM);
778 }
779 
780 /****************************************************************
781   Item "HELP_CONTROLS" callback.
782 *****************************************************************/
help_controls_callback(GtkMenuItem * item,gpointer data)783 static void help_controls_callback(GtkMenuItem *item, gpointer data)
784 {
785   popup_help_dialog_string(HELP_CONTROLS_ITEM);
786 }
787 
788 /****************************************************************
789   Item "HELP_CHATLINE" callback.
790 *****************************************************************/
help_chatline_callback(GtkMenuItem * item,gpointer data)791 static void help_chatline_callback(GtkMenuItem *item, gpointer data)
792 {
793   popup_help_dialog_string(HELP_CHATLINE_ITEM);
794 }
795 
796 /****************************************************************
797   Item "HELP_WORKLIST_EDITOR" callback.
798 *****************************************************************/
help_worklist_editor_callback(GtkMenuItem * item,gpointer data)799 static void help_worklist_editor_callback(GtkMenuItem *item, gpointer data)
800 {
801   popup_help_dialog_string(HELP_WORKLIST_EDITOR_ITEM);
802 }
803 
804 /****************************************************************
805   Item "HELP_CMA" callback.
806 *****************************************************************/
help_cma_callback(GtkMenuItem * item,gpointer data)807 static void help_cma_callback(GtkMenuItem *item, gpointer data)
808 {
809   popup_help_dialog_string(HELP_CMA_ITEM);
810 }
811 
812 /****************************************************************
813   Item "HELP_OVERVIEW" callback.
814 *****************************************************************/
help_overview_callback(GtkMenuItem * item,gpointer data)815 static void help_overview_callback(GtkMenuItem *item, gpointer data)
816 {
817   popup_help_dialog_string(HELP_OVERVIEW_ITEM);
818 }
819 
820 /****************************************************************
821   Item "HELP_PLAYING" callback.
822 *****************************************************************/
help_playing_callback(GtkMenuItem * item,gpointer data)823 static void help_playing_callback(GtkMenuItem *item, gpointer data)
824 {
825   popup_help_dialog_string(HELP_PLAYING_ITEM);
826 }
827 
828 /****************************************************************
829   Item "HELP_RULESET" callback.
830 *****************************************************************/
help_ruleset_callback(GtkMenuItem * item,gpointer data)831 static void help_ruleset_callback(GtkMenuItem *item, gpointer data)
832 {
833   popup_help_dialog_string(HELP_RULESET_ITEM);
834 }
835 
836 /****************************************************************
837   Item "HELP_TILESET" callback.
838 *****************************************************************/
help_tileset_callback(GtkMenuItem * item,gpointer data)839 static void help_tileset_callback(GtkMenuItem *item, gpointer data)
840 {
841   popup_help_dialog_string(HELP_TILESET_ITEM);
842 }
843 
844 /****************************************************************
845   Item "HELP_ECONOMY" callback.
846 *****************************************************************/
help_economy_callback(GtkMenuItem * item,gpointer data)847 static void help_economy_callback(GtkMenuItem *item, gpointer data)
848 {
849   popup_help_dialog_string(HELP_ECONOMY_ITEM);
850 }
851 
852 /****************************************************************
853   Item "HELP_CITIES" callback.
854 *****************************************************************/
help_cities_callback(GtkMenuItem * item,gpointer data)855 static void help_cities_callback(GtkMenuItem *item, gpointer data)
856 {
857   popup_help_dialog_string(HELP_CITIES_ITEM);
858 }
859 
860 /****************************************************************
861   Item "HELP_IMPROVEMENTS" callback.
862 *****************************************************************/
help_improvements_callback(GtkMenuItem * item,gpointer data)863 static void help_improvements_callback(GtkMenuItem *item, gpointer data)
864 {
865   popup_help_dialog_string(HELP_IMPROVEMENTS_ITEM);
866 }
867 
868 /****************************************************************
869   Item "HELP_UNITS" callback.
870 *****************************************************************/
help_units_callback(GtkMenuItem * item,gpointer data)871 static void help_units_callback(GtkMenuItem *item, gpointer data)
872 {
873   popup_help_dialog_string(HELP_UNITS_ITEM);
874 }
875 
876 /****************************************************************
877   Item "HELP_COMBAT" callback.
878 *****************************************************************/
help_combat_callback(GtkMenuItem * item,gpointer data)879 static void help_combat_callback(GtkMenuItem *item, gpointer data)
880 {
881   popup_help_dialog_string(HELP_COMBAT_ITEM);
882 }
883 
884 /****************************************************************
885   Item "HELP_ZOC" callback.
886 *****************************************************************/
help_zoc_callback(GtkMenuItem * item,gpointer data)887 static void help_zoc_callback(GtkMenuItem *item, gpointer data)
888 {
889   popup_help_dialog_string(HELP_ZOC_ITEM);
890 }
891 
892 /****************************************************************
893   Item "HELP_TECH" callback.
894 *****************************************************************/
help_tech_callback(GtkMenuItem * item,gpointer data)895 static void help_tech_callback(GtkMenuItem *item, gpointer data)
896 {
897   popup_help_dialog_string(HELP_TECHS_ITEM);
898 }
899 
900 /****************************************************************
901   Item "HELP_TERRAIN" callback.
902 *****************************************************************/
help_terrain_callback(GtkMenuItem * item,gpointer data)903 static void help_terrain_callback(GtkMenuItem *item, gpointer data)
904 {
905   popup_help_dialog_string(HELP_TERRAIN_ITEM);
906 }
907 
908 /****************************************************************
909   Item "HELP_WONDERS" callback.
910 *****************************************************************/
help_wonders_callback(GtkMenuItem * item,gpointer data)911 static void help_wonders_callback(GtkMenuItem *item, gpointer data)
912 {
913   popup_help_dialog_string(HELP_WONDERS_ITEM);
914 }
915 
916 /****************************************************************
917   Item "HELP_GOVERNMENT" callback.
918 *****************************************************************/
help_government_callback(GtkMenuItem * item,gpointer data)919 static void help_government_callback(GtkMenuItem *item, gpointer data)
920 {
921   popup_help_dialog_string(HELP_GOVERNMENT_ITEM);
922 }
923 
924 /****************************************************************
925   Item "HELP_DIPLOMACY" callback.
926 *****************************************************************/
help_diplomacy_callback(GtkMenuItem * item,gpointer data)927 static void help_diplomacy_callback(GtkMenuItem *item, gpointer data)
928 {
929   popup_help_dialog_string(HELP_DIPLOMACY_ITEM);
930 }
931 
932 /****************************************************************
933   Item "HELP_SPACE_RACE" callback.
934 *****************************************************************/
help_space_race_callback(GtkMenuItem * item,gpointer data)935 static void help_space_race_callback(GtkMenuItem *item, gpointer data)
936 {
937   popup_help_dialog_string(HELP_SPACE_RACE_ITEM);
938 }
939 
940 /****************************************************************
941   Item "HELP_NATIONS" callback.
942 *****************************************************************/
help_nations_callback(GtkMenuItem * item,gpointer data)943 static void help_nations_callback(GtkMenuItem *item, gpointer data)
944 {
945   popup_help_dialog_string(HELP_NATIONS_ITEM);
946 }
947 
948 /****************************************************************
949   Item "HELP_COPYING" callback.
950 *****************************************************************/
help_copying_callback(GtkMenuItem * item,gpointer data)951 static void help_copying_callback(GtkMenuItem *item, gpointer data)
952 {
953   popup_help_dialog_string(HELP_COPYING_ITEM);
954 }
955 
956 /****************************************************************
957   Item "HELP_ABOUT" callback.
958 *****************************************************************/
help_about_callback(GtkMenuItem * item,gpointer data)959 static void help_about_callback(GtkMenuItem *item, gpointer data)
960 {
961   popup_help_dialog_string(HELP_ABOUT_ITEM);
962 }
963 
964 /****************************************************************
965   Item "SAVE_OPTIONS_ON_EXIT" callback.
966 *****************************************************************/
save_options_on_exit_callback(GtkCheckMenuItem * item,gpointer data)967 static void save_options_on_exit_callback(GtkCheckMenuItem *item,
968                                           gpointer data)
969 {
970   gui_options.save_options_on_exit = gtk_check_menu_item_get_active(item);
971 }
972 
973 /****************************************************************
974   Item "EDIT_MODE" callback.
975 *****************************************************************/
edit_mode_callback(GtkCheckMenuItem * item,gpointer data)976 static void edit_mode_callback(GtkCheckMenuItem *item, gpointer data)
977 {
978   if (game.info.is_edit_mode ^ gtk_check_menu_item_get_active(item)) {
979     key_editor_toggle();
980     /* Unreachbale techs in reqtree on/off */
981     science_report_dialog_popdown();
982   }
983 }
984 
985 /****************************************************************
986   Item "SHOW_CITY_OUTLINES" callback.
987 *****************************************************************/
show_city_outlines_callback(GtkCheckMenuItem * item,gpointer data)988 static void show_city_outlines_callback(GtkCheckMenuItem *item,
989                                         gpointer data)
990 {
991   if (gui_options.draw_city_outlines ^ gtk_check_menu_item_get_active(item)) {
992     key_city_outlines_toggle();
993   }
994 }
995 
996 /****************************************************************
997   Item "SHOW_CITY_OUTPUT" callback.
998 *****************************************************************/
show_city_output_callback(GtkCheckMenuItem * item,gpointer data)999 static void show_city_output_callback(GtkCheckMenuItem *item,
1000                                       gpointer data)
1001 {
1002   if (gui_options.draw_city_output ^ gtk_check_menu_item_get_active(item)) {
1003     key_city_output_toggle();
1004   }
1005 }
1006 
1007 /****************************************************************
1008   Item "SHOW_MAP_GRID" callback.
1009 *****************************************************************/
show_map_grid_callback(GtkCheckMenuItem * item,gpointer data)1010 static void show_map_grid_callback(GtkCheckMenuItem *item,
1011                                    gpointer data)
1012 {
1013   if (gui_options.draw_map_grid ^ gtk_check_menu_item_get_active(item)) {
1014     key_map_grid_toggle();
1015   }
1016 }
1017 
1018 /****************************************************************
1019   Item "SHOW_NATIONAL_BORDERS" callback.
1020 *****************************************************************/
show_national_borders_callback(GtkCheckMenuItem * item,gpointer data)1021 static void show_national_borders_callback(GtkCheckMenuItem *item,
1022                                            gpointer data)
1023 {
1024   if (gui_options.draw_borders ^ gtk_check_menu_item_get_active(item)) {
1025     key_map_borders_toggle();
1026   }
1027 }
1028 
1029 /****************************************************************
1030   Item "SHOW_NATIVE_TILES" callback.
1031 *****************************************************************/
show_native_tiles_callback(GtkCheckMenuItem * item,gpointer data)1032 static void show_native_tiles_callback(GtkCheckMenuItem *item,
1033                                        gpointer data)
1034 {
1035   if (gui_options.draw_native ^ gtk_check_menu_item_get_active(item)) {
1036     key_map_native_toggle();
1037   }
1038 }
1039 
1040 /****************************************************************
1041   Item "SHOW_CITY_FULL_BAR" callback.
1042 *****************************************************************/
show_city_full_bar_callback(GtkCheckMenuItem * item,gpointer data)1043 static void show_city_full_bar_callback(GtkCheckMenuItem *item,
1044                                         gpointer data)
1045 {
1046   if (gui_options.draw_full_citybar ^ gtk_check_menu_item_get_active(item)) {
1047     key_city_full_bar_toggle();
1048     view_menu_update_sensitivity();
1049   }
1050 }
1051 
1052 /****************************************************************
1053   Item "SHOW_CITY_NAMES" callback.
1054 *****************************************************************/
show_city_names_callback(GtkCheckMenuItem * item,gpointer data)1055 static void show_city_names_callback(GtkCheckMenuItem *item,
1056                                      gpointer data)
1057 {
1058   if (gui_options.draw_city_names ^ gtk_check_menu_item_get_active(item)) {
1059     key_city_names_toggle();
1060     view_menu_update_sensitivity();
1061   }
1062 }
1063 
1064 /****************************************************************
1065   Item "SHOW_CITY_GROWTH" callback.
1066 *****************************************************************/
show_city_growth_callback(GtkCheckMenuItem * item,gpointer data)1067 static void show_city_growth_callback(GtkCheckMenuItem *item,
1068                                       gpointer data)
1069 {
1070   if (gui_options.draw_city_growth ^ gtk_check_menu_item_get_active(item)) {
1071     key_city_growth_toggle();
1072   }
1073 }
1074 
1075 /****************************************************************
1076   Item "SHOW_CITY_PRODUCTIONS" callback.
1077 *****************************************************************/
show_city_productions_callback(GtkCheckMenuItem * item,gpointer data)1078 static void show_city_productions_callback(GtkCheckMenuItem *item,
1079                                            gpointer data)
1080 {
1081   if (gui_options.draw_city_productions ^ gtk_check_menu_item_get_active(item)) {
1082     key_city_productions_toggle();
1083     view_menu_update_sensitivity();
1084   }
1085 }
1086 
1087 /****************************************************************
1088   Item "SHOW_CITY_BUY_COST" callback.
1089 *****************************************************************/
show_city_buy_cost_callback(GtkCheckMenuItem * item,gpointer data)1090 static void show_city_buy_cost_callback(GtkCheckMenuItem *item,
1091                                         gpointer data)
1092 {
1093   if (gui_options.draw_city_buycost ^ gtk_check_menu_item_get_active(item)) {
1094     key_city_buycost_toggle();
1095   }
1096 }
1097 
1098 /****************************************************************
1099   Item "SHOW_CITY_TRADE_ROUTES" callback.
1100 *****************************************************************/
show_city_trade_routes_callback(GtkCheckMenuItem * item,gpointer data)1101 static void show_city_trade_routes_callback(GtkCheckMenuItem *item,
1102                                             gpointer data)
1103 {
1104   if (gui_options.draw_city_trade_routes ^ gtk_check_menu_item_get_active(item)) {
1105     key_city_trade_routes_toggle();
1106   }
1107 }
1108 
1109 /****************************************************************
1110   Item "SHOW_TERRAIN" callback.
1111 *****************************************************************/
show_terrain_callback(GtkCheckMenuItem * item,gpointer data)1112 static void show_terrain_callback(GtkCheckMenuItem *item, gpointer data)
1113 {
1114   if (gui_options.draw_terrain ^ gtk_check_menu_item_get_active(item)) {
1115     key_terrain_toggle();
1116     view_menu_update_sensitivity();
1117   }
1118 }
1119 
1120 /****************************************************************
1121   Item "SHOW_COASTLINE" callback.
1122 *****************************************************************/
show_coastline_callback(GtkCheckMenuItem * item,gpointer data)1123 static void show_coastline_callback(GtkCheckMenuItem *item, gpointer data)
1124 {
1125   if (gui_options.draw_coastline ^ gtk_check_menu_item_get_active(item)) {
1126     key_coastline_toggle();
1127   }
1128 }
1129 
1130 /****************************************************************
1131   Item "SHOW_ROAD_RAILS" callback.
1132 *****************************************************************/
show_road_rails_callback(GtkCheckMenuItem * item,gpointer data)1133 static void show_road_rails_callback(GtkCheckMenuItem *item, gpointer data)
1134 {
1135   if (gui_options.draw_roads_rails ^ gtk_check_menu_item_get_active(item)) {
1136     key_roads_rails_toggle();
1137   }
1138 }
1139 
1140 /****************************************************************
1141   Item "SHOW_IRRIGATION" callback.
1142 *****************************************************************/
show_irrigation_callback(GtkCheckMenuItem * item,gpointer data)1143 static void show_irrigation_callback(GtkCheckMenuItem *item, gpointer data)
1144 {
1145   if (gui_options.draw_irrigation ^ gtk_check_menu_item_get_active(item)) {
1146     key_irrigation_toggle();
1147   }
1148 }
1149 
1150 /****************************************************************
1151   Item "SHOW_MINE" callback.
1152 *****************************************************************/
show_mine_callback(GtkCheckMenuItem * item,gpointer data)1153 static void show_mine_callback(GtkCheckMenuItem *item, gpointer data)
1154 {
1155   if (gui_options.draw_mines ^ gtk_check_menu_item_get_active(item)) {
1156     key_mines_toggle();
1157   }
1158 }
1159 
1160 /****************************************************************
1161   Item "SHOW_BASES" callback.
1162 *****************************************************************/
show_bases_callback(GtkCheckMenuItem * item,gpointer data)1163 static void show_bases_callback(GtkCheckMenuItem *item, gpointer data)
1164 {
1165   if (gui_options.draw_fortress_airbase ^ gtk_check_menu_item_get_active(item)) {
1166     key_bases_toggle();
1167   }
1168 }
1169 
1170 /****************************************************************
1171   Item "SHOW_RESOURCES" callback.
1172 *****************************************************************/
show_resources_callback(GtkCheckMenuItem * item,gpointer data)1173 static void show_resources_callback(GtkCheckMenuItem *item, gpointer data)
1174 {
1175   if (gui_options.draw_specials ^ gtk_check_menu_item_get_active(item)) {
1176     key_resources_toggle();
1177   }
1178 }
1179 
1180 /****************************************************************
1181   Item "SHOW_HUTS" callback.
1182 *****************************************************************/
show_huts_callback(GtkCheckMenuItem * item,gpointer data)1183 static void show_huts_callback(GtkCheckMenuItem *item, gpointer data)
1184 {
1185   if (gui_options.draw_huts ^ gtk_check_menu_item_get_active(item)) {
1186     key_huts_toggle();
1187   }
1188 }
1189 
1190 /****************************************************************
1191   Item "SHOW_POLLUTION" callback.
1192 *****************************************************************/
show_pollution_callback(GtkCheckMenuItem * item,gpointer data)1193 static void show_pollution_callback(GtkCheckMenuItem *item, gpointer data)
1194 {
1195   if (gui_options.draw_pollution ^ gtk_check_menu_item_get_active(item)) {
1196     key_pollution_toggle();
1197   }
1198 }
1199 
1200 /****************************************************************
1201   Item "SHOW_CITIES" callback.
1202 *****************************************************************/
show_cities_callback(GtkCheckMenuItem * item,gpointer data)1203 static void show_cities_callback(GtkCheckMenuItem *item, gpointer data)
1204 {
1205   if (gui_options.draw_cities ^ gtk_check_menu_item_get_active(item)) {
1206     key_cities_toggle();
1207   }
1208 }
1209 
1210 /****************************************************************
1211   Item "SHOW_UNITS" callback.
1212 *****************************************************************/
show_units_callback(GtkCheckMenuItem * item,gpointer data)1213 static void show_units_callback(GtkCheckMenuItem *item, gpointer data)
1214 {
1215   if (gui_options.draw_units ^ gtk_check_menu_item_get_active(item)) {
1216     key_units_toggle();
1217     view_menu_update_sensitivity();
1218   }
1219 }
1220 
1221 /****************************************************************
1222   Item "SHOW_UNIT_SOLID_BG" callback.
1223 *****************************************************************/
show_unit_solid_bg_callback(GtkCheckMenuItem * item,gpointer data)1224 static void show_unit_solid_bg_callback(GtkCheckMenuItem *item,
1225                                         gpointer data)
1226 {
1227   if (gui_options.solid_color_behind_units ^ gtk_check_menu_item_get_active(item)) {
1228     key_unit_solid_bg_toggle();
1229   }
1230 }
1231 
1232 /****************************************************************
1233   Item "SHOW_UNIT_SHIELDS" callback.
1234 *****************************************************************/
show_unit_shields_callback(GtkCheckMenuItem * item,gpointer data)1235 static void show_unit_shields_callback(GtkCheckMenuItem *item,
1236                                        gpointer data)
1237 {
1238   if (gui_options.draw_unit_shields ^ gtk_check_menu_item_get_active(item)) {
1239     key_unit_shields_toggle();
1240   }
1241 }
1242 
1243 /****************************************************************
1244   Item "SHOW_FOCUS_UNIT" callback.
1245 *****************************************************************/
show_focus_unit_callback(GtkCheckMenuItem * item,gpointer data)1246 static void show_focus_unit_callback(GtkCheckMenuItem *item, gpointer data)
1247 {
1248   if (gui_options.draw_focus_unit ^ gtk_check_menu_item_get_active(item)) {
1249     key_focus_unit_toggle();
1250     view_menu_update_sensitivity();
1251   }
1252 }
1253 
1254 /****************************************************************
1255   Item "SHOW_FOG_OF_WAR" callback.
1256 *****************************************************************/
show_fog_of_war_callback(GtkCheckMenuItem * item,gpointer data)1257 static void show_fog_of_war_callback(GtkCheckMenuItem *item, gpointer data)
1258 {
1259   if (gui_options.draw_fog_of_war ^ gtk_check_menu_item_get_active(item)) {
1260     key_fog_of_war_toggle();
1261     view_menu_update_sensitivity();
1262   }
1263 }
1264 
1265 /****************************************************************
1266   Item "FULL_SCREEN" callback.
1267 *****************************************************************/
full_screen_callback(GtkCheckMenuItem * item,gpointer data)1268 static void full_screen_callback(GtkCheckMenuItem *item, gpointer data)
1269 {
1270   if (GUI_GTK_OPTION(fullscreen) ^ gtk_check_menu_item_get_active(item)) {
1271     GUI_GTK_OPTION(fullscreen) ^= 1;
1272 
1273     if (GUI_GTK_OPTION(fullscreen)) {
1274       gtk_window_fullscreen(GTK_WINDOW(toplevel));
1275     } else {
1276       gtk_window_unfullscreen(GTK_WINDOW(toplevel));
1277     }
1278   }
1279 }
1280 
1281 /****************************************************************
1282   Item "RECALC_BORDERS" callback.
1283 *****************************************************************/
recalc_borders_callback(GtkMenuItem * item,gpointer data)1284 static void recalc_borders_callback(GtkMenuItem *item, gpointer data)
1285 {
1286   key_editor_recalculate_borders();
1287 }
1288 
1289 /****************************************************************
1290   Item "TOGGLE_FOG" callback.
1291 *****************************************************************/
toggle_fog_callback(GtkMenuItem * item,gpointer data)1292 static void toggle_fog_callback(GtkMenuItem *item, gpointer data)
1293 {
1294   key_editor_toggle_fogofwar();
1295 }
1296 
1297 /****************************************************************
1298   Item "SCENARIO_PROPERTIES" callback.
1299 *****************************************************************/
scenario_properties_callback(GtkMenuItem * item,gpointer data)1300 static void scenario_properties_callback(GtkMenuItem *item, gpointer data)
1301 {
1302   struct property_editor *pe;
1303 
1304   pe = editprop_get_property_editor();
1305   property_editor_reload(pe, OBJTYPE_GAME);
1306   property_editor_popup(pe, OBJTYPE_GAME);
1307 }
1308 
1309 /****************************************************************
1310   Item "SAVE_SCENARIO" callback.
1311 *****************************************************************/
save_scenario_callback(GtkMenuItem * item,gpointer data)1312 static void save_scenario_callback(GtkMenuItem *item, gpointer data)
1313 {
1314   save_scenario_dialog_popup();
1315 }
1316 
1317 /****************************************************************
1318   Item "SELECT_SINGLE" callback.
1319 *****************************************************************/
select_single_callback(GtkMenuItem * item,gpointer data)1320 static void select_single_callback(GtkMenuItem *item, gpointer data)
1321 {
1322   request_unit_select(get_units_in_focus(), SELTYPE_SINGLE, SELLOC_TILE);
1323 }
1324 
1325 /****************************************************************
1326   Item "SELECT_ALL_ON_TILE" callback.
1327 *****************************************************************/
select_all_on_tile_callback(GtkMenuItem * item,gpointer data)1328 static void select_all_on_tile_callback(GtkMenuItem *item, gpointer data)
1329 {
1330   request_unit_select(get_units_in_focus(), SELTYPE_ALL, SELLOC_TILE);
1331 }
1332 
1333 /****************************************************************
1334   Item "SELECT_SAME_TYPE_TILE" callback.
1335 *****************************************************************/
select_same_type_tile_callback(GtkMenuItem * item,gpointer data)1336 static void select_same_type_tile_callback(GtkMenuItem *item, gpointer data)
1337 {
1338   request_unit_select(get_units_in_focus(), SELTYPE_SAME, SELLOC_TILE);
1339 }
1340 
1341 /****************************************************************
1342   Item "SELECT_SAME_TYPE_CONT" callback.
1343 *****************************************************************/
select_same_type_cont_callback(GtkMenuItem * item,gpointer data)1344 static void select_same_type_cont_callback(GtkMenuItem *item, gpointer data)
1345 {
1346   request_unit_select(get_units_in_focus(), SELTYPE_SAME, SELLOC_CONT);
1347 }
1348 
1349 /****************************************************************
1350   Item "SELECT_SAME_TYPE" callback.
1351 *****************************************************************/
select_same_type_callback(GtkMenuItem * item,gpointer data)1352 static void select_same_type_callback(GtkMenuItem *item, gpointer data)
1353 {
1354   request_unit_select(get_units_in_focus(), SELTYPE_SAME, SELLOC_WORLD);
1355 }
1356 
1357 /*****************************************************************************
1358   Open unit selection dialog.
1359 *****************************************************************************/
select_dialog_callback(GtkMenuItem * item,gpointer data)1360 static void select_dialog_callback(GtkMenuItem *item, gpointer data)
1361 {
1362   unit_select_dialog_popup(NULL);
1363 }
1364 
1365 /****************************************************************
1366   Item "UNIT_WAIT" callback.
1367 *****************************************************************/
unit_wait_callback(GtkMenuItem * item,gpointer data)1368 static void unit_wait_callback(GtkMenuItem *item, gpointer data)
1369 {
1370   key_unit_wait();
1371 }
1372 
1373 /****************************************************************
1374   Item "UNIT_DONE" callback.
1375 *****************************************************************/
unit_done_callback(GtkMenuItem * item,gpointer data)1376 static void unit_done_callback(GtkMenuItem *item, gpointer data)
1377 {
1378   key_unit_done();
1379 }
1380 
1381 /****************************************************************
1382   Item "UNIT_GOTO" callback.
1383 *****************************************************************/
unit_goto_callback(GtkMenuItem * item,gpointer data)1384 static void unit_goto_callback(GtkMenuItem *item, gpointer data)
1385 {
1386   key_unit_goto();
1387 }
1388 
1389 /****************************************************************
1390   Item "UNIT_GOTO_CITY" callback.
1391 *****************************************************************/
unit_goto_city_callback(GtkMenuItem * item,gpointer data)1392 static void unit_goto_city_callback(GtkMenuItem *item, gpointer data)
1393 {
1394   if (get_num_units_in_focus() > 0) {
1395     popup_goto_dialog();
1396   }
1397 }
1398 
1399 /****************************************************************
1400   Item "UNIT_RETURN" callback.
1401 *****************************************************************/
unit_return_callback(GtkMenuItem * item,gpointer data)1402 static void unit_return_callback(GtkMenuItem *item, gpointer data)
1403 {
1404   unit_list_iterate(get_units_in_focus(), punit) {
1405     request_unit_return(punit);
1406   } unit_list_iterate_end;
1407 }
1408 
1409 /****************************************************************
1410   Item "UNIT_EXPLORE" callback.
1411 *****************************************************************/
unit_explore_callback(GtkMenuItem * item,gpointer data)1412 static void unit_explore_callback(GtkMenuItem *item, gpointer data)
1413 {
1414   key_unit_auto_explore();
1415 }
1416 
1417 /****************************************************************
1418   Item "UNIT_PATROL" callback.
1419 *****************************************************************/
unit_patrol_callback(GtkMenuItem * item,gpointer data)1420 static void unit_patrol_callback(GtkMenuItem *item, gpointer data)
1421 {
1422   key_unit_patrol();
1423 }
1424 
1425 /****************************************************************
1426   Item "UNIT_SENTRY" callback.
1427 *****************************************************************/
unit_sentry_callback(GtkMenuItem * item,gpointer data)1428 static void unit_sentry_callback(GtkMenuItem *item, gpointer data)
1429 {
1430   key_unit_sentry();
1431 }
1432 
1433 /****************************************************************
1434   Item "UNIT_UNSENTRY" callback.
1435 *****************************************************************/
unit_unsentry_callback(GtkMenuItem * item,gpointer data)1436 static void unit_unsentry_callback(GtkMenuItem *item, gpointer data)
1437 {
1438   key_unit_wakeup_others();
1439 }
1440 
1441 /****************************************************************
1442   Item "UNIT_LOAD" callback.
1443 *****************************************************************/
unit_load_callback(GtkMenuItem * item,gpointer data)1444 static void unit_load_callback(GtkMenuItem *item, gpointer data)
1445 {
1446   unit_list_iterate(get_units_in_focus(), punit) {
1447     request_transport(punit, unit_tile(punit));
1448   } unit_list_iterate_end;
1449 }
1450 
1451 /****************************************************************
1452   Item "UNIT_UNLOAD" callback.
1453 *****************************************************************/
unit_unload_callback(GtkMenuItem * item,gpointer data)1454 static void unit_unload_callback(GtkMenuItem *item, gpointer data)
1455 {
1456   unit_list_iterate(get_units_in_focus(), punit) {
1457     request_unit_unload(punit);
1458   } unit_list_iterate_end;
1459 }
1460 
1461 /****************************************************************
1462   Item "UNIT_UNLOAD_TRANSPORTER" callback.
1463 *****************************************************************/
unit_unload_transporter_callback(GtkMenuItem * item,gpointer data)1464 static void unit_unload_transporter_callback(GtkMenuItem *item,
1465                                              gpointer data)
1466 {
1467   key_unit_unload_all();
1468 }
1469 
1470 /****************************************************************
1471   Item "UNIT_HOMECITY" callback.
1472 *****************************************************************/
unit_homecity_callback(GtkMenuItem * item,gpointer data)1473 static void unit_homecity_callback(GtkMenuItem *item, gpointer data)
1474 {
1475   key_unit_homecity();
1476 }
1477 
1478 /****************************************************************
1479   Item "UNIT_UPGRADE" callback.
1480 *****************************************************************/
unit_upgrade_callback(GtkMenuItem * item,gpointer data)1481 static void unit_upgrade_callback(GtkMenuItem *item, gpointer data)
1482 {
1483   popup_upgrade_dialog(get_units_in_focus());
1484 }
1485 
1486 /****************************************************************
1487   Item "UNIT_CONVERT" callback.
1488 *****************************************************************/
unit_convert_callback(GtkMenuItem * item,gpointer data)1489 static void unit_convert_callback(GtkMenuItem *item, gpointer data)
1490 {
1491   key_unit_convert();
1492 }
1493 
1494 /****************************************************************
1495   Item "UNIT_DISBAND" callback.
1496 *****************************************************************/
unit_disband_callback(GtkMenuItem * item,gpointer data)1497 static void unit_disband_callback(GtkMenuItem *item, gpointer data)
1498 {
1499   popup_disband_dialog(get_units_in_focus());
1500 }
1501 
1502 /****************************************************************
1503   Item "BUILD_CITY" callback.
1504 *****************************************************************/
build_city_callback(GtkMenuItem * item,gpointer data)1505 static void build_city_callback(GtkMenuItem *item, gpointer data)
1506 {
1507   unit_list_iterate(get_units_in_focus(), punit) {
1508     /* FIXME: this can provide different items for different units...
1509      * not good! */
1510     /* Enable the button for adding to a city in all cases, so we
1511        get an eventual error message from the server if we try. */
1512     if (unit_can_add_or_build_city(punit)) {
1513       request_unit_build_city(punit);
1514     } else if (utype_can_do_action(unit_type_get(punit),
1515                                    ACTION_HELP_WONDER)) {
1516       request_unit_caravan_action(punit, ACTION_HELP_WONDER);
1517     }
1518   } unit_list_iterate_end;
1519 }
1520 
1521 /****************************************************************
1522   Action "GO_BUILD_CITY" callback.
1523 *****************************************************************/
go_build_city_callback(GtkMenuItem * action,gpointer data)1524 static void go_build_city_callback(GtkMenuItem *action, gpointer data)
1525 {
1526   request_unit_goto(ORDER_BUILD_CITY);
1527 }
1528 
1529 /****************************************************************
1530   Action "AUTO_SETTLE" callback.
1531 *****************************************************************/
auto_settle_callback(GtkMenuItem * action,gpointer data)1532 static void auto_settle_callback(GtkMenuItem *action, gpointer data)
1533 {
1534   key_unit_auto_settle();
1535 }
1536 
1537 /****************************************************************
1538   Action "BUILD_ROAD" callback.
1539 *****************************************************************/
build_road_callback(GtkMenuItem * action,gpointer data)1540 static void build_road_callback(GtkMenuItem *action, gpointer data)
1541 {
1542   unit_list_iterate(get_units_in_focus(), punit) {
1543     /* FIXME: this can provide different actions for different units...
1544      * not good! */
1545     struct extra_type *tgt = next_extra_for_tile(unit_tile(punit),
1546                                                  EC_ROAD,
1547                                                  unit_owner(punit),
1548                                                  punit);
1549     bool building_road = FALSE;
1550 
1551     if (tgt != NULL
1552         && can_unit_do_activity_targeted(punit, ACTIVITY_GEN_ROAD, tgt)) {
1553       request_new_unit_activity_targeted(punit, ACTIVITY_GEN_ROAD, tgt);
1554       building_road = TRUE;
1555     }
1556 
1557     if (!building_road && unit_can_est_trade_route_here(punit)) {
1558       request_unit_caravan_action(punit, ACTION_TRADE_ROUTE);
1559     }
1560   } unit_list_iterate_end;
1561 }
1562 
1563 /****************************************************************
1564   Action "BUILD_IRRIGATION" callback.
1565 *****************************************************************/
build_irrigation_callback(GtkMenuItem * action,gpointer data)1566 static void build_irrigation_callback(GtkMenuItem *action, gpointer data)
1567 {
1568   key_unit_irrigate();
1569 }
1570 
1571 /****************************************************************
1572   Action "BUILD_MINE" callback.
1573 *****************************************************************/
build_mine_callback(GtkMenuItem * action,gpointer data)1574 static void build_mine_callback(GtkMenuItem *action, gpointer data)
1575 {
1576   key_unit_mine();
1577 }
1578 
1579 /****************************************************************
1580   Action "CONNECT_ROAD" callback.
1581 *****************************************************************/
connect_road_callback(GtkMenuItem * action,gpointer data)1582 static void connect_road_callback(GtkMenuItem *action, gpointer data)
1583 {
1584   struct road_type *proad = road_by_compat_special(ROCO_ROAD);
1585 
1586   if (proad != NULL) {
1587     struct extra_type *tgt;
1588 
1589     tgt = road_extra_get(proad);
1590 
1591     key_unit_connect(ACTIVITY_GEN_ROAD, tgt);
1592   }
1593 }
1594 
1595 /****************************************************************
1596   Action "CONNECT_RAIL" callback.
1597 *****************************************************************/
connect_rail_callback(GtkMenuItem * action,gpointer data)1598 static void connect_rail_callback(GtkMenuItem *action, gpointer data)
1599 {
1600   struct road_type *prail = road_by_compat_special(ROCO_RAILROAD);
1601 
1602   if (prail != NULL) {
1603     struct extra_type *tgt;
1604 
1605     tgt = road_extra_get(prail);
1606 
1607     key_unit_connect(ACTIVITY_GEN_ROAD, tgt);
1608   }
1609 }
1610 
1611 /****************************************************************
1612   Action "CONNECT_IRRIGATION" callback.
1613 *****************************************************************/
connect_irrigation_callback(GtkMenuItem * action,gpointer data)1614 static void connect_irrigation_callback(GtkMenuItem *action, gpointer data)
1615 {
1616   struct extra_type_list *extras = extra_type_list_by_cause(EC_IRRIGATION);
1617 
1618   if (extra_type_list_size(extras) > 0) {
1619     struct extra_type *pextra;
1620 
1621     pextra = extra_type_list_get(extra_type_list_by_cause(EC_IRRIGATION), 0);
1622 
1623     key_unit_connect(ACTIVITY_IRRIGATE, pextra);
1624   }
1625 }
1626 
1627 /****************************************************************
1628   Action "TRANSFORM_TERRAIN" callback.
1629 *****************************************************************/
transform_terrain_callback(GtkMenuItem * action,gpointer data)1630 static void transform_terrain_callback(GtkMenuItem *action, gpointer data)
1631 {
1632   key_unit_transform();
1633 }
1634 
1635 /****************************************************************
1636   Action "CLEAN_POLLUTION" callback.
1637 *****************************************************************/
clean_pollution_callback(GtkMenuItem * action,gpointer data)1638 static void clean_pollution_callback(GtkMenuItem *action, gpointer data)
1639 {
1640   unit_list_iterate(get_units_in_focus(), punit) {
1641     /* FIXME: this can provide different actions for different units...
1642      * not good! */
1643     struct extra_type *pextra;
1644 
1645     pextra = prev_extra_in_tile(unit_tile(punit), ERM_CLEANPOLLUTION,
1646                                 unit_owner(punit), punit);
1647 
1648     if (pextra != NULL) {
1649       request_new_unit_activity_targeted(punit, ACTIVITY_POLLUTION, pextra);
1650     } else if (can_unit_paradrop(punit)) {
1651       /* FIXME: This is getting worse, we use a key_unit_*() function
1652        * which assign the order for all units!  Very bad! */
1653       key_unit_paradrop();
1654     }
1655   } unit_list_iterate_end;
1656 }
1657 
1658 /****************************************************************
1659   Action "CLEAN_FALLOUT" callback.
1660 *****************************************************************/
clean_fallout_callback(GtkMenuItem * action,gpointer data)1661 static void clean_fallout_callback(GtkMenuItem *action, gpointer data)
1662 {
1663   key_unit_fallout();
1664 }
1665 
1666 /****************************************************************
1667   Action "BUILD_FORTRESS" callback.
1668 *****************************************************************/
build_fortress_callback(GtkMenuItem * action,gpointer data)1669 static void build_fortress_callback(GtkMenuItem *action, gpointer data)
1670 {
1671   key_unit_fortress();
1672 }
1673 
1674 /****************************************************************
1675   Action "FORTIFY" callback.
1676 *****************************************************************/
fortify_callback(GtkMenuItem * action,gpointer data)1677 static void fortify_callback(GtkMenuItem *action, gpointer data)
1678 {
1679   unit_list_iterate(get_units_in_focus(), punit) {
1680     request_unit_fortify(punit);
1681   } unit_list_iterate_end;
1682 }
1683 
1684 /****************************************************************
1685   Action "BUILD_AIRBASE" callback.
1686 *****************************************************************/
build_airbase_callback(GtkMenuItem * action,gpointer data)1687 static void build_airbase_callback(GtkMenuItem *action, gpointer data)
1688 {
1689   key_unit_airbase();
1690 }
1691 
1692 /****************************************************************
1693   Action "DO_PILLAGE" callback.
1694 *****************************************************************/
do_pillage_callback(GtkMenuItem * action,gpointer data)1695 static void do_pillage_callback(GtkMenuItem *action, gpointer data)
1696 {
1697   key_unit_pillage();
1698 }
1699 
1700 /****************************************************************
1701   Action "DIPLOMAT_ACTION" callback.
1702 *****************************************************************/
diplomat_action_callback(GtkMenuItem * action,gpointer data)1703 static void diplomat_action_callback(GtkMenuItem *action, gpointer data)
1704 {
1705   key_unit_action_select_tgt();
1706 }
1707 
1708 /****************************************************************
1709   Action "EXPLODE_NUKE" callback.
1710 *****************************************************************/
explode_nuke_callback(GtkMenuItem * action,gpointer data)1711 static void explode_nuke_callback(GtkMenuItem *action, gpointer data)
1712 {
1713   key_unit_nuke();
1714 }
1715 
1716 /****************************************************************
1717   Action "TAX_RATE" callback.
1718 *****************************************************************/
tax_rate_callback(GtkMenuItem * action,gpointer data)1719 static void tax_rate_callback(GtkMenuItem *action, gpointer data)
1720 {
1721   popup_rates_dialog();
1722 }
1723 
1724 /****************************************************************
1725   Action "MULTIPLIERS" callback.
1726 *****************************************************************/
multiplier_callback(GtkMenuItem * action,gpointer data)1727 static void multiplier_callback(GtkMenuItem *action, gpointer data)
1728 {
1729   popup_multiplier_dialog();
1730 }
1731 
1732 /****************************************************************
1733   The player has chosen a government from the menu.
1734 *****************************************************************/
government_callback(GtkMenuItem * item,gpointer data)1735 static void government_callback(GtkMenuItem *item, gpointer data)
1736 {
1737   popup_revolution_dialog((struct government *) data);
1738 }
1739 
1740 /****************************************************************************
1741   The player has chosen a base to build from the menu.
1742 ****************************************************************************/
base_callback(GtkMenuItem * item,gpointer data)1743 static void base_callback(GtkMenuItem *item, gpointer data)
1744 {
1745   struct extra_type *pextra = data;
1746 
1747   unit_list_iterate(get_units_in_focus(), punit) {
1748     request_new_unit_activity_targeted(punit, ACTIVITY_BASE, pextra);
1749   } unit_list_iterate_end;
1750 }
1751 
1752 /****************************************************************************
1753   The player has chosen a road to build from the menu.
1754 ****************************************************************************/
road_callback(GtkMenuItem * item,gpointer data)1755 static void road_callback(GtkMenuItem *item, gpointer data)
1756 {
1757   struct extra_type *pextra = data;
1758 
1759   unit_list_iterate(get_units_in_focus(), punit) {
1760     request_new_unit_activity_targeted(punit, ACTIVITY_GEN_ROAD,
1761                                        pextra);
1762   } unit_list_iterate_end;
1763 }
1764 
1765 /****************************************************************
1766   Action "CENTER_VIEW" callback.
1767 *****************************************************************/
center_view_callback(GtkMenuItem * action,gpointer data)1768 static void center_view_callback(GtkMenuItem *action, gpointer data)
1769 {
1770   center_on_unit();
1771 }
1772 
1773 /****************************************************************
1774   Action "REPORT_UNITS" callback.
1775 *****************************************************************/
report_units_callback(GtkMenuItem * action,gpointer data)1776 static void report_units_callback(GtkMenuItem *action, gpointer data)
1777 {
1778   units_report_dialog_popup(TRUE);
1779 }
1780 
1781 /****************************************************************
1782   Action "REPORT_CITIES" callback.
1783 *****************************************************************/
report_cities_callback(GtkMenuItem * action,gpointer data)1784 static void report_cities_callback(GtkMenuItem *action, gpointer data)
1785 {
1786   city_report_dialog_popup(TRUE);
1787 }
1788 
1789 /****************************************************************
1790   Action "REPORT_ECONOMY" callback.
1791 *****************************************************************/
report_economy_callback(GtkMenuItem * action,gpointer data)1792 static void report_economy_callback(GtkMenuItem *action, gpointer data)
1793 {
1794   economy_report_dialog_popup(TRUE);
1795 }
1796 
1797 /****************************************************************
1798   Action "REPORT_RESEARCH" callback.
1799 *****************************************************************/
report_research_callback(GtkMenuItem * action,gpointer data)1800 static void report_research_callback(GtkMenuItem *action, gpointer data)
1801 {
1802   science_report_dialog_popup(TRUE);
1803 }
1804 
1805 /****************************************************************
1806   Action "REPORT_SPACESHIP" callback.
1807 *****************************************************************/
report_spaceship_callback(GtkMenuItem * action,gpointer data)1808 static void report_spaceship_callback(GtkMenuItem *action, gpointer data)
1809 {
1810   if (NULL != client.conn.playing) {
1811     popup_spaceship_dialog(client.conn.playing);
1812   }
1813 }
1814 
1815 /*****************************************************************
1816   Set name of the menu item.
1817 *****************************************************************/
menu_entry_init(GtkBuildable * item)1818 static void menu_entry_init(GtkBuildable *item)
1819 {
1820   const char *key = gtk_buildable_get_name(item);
1821   struct menu_entry_info *info = menu_entry_info_find(key);
1822 
1823   if (info != NULL) {
1824     gtk_menu_item_set_label(GTK_MENU_ITEM(item),
1825                             Q_(info->name));
1826     gtk_menu_item_set_use_underline(GTK_MENU_ITEM(item), TRUE);
1827     if (info->cb != NULL) {
1828       g_signal_connect(item, "activate", info->cb, NULL);
1829     }
1830 
1831     if (info->accel != 0) {
1832       const char *path = gtk_menu_item_get_accel_path(GTK_MENU_ITEM(item));
1833 
1834       if (path == NULL) {
1835         char buf[512];
1836 
1837         fc_snprintf(buf, sizeof(buf), "<MENU>/%s", key);
1838         gtk_menu_item_set_accel_path(GTK_MENU_ITEM(item), buf);
1839         path = buf; /* Not NULL, but not usable either outside this block */
1840       }
1841 
1842       if (path != NULL) {
1843         gtk_accel_map_add_entry(gtk_menu_item_get_accel_path(GTK_MENU_ITEM(item)),
1844                                 info->accel, info->accel_mod);
1845       }
1846     }
1847 
1848     return;
1849   }
1850 
1851   /* temporary naming solution */
1852   gtk_menu_item_set_label(GTK_MENU_ITEM(item), key);
1853 }
1854 
1855 /*****************************************************************
1856   Returns the name of the file readable by the GtkUIManager.
1857 *****************************************************************/
get_ui_filename(void)1858 static const gchar *get_ui_filename(void)
1859 {
1860   static char filename[256];
1861   const char *name;
1862 
1863   if ((name = getenv("FREECIV_MENUS"))
1864       || (name = fileinfoname(get_data_dirs(), "gtk3.22_menus.xml"))) {
1865     sz_strlcpy(filename, name);
1866   } else {
1867     log_error("Gtk menus: file definition not found");
1868     filename[0] = '\0';
1869   }
1870 
1871   log_verbose("ui menu file is \"%s\".", filename);
1872   return filename;
1873 }
1874 
1875 /*****************************************************************
1876   Creates the menu bar.
1877 *****************************************************************/
setup_menus(GtkWidget * window)1878 GtkWidget *setup_menus(GtkWidget *window)
1879 {
1880   GtkWidget *menubar = NULL;
1881   GError *error = NULL;
1882 
1883   ui_builder = gtk_builder_new();
1884   if (!gtk_builder_add_from_file(ui_builder, get_ui_filename(), &error)) {
1885     log_error("Gtk menus: %s", error->message);
1886     g_error_free(error);
1887   } else {
1888     GSList *entries;
1889     GSList *next;
1890 
1891     entries = gtk_builder_get_objects(ui_builder);
1892     next = entries;
1893 
1894     while (next != NULL) {
1895       GObject *obj = next->data;
1896 
1897       if (GTK_IS_MENU_ITEM(obj)) {
1898         if (!GTK_IS_SEPARATOR_MENU_ITEM(obj)) {
1899           menu_entry_init(GTK_BUILDABLE(obj));
1900         }
1901       } else if (GTK_IS_MENU(obj)) {
1902         const char *key = gtk_buildable_get_name(GTK_BUILDABLE(obj));
1903 
1904         if (key[0] == '<') {
1905           GtkAccelGroup *ac_group = gtk_menu_get_accel_group(GTK_MENU(obj));
1906 
1907           if (ac_group == NULL) {
1908             ac_group = gtk_accel_group_new();
1909             gtk_menu_set_accel_group(GTK_MENU(obj), ac_group);
1910           }
1911 
1912           gtk_window_add_accel_group(GTK_WINDOW(window), ac_group);
1913 
1914           gtk_menu_set_accel_path(GTK_MENU(obj), key);
1915         }
1916       }
1917 
1918       next = next->next;
1919     }
1920 
1921     g_slist_free(entries);
1922 
1923     menubar = GTK_WIDGET(gtk_builder_get_object(ui_builder, "MENU"));
1924     gtk_widget_set_visible(menubar, TRUE);
1925     gtk_widget_show_all(menubar);
1926   }
1927 
1928 #ifndef FREECIV_DEBUG
1929   menu_entry_set_visible("RELOAD_TILESET", FALSE, FALSE);
1930 #endif /* FREECIV_DEBUG */
1931 
1932   return menubar;
1933 }
1934 
1935 /*****************************************************************
1936   Find menu entry constrution data
1937 *****************************************************************/
menu_entry_info_find(const char * key)1938 static struct menu_entry_info *menu_entry_info_find(const char *key)
1939 {
1940   int i;
1941 
1942   for (i = 0; menu_entries[i].key != NULL; i++) {
1943     if (!strcmp(key, menu_entries[i].key)) {
1944       return &(menu_entries[i]);
1945     }
1946   }
1947 
1948   return NULL;
1949 }
1950 
1951 /*****************************************************************
1952   Sets an menu entry active.
1953 *****************************************************************/
menu_entry_set_active(const char * key,gboolean is_active)1954 static void menu_entry_set_active(const char *key,
1955                                   gboolean is_active)
1956 {
1957   GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM(gtk_builder_get_object(ui_builder, key));
1958 
1959   if (item != NULL) {
1960     gtk_check_menu_item_set_active(item, is_active);
1961   }
1962 }
1963 
1964 /*****************************************************************
1965   Sets sensitivity of an menu entry.
1966 *****************************************************************/
menu_entry_set_sensitive(const char * key,gboolean is_sensitive)1967 static void menu_entry_set_sensitive(const char *key,
1968                                      gboolean is_sensitive)
1969 {
1970   GtkWidget *item = GTK_WIDGET(gtk_builder_get_object(ui_builder, key));
1971 
1972   if (item != NULL) {
1973     gtk_widget_set_sensitive(item, is_sensitive);
1974   }
1975 }
1976 
1977 /*****************************************************************
1978   Set sensitivity of all entries in the group.
1979 *****************************************************************/
menu_entry_group_set_sensitive(enum menu_entry_grouping group,gboolean is_sensitive)1980 static void menu_entry_group_set_sensitive(enum menu_entry_grouping group,
1981                                            gboolean is_sensitive)
1982 {
1983   int i;
1984 
1985   for (i = 0; menu_entries[i].key != NULL; i++) {
1986     if (menu_entries[i].grouping == group || group == MGROUP_ALL) {
1987       menu_entry_set_sensitive(menu_entries[i].key, is_sensitive);
1988     }
1989   }
1990 }
1991 
1992 /****************************************************************
1993   Sets an action visible.
1994 *****************************************************************/
1995 #ifndef FREECIV_DEBUG
menu_entry_set_visible(const char * key,gboolean is_visible,gboolean is_sensitive)1996 static void menu_entry_set_visible(const char *key,
1997                                    gboolean is_visible,
1998                                    gboolean is_sensitive)
1999 {
2000   GtkWidget *item = GTK_WIDGET(gtk_builder_get_object(ui_builder, key));
2001 
2002   if (item != NULL) {
2003     gtk_widget_set_visible(item, is_visible);
2004     gtk_widget_set_sensitive(item, is_sensitive);
2005   }
2006 }
2007 #endif /* FREECIV_DEBUG */
2008 
2009 /****************************************************************
2010   Renames an action.
2011 *****************************************************************/
menus_rename(const char * key,const gchar * new_label)2012 static void menus_rename(const char *key,
2013                          const gchar *new_label)
2014 {
2015   GtkWidget *item = GTK_WIDGET(gtk_builder_get_object(ui_builder, key));
2016 
2017   if (item != NULL) {
2018     gtk_menu_item_set_label(GTK_MENU_ITEM(item), new_label);
2019   }
2020 }
2021 
2022 /****************************************************************
2023   Find the child menu of an action.
2024 *****************************************************************/
find_menu(const char * key)2025 static GtkMenu *find_menu(const char *key)
2026 {
2027   return GTK_MENU(gtk_builder_get_object(ui_builder, key));
2028 }
2029 
2030 /****************************************************************
2031   Update the sensitivity of the items in the view menu.
2032 *****************************************************************/
view_menu_update_sensitivity(void)2033 static void view_menu_update_sensitivity(void)
2034 {
2035   /* The "full" city bar (i.e. the new way of drawing the
2036    * city name), can draw the city growth even without drawing
2037    * the city name. But the old method cannot. */
2038   if (gui_options.draw_full_citybar) {
2039     menu_entry_set_sensitive("SHOW_CITY_GROWTH", TRUE);
2040     menu_entry_set_sensitive("SHOW_CITY_TRADE_ROUTES", TRUE);
2041   } else {
2042     menu_entry_set_sensitive("SHOW_CITY_GROWTH", gui_options.draw_city_names);
2043     menu_entry_set_sensitive("SHOW_CITY_TRADE_ROUTES",
2044                              gui_options.draw_city_names);
2045   }
2046 
2047   menu_entry_set_sensitive("SHOW_CITY_BUY_COST",
2048                            gui_options.draw_city_productions);
2049   menu_entry_set_sensitive("SHOW_COASTLINE", !gui_options.draw_terrain);
2050   menu_entry_set_sensitive("SHOW_UNIT_SOLID_BG",
2051                            gui_options.draw_units || gui_options.draw_focus_unit);
2052   menu_entry_set_sensitive("SHOW_UNIT_SHIELDS",
2053                            gui_options.draw_units || gui_options.draw_focus_unit);
2054   menu_entry_set_sensitive("SHOW_FOCUS_UNIT", !gui_options.draw_units);
2055 }
2056 
2057 /****************************************************************************
2058   Return the text for the tile, changed by the activity.
2059 
2060   Should only be called for irrigation, mining, or transformation, and
2061   only when the activity changes the base terrain type.
2062 ****************************************************************************/
get_tile_change_menu_text(struct tile * ptile,enum unit_activity activity)2063 static const char *get_tile_change_menu_text(struct tile *ptile,
2064                                              enum unit_activity activity)
2065 {
2066   struct tile *newtile = tile_virtual_new(ptile);
2067   const char *text;
2068 
2069   tile_apply_activity(newtile, activity, NULL);
2070   text = tile_get_info_text(newtile, FALSE, 0);
2071   tile_virtual_destroy(newtile);
2072   return text;
2073 }
2074 
2075 /****************************************************************
2076   Updates the menus.
2077 *****************************************************************/
real_menus_update(void)2078 void real_menus_update(void)
2079 {
2080   struct unit_list *punits = NULL;
2081   bool units_all_same_tile = TRUE, units_all_same_type = TRUE;
2082   GtkMenu *menu;
2083   char acttext[128], irrtext[128], mintext[128], transtext[128];
2084   struct terrain *pterrain;
2085   bool conn_possible;
2086   struct road_type *proad;
2087   struct extra_type_list *extras;
2088 
2089   if (ui_builder == NULL || !can_client_change_view()) {
2090     return;
2091   }
2092 
2093   if (get_num_units_in_focus() > 0) {
2094     const struct tile *ptile = NULL;
2095     const struct unit_type *ptype = NULL;
2096     punits = get_units_in_focus();
2097     unit_list_iterate(punits, punit) {
2098       fc_assert((ptile==NULL) == (ptype==NULL));
2099       if (ptile || ptype) {
2100         if (unit_tile(punit) != ptile) {
2101           units_all_same_tile = FALSE;
2102         }
2103         if (unit_type_get(punit) != ptype) {
2104           units_all_same_type = FALSE;
2105         }
2106       } else {
2107         ptile = unit_tile(punit);
2108         ptype = unit_type_get(punit);
2109       }
2110     } unit_list_iterate_end;
2111   }
2112 
2113   menu_entry_group_set_sensitive(MGROUP_EDIT, editor_is_active());
2114   menu_entry_group_set_sensitive(MGROUP_PLAYING, can_client_issue_orders()
2115                                  && !editor_is_active());
2116   menu_entry_group_set_sensitive(MGROUP_UNIT, can_client_issue_orders()
2117                                  && !editor_is_active() && punits != NULL);
2118 
2119   menu_entry_set_active("EDIT_MODE", game.info.is_edit_mode);
2120   menu_entry_set_sensitive("EDIT_MODE",
2121                            can_conn_enable_editing(&client.conn));
2122   editgui_refresh();
2123 
2124   {
2125     char road_buf[500];
2126 
2127     proad = road_by_compat_special(ROCO_ROAD);
2128     if (proad != NULL) {
2129       /* TRANS: Connect with some road type (Road/Railroad) */
2130       snprintf(road_buf, sizeof(road_buf), _("Connect With %s"),
2131                extra_name_translation(road_extra_get(proad)));
2132       menus_rename("CONNECT_ROAD", road_buf);
2133     }
2134 
2135     proad = road_by_compat_special(ROCO_RAILROAD);
2136     if (proad != NULL) {
2137       snprintf(road_buf, sizeof(road_buf), _("Connect With %s"),
2138                extra_name_translation(road_extra_get(proad)));
2139       menus_rename("CONNECT_RAIL", road_buf);
2140     }
2141   }
2142 
2143   if (!can_client_issue_orders()) {
2144     return;
2145   }
2146 
2147   /* Set government sensitivity. */
2148   if ((menu = find_menu("<MENU>/GOVERNMENT"))) {
2149     GList *list, *iter;
2150     struct government *pgov;
2151 
2152     list = gtk_container_get_children(GTK_CONTAINER(menu));
2153     for (iter = list; NULL != iter; iter = g_list_next(iter)) {
2154       pgov = g_object_get_data(G_OBJECT(iter->data), "government");
2155       if (NULL != pgov) {
2156         gtk_widget_set_sensitive(GTK_WIDGET(iter->data),
2157                                  can_change_to_government(client_player(),
2158                                                           pgov));
2159       } else {
2160         /* Revolution without target government */
2161         gtk_widget_set_sensitive(GTK_WIDGET(iter->data),
2162                                  untargeted_revolution_allowed());
2163       }
2164     }
2165     g_list_free(list);
2166   }
2167 
2168   if (!punits) {
2169     return;
2170   }
2171 
2172   /* Remaining part of this function: Update Unit, Work, and Combat menus */
2173 
2174   /* Set base sensitivity. */
2175   if ((menu = find_menu("<MENU>/BUILD_BASE"))) {
2176     GList *list, *iter;
2177     struct extra_type *pextra;
2178 
2179     list = gtk_container_get_children(GTK_CONTAINER(menu));
2180     for (iter = list; NULL != iter; iter = g_list_next(iter)) {
2181       pextra = g_object_get_data(G_OBJECT(iter->data), "base");
2182       if (NULL != pextra) {
2183         gtk_widget_set_sensitive(GTK_WIDGET(iter->data),
2184                                  can_units_do_activity_targeted(punits,
2185                                                                 ACTIVITY_BASE,
2186                                                                 pextra));
2187       }
2188     }
2189     g_list_free(list);
2190   }
2191 
2192   /* Set road sensitivity. */
2193   if ((menu = find_menu("<MENU>/BUILD_PATH"))) {
2194     GList *list, *iter;
2195     struct extra_type *pextra;
2196 
2197     list = gtk_container_get_children(GTK_CONTAINER(menu));
2198     for (iter = list; NULL != iter; iter = g_list_next(iter)) {
2199       pextra = g_object_get_data(G_OBJECT(iter->data), "road");
2200       if (NULL != pextra) {
2201         gtk_widget_set_sensitive(GTK_WIDGET(iter->data),
2202                                  can_units_do_activity_targeted(punits,
2203                                                                 ACTIVITY_GEN_ROAD,
2204                                                                 pextra));
2205       }
2206     }
2207     g_list_free(list);
2208   }
2209 
2210   /* Enable the button for adding to a city in all cases, so we
2211    * get an eventual error message from the server if we try. */
2212   menu_entry_set_sensitive("BUILD_CITY",
2213                            (can_units_do(punits, unit_can_add_or_build_city)
2214                             || can_units_do(punits, unit_can_help_build_wonder_here)));
2215   menu_entry_set_sensitive("GO_BUILD_CITY",
2216                            units_contain_cityfounder(punits));
2217   menu_entry_set_sensitive("BUILD_ROAD",
2218                            (can_units_do_any_road(punits)
2219                             || can_units_do(punits,
2220                                             unit_can_est_trade_route_here)));
2221   menu_entry_set_sensitive("BUILD_IRRIGATION",
2222                            can_units_do_activity(punits, ACTIVITY_IRRIGATE));
2223   menu_entry_set_sensitive("BUILD_MINE",
2224                            can_units_do_activity(punits, ACTIVITY_MINE));
2225   menu_entry_set_sensitive("TRANSFORM_TERRAIN",
2226                            can_units_do_activity(punits, ACTIVITY_TRANSFORM));
2227   menu_entry_set_sensitive("FORTIFY",
2228                            can_units_do_activity(punits,
2229                                                  ACTIVITY_FORTIFYING));
2230   menu_entry_set_sensitive("BUILD_FORTRESS",
2231                            can_units_do_base_gui(punits, BASE_GUI_FORTRESS));
2232   menu_entry_set_sensitive("BUILD_AIRBASE",
2233                            can_units_do_base_gui(punits, BASE_GUI_AIRBASE));
2234   menu_entry_set_sensitive("CLEAN_POLLUTION",
2235                            (can_units_do_activity(punits, ACTIVITY_POLLUTION)
2236                             || can_units_do(punits, can_unit_paradrop)));
2237   menu_entry_set_sensitive("CLEAN_FALLOUT",
2238                            can_units_do_activity(punits, ACTIVITY_FALLOUT));
2239   menu_entry_set_sensitive("UNIT_SENTRY",
2240                            can_units_do_activity(punits, ACTIVITY_SENTRY));
2241   /* FIXME: should conditionally rename "Pillage" to "Pillage..." in cases where
2242    * selecting the command results in a dialog box listing options of what to pillage */
2243   menu_entry_set_sensitive("DO_PILLAGE",
2244                            can_units_do_activity(punits, ACTIVITY_PILLAGE));
2245   menu_entry_set_sensitive("UNIT_DISBAND",
2246                            units_have_type_flag(punits, UTYF_UNDISBANDABLE, FALSE));
2247   menu_entry_set_sensitive("UNIT_UPGRADE",
2248                            units_can_upgrade(punits));
2249   /* "UNIT_CONVERT" dealt with below */
2250   menu_entry_set_sensitive("UNIT_HOMECITY",
2251                            can_units_do(punits, can_unit_change_homecity));
2252   menu_entry_set_sensitive("UNIT_UNLOAD_TRANSPORTER",
2253                            units_are_occupied(punits));
2254   menu_entry_set_sensitive("UNIT_LOAD",
2255                            units_can_load(punits));
2256   menu_entry_set_sensitive("UNIT_UNLOAD",
2257                            units_can_unload(punits));
2258   menu_entry_set_sensitive("UNIT_UNSENTRY",
2259                            units_have_activity_on_tile(punits,
2260                                                        ACTIVITY_SENTRY));
2261   menu_entry_set_sensitive("AUTO_SETTLER",
2262                            can_units_do(punits, can_unit_do_autosettlers));
2263   menu_entry_set_sensitive("UNIT_EXPLORE",
2264                            can_units_do_activity(punits, ACTIVITY_EXPLORE));
2265 
2266   proad = road_by_compat_special(ROCO_ROAD);
2267   if (proad != NULL) {
2268     struct extra_type *tgt;
2269 
2270     tgt = road_extra_get(proad);
2271 
2272     conn_possible = can_units_do_connect(punits, ACTIVITY_GEN_ROAD, tgt);
2273   } else {
2274     conn_possible = FALSE;
2275   }
2276   menu_entry_set_sensitive("CONNECT_ROAD", conn_possible);
2277 
2278   proad = road_by_compat_special(ROCO_RAILROAD);
2279   if (proad != NULL) {
2280     struct extra_type *tgt;
2281 
2282     tgt = road_extra_get(proad);
2283 
2284     conn_possible = can_units_do_connect(punits, ACTIVITY_GEN_ROAD, tgt);
2285   } else {
2286     conn_possible = FALSE;
2287   }
2288   menu_entry_set_sensitive("CONNECT_RAIL", conn_possible);
2289 
2290   extras = extra_type_list_by_cause(EC_IRRIGATION);
2291 
2292   if (extra_type_list_size(extras) > 0) {
2293     struct extra_type *tgt;
2294 
2295     tgt = extra_type_list_get(extras, 0);
2296     conn_possible = can_units_do_connect(punits, ACTIVITY_IRRIGATE, tgt);
2297   } else {
2298     conn_possible = FALSE;
2299   }
2300   menu_entry_set_sensitive("CONNECT_IRRIGATION", conn_possible);
2301 
2302   menu_entry_set_sensitive("DIPLOMAT_ACTION",
2303                       units_can_do_action(punits, ACTION_ANY, TRUE));
2304   menu_entry_set_sensitive("EXPLODE_NUKE",
2305                            units_have_type_flag(punits, UTYF_NUCLEAR, TRUE));
2306 
2307   if (units_can_do_action(punits, ACTION_HELP_WONDER, TRUE)) {
2308     menus_rename("BUILD_CITY",
2309                  action_get_ui_name_mnemonic(ACTION_HELP_WONDER, "_"));
2310   } else {
2311     bool city_on_tile = FALSE;
2312 
2313     /* FIXME: this overloading doesn't work well with multiple focus
2314      * units. */
2315     unit_list_iterate(punits, punit) {
2316       if (tile_city(unit_tile(punit))) {
2317         city_on_tile = TRUE;
2318         break;
2319       }
2320     } unit_list_iterate_end;
2321 
2322     if (city_on_tile && units_have_type_flag(punits, UTYF_ADD_TO_CITY, TRUE)) {
2323       menus_rename("BUILD_CITY", _("Add to City"));
2324     } else {
2325       /* refresh default order */
2326       menus_rename("BUILD_CITY", _("_Build City"));
2327     }
2328   }
2329 
2330   if (units_can_do_action(punits, ACTION_TRADE_ROUTE, TRUE)) {
2331     menus_rename("BUILD_ROAD",
2332                  action_get_ui_name_mnemonic(ACTION_TRADE_ROUTE, "_"));
2333   } else if (units_have_type_flag(punits, UTYF_SETTLERS, TRUE)) {
2334     char road_item[500];
2335     struct extra_type *pextra = NULL;
2336 
2337     /* FIXME: this overloading doesn't work well with multiple focus
2338      * units. */
2339     unit_list_iterate(punits, punit) {
2340       pextra = next_extra_for_tile(unit_tile(punit), EC_ROAD,
2341                                    unit_owner(punit), punit);
2342       if (pextra != NULL) {
2343         break;
2344       }
2345     } unit_list_iterate_end;
2346 
2347     if (pextra != NULL) {
2348       /* TRANS: Build road of specific type (Road/Railroad) */
2349       snprintf(road_item, sizeof(road_item), _("Build %s"),
2350                extra_name_translation(pextra));
2351       menus_rename("BUILD_ROAD", road_item);
2352     }
2353   } else {
2354     menus_rename("BUILD_ROAD", _("Build _Road"));
2355   }
2356 
2357   if (units_all_same_type) {
2358     struct unit *punit = unit_list_get(punits, 0);
2359     struct unit_type *to_unittype =
2360       can_upgrade_unittype(client_player(), unit_type_get(punit));
2361     if (to_unittype) {
2362       /* TRANS: %s is a unit type. */
2363       fc_snprintf(acttext, sizeof(acttext), _("Upgr_ade to %s"),
2364                   utype_name_translation(
2365                     can_upgrade_unittype(client_player(),
2366                                          unit_type_get(punit))));
2367     } else {
2368       acttext[0] = '\0';
2369     }
2370   } else {
2371     acttext[0] = '\0';
2372   }
2373   if ('\0' != acttext[0]) {
2374     menus_rename("UNIT_UPGRADE", acttext);
2375   } else {
2376     menus_rename("UNIT_UPGRADE", _("Upgr_ade"));
2377   }
2378 
2379   if (units_can_convert(punits)) {
2380     menu_entry_set_sensitive("UNIT_CONVERT", TRUE);
2381     if (units_all_same_type) {
2382       struct unit *punit = unit_list_get(punits, 0);
2383       /* TRANS: %s is a unit type. */
2384       fc_snprintf(acttext, sizeof(acttext), _("C_onvert to %s"),
2385                   utype_name_translation(unit_type_get(punit)->converted_to));
2386     } else {
2387       acttext[0] = '\0';
2388     }
2389   } else {
2390     menu_entry_set_sensitive("UNIT_CONVERT", FALSE);
2391     acttext[0] = '\0';
2392   }
2393   if ('\0' != acttext[0]) {
2394     menus_rename("UNIT_CONVERT", acttext);
2395   } else {
2396     menus_rename("UNIT_CONVERT", _("C_onvert"));
2397   }
2398 
2399   if (units_all_same_tile) {
2400     struct unit *first = unit_list_get(punits, 0);
2401 
2402     pterrain = tile_terrain(unit_tile(first));
2403     if (pterrain->irrigation_result != T_NONE
2404         && pterrain->irrigation_result != pterrain) {
2405       fc_snprintf(irrtext, sizeof(irrtext), _("Change to %s"),
2406                   get_tile_change_menu_text(unit_tile(first),
2407                                             ACTIVITY_IRRIGATE));
2408     } else if (units_have_type_flag(punits, UTYF_SETTLERS, TRUE)) {
2409       struct extra_type *pextra = NULL;
2410 
2411       /* FIXME: this overloading doesn't work well with multiple focus
2412        * units. */
2413       unit_list_iterate(punits, punit) {
2414         pextra = next_extra_for_tile(unit_tile(punit), EC_IRRIGATION,
2415                                      unit_owner(punit), punit);
2416         if (pextra != NULL) {
2417           break;
2418         }
2419       } unit_list_iterate_end;
2420 
2421       if (pextra != NULL) {
2422         /* TRANS: Build irrigation of specific type */
2423         snprintf(irrtext, sizeof(irrtext), _("Build %s"),
2424                  extra_name_translation(pextra));
2425       } else {
2426         sz_strlcpy(irrtext, _("Build _Irrigation"));
2427       }
2428     } else {
2429       sz_strlcpy(irrtext, _("Build _Irrigation"));
2430     }
2431 
2432     if (pterrain->mining_result != T_NONE
2433         && pterrain->mining_result != pterrain) {
2434       fc_snprintf(mintext, sizeof(mintext), _("Change to %s"),
2435                   get_tile_change_menu_text(unit_tile(first), ACTIVITY_MINE));
2436     } else if (units_have_type_flag(punits, UTYF_SETTLERS, TRUE)) {
2437       struct extra_type *pextra = NULL;
2438 
2439       /* FIXME: this overloading doesn't work well with multiple focus
2440        * units. */
2441       unit_list_iterate(punits, punit) {
2442         pextra = next_extra_for_tile(unit_tile(punit), EC_MINE,
2443                                      unit_owner(punit), punit);
2444         if (pextra != NULL) {
2445           break;
2446         }
2447       } unit_list_iterate_end;
2448 
2449       if (pextra != NULL) {
2450         /* TRANS: Build mine of specific type */
2451         snprintf(mintext, sizeof(mintext), _("Build %s"),
2452                  extra_name_translation(pextra));
2453       } else {
2454         sz_strlcpy(mintext, _("Build _Mine"));
2455       }
2456     } else {
2457       sz_strlcpy(mintext, _("Build _Mine"));
2458     }
2459 
2460     if (pterrain->transform_result != T_NONE
2461         && pterrain->transform_result != pterrain) {
2462       fc_snprintf(transtext, sizeof(transtext), _("Transf_orm to %s"),
2463                   get_tile_change_menu_text(unit_tile(first),
2464                                             ACTIVITY_TRANSFORM));
2465     } else {
2466       sz_strlcpy(transtext, _("Transf_orm Terrain"));
2467     }
2468   } else {
2469     sz_strlcpy(irrtext, _("Build _Irrigation"));
2470     sz_strlcpy(mintext, _("Build _Mine"));
2471     sz_strlcpy(transtext, _("Transf_orm Terrain"));
2472   }
2473 
2474   menus_rename("BUILD_IRRIGATION", irrtext);
2475   menus_rename("BUILD_MINE", mintext);
2476   menus_rename("TRANSFORM_TERRAIN", transtext);
2477 
2478   if (units_have_type_flag(punits, UTYF_PARATROOPERS, TRUE)) {
2479     menus_rename("CLEAN_POLLUTION", _("Drop _Paratrooper"));
2480   } else {
2481     menus_rename("CLEAN_POLLUTION", _("Clean _Pollution"));
2482   }
2483 }
2484 
2485 /**************************************************************************
2486   Initialize menus (sensitivity, name, etc.) based on the
2487   current state and current ruleset, etc.  Call menus_update().
2488 **************************************************************************/
real_menus_init(void)2489 void real_menus_init(void)
2490 {
2491   GtkMenu *menu;
2492 
2493   if (ui_builder == NULL) {
2494     return;
2495   }
2496 
2497   menu_entry_set_sensitive("GAME_SAVE_AS",
2498                            can_client_access_hack()
2499                            && C_S_RUNNING <= client_state());
2500   menu_entry_set_sensitive("GAME_SAVE",
2501                            can_client_access_hack()
2502                            && C_S_RUNNING <= client_state());
2503 
2504   menu_entry_set_active("SAVE_OPTIONS_ON_EXIT",
2505                         gui_options.save_options_on_exit);
2506   menu_entry_set_sensitive("SERVER_OPTIONS", client.conn.established);
2507 
2508   menu_entry_set_sensitive("LEAVE",
2509                            client.conn.established);
2510 
2511   if (!can_client_change_view()) {
2512     menu_entry_group_set_sensitive(MGROUP_ALL, FALSE);
2513 
2514     return;
2515   }
2516 
2517   menus_rename("BUILD_FORTRESS", Q_(terrain_control.gui_type_base0));
2518   menus_rename("BUILD_AIRBASE", Q_(terrain_control.gui_type_base1));
2519 
2520   if ((menu = find_menu("<MENU>/GOVERNMENT"))) {
2521     GList *list, *iter;
2522     GtkWidget *item;
2523     char buf[256];
2524 
2525     /* Remove previous government entries. */
2526     list = gtk_container_get_children(GTK_CONTAINER(menu));
2527     for (iter = list; NULL != iter; iter = g_list_next(iter)) {
2528       if (g_object_get_data(G_OBJECT(iter->data), "government") != NULL
2529           || GTK_IS_SEPARATOR_MENU_ITEM(iter->data)) {
2530         gtk_widget_destroy(GTK_WIDGET(iter->data));
2531       }
2532     }
2533     g_list_free(list);
2534 
2535     /* Add new government entries. */
2536     item = gtk_separator_menu_item_new();
2537     gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2538     gtk_widget_show(item);
2539 
2540     governments_iterate(g) {
2541       if (g != game.government_during_revolution) {
2542         /* TRANS: %s is a government name */
2543         fc_snprintf(buf, sizeof(buf), _("%s..."),
2544                     government_name_translation(g));
2545         item = gtk_menu_item_new_with_label(buf);
2546         g_object_set_data(G_OBJECT(item), "government", g);
2547         g_signal_connect(item, "activate",
2548                          G_CALLBACK(government_callback), g);
2549         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2550         gtk_widget_show(item);
2551       }
2552     } governments_iterate_end;
2553   }
2554 
2555   if ((menu = find_menu("<MENU>/BUILD_BASE"))) {
2556     GList *list, *iter;
2557     GtkWidget *item;
2558 
2559     /* Remove previous base entries. */
2560     list = gtk_container_get_children(GTK_CONTAINER(menu));
2561     for (iter = list; NULL != iter; iter = g_list_next(iter)) {
2562       gtk_widget_destroy(GTK_WIDGET(iter->data));
2563     }
2564     g_list_free(list);
2565 
2566     /* Add new base entries. */
2567     extra_type_by_cause_iterate(EC_BASE, pextra) {
2568       if (pextra->buildable) {
2569         item = gtk_menu_item_new_with_label(extra_name_translation(pextra));
2570         g_object_set_data(G_OBJECT(item), "base", pextra);
2571         g_signal_connect(item, "activate", G_CALLBACK(base_callback), pextra);
2572         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2573         gtk_widget_show(item);
2574       }
2575     } extra_type_by_cause_iterate_end;
2576   }
2577 
2578   if ((menu = find_menu("<MENU>/BUILD_PATH"))) {
2579     GList *list, *iter;
2580     GtkWidget *item;
2581 
2582     /* Remove previous road entries. */
2583     list = gtk_container_get_children(GTK_CONTAINER(menu));
2584     for (iter = list; NULL != iter; iter = g_list_next(iter)) {
2585       gtk_widget_destroy(GTK_WIDGET(iter->data));
2586     }
2587     g_list_free(list);
2588 
2589     /* Add new road entries. */
2590     extra_type_by_cause_iterate(EC_ROAD, pextra) {
2591       if (pextra->buildable) {
2592         item = gtk_menu_item_new_with_label(extra_name_translation(pextra));
2593         g_object_set_data(G_OBJECT(item), "road", pextra);
2594         g_signal_connect(item, "activate", G_CALLBACK(road_callback), pextra);
2595         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2596         gtk_widget_show(item);
2597       }
2598     } extra_type_by_cause_iterate_end;
2599   }
2600 
2601   menu_entry_group_set_sensitive(MGROUP_SAFE, TRUE);
2602   menu_entry_group_set_sensitive(MGROUP_PLAYER, client_has_player());
2603 
2604   menu_entry_set_sensitive("TAX_RATE",
2605                            game.info.changable_tax
2606                            && can_client_issue_orders());
2607   menu_entry_set_sensitive("POLICIES",
2608                            multiplier_count() > 0);
2609 
2610   menu_entry_set_active("SHOW_CITY_OUTLINES",
2611                         gui_options.draw_city_outlines);
2612   menu_entry_set_active("SHOW_CITY_OUTPUT",
2613                         gui_options.draw_city_output);
2614   menu_entry_set_active("SHOW_MAP_GRID",
2615                         gui_options.draw_map_grid);
2616   menu_entry_set_active("SHOW_NATIONAL_BORDERS",
2617                         gui_options.draw_borders);
2618   menu_entry_set_sensitive("SHOW_NATIONAL_BORDERS",
2619                            BORDERS_DISABLED != game.info.borders);
2620   menu_entry_set_active("SHOW_NATIVE_TILES",
2621                         gui_options.draw_native);
2622   menu_entry_set_active("SHOW_CITY_FULL_BAR",
2623                         gui_options.draw_full_citybar);
2624   menu_entry_set_active("SHOW_CITY_NAMES",
2625                         gui_options.draw_city_names);
2626   menu_entry_set_active("SHOW_CITY_GROWTH",
2627                         gui_options.draw_city_growth);
2628   menu_entry_set_active("SHOW_CITY_PRODUCTIONS",
2629                         gui_options.draw_city_productions);
2630   menu_entry_set_active("SHOW_CITY_BUY_COST",
2631                         gui_options.draw_city_buycost);
2632   menu_entry_set_active("SHOW_CITY_TRADE_ROUTES",
2633                         gui_options.draw_city_trade_routes);
2634   menu_entry_set_active("SHOW_TERRAIN",
2635                         gui_options.draw_terrain);
2636   menu_entry_set_active("SHOW_COASTLINE",
2637                         gui_options.draw_coastline);
2638   menu_entry_set_active("SHOW_PATHS",
2639                         gui_options.draw_roads_rails);
2640   menu_entry_set_active("SHOW_IRRIGATION",
2641                         gui_options.draw_irrigation);
2642   menu_entry_set_active("SHOW_MINES",
2643                         gui_options.draw_mines);
2644   menu_entry_set_active("SHOW_BASES",
2645                         gui_options.draw_fortress_airbase);
2646   menu_entry_set_active("SHOW_RESOURCES",
2647                         gui_options.draw_specials);
2648   menu_entry_set_active("SHOW_HUTS",
2649                         gui_options.draw_huts);
2650   menu_entry_set_active("SHOW_POLLUTION",
2651                         gui_options.draw_pollution);
2652   menu_entry_set_active("SHOW_CITIES",
2653                         gui_options.draw_cities);
2654   menu_entry_set_active("SHOW_UNITS",
2655                         gui_options.draw_units);
2656   menu_entry_set_active("SHOW_UNIT_SOLID_BG",
2657                         gui_options.solid_color_behind_units);
2658   menu_entry_set_active("SHOW_UNIT_SHIELDS",
2659                         gui_options.draw_unit_shields);
2660   menu_entry_set_active("SHOW_FOCUS_UNIT",
2661                         gui_options.draw_focus_unit);
2662   menu_entry_set_active("SHOW_FOG_OF_WAR",
2663                         gui_options.draw_fog_of_war);
2664 
2665   view_menu_update_sensitivity();
2666 
2667   menu_entry_set_active("FULL_SCREEN", GUI_GTK_OPTION(fullscreen));
2668 }
2669