1 /***********************************************************************
2  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 
21 #include <X11/Intrinsic.h>
22 #include <X11/StringDefs.h>
23 #include <X11/Xaw/MenuButton.h>
24 #include <X11/Xaw/SimpleMenu.h>
25 #include <X11/Xaw/SmeBSB.h>
26 #include <X11/Xaw/SmeLine.h>
27 
28 /* utility */
29 #include "fcintl.h"
30 #include "log.h"
31 #include "mem.h"
32 #include "movement.h"
33 #include "support.h"
34 
35 /* common */
36 #include "game.h"
37 #include "government.h"
38 #include "map.h"
39 #include "unit.h"
40 #include "unitlist.h"
41 
42 /* client */
43 #include "chatline.h"
44 #include "cityrep.h"
45 #include "client_main.h"
46 #include "climisc.h"	/* can_units_do_connect */
47 #include "clinet.h"
48 #include "control.h" /* request_xxx and get_unit_in_focus */
49 #include "dialogs.h"
50 #include "finddlg.h"
51 #include "gotodlg.h"
52 #include "gui_main.h"
53 #include "gui_stuff.h"
54 #include "helpdlg.h"
55 #include "mapctrl.h"
56 #include "messagedlg.h"
57 #include "messagewin.h"
58 #include "optiondlg.h"
59 #include "options.h"
60 #include "packhand.h"
61 #include "plrdlg.h"
62 #include "ratesdlg.h"
63 #include "repodlgs.h"
64 #include "spaceshipdlg.h"
65 #include "wldlg.h"
66 
67 #include "menu.h"
68 
69 /* stuff for run-time mutable menu text */
70 
71 #define MAX_LEN_TERR_NAME_DISP  9
72 #define MAX_VARIANTS  3
73 #define ACEL_SPACE  1
74 
75 #define TEXT_ORDER_CITY_BUILD   0
76 #define TEXT_ORDER_CITY_ADD_TO  1
77 
78 #define TEXT_ORDER_IRRIGATE            0
79 #define TEXT_ORDER_IRRIGATE_GENERIC    1
80 #define TEXT_ORDER_IRRIGATE_CHANGE_TO  2
81 
82 #define TEXT_ORDER_MINE            0
83 #define TEXT_ORDER_MINE_GENERIC    1
84 #define TEXT_ORDER_MINE_CHANGE_TO  2
85 
86 #define TEXT_ORDER_TRANSFORM_TERRAIN       0
87 #define TEXT_ORDER_TRANSFORM_TRANSFORM_TO  1
88 
89 #define TEXT_ORDER_POLLUTION_POLLUTION  0
90 #define TEXT_ORDER_POLLUTION_PARADROP   1
91 
92 /* The acel strings, is the string that show which is the acelerator key
93  * in the menus. No check is made to ensure that this is the acelerator
94  * key. This is use for translation-layout porpouses in i18n texts
95  * added by Serrada */
96 
97 struct MenuEntry {
98   char *text[MAX_VARIANTS+1];
99   char *acel;               /* Acelerator key */
100   enum  MenuID id;
101   Widget w;
102 };
103 
104 struct Menu {
105   Widget button, shell;
106   int maxitemlen;
107   int maxacellen;
108   struct MenuEntry *entries;
109 };
110 
111 static struct Menu *menus[MENU_LAST];
112 
113 static struct MenuEntry game_menu_entries[]={
114     { { N_("Local Options"), 0        },      "", MENU_GAME_OPTIONS, 0 },
115     { { N_("Message Options"), 0      },      "", MENU_GAME_MSG_OPTIONS, 0 },
116     { { N_("Save Settings"), 0        },      "", MENU_GAME_SAVE_SETTINGS, 0 },
117     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
118     { { N_("Server Options"), 0       },      "", MENU_GAME_SERVER_OPTIONS, 0 },
119     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
120     { { N_("Export Log"), 0           },      "", MENU_GAME_OUTPUT_LOG, 0 },
121     { { N_("Clear Log"), 0            },      "", MENU_GAME_CLEAR_OUTPUT, 0 },
122     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
123     { { N_("Disconnect"), 0           },      "", MENU_GAME_DISCONNECT, 0 },
124     { { N_("Quit"), 0                 },      "Ctl-Q", MENU_GAME_QUIT, 0 },
125     { { 0,                            },       0, MENU_END_OF_LIST, 0 }
126 };
127 
128 static struct MenuEntry government_menu_entries[]={
129     { { N_("Tax Rates..."), 0         },     "Ctl-T", MENU_GOVERNMENT_RATES, 0 },
130     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
131     { { N_("Find City"), 0            },     "Ctl-F", MENU_GOVERNMENT_FIND_CITY, 0 },
132     { { N_("Worklists"), 0            },     "Ctl-L", MENU_GOVERNMENT_WORKLISTS, 0 },
133     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
134     { { N_("Revolution..."), 0        },     "Ctl-Shift-R", MENU_GOVERNMENT_REVOLUTION, 0 },
135     { { 0,                            },       0, MENU_END_OF_LIST, 0 }
136 };
137 
138 /* One entry for every government, appended to the government menu. */
139 static int num_government_entries = 0;
140 static Widget government_widgets[G_LAST];
141 
142 static struct MenuEntry view_menu_entries[]={
143     { { N_("Map Grid"), 0             }, "ctl-g", MENU_VIEW_SHOW_MAP_GRID, 0 },
144     { { N_("National Borders"), 0     }, "ctl-b",
145       MENU_VIEW_SHOW_NATIONAL_BORDERS, 0 },
146     { { N_("City Names"), 0           }, "ctl-n", MENU_VIEW_SHOW_CITY_NAMES, 0 },
147     { { N_("City Growth"), 0          }, "ctl-r",
148       MENU_VIEW_SHOW_CITY_GROWTH, 0 },
149     { { N_("City Production Levels"), 0 }, "ctl-p", MENU_VIEW_SHOW_CITY_PRODUCTIONS, 0 },
150     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
151     { { N_("Terrain"), 0              },      "", MENU_VIEW_SHOW_TERRAIN, 0 },
152     { { N_("Coastline"), 0            },      "", MENU_VIEW_SHOW_COASTLINE, 0 },
153     { { N_("Paths"), 0                },      "", MENU_VIEW_SHOW_PATHS, 0 },
154     { { N_("Irrigation"), 0           },      "", MENU_VIEW_SHOW_IRRIGATION, 0 },
155     { { N_("Mines"), 0                },      "", MENU_VIEW_SHOW_MINES, 0 },
156     { { N_("Bases"), 0                },      "", MENU_VIEW_SHOW_BASES, 0 },
157     { { N_("Resources"), 0            },      "", MENU_VIEW_SHOW_RESOURCES, 0 },
158     { { N_("Huts"), 0                 },      "", MENU_VIEW_SHOW_HUTS, 0 },
159     { { N_("Pollution & Fallout"), 0  },      "", MENU_VIEW_SHOW_POLLUTION, 0 },
160     { { N_("Cities"), 0               },      "", MENU_VIEW_SHOW_CITIES, 0 },
161     { { N_("Units"), 0                },      "", MENU_VIEW_SHOW_UNITS, 0 },
162     { { N_("Focus Unit"), 0           },      "", MENU_VIEW_SHOW_FOCUS_UNIT, 0 },
163     { { N_("Fog of War"), 0           },      "", MENU_VIEW_SHOW_FOG_OF_WAR, 0 },
164     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
165     { { N_("Center View"), 0          },     "c", MENU_VIEW_CENTER_VIEW, 0 },
166     { { 0,                            },       0, MENU_END_OF_LIST, 0 }
167 };
168 
169 static struct MenuEntry order_menu_entries[]={
170     { { N_("Build City"),
171         N_("Add to City"), 0          },     "b", MENU_ORDER_BUILD_CITY, 0 },
172     { { N_("Build Road"), 0           },     "r", MENU_ORDER_ROAD, 0 },
173     { { N_("Build %s"),
174         N_("Build Irrigation"),
175         N_("Change to %s"), 0         },     "i", MENU_ORDER_IRRIGATE, 0 },
176     { { N_("Build %s"),
177         N_("Build Mine"),
178         N_("Change to %s"), 0         },     "m", MENU_ORDER_MINE, 0 },
179     { { N_("Transform Terrain"),
180         N_("Transform to %s"), 0      },     "o", MENU_ORDER_TRANSFORM, 0 },
181     { { N_("Build Fortress"), 0       },     "F", MENU_ORDER_FORTRESS, 0 },
182     { { N_("Build Airbase"), 0        },     "E", MENU_ORDER_AIRBASE, 0 },
183     { { N_("Clean Pollution"),
184 	N_("Drop Paratrooper"), 0             },     "p", MENU_ORDER_POLLUTION, 0 },
185     { { N_("Clean Nuclear Fallout"), 0},     "n", MENU_ORDER_FALLOUT, 0 },
186     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
187     { { N_("Fortify Unit"), 0         },     "f", MENU_ORDER_FORTIFY, 0 },
188     { { N_("Sentry Unit"), 0          },     "s", MENU_ORDER_SENTRY, 0 },
189     { { N_("Pillage"), 0              },     "P", MENU_ORDER_PILLAGE, 0 },
190     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
191     { { N_("Set Home City"), 0        },     "h", MENU_ORDER_HOMECITY, 0 },
192     { { N_("Unload All From Transporter"), 0 }, "T",
193       MENU_ORDER_UNLOAD_TRANSPORTER, 0 },
194     { { N_("Load Unit"), 0            },     "l", MENU_ORDER_LOAD, 0 },
195     { { N_("Unload Unit"), 0          },     "u", MENU_ORDER_UNLOAD, 0 },
196     { { N_("Unsentry All On Tile"), 0 },     "S", MENU_ORDER_WAKEUP_OTHERS, 0 },
197     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
198     { { N_("Auto Settler"), 0         },     "a", MENU_ORDER_AUTO_SETTLER, 0 },
199     { { N_("Auto Attack"), 0          },     "a", MENU_ORDER_AUTO_ATTACK, 0 },
200     { { N_("Auto Explore"), 0         },     "x", MENU_ORDER_AUTO_EXPLORE, 0 },
201     { { N_("Connect With Road"), 0    },     "R", MENU_ORDER_CONNECT_ROAD, 0 },
202     { { N_("Connect With Rail"), 0    },     "L", MENU_ORDER_CONNECT_RAIL, 0 },
203     { { N_("Connect With Irrigation"), 0 },  "I", MENU_ORDER_CONNECT_IRRIGATE, 0 },
204     { { N_("Patrol"), 0               },     "q", MENU_ORDER_PATROL, 0 },
205     { { N_("Go to Tile"), 0           },     "g", MENU_ORDER_GOTO, 0 },
206     { { N_("Go to/Airlift to City..."), 0 }, "t", MENU_ORDER_GOTO_CITY, 0 },
207     { { N_("Return to Nearest City"), 0 },   "G", MENU_ORDER_RETURN, 0 },
208     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
209     { { N_("Convert Unit"), 0         },     "O", MENU_ORDER_CONVERT, 0 },
210     { { N_("Disband Unit"), 0         },     "D", MENU_ORDER_DISBAND, 0 },
211     { { N_("Help Build Wonder"), 0    },     "b", MENU_ORDER_BUILD_WONDER, 0 },
212     { { N_("Establish Trade Route"), 0 },    "r", MENU_ORDER_TRADE_ROUTE, 0 },
213     { { N_("Diplomat/Spy Actions"), 0 },     "d", MENU_ORDER_DIPLOMAT_DLG, 0},
214     { { N_("Explode Nuclear"), 0      },     "N", MENU_ORDER_NUKE, 0 },
215     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
216     { { N_("Select Same Type Everywhere"), 0 }, "X", MENU_ORDER_SELECT_SAME_TYPE, 0 },
217     { { N_("Wait"), 0                 },     "w", MENU_ORDER_WAIT, 0 },
218     { { N_("Done"), 0                 },   "spc", MENU_ORDER_DONE, 0 },
219     { { 0,                            },       0, MENU_END_OF_LIST, 0 }
220 };
221 
222 static struct MenuEntry reports_menu_entries[]={
223     { { N_("Units"), 0                },    "F2", MENU_REPORT_UNITS, 0 },
224     /* TRANS: Nations report action */
225     { { N_("Nations"), 0              },    "F3", MENU_REPORT_PLAYERS, 0 },
226     { { N_("Cities"), 0               },    "F4", MENU_REPORT_CITIES, 0 },
227     { { N_("Economy"), 0              },    "F5", MENU_REPORT_ECONOMY, 0 },
228     /* TRANS: Research report action */
229     { { N_("Research"), 0             },    "F6", MENU_REPORT_SCIENCE, 0 },
230     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
231     { { N_("Wonders of the World"), 0 },    "F7", MENU_REPORT_WOW, 0 },
232     { { N_("Top Five Cities"), 0      },    "F8", MENU_REPORT_TOP_CITIES, 0 },
233     { { N_("Messages"), 0             },    "F9", MENU_REPORT_MESSAGES, 0 },
234     { { N_("Demographics"), 0         },   "F11", MENU_REPORT_DEMOGRAPHIC, 0 },
235     { { N_("Spaceship"), 0            },   "F12", MENU_REPORT_SPACESHIP, 0 },
236     { { N_("Achievements"), 0         },      "", MENU_REPORT_ACHIEVEMENTS, 0},
237     { { 0,                            },       0, MENU_END_OF_LIST, 0 }
238 };
239 
240 static struct MenuEntry editor_menu_entries[] = {
241     { { N_("Editing Mode"), 0         },      "", MENU_EDITOR_TOGGLE, 0 },
242     { { N_("Tools"), 0                },      "", MENU_EDITOR_TOOLS, 0 },
243     { { 0,                            },       0, MENU_END_OF_LIST, 0 }
244 };
245 
246 static struct MenuEntry help_menu_entries[]={
247     /* TRANS: "Overview" topic in built-in help */
248     { { N_("?help:Overview"), 0       },      "", MENU_HELP_OVERVIEW, 0 },
249     { { N_("Strategy and Tactics"), 0 },      "", MENU_HELP_PLAYING, 0 },
250     { { N_("Terrain"), 0              },      "", MENU_HELP_TERRAIN, 0 },
251     { { N_("Economy"), 0              },      "", MENU_HELP_ECONOMY, 0 },
252     { { N_("Cities"), 0               },      "", MENU_HELP_CITIES, 0 },
253     { { N_("City Improvements"), 0    },      "", MENU_HELP_IMPROVEMENTS, 0 },
254     { { N_("Wonders of the World"), 0 },      "", MENU_HELP_WONDERS, 0 },
255     { { N_("Units"), 0                },      "", MENU_HELP_UNITS, 0 },
256     { { N_("Combat"), 0               },      "", MENU_HELP_COMBAT, 0 },
257     { { N_("ZOC"), 0                  },      "", MENU_HELP_ZOC, 0 },
258     { { N_("Government"), 0           },      "", MENU_HELP_GOVERNMENT, 0 },
259     { { N_("Diplomacy"), 0            },      "", MENU_HELP_DIPLOMACY, 0 },
260     { { N_("Technology"), 0           },      "", MENU_HELP_TECH, 0 },
261     { { N_("Space Race"), 0           },      "", MENU_HELP_SPACE_RACE, 0 },
262     { { N_("About Ruleset"), 0        },      "", MENU_HELP_RULESET, 0 },
263     { { N_("About Nations"), 0        },      "", MENU_HELP_NATIONS, 0 },
264     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
265     { { N_("Connecting"), 0           },      "", MENU_HELP_CONNECTING, 0 },
266     { { N_("Controls"), 0             },      "", MENU_HELP_CONTROLS, 0 },
267     { { N_("Citizen Governor"), 0     },      "", MENU_HELP_CMA, 0 },
268     { { N_("Chatline"), 0             },      "", MENU_HELP_CHATLINE, 0 },
269     { { N_("Worklist Editor"), 0      },      "", MENU_HELP_WORKLIST_EDITOR, 0 },
270     { { 0                             },      "", MENU_SEPARATOR_LINE, 0 },
271     { { N_("Languages"), 0            },      "", MENU_HELP_LANGUAGES, 0 },
272     { { N_("Copying"), 0              },      "", MENU_HELP_COPYING, 0 },
273     { { N_("About Freeciv"), 0        },      "", MENU_HELP_ABOUT, 0 },
274     { { 0,                            },       0, MENU_END_OF_LIST, 0 }
275 };
276 
277 
278 static void create_menu(enum MenuIndex menu, char *name, struct MenuEntry entries[],
279 			void (*menucallback)(Widget, XtPointer, XtPointer),
280 			Widget parent);
281 static void menu_entry_sensitive(enum MenuIndex menu, enum MenuID id, Bool s);
282 static void menu_entry_rename(enum MenuIndex menu, enum MenuID id, int var,
283 			      const char *terr);
284 static char *menu_entry_text(enum MenuIndex menu, int ent, int var,
285 			     const char *terr);
286 
287 static void revolution_menu_callback(Widget w, XtPointer client_data,
288 				     XtPointer garbage);
289 
290 /**************************************************************************
291   Initialize menus (sensitivity, name, etc.) based on the
292   current state and current ruleset, etc.  Call menus_update().
293 **************************************************************************/
real_menus_init(void)294 void real_menus_init(void)
295 {
296   /* PORTME */
297 }
298 
299 /****************************************************************
300 ...
301 *****************************************************************/
real_menus_update(void)302 void real_menus_update(void)
303 {
304   if (!can_client_change_view()) {
305     XtSetSensitive(menus[MENU_REPORT]->button, False);
306     XtSetSensitive(menus[MENU_ORDER]->button, False);
307     XtSetSensitive(menus[MENU_VIEW]->button, False);
308     XtSetSensitive(menus[MENU_GOVERNMENT]->button, False);
309 
310     menu_entry_sensitive(MENU_GAME, MENU_GAME_OPTIONS, 0);
311     menu_entry_sensitive(MENU_GAME, MENU_GAME_MSG_OPTIONS, 0);
312     menu_entry_sensitive(MENU_GAME, MENU_GAME_SAVE_SETTINGS, 0);
313     menu_entry_sensitive(MENU_GAME, MENU_GAME_SERVER_OPTIONS, 1);
314     menu_entry_sensitive(MENU_GAME, MENU_GAME_OUTPUT_LOG, 1);
315     menu_entry_sensitive(MENU_GAME, MENU_GAME_CLEAR_OUTPUT, 1);
316   } else {
317     int i;
318     int any_cities = FALSE;
319 
320     players_iterate(pplayer) {
321       if (city_list_size(pplayer->cities)) {
322 	any_cities = TRUE;
323 	break;
324       }
325     } players_iterate_end;
326 
327     XtSetSensitive(menus[MENU_REPORT]->button, True);
328     XtSetSensitive(menus[MENU_VIEW]->button, True);
329     XtSetSensitive(menus[MENU_GOVERNMENT]->button, True);
330 
331     menu_entry_sensitive(MENU_GOVERNMENT, MENU_GOVERNMENT_RATES,
332                          can_client_issue_orders());
333     menu_entry_sensitive(MENU_GOVERNMENT, MENU_GOVERNMENT_WORKLISTS,
334                          can_client_issue_orders());
335     menu_entry_sensitive(MENU_GOVERNMENT, MENU_GOVERNMENT_REVOLUTION,
336                          can_client_issue_orders());
337 
338     /* Destroy all government-change entries and build them from scratch.
339      * This could probably be done more efficiently if it were only done
340      * when the client receives the rulesets or disconnects. */
341     for (i = 0; i < num_government_entries; i++) {
342       XtDestroyWidget(government_widgets[i]);
343     }
344     i = 0;
345     governments_iterate(pgovernment) {
346       Widget w;
347 
348       if (pgovernment == game.government_during_revolution) {
349 	continue;
350       }
351 
352       w = XtCreateManagedWidget(government_name_translation(pgovernment),
353 				smeBSBObjectClass,
354 				menus[MENU_GOVERNMENT]->shell, NULL, 0);
355       XtAddCallback(w, XtNcallback, revolution_menu_callback, pgovernment);
356       XtSetSensitive(w, can_change_to_government(client.conn.playing,
357 						 pgovernment));
358 
359       government_widgets[i] = w;
360       i++;
361     } governments_iterate_end;
362     num_government_entries = i;
363 
364     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_CITY_GROWTH,
365                          gui_options.draw_city_names);
366     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_TERRAIN, 1);
367     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_COASTLINE,
368                          !gui_options.draw_terrain);
369     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_PATHS, 1);
370     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_IRRIGATION, 1);
371     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_MINES, 1);
372     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_BASES, 1);
373     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_RESOURCES, 1);
374     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_HUTS, 1);
375     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_POLLUTION, 1);
376     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_CITIES, 1);
377     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_UNITS, 1);
378     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_FOCUS_UNIT,
379                          !gui_options.draw_units);
380     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_FOG_OF_WAR, 1);
381 
382     menu_entry_sensitive(MENU_GAME, MENU_GAME_OPTIONS, 1);
383     menu_entry_sensitive(MENU_GAME, MENU_GAME_MSG_OPTIONS, 1);
384     menu_entry_sensitive(MENU_GAME, MENU_GAME_SAVE_SETTINGS, 1);
385     menu_entry_sensitive(MENU_GAME, MENU_GAME_SERVER_OPTIONS, 1);
386     menu_entry_sensitive(MENU_GAME, MENU_GAME_OUTPUT_LOG, 1);
387     menu_entry_sensitive(MENU_GAME, MENU_GAME_CLEAR_OUTPUT, 1);
388     menu_entry_sensitive(MENU_GAME, MENU_GAME_DISCONNECT, 1);
389 
390     if (NULL != client.conn.playing) {
391       menu_entry_sensitive(MENU_REPORT, MENU_REPORT_SPACESHIP,
392 			   (SSHIP_NONE != client.conn.playing->spaceship.state));
393     } else {
394       menu_entry_sensitive(MENU_REPORT, MENU_REPORT_SPACESHIP, 0);
395     }
396 
397     if ((get_num_units_in_focus() > 0) && can_client_issue_orders()) {
398       struct terrain *tinfo;
399       struct tile *ptile = NULL;
400       bool can_build;
401       struct unit_list *punits = get_units_in_focus();
402       bool conn_possible;
403       struct road_type *proad;
404       struct extra_type_list *extras;
405 
406       XtSetSensitive(menus[MENU_ORDER]->button, True);
407 
408       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_SELECT_SAME_TYPE, True);
409 
410       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_BUILD_CITY,
411                            can_units_do(punits, unit_can_add_or_build_city));
412       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_ROAD,
413                            can_units_do_any_road(punits));
414       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_IRRIGATE,
415 			   can_units_do_activity(punits, ACTIVITY_IRRIGATE));
416       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_MINE,
417 			   can_units_do_activity(punits, ACTIVITY_MINE));
418       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_TRANSFORM,
419 			   can_units_do_activity(punits, ACTIVITY_TRANSFORM));
420       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_FORTRESS,
421 			   can_units_do_base_gui(punits, BASE_GUI_FORTRESS));
422       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_AIRBASE,
423 			   can_units_do_base_gui(punits, BASE_GUI_AIRBASE));
424       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_POLLUTION,
425 			   can_units_do_activity(punits, ACTIVITY_POLLUTION)
426 			   || can_units_do(punits, can_unit_paradrop));
427       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_FALLOUT,
428 			   can_units_do_activity(punits, ACTIVITY_FALLOUT));
429       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_FORTIFY,
430 			   can_units_do_activity(punits, ACTIVITY_FORTIFYING));
431       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_SENTRY,
432 			   can_units_do_activity(punits, ACTIVITY_SENTRY));
433       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_PILLAGE,
434 			   can_units_do_activity(punits, ACTIVITY_PILLAGE));
435       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_HOMECITY,
436 			   can_units_do(punits, can_unit_change_homecity));
437       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_UNLOAD_TRANSPORTER,
438 			   units_are_occupied(punits));
439       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_LOAD,
440 			   units_can_load(punits));
441       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_UNLOAD,
442 			   units_can_unload(punits));
443       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_WAKEUP_OTHERS,
444 			   units_have_activity_on_tile(punits,
445 						       ACTIVITY_SENTRY));
446       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_AUTO_SETTLER,
447 			   can_units_do(punits, can_unit_do_autosettlers));
448       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_AUTO_ATTACK, false);
449       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_CONVERT,
450 			   units_can_convert(punits));
451       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_DISBAND,
452 			   units_have_type_flag(punits, UTYF_UNDISBANDABLE,
453                                                 FALSE));
454       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_AUTO_EXPLORE,
455 			   can_units_do_activity(punits, ACTIVITY_EXPLORE));
456 
457       proad = road_by_compat_special(ROCO_ROAD);
458       if (proad != NULL) {
459         struct extra_type *tgt;
460 
461         tgt = road_extra_get(proad);
462 
463         conn_possible = can_units_do_connect(punits, ACTIVITY_GEN_ROAD, tgt);
464       } else {
465         conn_possible = FALSE;
466       }
467       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_CONNECT_ROAD, conn_possible);
468 
469       proad = road_by_compat_special(ROCO_RAILROAD);
470       if (proad != NULL) {
471         struct extra_type *tgt;
472 
473         tgt = road_extra_get(proad);
474 
475         conn_possible = can_units_do_connect(punits, ACTIVITY_GEN_ROAD, tgt);
476       } else {
477         conn_possible = FALSE;
478       }
479       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_CONNECT_RAIL,
480                            conn_possible);
481 
482       extras = extra_type_list_by_cause(EC_IRRIGATION);
483 
484       if (extra_type_list_size(extras) > 0) {
485         struct extra_type *tgt;
486 
487         tgt = extra_type_list_get(extras, 0);
488         conn_possible = can_units_do_connect(punits, ACTIVITY_IRRIGATE, tgt);
489       } else {
490         conn_possible = FALSE;
491       }
492 
493       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_CONNECT_IRRIGATE, conn_possible);
494       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_GOTO_CITY,
495 			   any_cities);
496       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_BUILD_WONDER,
497 			   can_units_do(punits,
498 				        unit_can_help_build_wonder_here));
499       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_TRADE_ROUTE,
500 			   can_units_do(punits,
501 				        unit_can_est_trade_route_here));
502       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_DIPLOMAT_DLG,
503                            can_units_act_against_own_tile(punits));
504       menu_entry_sensitive(MENU_ORDER, MENU_ORDER_NUKE,
505                            units_have_type_flag(punits, UTYF_NUCLEAR, TRUE));
506 
507       /* FiXME: very odd, iterating for the first entry! */
508       unit_list_iterate(punits, punit) {
509 	ptile = unit_tile(punit);
510 	break;
511       } unit_list_iterate_end;
512 
513       tinfo = tile_terrain(ptile);
514       can_build = !(tile_city(ptile));
515 
516       if (units_contain_cityfounder(punits)) {
517         if (!can_build) {
518           menu_entry_rename(MENU_ORDER, MENU_ORDER_BUILD_CITY,
519                             TEXT_ORDER_CITY_ADD_TO, NULL);
520         } else {
521           menu_entry_rename(MENU_ORDER, MENU_ORDER_BUILD_CITY,
522                             TEXT_ORDER_CITY_BUILD, NULL);
523         }
524       }
525 
526       if ((tinfo->irrigation_result != T_NONE)
527 	  && (tinfo->irrigation_result != tinfo)) {
528 	menu_entry_rename(MENU_ORDER, MENU_ORDER_IRRIGATE,
529 			  TEXT_ORDER_IRRIGATE_CHANGE_TO,
530 			  terrain_name_translation(tinfo->irrigation_result));
531       } else if (units_have_type_flag(punits, UTYF_SETTLERS, TRUE)) {
532         struct extra_type *pextra = NULL;
533 
534         /* FIXME: this overloading doesn't work well with multiple focus
535          * units. */
536         unit_list_iterate(punits, punit) {
537           pextra = next_extra_for_tile(unit_tile(punit), EC_IRRIGATION,
538                                        unit_owner(punit), punit);
539           if (pextra != NULL) {
540             break;
541           }
542         } unit_list_iterate_end;
543 
544         if (pextra != NULL) {
545           /* TRANS: Build irrigation of specific type */
546           menu_entry_rename(MENU_ORDER, MENU_ORDER_IRRIGATE,
547                             TEXT_ORDER_IRRIGATE, extra_name_translation(pextra));
548         } else {
549           menu_entry_rename(MENU_ORDER, MENU_ORDER_IRRIGATE,
550                             TEXT_ORDER_IRRIGATE_GENERIC, NULL);
551         }
552       }
553 
554       if ((tinfo->mining_result != T_NONE)
555 	  && (tinfo->mining_result != tinfo)) {
556 	menu_entry_rename(MENU_ORDER, MENU_ORDER_MINE,
557 			  TEXT_ORDER_MINE_CHANGE_TO,
558 			  terrain_name_translation(tinfo->mining_result));
559       } else if (units_have_type_flag(punits, UTYF_SETTLERS, TRUE)) {
560         struct extra_type *pextra = NULL;
561 
562         /* FIXME: this overloading doesn't work well with multiple focus
563          * units. */
564         unit_list_iterate(punits, punit) {
565           pextra = next_extra_for_tile(unit_tile(punit), EC_MINE,
566                                        unit_owner(punit), punit);
567           if (pextra != NULL) {
568             break;
569           }
570         } unit_list_iterate_end;
571 
572         if (pextra != NULL) {
573           /* TRANS: Build mine of specific type */
574           menu_entry_rename(MENU_ORDER, MENU_ORDER_MINE,
575                             TEXT_ORDER_MINE, extra_name_translation(pextra));
576         } else {
577           menu_entry_rename(MENU_ORDER, MENU_ORDER_MINE,
578                             TEXT_ORDER_MINE_GENERIC, NULL);
579         }
580       }
581 
582       if ((tinfo->transform_result != T_NONE)
583 	  && (tinfo->transform_result != tinfo)) {
584 	menu_entry_rename(MENU_ORDER, MENU_ORDER_TRANSFORM,
585 			  TEXT_ORDER_TRANSFORM_TRANSFORM_TO,
586 			  terrain_name_translation(tinfo->transform_result));
587       } else {
588 	menu_entry_rename(MENU_ORDER, MENU_ORDER_TRANSFORM,
589 			  TEXT_ORDER_TRANSFORM_TERRAIN, NULL);
590       }
591 
592       if (units_have_type_flag(punits, UTYF_PARATROOPERS, TRUE)) {
593 	menu_entry_rename(MENU_ORDER, MENU_ORDER_POLLUTION,
594 			  TEXT_ORDER_POLLUTION_PARADROP, NULL);
595       } else {
596 	menu_entry_rename(MENU_ORDER, MENU_ORDER_POLLUTION,
597 			  TEXT_ORDER_POLLUTION_POLLUTION, NULL);
598       }
599     }
600   }
601 }
602 
603 /****************************************************************
604 ...
605 *****************************************************************/
game_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)606 static void game_menu_callback(Widget w, XtPointer client_data,
607 			       XtPointer garbage)
608 {
609   size_t pane_num = (size_t)client_data;
610 
611   switch(pane_num) {
612   case MENU_GAME_OPTIONS:
613     option_dialog_popup(_("Local Options"), client_optset);
614     break;
615   case MENU_GAME_MSG_OPTIONS:
616     popup_messageopt_dialog();
617     break;
618   case MENU_GAME_SAVE_SETTINGS:
619     options_save(NULL);
620     break;
621   case MENU_GAME_SERVER_OPTIONS:
622     option_dialog_popup(_("Game Settings"), server_optset);
623     break;
624   case MENU_GAME_OUTPUT_LOG:
625     log_output_window();
626     break;
627   case MENU_GAME_CLEAR_OUTPUT:
628     clear_output_window();
629     break;
630   case MENU_GAME_DISCONNECT:
631     disconnect_from_server();
632     break;
633   case MENU_GAME_QUIT:
634     xaw_ui_exit();
635     break;
636   }
637 }
638 
639 /****************************************************************
640 ...
641 *****************************************************************/
government_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)642 static void government_menu_callback(Widget w, XtPointer client_data,
643 				     XtPointer garbage)
644 {
645   size_t pane_num = (size_t)client_data;
646 
647   switch(pane_num) {
648   case MENU_GOVERNMENT_FIND_CITY:
649     popup_find_dialog();
650     break;
651   case MENU_GOVERNMENT_RATES:
652     popup_rates_dialog();
653     break;
654   case MENU_GOVERNMENT_WORKLISTS:
655     popup_worklists_dialog(client.conn.playing);
656     break;
657   case MENU_GOVERNMENT_REVOLUTION:
658     popup_revolution_dialog(NULL);
659     break;
660   }
661 }
662 
663 /****************************************************************************
664   Callback for the government change entries in the government menu.
665 ****************************************************************************/
revolution_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)666 static void revolution_menu_callback(Widget w, XtPointer client_data,
667 				     XtPointer garbage)
668 {
669   struct government *pgovernment = client_data;
670 
671   if (!can_client_issue_orders()) {
672     return;
673   }
674   if (-1 == client.conn.playing->revolution_finishes) {
675     popup_revolution_dialog(pgovernment);
676   } else {
677     /* Player already has a revolution and should just choose a government */
678     set_government_choice(pgovernment);
679   }
680 }
681 
682 /****************************************************************
683 ...
684 *****************************************************************/
view_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)685 static void view_menu_callback(Widget w, XtPointer client_data,
686 			       XtPointer garbage)
687 {
688   size_t pane_num = (size_t)client_data;
689 
690   switch(pane_num) {
691   case MENU_VIEW_SHOW_MAP_GRID:
692     key_map_grid_toggle();
693     break;
694   case MENU_VIEW_SHOW_NATIONAL_BORDERS:
695     key_map_borders_toggle();
696     break;
697   case MENU_VIEW_SHOW_CITY_NAMES:
698     key_city_names_toggle();
699     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_CITY_GROWTH,
700                          gui_options.draw_city_names);
701     break;
702   case MENU_VIEW_SHOW_CITY_GROWTH:
703     key_city_growth_toggle();
704     break;
705   case MENU_VIEW_SHOW_CITY_PRODUCTIONS:
706     key_city_productions_toggle();
707     break;
708   case MENU_VIEW_SHOW_TERRAIN:
709     key_terrain_toggle();
710     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_COASTLINE,
711                          !gui_options.draw_terrain);
712     break;
713   case MENU_VIEW_SHOW_COASTLINE:
714     key_coastline_toggle();
715     break;
716   case MENU_VIEW_SHOW_PATHS:
717     key_roads_rails_toggle();
718     break;
719   case MENU_VIEW_SHOW_IRRIGATION:
720     key_irrigation_toggle();
721     break;
722   case MENU_VIEW_SHOW_MINES:
723     key_mines_toggle();
724     break;
725   case MENU_VIEW_SHOW_BASES:
726     key_bases_toggle();
727     break;
728   case MENU_VIEW_SHOW_RESOURCES:
729     key_resources_toggle();
730     break;
731   case MENU_VIEW_SHOW_HUTS:
732     key_huts_toggle();
733     break;
734   case MENU_VIEW_SHOW_POLLUTION:
735     key_pollution_toggle();
736     break;
737   case MENU_VIEW_SHOW_CITIES:
738     key_cities_toggle();
739     break;
740   case MENU_VIEW_SHOW_UNITS:
741     key_units_toggle();
742     menu_entry_sensitive(MENU_VIEW, MENU_VIEW_SHOW_FOCUS_UNIT,
743                          !gui_options.draw_units);
744     break;
745   case MENU_VIEW_SHOW_FOCUS_UNIT:
746     key_focus_unit_toggle();
747     break;
748   case MENU_VIEW_SHOW_FOG_OF_WAR:
749     key_fog_of_war_toggle();
750     break;
751   case MENU_VIEW_CENTER_VIEW:
752     request_center_focus_unit();
753     break;
754   }
755 }
756 
757 /****************************************************************
758   Order selected from the orders menu.
759 *****************************************************************/
orders_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)760 static void orders_menu_callback(Widget w, XtPointer client_data,
761                                  XtPointer garbage)
762 {
763   size_t pane_num = (size_t)client_data;
764 
765   switch(pane_num) {
766   case MENU_ORDER_BUILD_CITY:
767     key_unit_build_city();
768     break;
769   case MENU_ORDER_ROAD:
770     key_unit_road();
771     break;
772   case MENU_ORDER_IRRIGATE:
773     key_unit_irrigate();
774     break;
775   case MENU_ORDER_MINE:
776     key_unit_mine();
777     break;
778   case MENU_ORDER_TRANSFORM:
779     key_unit_transform();
780     break;
781   case MENU_ORDER_FORTRESS:
782     key_unit_fortress();
783     break;
784   case MENU_ORDER_AIRBASE:
785     key_unit_airbase();
786     break;
787   case MENU_ORDER_POLLUTION: /* or MENU_ORDER_PARADROP */
788     /* FIXME: This calls key_unit_paradrop() / key_unit_pollution()
789      * as many times as there's focus units while those functions
790      * themselves handle all focus units at once. */
791     unit_list_iterate(get_units_in_focus(), punit) {
792       if (can_unit_paradrop(punit)) {
793 	key_unit_paradrop();
794       } else {
795 	key_unit_pollution();
796       }
797     } unit_list_iterate_end;
798     break;
799   case MENU_ORDER_FALLOUT:
800     key_unit_fallout();
801     break;
802   case MENU_ORDER_FORTIFY:
803     key_unit_fortify();
804     break;
805   case MENU_ORDER_SENTRY:
806     key_unit_sentry();
807     break;
808   case MENU_ORDER_PILLAGE:
809     key_unit_pillage();
810     break;
811   case MENU_ORDER_HOMECITY:
812     key_unit_homecity();
813     break;
814   case MENU_ORDER_UNLOAD_TRANSPORTER:
815     key_unit_unload_all();
816     break;
817   case MENU_ORDER_LOAD:
818     unit_list_iterate(get_units_in_focus(), punit) {
819       request_unit_load(punit, NULL, unit_tile(punit));
820     } unit_list_iterate_end;
821     break;
822   case MENU_ORDER_UNLOAD:
823     unit_list_iterate(get_units_in_focus(), punit) {
824       request_unit_unload(punit);
825     } unit_list_iterate_end;
826     break;
827   case MENU_ORDER_WAKEUP_OTHERS:
828     key_unit_wakeup_others();
829     break;
830   case MENU_ORDER_AUTO_SETTLER:
831     key_unit_auto_settle();
832     break;
833   case MENU_ORDER_AUTO_EXPLORE:
834     key_unit_auto_explore();
835     break;
836   case MENU_ORDER_CONNECT_ROAD:
837     {
838       struct road_type *proad = road_by_compat_special(ROCO_ROAD);
839 
840       if (proad != NULL) {
841         struct extra_type *tgt;
842 
843         tgt = road_extra_get(proad);
844 
845         key_unit_connect(ACTIVITY_GEN_ROAD, tgt);
846       }
847     }
848     break;
849   case MENU_ORDER_CONNECT_RAIL:
850     {
851       struct road_type *proad = road_by_compat_special(ROCO_RAILROAD);
852 
853       if (proad != NULL) {
854         struct extra_type *tgt;
855 
856         tgt = road_extra_get(proad);
857 
858         key_unit_connect(ACTIVITY_GEN_ROAD, tgt);
859       }
860     }
861     break;
862   case MENU_ORDER_CONNECT_IRRIGATE:
863     {
864       struct extra_type_list *extras = extra_type_list_by_cause(EC_IRRIGATION);
865 
866       if (extra_type_list_size(extras) > 0) {
867         struct extra_type *pextra;
868 
869         pextra = extra_type_list_get(extra_type_list_by_cause(EC_IRRIGATION), 0);
870 
871         key_unit_connect(ACTIVITY_IRRIGATE, pextra);
872       }
873     }
874     break;
875   case MENU_ORDER_PATROL:
876     key_unit_patrol();
877     break;
878   case MENU_ORDER_GOTO:
879     key_unit_goto();
880     break;
881   case MENU_ORDER_GOTO_CITY:
882     if (get_num_units_in_focus() > 0)
883       popup_goto_dialog();
884     break;
885   case MENU_ORDER_RETURN:
886     unit_list_iterate(get_units_in_focus(), punit) {
887       request_unit_return(punit);
888     } unit_list_iterate_end;
889     break;
890   case MENU_ORDER_CONVERT:
891     key_unit_convert();
892     break;
893   case MENU_ORDER_DISBAND:
894     popup_disband_dialog(get_units_in_focus());
895     break;
896   case MENU_ORDER_BUILD_WONDER:
897     key_unit_build_wonder();
898     break;
899   case MENU_ORDER_TRADE_ROUTE:
900     key_unit_trade_route();
901     break;
902   case MENU_ORDER_DIPLOMAT_DLG:
903     key_unit_action_select();
904     break;
905   case MENU_ORDER_NUKE:
906     key_unit_nuke();
907     break;
908   case MENU_ORDER_SELECT_SAME_TYPE:
909     request_unit_select(get_units_in_focus(), SELTYPE_SAME, SELLOC_WORLD);
910     break;
911   case MENU_ORDER_WAIT:
912     key_unit_wait();
913     break;
914   case MENU_ORDER_DONE:
915     key_unit_done();
916     break;
917   }
918 }
919 
920 /****************************************************************
921   User has selected item from reports menu
922 *****************************************************************/
reports_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)923 static void reports_menu_callback(Widget w, XtPointer client_data,
924 				  XtPointer garbage)
925 {
926   size_t pane_num = (size_t)client_data;
927 
928   switch(pane_num) {
929   case MENU_REPORT_CITIES:
930     city_report_dialog_popup(FALSE);
931     break;
932   case MENU_REPORT_UNITS:
933     units_report_dialog_popup(FALSE);
934     break;
935   case MENU_REPORT_PLAYERS:
936     popup_players_dialog(FALSE);
937     break;
938   case MENU_REPORT_ECONOMY:
939     economy_report_dialog_popup(FALSE);
940     break;
941   case MENU_REPORT_SCIENCE:
942     science_report_dialog_popup(FALSE);
943     break;
944   case MENU_REPORT_WOW:
945     send_report_request(REPORT_WONDERS_OF_THE_WORLD);
946     break;
947   case MENU_REPORT_TOP_CITIES:
948     send_report_request(REPORT_TOP_5_CITIES);
949     break;
950   case MENU_REPORT_MESSAGES:
951     meswin_dialog_popup(FALSE);
952     break;
953   case MENU_REPORT_DEMOGRAPHIC:
954     send_report_request(REPORT_DEMOGRAPHIC);
955     break;
956   case MENU_REPORT_ACHIEVEMENTS:
957     send_report_request(REPORT_ACHIEVEMENTS);
958     break;
959   case MENU_REPORT_SPACESHIP:
960     if (NULL != client.conn.playing) {
961       popup_spaceship_dialog(client.conn.playing);
962     }
963     break;
964   }
965 }
966 
967 /****************************************************************
968   Callback for Editor menu entries.
969 *****************************************************************/
editor_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)970 static void editor_menu_callback(Widget w, XtPointer client_data,
971 				 XtPointer garbage)
972 {
973   size_t pane_num = (size_t)client_data;
974 
975   switch(pane_num) {
976   case MENU_EDITOR_TOGGLE:
977     key_editor_toggle();
978     break;
979   case MENU_EDITOR_TOOLS:
980     break;
981   }
982 }
983 
984 /****************************************************************
985 ...
986 *****************************************************************/
help_menu_callback(Widget w,XtPointer client_data,XtPointer garbage)987 static void help_menu_callback(Widget w, XtPointer client_data,
988 			       XtPointer garbage)
989 {
990   size_t pane_num = (size_t)client_data;
991 
992   switch(pane_num) {
993   case MENU_HELP_LANGUAGES:
994     popup_help_dialog_string(HELP_LANGUAGES_ITEM);
995     break;
996   case MENU_HELP_CONNECTING:
997     popup_help_dialog_string(HELP_CONNECTING_ITEM);
998     break;
999   case MENU_HELP_CONTROLS:
1000     popup_help_dialog_string(HELP_CONTROLS_ITEM);
1001     break;
1002   case MENU_HELP_CMA:
1003     popup_help_dialog_string(HELP_CMA_ITEM);
1004     break;
1005   case MENU_HELP_CHATLINE:
1006     popup_help_dialog_string(HELP_CHATLINE_ITEM);
1007     break;
1008   case MENU_HELP_WORKLIST_EDITOR:
1009     popup_help_dialog_string(HELP_WORKLIST_EDITOR_ITEM);
1010     break;
1011   case MENU_HELP_OVERVIEW:
1012     popup_help_dialog_string(HELP_OVERVIEW_ITEM);
1013     break;
1014   case MENU_HELP_PLAYING:
1015     popup_help_dialog_string(HELP_PLAYING_ITEM);
1016     break;
1017   case MENU_HELP_ECONOMY:
1018     popup_help_dialog_string(HELP_ECONOMY_ITEM);
1019     break;
1020   case MENU_HELP_CITIES:
1021     popup_help_dialog_string(HELP_CITIES_ITEM);
1022     break;
1023   case MENU_HELP_IMPROVEMENTS:
1024     popup_help_dialog_string(HELP_IMPROVEMENTS_ITEM);
1025     break;
1026   case MENU_HELP_UNITS:
1027     popup_help_dialog_string(HELP_UNITS_ITEM);
1028     break;
1029   case MENU_HELP_COMBAT:
1030     popup_help_dialog_string(HELP_COMBAT_ITEM);
1031     break;
1032   case MENU_HELP_ZOC:
1033     popup_help_dialog_string(HELP_ZOC_ITEM);
1034     break;
1035   case MENU_HELP_TECH:
1036     popup_help_dialog_string(HELP_TECHS_ITEM);
1037     break;
1038   case MENU_HELP_TERRAIN:
1039     popup_help_dialog_string(HELP_TERRAIN_ITEM);
1040     break;
1041   case MENU_HELP_WONDERS:
1042     popup_help_dialog_string(HELP_WONDERS_ITEM);
1043     break;
1044   case MENU_HELP_GOVERNMENT:
1045     popup_help_dialog_string(HELP_GOVERNMENT_ITEM);
1046     break;
1047   case MENU_HELP_DIPLOMACY:
1048     popup_help_dialog_string(HELP_DIPLOMACY_ITEM);
1049     break;
1050   case MENU_HELP_SPACE_RACE:
1051     popup_help_dialog_string(HELP_SPACE_RACE_ITEM);
1052     break;
1053   case MENU_HELP_RULESET:
1054     popup_help_dialog_string(HELP_RULESET_ITEM);
1055     break;
1056   case MENU_HELP_NATIONS:
1057     popup_help_dialog_string(HELP_NATIONS_ITEM);
1058     break;
1059   case MENU_HELP_COPYING:
1060     popup_help_dialog_string(HELP_COPYING_ITEM);
1061     break;
1062   case MENU_HELP_ABOUT:
1063     popup_help_dialog_string(HELP_ABOUT_ITEM);
1064     break;
1065   }
1066 }
1067 
1068 /****************************************************************
1069  Initialize menus.
1070 *****************************************************************/
setup_menus(Widget parent_form)1071 void setup_menus(Widget parent_form)
1072 {
1073   create_menu(MENU_GAME, "gamemenu",
1074 	      game_menu_entries, game_menu_callback,
1075 	      parent_form);
1076   create_menu(MENU_GOVERNMENT, "governmentmenu",
1077 	      government_menu_entries, government_menu_callback,
1078 	      parent_form);
1079   create_menu(MENU_VIEW, "viewmenu",
1080 	      view_menu_entries, view_menu_callback,
1081 	      parent_form);
1082   create_menu(MENU_ORDER, "ordersmenu",
1083 	      order_menu_entries, orders_menu_callback,
1084 	      parent_form);
1085   create_menu(MENU_REPORT, "reportsmenu",
1086 	      reports_menu_entries, reports_menu_callback,
1087 	      parent_form);
1088   create_menu(MENU_EDITOR, "editormenu",
1089 	      editor_menu_entries, editor_menu_callback,
1090 	      parent_form);
1091   create_menu(MENU_HELP, "helpmenu",
1092 	      help_menu_entries, help_menu_callback,
1093 	      parent_form);
1094 }
1095 
1096 /****************************************************************
1097  Determine whether menu item is active or not.
1098 *****************************************************************/
is_menu_item_active(enum MenuIndex menu,enum MenuID id)1099 int is_menu_item_active(enum MenuIndex menu, enum MenuID id)
1100 {
1101   struct Menu *pmenu = menus[menu];
1102   int i;
1103 
1104   for (i = 0; pmenu->entries[i].id != MENU_END_OF_LIST; i++) {
1105     if(pmenu->entries[i].id==id) {
1106       return XtIsSensitive(pmenu->entries[i].w);
1107     }
1108   }
1109 
1110   return FALSE;
1111 }
1112 
1113 /****************************************************************
1114   Create one of the main menus
1115 *****************************************************************/
create_menu(enum MenuIndex menu,char * name,struct MenuEntry entries[],void (* menucallback)(Widget,XtPointer,XtPointer),Widget parent)1116 void create_menu(enum MenuIndex menu, char *name, struct MenuEntry entries[],
1117 		 void (*menucallback)(Widget, XtPointer, XtPointer),
1118 		 Widget parent)
1119 {
1120   int i, j;
1121   struct Menu *mymenu;
1122   const char *xlt;
1123   int lstr;
1124   int litem;
1125   int lacel;
1126 
1127   mymenu=fc_malloc(sizeof(struct Menu));
1128   menus[menu]=mymenu;
1129   mymenu->entries=entries;
1130 
1131   /* Calculate the longest string in this menu so if the font
1132    * is fixed then we will know where to put the accelerator key.- Serrada */
1133   litem=lacel=0;
1134   for (i = 0; entries[i].id != MENU_END_OF_LIST; i++) {
1135     if (entries[i].id != MENU_SEPARATOR_LINE) {
1136       lstr=strlen(entries[i].acel);
1137       if (lacel<lstr) {
1138 	lacel=lstr;
1139       }
1140       for (j = 0; entries[i].text[j]; j++) {
1141 	xlt=Q_(entries[i].text[j]);
1142 	lstr=strlen(xlt);
1143 	if (strstr(xlt, "%s")) {
1144 	  lstr+=MAX_LEN_TERR_NAME_DISP;
1145 	}
1146 	if (litem<lstr) {
1147 	  litem=lstr;
1148 	}
1149       }
1150     }
1151   }
1152   if ((litem>0) && (lacel>0)) {
1153     litem+=(ACEL_SPACE/2);
1154     lacel+=(ACEL_SPACE-(ACEL_SPACE/2));
1155   }
1156   mymenu->maxitemlen=litem;
1157   mymenu->maxacellen=lacel;
1158 
1159   I_L(mymenu->button=XtVaCreateManagedWidget(name,
1160 					 menuButtonWidgetClass,
1161 					 parent,
1162 					 NULL));
1163 
1164   mymenu->shell=XtCreatePopupShell("menu", simpleMenuWidgetClass,
1165 				   mymenu->button, NULL, 0);
1166 
1167   for (i = 0; entries[i].id != MENU_END_OF_LIST; i++) {
1168     if (entries[i].id == MENU_SEPARATOR_LINE) {
1169       entries[i].w = XtCreateManagedWidget(NULL, smeLineObjectClass,
1170 					   mymenu->shell, NULL, 0);
1171     } else {
1172       xlt=menu_entry_text(menu, i, 0, "");
1173       entries[i].w = XtCreateManagedWidget(xlt, smeBSBObjectClass,
1174                                            mymenu->shell, NULL, 0);
1175       XtAddCallback(entries[i].w, XtNcallback, menucallback,
1176                     INT_TO_XTPOINTER(entries[i].id));
1177     }
1178   }
1179 
1180   return;
1181 }
1182 
1183 /****************************************************************
1184 ...
1185 *****************************************************************/
menu_entry_rename(enum MenuIndex menu,enum MenuID id,int var,const char * terr)1186 void menu_entry_rename(enum MenuIndex menu, enum MenuID id, int var,
1187 		       const char *terr)
1188 {
1189   struct Menu *pmenu = menus[menu];
1190   int i;
1191   char *item;
1192 
1193   for (i = 0; pmenu->entries[i].id != MENU_END_OF_LIST; i++) {
1194     if (pmenu->entries[i].id == id) {
1195       item = menu_entry_text(menu, i, var, terr);
1196       XtVaSetValues(pmenu->entries[i].w, XtNlabel, item, NULL);
1197       return;
1198     }
1199   }
1200 }
1201 
1202 /****************************************************************
1203 ...
1204 *****************************************************************/
menu_entry_sensitive(enum MenuIndex menu,enum MenuID id,Bool s)1205 void menu_entry_sensitive(enum MenuIndex menu, enum MenuID id, Bool s)
1206 {
1207   struct Menu *pmenu = menus[menu];
1208   int i;
1209 
1210   for (i = 0; pmenu->entries[i].id != MENU_END_OF_LIST; i++) {
1211     if(pmenu->entries[i].id==id) {
1212       XtSetSensitive(pmenu->entries[i].w, (s ? True : False));
1213       return;
1214     }
1215   }
1216 }
1217 
1218 /****************************************************************
1219 ...
1220 *****************************************************************/
menu_entry_text(enum MenuIndex menu,int ent,int var,const char * terr)1221 static char *menu_entry_text(enum MenuIndex menu, int ent, int var,
1222 			     const char *terr)
1223 {
1224   struct Menu *pmenu = menus[menu];
1225   static char retbuf[256];
1226   char tmp[256];
1227   const char *xlt;
1228 
1229   xlt=Q_(pmenu->entries[ent].text[var]);
1230 
1231   if (strstr(xlt, "%s")) {
1232     fc_snprintf(tmp, sizeof(tmp), xlt, terr);
1233     xlt=tmp;
1234   }
1235 
1236   fc_snprintf(retbuf, sizeof(retbuf), "%*.*s%*.*s",
1237 	  -pmenu->maxitemlen, pmenu->maxitemlen, xlt,
1238 	  pmenu->maxacellen, pmenu->maxacellen, pmenu->entries[ent].acel);
1239 
1240   return (retbuf);
1241 }
1242