Freeciv-3.2
Loading...
Searching...
No Matches
gotodlg.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <gtk/gtk.h>
23#include <gdk/gdkkeysyms.h>
24
25/* utility */
26#include "astring.h"
27#include "fcintl.h"
28#include "log.h"
29#include "support.h"
30
31/* common */
32#include "game.h"
33#include "map.h"
34#include "packets.h"
35#include "player.h"
36#include "unit.h"
37#include "unitlist.h"
38
39/* client */
40#include "client_main.h"
41#include "control.h"
42#include "goto.h"
43#include "options.h"
44#include "text.h"
45
46/* clien/gui-gtk-3.22 */
47#include "plrdlg.h"
48#include "dialogs.h"
49#include "gui_main.h"
50#include "gui_stuff.h"
51#include "mapview.h"
52
53#include "gotodlg.h"
54
55
63static bool gotodlg_updating = FALSE;
64
65static void update_goto_dialog(GtkToggleButton *button);
66static void update_source_label(void);
67static void refresh_airlift_column(void);
68static void refresh_airlift_button(void);
69static void goto_selection_callback(GtkTreeSelection *selection, gpointer data);
70
71static struct city *get_selected_city(void);
72
73enum {
75};
76
77enum {
78 GD_COL_CITY_ID = 0, /* Not shown if not compiled with --enable-debug. */
83
85};
86
87/**********************************************************************/
90static void goto_cmd_callback(GtkWidget *dlg, gint arg)
91{
92 switch (arg) {
95 break;
96
97 case CMD_AIRLIFT:
98 {
100
101 if (pdestcity) {
105 }
107 }
108 }
109 break;
110
111 case CMD_GOTO:
112 {
113 struct city *pdestcity = get_selected_city();
114
115 if (pdestcity) {
119 }
120 }
121 break;
122
123 default:
124 break;
125 }
126
128 dshell = NULL;
129}
130
131
132/**********************************************************************/
135static void create_goto_dialog(void)
136{
137 GtkWidget *sw, *label, *frame, *vbox;
140
141 dshell = gtk_dialog_new_with_buttons(_("Goto/Airlift Unit"),
142 NULL,
143 0,
144 _("_Cancel"),
146 _("Air_lift"),
148 _("_Goto"),
149 CMD_GOTO,
150 NULL);
154 g_signal_connect(dshell, "destroy",
156 g_signal_connect(dshell, "response",
158
159 source = gtk_label_new("" /* filled in later */);
163 source, FALSE, FALSE, 0);
164
166 "use-underline", TRUE,
167 "label", _("Select destination ci_ty"),
168 "xalign", 0.0,
169 "yalign", 0.5,
170 NULL);
171 frame = gtk_frame_new("");
174 frame, TRUE, TRUE, 0);
175
176 vbox = gtk_grid_new();
180 gtk_container_add(GTK_CONTAINER(frame), vbox);
181
186
195
196 /* Set the mnemonic in the frame label to focus the city list */
198
199#ifdef FREECIV_DEBUG
202 "text", GD_COL_CITY_ID, NULL);
205#endif /* FREECIV_DEBUG */
206
209 "text", GD_COL_CITY_NAME, NULL);
212
215 "pixbuf", GD_COL_FLAG, NULL);
217
220 "text", GD_COL_NATION, NULL);
223
226 "text", GD_COL_AIRLIFT, NULL);
229
235
237
238 all_toggle = gtk_check_button_new_with_mnemonic(_("Show _All Cities"));
240
242
245
247
249
253}
254
255/**********************************************************************/
259{
261 return;
262 }
263
264 if (!dshell) {
266 }
267
269}
270
271/**********************************************************************/
274static struct city *get_selected_city(void)
275{
276 GtkTreeModel *model;
277 GtkTreeIter it;
278 int city_id;
279
281 return NULL;
282 }
283
285
286 gtk_tree_model_get(model, &it, GD_COL_CITY_ID, &city_id, -1);
287
288 return game_city_by_number(city_id);
289}
290
291/**********************************************************************/
295 const struct player *pplayer)
296{
297 GtkTreeIter it;
298 struct nation_type *pnation = nation_of_player(pplayer);
299 const char *nation = nation_adjective_translation(pnation);
301
302 if (city_list_size(pplayer->cities) == 0) {
303 return FALSE;
304 }
305
306 pixbuf = get_flag(pnation);
307
308 city_list_iterate(pplayer->cities, pcity) {
309 gtk_list_store_append(store, &it);
310 gtk_list_store_set(store, &it,
311 GD_COL_CITY_ID, pcity->id,
314 GD_COL_NATION, nation,
315 /* GD_COL_AIRLIFT is populated later */
316 -1);
319
320 return TRUE;
321}
322
323/**********************************************************************/
327static void update_source_label(void)
328{
329 /* Arbitrary limit to stop the label getting ridiculously long */
330 static const int max_cities = 10;
331 struct {
332 const struct city *city;
333 struct unit_list *units;
335 int ncities = 0;
336 bool too_many = FALSE;
337 bool no_city = FALSE; /* any units not in a city? */
338 struct astring strs[max_cities];
339 int nstrs;
340 char *last_str;
341 const char *descriptions[max_cities+1];
342 int i;
343
344 /* Sanity check: if no units selected, give up */
346 gtk_label_set_text(GTK_LABEL(source), _("No units selected."));
347 return;
348 }
349
350 /* Divide selected units up into a list of unique cities */
352 const struct city *pcity = tile_city(unit_tile(punit));
353 if (pcity) {
354 /* Inefficient, but it's not a long list */
355 for (i = 0; i < ncities; i++) {
356 if (cities[i].city == pcity) {
358 break;
359 }
360 }
361 if (i == ncities) {
362 if (ncities < max_cities) {
363 cities[ncities].city = pcity;
364 cities[ncities].units = unit_list_new();
366 ncities++;
367 } else {
368 too_many = TRUE;
369 break;
370 }
371 }
372 } else {
373 no_city = TRUE;
374 }
376
377 /* Describe the individual cities. */
378 for (i = 0; i < ncities; i++) {
379 const char *air_text = get_airlift_text(cities[i].units, NULL);
380
381 astr_init(&strs[i]);
382 if (air_text != NULL) {
383 astr_add(&strs[i],
384 /* TRANS: goto/airlift dialog. "Paris (airlift: 2/4)".
385 * A set of these appear in an "and"-separated list. */
386 _("%s (airlift: %s)"),
388 } else {
390 }
391 descriptions[i] = astr_str(&strs[i]);
392 unit_list_destroy(cities[i].units);
393 }
394 if (too_many) {
395 /* TRANS: goto/airlift dialog. Too many cities to list, some omitted.
396 * Appears at the end of an "and"-separated list. */
397 descriptions[ncities] = last_str = fc_strdup(Q_("?gotodlg:more"));
398 nstrs = ncities+1;
399 } else if (no_city) {
400 /* TRANS: goto/airlift dialog. For units not currently in a city.
401 * Appears at the end of an "and"-separated list. */
402 descriptions[ncities] = last_str = fc_strdup(Q_("?gotodlg:no city"));
403 nstrs = ncities+1;
404 } else {
405 last_str = NULL;
406 nstrs = ncities;
407 }
408
409 /* Finally, update the label. */
410 {
411 struct astring label = ASTRING_INIT, list = ASTRING_INIT;
412 astr_set(&label,
413 /* TRANS: goto/airlift dialog. Current location of units; %s is an
414 * "and"-separated list of cities and associated info */
415 _("Currently in: %s"),
416 astr_build_and_list(&list, descriptions, nstrs));
417 astr_free(&list);
419 astr_free(&label);
420 }
421
422 /* Clear up. */
423 for (i = 0; i < ncities; i++) {
424 astr_free(&strs[i]);
425 }
426 free(last_str); /* might have been NULL */
427}
428
429/**********************************************************************/
433{
434 bool nonempty = FALSE;
435
436 if (!client_has_player()) {
437 /* Case global observer. */
438 return;
439 }
440
442
444
445 if (gtk_toggle_button_get_active(button)) {
446 players_iterate(pplayer) {
449 } else {
451 }
452
454
456
457 if (!nonempty) {
458 /* No selection causes callbacks to fire, causing also Airlift button
459 * to update. Do it here. */
461 }
462}
463
464/**********************************************************************/
467static void refresh_airlift_column(void)
468{
470 bool valid;
471
473 while (valid) {
474 int city_id;
475 const struct city *pcity;
476 const char *air_text;
477
479 GD_COL_CITY_ID, &city_id, -1);
480 pcity = game_city_by_number(city_id);
481 fc_assert_ret(pcity != NULL);
484 GD_COL_AIRLIFT, air_text ? air_text : "-", -1);
486 }
487}
488
489/**********************************************************************/
493static void refresh_airlift_button(void)
494{
495 struct city *pdestcity = get_selected_city();
496
497 if (NULL != pdestcity) {
498 bool can_airlift = FALSE;
499
500 /* Allow action if any of the selected units can airlift. */
504 break;
505 }
507
508 if (can_airlift) {
511 return;
512 }
513 }
515}
516
517/**********************************************************************/
522 gpointer data)
523{
524 struct city *pdestcity;
525
526 if (gotodlg_updating) {
527 return;
528 }
529
531
532 if (NULL != pdestcity) {
534 }
536}
537
538/**********************************************************************/
542{
543 /* Is the dialog currently being displayed? */
544 if (dshell) {
545 /* Location of current units and ability to airlift may have changed */
549 }
550}
void astr_free(struct astring *astr)
Definition astring.c:153
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
const char * astr_build_and_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:367
void astr_init(struct astring *astr)
Definition astring.c:144
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:564
#define city_list_iterate_end
Definition city.h:510
bool can_client_issue_orders(void)
bool client_has_player(void)
#define client_player()
static struct fc_sockaddr_list * list
Definition clinet.c:102
char * incite_cost
Definition comments.c:75
void request_unit_airlift(struct unit *punit, struct city *pcity)
Definition control.c:1543
struct unit_list * get_units_in_focus(void)
Definition control.c:177
int get_num_units_in_focus(void)
Definition control.c:185
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
struct world wld
Definition game.c:63
struct city * game_city_by_number(int id)
Definition game.c:107
bool send_goto_tile(struct unit *punit, struct tile *ptile)
Definition goto.c:1551
static GtkListStore * goto_list_store
Definition gotodlg.c:60
static void update_source_label(void)
Definition gotodlg.c:327
static void goto_cmd_callback(GtkWidget *dlg, gint arg)
Definition gotodlg.c:90
static GtkTreeSelection * goto_list_selection
Definition gotodlg.c:61
static void refresh_airlift_column(void)
Definition gotodlg.c:467
void goto_dialog_focus_units_changed(void)
Definition gotodlg.c:541
struct tile * original_tile
Definition gotodlg.c:62
void popup_goto_dialog(void)
Definition gotodlg.c:258
static GtkWidget * dshell
Definition gotodlg.c:56
static bool list_store_append_player_cities(GtkListStore *store, const struct player *pplayer)
Definition gotodlg.c:294
static GtkWidget * all_toggle
Definition gotodlg.c:59
static bool gotodlg_updating
Definition gotodlg.c:63
static struct city * get_selected_city(void)
Definition gotodlg.c:274
@ CMD_AIRLIFT
Definition gotodlg.c:74
@ CMD_GOTO
Definition gotodlg.c:74
@ GD_COL_CITY_ID
Definition gotodlg.c:78
@ GD_COL_FLAG
Definition gotodlg.c:80
@ GD_COL_AIRLIFT
Definition gotodlg.c:82
@ GD_COL_NATION
Definition gotodlg.c:81
@ GD_COL_CITY_NAME
Definition gotodlg.c:79
@ GD_COL_NUM
Definition gotodlg.c:84
static void refresh_airlift_button(void)
Definition gotodlg.c:493
static GtkWidget * source
Definition gotodlg.c:58
static GtkWidget * view
Definition gotodlg.c:57
static void create_goto_dialog(void)
Definition gotodlg.c:135
static void goto_selection_callback(GtkTreeSelection *selection, gpointer data)
Definition gotodlg.c:521
GtkWidget * toplevel
Definition gui_main.c:125
void gtk_tree_view_focus(GtkTreeView *view)
Definition gui_stuff.c:236
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
GdkPixbuf * get_flag(const struct nation_type *nation)
Definition plrdlg.c:607
static void update_goto_dialog(void)
Definition gotodlg.c:135
#define fc_assert_ret(condition)
Definition log.h:191
struct tile * get_center_tile_mapcanvas(void)
void center_tile_mapcanvas(const struct tile *ptile)
#define fc_strdup(str)
Definition mem.h:43
const char * nation_adjective_translation(const struct nation_type *pnation)
Definition nation.c:149
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
struct city_list * cities
Definition packhand.c:119
#define players_iterate_end
Definition player.h:537
#define players_iterate(_pplayer)
Definition player.h:532
Definition city.h:320
struct city_list * cities
Definition player.h:279
Definition tile.h:50
struct tile * tile
Definition unit.h:140
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char * get_airlift_text(const struct unit_list *punits, const struct city *pdest)
Definition text.c:545
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
bool unit_can_airlift_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:186
#define unit_tile(_pu)
Definition unit.h:397
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33