webperimental: killstack decides stack protects.
[freeciv.git] / client / gui-gtk-3.0 / plrdlg.c
blobd74f55c88d309cc99d09637850c38dcc8b70a153
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
22 #include <gtk/gtk.h>
23 #include <gdk/gdkkeysyms.h>
25 /* utility */
26 #include "astring.h"
27 #include "fcintl.h"
28 #include "support.h"
30 /* common */
31 #include "diptreaty.h"
32 #include "packets.h"
33 #include "nation.h"
34 #include "player.h"
36 /* client */
37 #include "client_main.h"
38 #include "climisc.h"
39 #include "connectdlg_common.h"
40 #include "tilespec.h"
41 #include "colors.h"
42 #include "graphics.h"
43 #include "options.h"
44 #include "text.h"
46 /* client/gui-gtk-3.0 */
47 #include "chatline.h"
48 #include "dialogs.h"
49 #include "gui_main.h"
50 #include "gui_stuff.h"
51 #include "inteldlg.h"
52 #include "spaceshipdlg.h"
53 #include "colors.h"
54 #include "graphics.h"
56 #include "plrdlg.h"
58 struct gui_dialog *players_dialog_shell;
59 static GtkWidget *players_list;
60 static GtkTreeSelection *players_selection;
61 static GtkWidget *players_int_command;
62 static GtkWidget *players_meet_command;
63 static GtkWidget *players_war_command;
64 static GtkWidget *players_vision_command;
65 static GtkWidget *players_sship_command;
67 static GtkListStore *players_dialog_store;
68 #define PLR_DLG_COL_STYLE (0 + num_player_dlg_columns)
69 #define PLR_DLG_COL_WEIGHT (1 + num_player_dlg_columns)
70 #define PLR_DLG_COL_ID (2 + num_player_dlg_columns)
72 static void create_players_dialog(void);
73 static void players_meet_callback(GtkMenuItem *item, gpointer data);
74 static void players_war_callback(GtkMenuItem *item, gpointer data);
75 static void players_vision_callback(GtkMenuItem *item, gpointer data);
76 static void players_intel_callback(GtkMenuItem *item, gpointer data);
77 static void players_sship_callback(GtkMenuItem *item, gpointer data);
78 static void players_ai_toggle_callback(GtkMenuItem *item, gpointer data);
79 static void players_ai_skill_callback(GtkMenuItem *item, gpointer data);
82 static void update_views(void);
84 /**************************************************************************
85 popup the dialog 10% inside the main-window, and optionally raise it.
86 **************************************************************************/
87 void popup_players_dialog(bool raise)
89 if (!players_dialog_shell){
90 create_players_dialog();
92 gui_dialog_present(players_dialog_shell);
93 if (raise) {
94 gui_dialog_raise(players_dialog_shell);
98 /****************************************************************
99 Closes the players dialog.
100 *****************************************************************/
101 void popdown_players_dialog(void)
103 if (players_dialog_shell) {
104 gui_dialog_destroy(players_dialog_shell);
108 /***************************************************************************
109 Create a small colored square representing the player color, for use
110 in player lists.
111 May return NULL if the player has no color yet.
112 ***************************************************************************/
113 GdkPixbuf *create_player_icon(const struct player *plr)
115 int width, height;
116 GdkPixbuf *tmp;
117 cairo_surface_t *surface;
118 struct color *color;
119 cairo_t *cr;
121 if (!player_has_color(tileset, plr)) {
122 return NULL;
125 gtk_icon_size_lookup_for_settings(
126 gtk_settings_get_for_screen(gtk_widget_get_screen(top_notebook)),
127 GTK_ICON_SIZE_MENU, &width, &height);
128 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
130 cr = cairo_create(surface);
132 color = get_color(tileset, COLOR_PLAYER_COLOR_BACKGROUND);
133 gdk_cairo_set_source_rgba(cr, &color->color);
134 cairo_rectangle(cr, 0, 0, width, height);
135 cairo_fill(cr);
137 color = get_player_color(tileset, plr);
138 gdk_cairo_set_source_rgba(cr, &color->color);
139 cairo_rectangle(cr, 1, 1, width - 2, height - 2);
140 cairo_fill(cr);
142 cairo_destroy(cr);
143 tmp = surface_get_pixbuf(surface, width, height);
144 cairo_surface_destroy(surface);
146 return tmp;
149 /**************************************************************************
150 Refresh player menu
151 **************************************************************************/
152 static void update_players_menu(void)
154 GtkTreeModel *model;
155 GtkTreeIter it;
157 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
158 struct player *plr;
159 gint plrno;
161 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
162 plr = player_by_number(plrno);
164 if (plr->spaceship.state != SSHIP_NONE) {
165 gtk_widget_set_sensitive(players_sship_command, TRUE);
166 } else {
167 gtk_widget_set_sensitive(players_sship_command, FALSE);
170 if (NULL != client.conn.playing) {
171 /* We keep button sensitive in case of DIPL_SENATE_BLOCKING, so that player
172 * can request server side to check requirements of those effects with omniscience */
173 gtk_widget_set_sensitive(players_war_command,
174 can_client_issue_orders()
175 && pplayer_can_cancel_treaty(client_player(),
176 player_by_number(plrno))
177 != DIPL_ERROR);
178 } else {
179 gtk_widget_set_sensitive(players_war_command, FALSE);
182 gtk_widget_set_sensitive(players_vision_command,
183 can_client_issue_orders()
184 && gives_shared_vision(client.conn.playing, plr)
185 && !players_on_same_team(client.conn.playing, plr));
187 gtk_widget_set_sensitive(players_meet_command, can_meet_with_player(plr));
188 gtk_widget_set_sensitive(players_int_command, can_intel_with_player(plr));
189 return;
192 gtk_widget_set_sensitive(players_meet_command, FALSE);
193 gtk_widget_set_sensitive(players_int_command, FALSE);
196 /**************************************************************************
197 Something selected from player menu
198 **************************************************************************/
199 static void selection_callback(GtkTreeSelection *selection, gpointer data)
201 update_players_menu();
204 /**************************************************************************
205 Button pressed on player list
206 **************************************************************************/
207 static gboolean button_press_callback(GtkTreeView *view, GdkEventButton *ev)
209 if (ev->type == GDK_2BUTTON_PRESS) {
210 GtkTreePath *path;
212 gtk_tree_view_get_cursor(view, &path, NULL);
213 if (path) {
214 GtkTreeModel *model = gtk_tree_view_get_model(view);
215 GtkTreeIter it;
216 gint id;
217 struct player *plr;
219 gtk_tree_model_get_iter(model, &it, path);
220 gtk_tree_path_free(path);
222 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &id, -1);
223 plr = player_by_number(id);
225 if (ev->button == 1) {
226 if (can_intel_with_player(plr)) {
227 popup_intel_dialog(plr);
229 } else if (can_meet_with_player(plr)) {
230 dsend_packet_diplomacy_init_meeting_req(&client.conn, id);
234 return FALSE;
237 /**************************************************************************
238 Sorting function for plr dlg.
239 **************************************************************************/
240 static gint plrdlg_sort_func(GtkTreeModel *model,
241 GtkTreeIter *a, GtkTreeIter *b, gpointer data)
243 GValue value = { 0, };
244 struct player *player1;
245 struct player *player2;
246 gint n;
248 n = GPOINTER_TO_INT(data);
250 gtk_tree_model_get_value(model, a, PLR_DLG_COL_ID, &value);
251 player1 = player_by_number(g_value_get_int(&value));
252 g_value_unset(&value);
254 gtk_tree_model_get_value(model, b, PLR_DLG_COL_ID, &value);
255 player2 = player_by_number(g_value_get_int(&value));
256 g_value_unset(&value);
258 return player_dlg_columns[n].sort_func(player1, player2);
261 /****************************************************************************
262 Create a player dialog store.
263 ****************************************************************************/
264 static GtkListStore *players_dialog_store_new(void)
266 GtkListStore *store;
267 GType model_types[num_player_dlg_columns + 3];
268 int i;
270 for (i = 0; i < num_player_dlg_columns; i++) {
271 switch (player_dlg_columns[i].type) {
272 case COL_FLAG:
273 model_types[i] = GDK_TYPE_PIXBUF;
274 break;
275 case COL_COLOR:
276 model_types[i] = GDK_TYPE_PIXBUF;
277 break;
278 case COL_BOOLEAN:
279 model_types[i] = G_TYPE_BOOLEAN;
280 break;
281 case COL_TEXT:
282 case COL_RIGHT_TEXT:
283 model_types[i] = G_TYPE_STRING;
284 break;
287 /* special (invisible rows) - Text style, weight and player id */
288 model_types[i++] = G_TYPE_INT; /* PLR_DLG_COL_STYLE. */
289 model_types[i++] = G_TYPE_INT; /* PLR_DLG_COL_WEIGHT. */
290 model_types[i++] = G_TYPE_INT; /* PLR_DLG_COL_ID. */
292 store = gtk_list_store_newv(i, model_types);
294 /* Set sort order */
295 for (i = 0; i < num_player_dlg_columns; i++) {
296 if (player_dlg_columns[i].sort_func != NULL) {
297 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), i,
298 plrdlg_sort_func, GINT_TO_POINTER(i),
299 NULL);
303 return store;
306 /**************************************************************************
307 Toggled column visibility
308 **************************************************************************/
309 static void toggle_view(GtkCheckMenuItem* item, gpointer data)
311 struct player_dlg_column* pcol = data;
313 pcol->show = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
314 update_views();
317 /*************************************************************************
318 Called whenever player toggles the 'Show/Dead Players' menu item
319 *************************************************************************/
320 static void toggle_dead_players(GtkCheckMenuItem* item, gpointer data)
322 gui_options.player_dlg_show_dead_players =
323 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
324 real_players_dialog_update();
327 /**************************************************************************
328 Create and return the "diplomacy" menu for the player report. This menu
329 contains diplomacy actions the current player can use on other nations.
330 **************************************************************************/
331 static GtkWidget *create_diplomacy_menu(void)
333 GtkWidget *menu, *item;
335 menu = gtk_menu_new();
337 item = gtk_menu_item_new_with_mnemonic(_("_Meet"));
338 g_signal_connect(item, "activate",
339 G_CALLBACK(players_meet_callback), NULL);
340 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
341 players_meet_command = item;
343 item = gtk_menu_item_new_with_mnemonic(_("Cancel _Treaty"));
344 g_signal_connect(item, "activate",
345 G_CALLBACK(players_war_callback), NULL);
346 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
347 players_war_command = item;
349 item = gtk_menu_item_new_with_mnemonic(_("_Withdraw Vision"));
350 g_signal_connect(item, "activate",
351 G_CALLBACK(players_vision_callback), NULL);
352 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
353 players_vision_command = item;
355 return menu;
358 /**************************************************************************
359 Create and return the "intelligence" menu. The items in this menu are
360 used by the player to see more detailed information about other nations.
361 **************************************************************************/
362 static GtkWidget *create_intelligence_menu(void)
364 GtkWidget *menu, *item;
366 menu = gtk_menu_new();
368 item = gtk_menu_item_new_with_mnemonic(_("_Report"));
369 g_signal_connect(item, "activate",
370 G_CALLBACK(players_intel_callback), NULL);
371 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
372 players_int_command = item;
374 item = gtk_menu_item_new_with_mnemonic(_("_Spaceship"));
375 g_signal_connect(item, "activate",
376 G_CALLBACK(players_sship_callback), NULL);
377 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
378 players_sship_command = item;
380 return menu;
383 /**************************************************************************
384 Create 'show' menu for player dialog
385 **************************************************************************/
386 static GtkWidget* create_show_menu(void)
388 int i;
389 GtkWidget *menu = gtk_menu_new();
390 GtkWidget *item;
392 /* index starting at one (1) here to force playername to always be shown */
393 for (i = 1; i < num_player_dlg_columns; i++) {
394 struct player_dlg_column *pcol;
396 pcol = &player_dlg_columns[i];
397 item = gtk_check_menu_item_new_with_label(pcol->title);
398 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), pcol->show);
399 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
400 g_signal_connect(item, "toggled", G_CALLBACK(toggle_view), pcol);
403 item = gtk_separator_menu_item_new();
404 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
406 item = gtk_check_menu_item_new_with_label(Q_("?show:Dead Players"));
407 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
408 gui_options.player_dlg_show_dead_players);
409 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
410 g_signal_connect(item, "toggled", G_CALLBACK(toggle_dead_players), NULL);
412 return menu;
415 /**************************************************************************
416 Create all of player dialog
417 **************************************************************************/
418 void create_players_dialog(void)
420 int i;
421 GtkWidget *sep, *sw;
422 GtkWidget *menubar, *menu, *item, *vbox;
423 enum ai_level level;
425 gui_dialog_new(&players_dialog_shell, GTK_NOTEBOOK(top_notebook), NULL,
426 TRUE);
427 /* TRANS: Nations report title */
428 gui_dialog_set_title(players_dialog_shell, _("Nations"));
430 gui_dialog_add_button(players_dialog_shell,
431 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
433 gui_dialog_set_default_size(players_dialog_shell, -1, 270);
435 players_dialog_store = players_dialog_store_new();
437 players_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL
438 (players_dialog_store));
439 gtk_widget_set_hexpand(players_list, TRUE);
440 gtk_widget_set_vexpand(players_list, TRUE);
441 g_object_unref(players_dialog_store);
442 gtk_widget_set_name(players_list, "small_font");
444 players_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(players_list));
445 g_signal_connect(players_selection, "changed",
446 G_CALLBACK(selection_callback), NULL);
447 g_signal_connect(players_list, "button_press_event",
448 G_CALLBACK(button_press_callback), NULL);
450 for (i = 0; i < num_player_dlg_columns; i++) {
451 struct player_dlg_column *pcol;
452 GtkCellRenderer *renderer;
453 GtkTreeViewColumn *col;
455 pcol = &player_dlg_columns[i];
456 col = NULL;
458 switch (pcol->type) {
459 case COL_FLAG:
460 renderer = gtk_cell_renderer_pixbuf_new();
462 col = gtk_tree_view_column_new_with_attributes(pcol->title,
463 renderer, "pixbuf", i, NULL);
464 break;
465 case COL_BOOLEAN:
466 renderer = gtk_cell_renderer_toggle_new();
468 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
469 "active", i, NULL);
470 break;
471 case COL_COLOR:
472 renderer = gtk_cell_renderer_pixbuf_new();
474 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
475 "pixbuf", i, NULL);
476 break;
477 case COL_TEXT:
478 renderer = gtk_cell_renderer_text_new();
479 g_object_set(renderer, "style-set", TRUE, "weight-set", TRUE, NULL);
481 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
482 "text", i,
483 "style", PLR_DLG_COL_STYLE,
484 "weight", PLR_DLG_COL_WEIGHT,
485 NULL);
486 gtk_tree_view_column_set_sort_column_id(col, i);
487 break;
488 case COL_RIGHT_TEXT:
489 renderer = gtk_cell_renderer_text_new();
490 g_object_set(renderer, "style-set", TRUE, "weight-set", TRUE, NULL);
492 col = gtk_tree_view_column_new_with_attributes(pcol->title, renderer,
493 "text", i,
494 "style", PLR_DLG_COL_STYLE,
495 "weight", PLR_DLG_COL_WEIGHT,
496 NULL);
497 gtk_tree_view_column_set_sort_column_id(col, i);
498 g_object_set(renderer, "xalign", 1.0, NULL);
499 gtk_tree_view_column_set_alignment(col, 1.0);
500 break;
503 if (col) {
504 gtk_tree_view_append_column(GTK_TREE_VIEW(players_list), col);
508 gtk_tree_view_set_search_column(GTK_TREE_VIEW(players_list),
509 player_dlg_default_sort_column());
511 sw = gtk_scrolled_window_new(NULL, NULL);
512 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
513 GTK_SHADOW_ETCHED_IN);
514 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
515 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
516 gtk_container_add(GTK_CONTAINER(sw), players_list);
518 gtk_container_add(GTK_CONTAINER(players_dialog_shell->vbox), sw);
520 vbox = gtk_grid_new();
521 gtk_orientable_set_orientation(GTK_ORIENTABLE(vbox),
522 GTK_ORIENTATION_VERTICAL);
524 sep = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
525 gtk_container_add(GTK_CONTAINER(vbox), sep);
527 menubar = gtk_aux_menu_bar_new();
528 gtk_container_add(GTK_CONTAINER(vbox), menubar);
531 gui_dialog_add_widget(players_dialog_shell, vbox);
533 item = gtk_menu_item_new_with_mnemonic(_("Di_plomacy"));
534 menu = create_diplomacy_menu();
535 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
536 gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
538 item = gtk_menu_item_new_with_mnemonic(_("_Intelligence"));
539 menu = create_intelligence_menu();
540 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
541 gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
543 item = gtk_menu_item_new_with_mnemonic(_("_Display"));
544 menu = create_show_menu();
545 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
546 gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
548 item = gtk_menu_item_new_with_mnemonic(_("_AI"));
549 gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
551 menu = gtk_menu_new();
552 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
554 item = gtk_menu_item_new_with_mnemonic(_("_Toggle AI Mode"));
555 g_signal_connect(item, "activate",
556 G_CALLBACK(players_ai_toggle_callback), NULL);
557 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
559 sep = gtk_separator_menu_item_new();
560 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
562 for (level = 0; level < AI_LEVEL_COUNT; level++) {
563 if (is_settable_ai_level(level)) {
564 const char *level_name = ai_level_translated_name(level);
566 item = gtk_menu_item_new_with_label(level_name);
567 g_signal_connect(item, "activate",
568 G_CALLBACK(players_ai_skill_callback),
569 GUINT_TO_POINTER(level));
570 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
573 gtk_widget_show_all(menu);
575 gui_dialog_show_all(players_dialog_shell);
577 real_players_dialog_update();
579 gui_dialog_set_default_response(players_dialog_shell,
580 GTK_RESPONSE_CLOSE);
582 gtk_tree_view_focus(GTK_TREE_VIEW(players_list));
586 /**************************************************************************
588 **************************************************************************/
589 #define MIN_DIMENSION 5
591 /**************************************************************************
592 Builds the flag pixmap. May return NULL if there is not enough memory.
593 You must call g_object_unref on the returned pixbuf when it is no
594 longer needed.
595 **************************************************************************/
596 GdkPixbuf *get_flag(const struct nation_type *nation)
598 int x0, y0, x1, y1, w, h;
599 GdkPixbuf *im;
600 struct sprite *flag;
602 flag = get_nation_flag_sprite(tileset, nation);
604 /* calculate the bounding box ... */
605 sprite_get_bounding_box(flag, &x0, &y0, &x1, &y1);
607 fc_assert_ret_val(x0 != -1, NULL);
608 fc_assert_ret_val(y0 != -1, NULL);
609 fc_assert_ret_val(x1 != -1, NULL);
610 fc_assert_ret_val(y1 != -1, NULL);
612 w = (x1 - x0) + 1;
613 h = (y1 - y0) + 1;
615 /* if the flag is smaller then 5 x 5, something is wrong */
616 fc_assert_ret_val(w >= MIN_DIMENSION && h >= MIN_DIMENSION, NULL);
618 /* croping */
619 im = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
620 if (im != NULL) {
621 GdkPixbuf *pixbuf = sprite_get_pixbuf(flag);
623 gdk_pixbuf_copy_area(pixbuf, x0, y0, w, h,
624 im, 0, 0);
625 g_object_unref(G_OBJECT(pixbuf));
628 /* and finally store the scaled flag pixbuf in the static flags array */
629 return im;
633 /**************************************************************************
634 Fills the player list with the information for 'pplayer' at the row
635 given by 'it'.
636 **************************************************************************/
637 static void fill_row(GtkListStore *store, GtkTreeIter *it,
638 const struct player *pplayer)
640 struct player_dlg_column* pcol;
641 GdkPixbuf *pixbuf;
642 int style = PANGO_STYLE_NORMAL, weight = PANGO_WEIGHT_NORMAL;
643 int k;
645 for (k = 0; k < num_player_dlg_columns; k++) {
646 pcol = &player_dlg_columns[k];
647 switch (pcol->type) {
648 case COL_TEXT:
649 case COL_RIGHT_TEXT:
650 gtk_list_store_set(store, it, k, pcol->func(pplayer), -1);
651 break;
652 case COL_FLAG:
653 pixbuf = get_flag(nation_of_player(pplayer));
654 if (pixbuf != NULL) {
655 gtk_list_store_set(store, it, k, pixbuf, -1);
656 g_object_unref(pixbuf);
658 break;
659 case COL_COLOR:
660 pixbuf = create_player_icon(pplayer);
661 if (pixbuf != NULL) {
662 gtk_list_store_set(store, it, k, pixbuf, -1);
663 g_object_unref(pixbuf);
665 break;
666 case COL_BOOLEAN:
667 gtk_list_store_set(store, it, k, pcol->bool_func(pplayer), -1);
668 break;
672 /* now add some eye candy ... */
673 if (client_has_player()) {
674 switch (player_diplstate_get(client_player(), pplayer)->type) {
675 case DS_WAR:
676 weight = PANGO_WEIGHT_NORMAL;
677 style = PANGO_STYLE_ITALIC;
678 break;
679 case DS_ALLIANCE:
680 case DS_TEAM:
681 weight = PANGO_WEIGHT_BOLD;
682 style = PANGO_STYLE_NORMAL;
683 break;
684 case DS_ARMISTICE:
685 case DS_CEASEFIRE:
686 case DS_PEACE:
687 case DS_NO_CONTACT:
688 weight = PANGO_WEIGHT_NORMAL;
689 style = PANGO_STYLE_NORMAL;
690 break;
691 case DS_LAST:
692 break;
696 gtk_list_store_set(store, it,
697 PLR_DLG_COL_STYLE, style,
698 PLR_DLG_COL_WEIGHT, weight,
699 PLR_DLG_COL_ID, player_number(pplayer),
700 -1);
703 /**************************************************************************
704 Return TRUE if the player should be shown in the player list.
705 **************************************************************************/
706 static bool player_should_be_shown(const struct player *pplayer)
708 return NULL != pplayer && (gui_options.player_dlg_show_dead_players
709 || pplayer->is_alive)
710 && (!is_barbarian(pplayer));
713 /**************************************************************************
714 Clear and refill the entire player list.
715 **************************************************************************/
716 void real_players_dialog_update(void)
718 GtkTreeModel *model;
719 GtkTreeIter iter;
720 int selected;
722 if (NULL == players_dialog_shell) {
723 return;
726 /* Save the selection. */
727 if (gtk_tree_selection_get_selected(players_selection, &model, &iter)) {
728 gtk_tree_model_get(model, &iter, PLR_DLG_COL_ID, &selected, -1);
729 } else {
730 selected = -1;
733 gtk_list_store_clear(players_dialog_store);
734 players_iterate(pplayer) {
735 if (!player_should_be_shown(pplayer)) {
736 continue;
738 gtk_list_store_append(players_dialog_store, &iter);
739 fill_row(players_dialog_store, &iter, pplayer);
740 if (player_number(pplayer) == selected) {
741 /* Restore the selection. */
742 gtk_tree_selection_select_iter(players_selection, &iter);
744 } players_iterate_end;
746 update_views();
749 /**************************************************************************
750 Callback for diplomatic meetings button. This button is enabled iff
751 we can meet with the other player.
752 **************************************************************************/
753 void players_meet_callback(GtkMenuItem *item, gpointer data)
755 GtkTreeModel *model;
756 GtkTreeIter it;
758 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
759 gint plrno;
761 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
763 dsend_packet_diplomacy_init_meeting_req(&client.conn, plrno);
767 /**************************************************************************
768 Confirm pact/treaty cancellation.
769 Frees strings passed in.
770 **************************************************************************/
771 static void confirm_cancel_pact(enum clause_type clause, int plrno,
772 char *title, char *question)
774 GtkWidget *shell;
776 shell = gtk_message_dialog_new(NULL, 0,
777 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
778 "%s", question);
779 gtk_window_set_title(GTK_WINDOW(shell), title);
780 setup_dialog(shell, toplevel);
781 gtk_dialog_set_default_response(GTK_DIALOG(shell), GTK_RESPONSE_NO);
783 if (gtk_dialog_run(GTK_DIALOG(shell)) == GTK_RESPONSE_YES) {
784 dsend_packet_diplomacy_cancel_pact(&client.conn, plrno, clause);
786 gtk_widget_destroy(shell);
787 FC_FREE(title);
788 FC_FREE(question);
791 /**************************************************************************
792 Pact cancellation requested
793 **************************************************************************/
794 void players_war_callback(GtkMenuItem *item, gpointer data)
796 GtkTreeModel *model;
797 GtkTreeIter it;
799 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
800 struct astring title = ASTRING_INIT, question = ASTRING_INIT;
801 gint plrno;
802 struct player *aplayer;
803 enum diplstate_type oldstate, newstate;
805 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
806 aplayer = player_by_number(plrno);
807 fc_assert_ret(aplayer != NULL);
809 oldstate = player_diplstate_get(client_player(), aplayer)->type;
810 newstate = cancel_pact_result(oldstate);
812 /* TRANS: %s is a diplomatic state: "Cancel Cease-fire" */
813 astr_set(&title, _("Cancel %s"), diplstate_type_translated_name(oldstate));
815 if (newstate == DS_WAR) {
816 astr_set(&question, _("Really declare war on the %s?"),
817 nation_plural_for_player(aplayer));
818 } else {
819 /* TRANS: "Cancel Belgian Alliance? ... will be Armistice." */
820 astr_set(&question, _("Cancel %s %s? New diplomatic state will be %s."),
821 nation_adjective_for_player(aplayer),
822 diplstate_type_translated_name(oldstate),
823 diplstate_type_translated_name(newstate));
826 /* can be any pact clause */
827 confirm_cancel_pact(CLAUSE_CEASEFIRE, plrno,
828 astr_to_str(&title), astr_to_str(&question));
832 /**************************************************************************
833 Withdrawing shared vision
834 **************************************************************************/
835 void players_vision_callback(GtkMenuItem *item, gpointer data)
837 GtkTreeModel *model;
838 GtkTreeIter it;
840 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
841 struct astring question = ASTRING_INIT;
842 gint plrno;
843 struct player *aplayer;
845 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
846 aplayer = player_by_number(plrno);
847 fc_assert_ret(aplayer != NULL);
849 /* TRANS: "...from the Belgians?" */
850 astr_set(&question, _("Withdraw shared vision from the %s?"),
851 nation_plural_for_player(aplayer));
853 confirm_cancel_pact(CLAUSE_VISION, plrno,
854 fc_strdup(_("Withdraw Shared Vision")),
855 astr_to_str(&question));
859 /**************************************************************************
860 Intelligence report query
861 **************************************************************************/
862 void players_intel_callback(GtkMenuItem *item, gpointer data)
864 GtkTreeModel *model;
865 GtkTreeIter it;
867 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
868 gint plrno;
870 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
872 if (can_intel_with_player(player_by_number(plrno))) {
873 popup_intel_dialog(player_by_number(plrno));
878 /**************************************************************************
879 Spaceship query callback
880 **************************************************************************/
881 void players_sship_callback(GtkMenuItem *item, gpointer data)
883 GtkTreeModel *model;
884 GtkTreeIter it;
886 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
887 gint plrno;
889 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
890 popup_spaceship_dialog(player_by_number(plrno));
894 /**************************************************************************
895 AI toggle callback.
896 **************************************************************************/
897 static void players_ai_toggle_callback(GtkMenuItem *item, gpointer data)
899 GtkTreeModel *model;
900 GtkTreeIter it;
902 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
903 gint plrno;
905 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
907 send_chat_printf("/aitoggle \"%s\"", player_name(player_by_number(plrno)));
911 /**************************************************************************
912 AI skill level setting callback.
913 **************************************************************************/
914 static void players_ai_skill_callback(GtkMenuItem *item, gpointer data)
916 GtkTreeModel *model;
917 GtkTreeIter it;
919 if (gtk_tree_selection_get_selected(players_selection, &model, &it)) {
920 gint plrno;
922 gtk_tree_model_get(model, &it, PLR_DLG_COL_ID, &plrno, -1);
924 send_chat_printf("/%s %s",
925 ai_level_cmd(GPOINTER_TO_UINT(data)),
926 player_name(player_by_number(plrno)));
930 /**************************************************************************
931 Refresh players dialog views.
932 **************************************************************************/
933 static void update_views(void)
935 int i;
937 for (i = 0; i < num_player_dlg_columns; i++) {
938 GtkTreeViewColumn *col;
940 col = gtk_tree_view_get_column(GTK_TREE_VIEW(players_list), i);
941 gtk_tree_view_column_set_visible(col, player_dlg_columns[i].show);