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