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)
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 ***********************************************************************/
15 #include <fc_config.h>
23 #include <gdk/gdkkeysyms.h>
31 #include "diptreaty.h"
38 #include "client_main.h"
40 #include "connectdlg_common.h"
43 #include "gui_stuff.h"
45 #include "spaceshipdlg.h"
54 struct gui_dialog
*players_dialog_shell
;
55 static GtkWidget
*players_list
;
56 static GtkTreeSelection
*players_selection
;
57 static GtkWidget
*players_int_command
;
58 static GtkWidget
*players_meet_command
;
59 static GtkWidget
*players_war_command
;
60 static GtkWidget
*players_vision_command
;
61 static GtkWidget
*players_sship_command
;
63 static GtkListStore
*players_dialog_store
;
64 #define PLR_DLG_COL_STYLE (0 + num_player_dlg_columns)
65 #define PLR_DLG_COL_WEIGHT (1 + num_player_dlg_columns)
66 #define PLR_DLG_COL_ID (2 + num_player_dlg_columns)
68 static void create_players_dialog(void);
69 static void players_meet_callback(GtkMenuItem
*item
, gpointer data
);
70 static void players_war_callback(GtkMenuItem
*item
, gpointer data
);
71 static void players_vision_callback(GtkMenuItem
*item
, gpointer data
);
72 static void players_intel_callback(GtkMenuItem
*item
, gpointer data
);
73 static void players_sship_callback(GtkMenuItem
*item
, gpointer data
);
74 static void players_ai_toggle_callback(GtkMenuItem
*item
, gpointer data
);
75 static void players_ai_skill_callback(GtkMenuItem
*item
, gpointer data
);
78 static void update_views(void);
80 /**************************************************************************
81 popup the dialog 10% inside the main-window, and optionally raise it.
82 **************************************************************************/
83 void popup_players_dialog(bool raise
)
85 if (!players_dialog_shell
){
86 create_players_dialog();
88 gui_dialog_present(players_dialog_shell
);
90 gui_dialog_raise(players_dialog_shell
);
94 /****************************************************************
95 Closes the players dialog.
96 *****************************************************************/
97 void popdown_players_dialog(void)
99 if (players_dialog_shell
) {
100 gui_dialog_destroy(players_dialog_shell
);
104 /***************************************************************************
105 Create a small colored square representing the player color, for use
107 May return NULL if the player has no color yet.
108 ***************************************************************************/
109 GdkPixbuf
*create_player_icon(const struct player
*plr
)
115 if (!player_has_color(tileset
, plr
)) {
119 gtk_icon_size_lookup(GTK_ICON_SIZE_MENU
, &width
, &height
);
121 pixmap
= gdk_pixmap_new(root_window
, width
, height
, -1);
123 gdk_gc_set_foreground(civ_gc
,
125 COLOR_PLAYER_COLOR_BACKGROUND
)->color
);
126 gdk_draw_rectangle(pixmap
, civ_gc
, TRUE
, 0, 0, width
, height
);
128 gdk_gc_set_foreground(civ_gc
, &get_player_color(tileset
, plr
)->color
);
129 gdk_draw_rectangle(pixmap
, civ_gc
, TRUE
, 1, 1, width
- 2, height
- 2);
131 tmp
= gdk_pixbuf_get_from_drawable(NULL
, pixmap
, NULL
,
134 g_object_unref(pixmap
);
138 /**************************************************************************
140 **************************************************************************/
141 static void update_players_menu(void)
146 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
150 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
151 plr
= player_by_number(plrno
);
153 if (plr
->spaceship
.state
!= SSHIP_NONE
) {
154 gtk_widget_set_sensitive(players_sship_command
, TRUE
);
156 gtk_widget_set_sensitive(players_sship_command
, FALSE
);
159 if (NULL
!= client
.conn
.playing
) {
160 /* We keep button sensitive in case of DIPL_SENATE_BLOCKING, so that player
161 * can request server side to check requirements of those effects with omniscience */
162 gtk_widget_set_sensitive(players_war_command
,
163 can_client_issue_orders()
164 && pplayer_can_cancel_treaty(client_player(),
165 player_by_number(plrno
))
168 gtk_widget_set_sensitive(players_war_command
, FALSE
);
171 gtk_widget_set_sensitive(players_vision_command
,
172 can_client_issue_orders()
173 && gives_shared_vision(client
.conn
.playing
, plr
)
174 && !players_on_same_team(client
.conn
.playing
, plr
));
176 gtk_widget_set_sensitive(players_meet_command
, can_meet_with_player(plr
));
177 gtk_widget_set_sensitive(players_int_command
, can_intel_with_player(plr
));
181 gtk_widget_set_sensitive(players_meet_command
, FALSE
);
182 gtk_widget_set_sensitive(players_int_command
, FALSE
);
185 /**************************************************************************
186 Something selected from player menu
187 **************************************************************************/
188 static void selection_callback(GtkTreeSelection
*selection
, gpointer data
)
190 update_players_menu();
193 /**************************************************************************
194 Button pressed on player list
195 **************************************************************************/
196 static gboolean
button_press_callback(GtkTreeView
*view
, GdkEventButton
*ev
)
198 if (ev
->type
== GDK_2BUTTON_PRESS
) {
201 gtk_tree_view_get_cursor(view
, &path
, NULL
);
203 GtkTreeModel
*model
= gtk_tree_view_get_model(view
);
208 gtk_tree_model_get_iter(model
, &it
, path
);
209 gtk_tree_path_free(path
);
211 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &id
, -1);
212 plr
= player_by_number(id
);
214 if (ev
->button
== 1) {
215 if (can_intel_with_player(plr
)) {
216 popup_intel_dialog(plr
);
218 } else if (can_meet_with_player(plr
)) {
219 dsend_packet_diplomacy_init_meeting_req(&client
.conn
, id
);
226 /**************************************************************************
227 Sorting function for plr dlg.
228 **************************************************************************/
229 static gint
plrdlg_sort_func(GtkTreeModel
*model
,
230 GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer data
)
232 GValue value
= { 0, };
233 struct player
*player1
;
234 struct player
*player2
;
237 n
= GPOINTER_TO_INT(data
);
239 gtk_tree_model_get_value(model
, a
, PLR_DLG_COL_ID
, &value
);
240 player1
= player_by_number(g_value_get_int(&value
));
241 g_value_unset(&value
);
243 gtk_tree_model_get_value(model
, b
, PLR_DLG_COL_ID
, &value
);
244 player2
= player_by_number(g_value_get_int(&value
));
245 g_value_unset(&value
);
247 return player_dlg_columns
[n
].sort_func(player1
, player2
);
250 /****************************************************************************
251 Create a player dialog store.
252 ****************************************************************************/
253 static GtkListStore
*players_dialog_store_new(void)
256 GType model_types
[num_player_dlg_columns
+ 3];
259 for (i
= 0; i
< num_player_dlg_columns
; i
++) {
260 switch (player_dlg_columns
[i
].type
) {
262 model_types
[i
] = GDK_TYPE_PIXBUF
;
265 model_types
[i
] = GDK_TYPE_PIXBUF
;
268 model_types
[i
] = G_TYPE_BOOLEAN
;
272 model_types
[i
] = G_TYPE_STRING
;
276 /* special (invisible rows) - Text style, weight and player id */
277 model_types
[i
++] = G_TYPE_INT
; /* PLR_DLG_COL_STYLE. */
278 model_types
[i
++] = G_TYPE_INT
; /* PLR_DLG_COL_WEIGHT. */
279 model_types
[i
++] = G_TYPE_INT
; /* PLR_DLG_COL_ID. */
281 store
= gtk_list_store_newv(i
, model_types
);
284 for (i
= 0; i
< num_player_dlg_columns
; i
++) {
285 if (player_dlg_columns
[i
].sort_func
!= NULL
) {
286 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), i
,
287 plrdlg_sort_func
, GINT_TO_POINTER(i
),
295 /**************************************************************************
296 Toggled column visibility
297 **************************************************************************/
298 static void toggle_view(GtkCheckMenuItem
* item
, gpointer data
)
300 struct player_dlg_column
* pcol
= data
;
302 pcol
->show
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item
));
306 /*************************************************************************
307 Called whenever player toggles the 'Show/Dead Players' menu item
308 *************************************************************************/
309 static void toggle_dead_players(GtkCheckMenuItem
* item
, gpointer data
)
311 gui_options
.player_dlg_show_dead_players
=
312 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item
));
313 real_players_dialog_update();
316 /**************************************************************************
317 Create and return the "diplomacy" menu for the player report. This menu
318 contains diplomacy actions the current player can use on other nations.
319 **************************************************************************/
320 static GtkWidget
*create_diplomacy_menu(void)
322 GtkWidget
*menu
, *item
;
324 menu
= gtk_menu_new();
326 item
= gtk_menu_item_new_with_mnemonic(_("_Meet"));
327 g_signal_connect(item
, "activate",
328 G_CALLBACK(players_meet_callback
), NULL
);
329 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
330 players_meet_command
= item
;
332 item
= gtk_menu_item_new_with_mnemonic(_("Cancel _Treaty"));
333 g_signal_connect(item
, "activate",
334 G_CALLBACK(players_war_callback
), NULL
);
335 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
336 players_war_command
= item
;
338 item
= gtk_menu_item_new_with_mnemonic(_("_Withdraw Vision"));
339 g_signal_connect(item
, "activate",
340 G_CALLBACK(players_vision_callback
), NULL
);
341 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
342 players_vision_command
= item
;
347 /**************************************************************************
348 Create and return the "intelligence" menu. The items in this menu are
349 used by the player to see more detailed information about other nations.
350 **************************************************************************/
351 static GtkWidget
*create_intelligence_menu(void)
353 GtkWidget
*menu
, *item
;
355 menu
= gtk_menu_new();
357 item
= gtk_menu_item_new_with_mnemonic(_("_Report"));
358 g_signal_connect(item
, "activate",
359 G_CALLBACK(players_intel_callback
), NULL
);
360 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
361 players_int_command
= item
;
363 item
= gtk_menu_item_new_with_mnemonic(_("_Spaceship"));
364 g_signal_connect(item
, "activate",
365 G_CALLBACK(players_sship_callback
), NULL
);
366 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
367 players_sship_command
= item
;
372 /**************************************************************************
373 Create 'show' menu for player dialog
374 **************************************************************************/
375 static GtkWidget
* create_show_menu(void)
378 GtkWidget
*menu
= gtk_menu_new();
381 /* index starting at one (1) here to force playername to always be shown */
382 for (i
= 1; i
< num_player_dlg_columns
; i
++) {
383 struct player_dlg_column
*pcol
;
385 pcol
= &player_dlg_columns
[i
];
386 item
= gtk_check_menu_item_new_with_label(pcol
->title
);
387 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item
), pcol
->show
);
388 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
389 g_signal_connect(item
, "toggled", G_CALLBACK(toggle_view
), pcol
);
392 item
= gtk_separator_menu_item_new();
393 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
395 item
= gtk_check_menu_item_new_with_label(Q_("?show:Dead Players"));
396 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item
),
397 gui_options
.player_dlg_show_dead_players
);
398 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
399 g_signal_connect(item
, "toggled", G_CALLBACK(toggle_dead_players
), NULL
);
404 /**************************************************************************
405 Create all of player dialog
406 **************************************************************************/
407 void create_players_dialog(void)
411 GtkWidget
*menubar
, *menu
, *item
, *vbox
;
414 gui_dialog_new(&players_dialog_shell
, GTK_NOTEBOOK(top_notebook
), NULL
,
416 /* TRANS: Nations report title */
417 gui_dialog_set_title(players_dialog_shell
, _("Nations"));
419 gui_dialog_add_button(players_dialog_shell
,
420 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
);
422 gui_dialog_set_default_size(players_dialog_shell
, -1, 270);
424 players_dialog_store
= players_dialog_store_new();
426 players_list
= gtk_tree_view_new_with_model(GTK_TREE_MODEL
427 (players_dialog_store
));
428 g_object_unref(players_dialog_store
);
429 gtk_widget_set_name(players_list
, "small_font");
431 players_selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(players_list
));
432 g_signal_connect(players_selection
, "changed",
433 G_CALLBACK(selection_callback
), NULL
);
434 g_signal_connect(players_list
, "button_press_event",
435 G_CALLBACK(button_press_callback
), NULL
);
437 for (i
= 0; i
< num_player_dlg_columns
; i
++) {
438 struct player_dlg_column
*pcol
;
439 GtkCellRenderer
*renderer
;
440 GtkTreeViewColumn
*col
;
442 pcol
= &player_dlg_columns
[i
];
445 switch (pcol
->type
) {
447 renderer
= gtk_cell_renderer_pixbuf_new();
449 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
,
450 renderer
, "pixbuf", i
, NULL
);
453 renderer
= gtk_cell_renderer_toggle_new();
455 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
, renderer
,
459 renderer
= gtk_cell_renderer_pixbuf_new();
461 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
, renderer
,
465 renderer
= gtk_cell_renderer_text_new();
466 g_object_set(renderer
, "style-set", TRUE
, "weight-set", TRUE
, NULL
);
468 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
, renderer
,
470 "style", PLR_DLG_COL_STYLE
,
471 "weight", PLR_DLG_COL_WEIGHT
,
473 gtk_tree_view_column_set_sort_column_id(col
, i
);
476 renderer
= gtk_cell_renderer_text_new();
477 g_object_set(renderer
, "style-set", TRUE
, "weight-set", TRUE
, NULL
);
479 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
, renderer
,
481 "style", PLR_DLG_COL_STYLE
,
482 "weight", PLR_DLG_COL_WEIGHT
,
484 gtk_tree_view_column_set_sort_column_id(col
, i
);
485 g_object_set(renderer
, "xalign", 1.0, NULL
);
486 gtk_tree_view_column_set_alignment(col
, 1.0);
491 gtk_tree_view_append_column(GTK_TREE_VIEW(players_list
), col
);
495 gtk_tree_view_set_search_column(GTK_TREE_VIEW(players_list
),
496 player_dlg_default_sort_column());
498 sw
= gtk_scrolled_window_new(NULL
, NULL
);
499 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
),
500 GTK_SHADOW_ETCHED_IN
);
501 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
),
502 GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
);
503 gtk_container_add(GTK_CONTAINER(sw
), players_list
);
505 gtk_box_pack_start(GTK_BOX(players_dialog_shell
->vbox
), sw
,
508 vbox
= gtk_vbox_new(FALSE
, 0);
510 sep
= gtk_hseparator_new();
511 gtk_box_pack_start(GTK_BOX(vbox
), sep
, FALSE
, FALSE
, 0);
513 menubar
= gtk_aux_menu_bar_new();
514 gtk_box_pack_start(GTK_BOX(vbox
), menubar
, TRUE
, TRUE
, 0);
517 gui_dialog_add_widget(players_dialog_shell
, vbox
);
518 gtk_box_set_child_packing(GTK_BOX(players_dialog_shell
->action_area
),
519 vbox
, FALSE
, FALSE
, 0, GTK_PACK_START
);
521 item
= gtk_menu_item_new_with_mnemonic(_("Di_plomacy"));
522 menu
= create_diplomacy_menu();
523 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item
), menu
);
524 gtk_menu_shell_append(GTK_MENU_SHELL(menubar
), item
);
526 item
= gtk_menu_item_new_with_mnemonic(_("_Intelligence"));
527 menu
= create_intelligence_menu();
528 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item
), menu
);
529 gtk_menu_shell_append(GTK_MENU_SHELL(menubar
), item
);
531 item
= gtk_menu_item_new_with_mnemonic(_("_Display"));
532 menu
= create_show_menu();
533 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item
), menu
);
534 gtk_menu_shell_append(GTK_MENU_SHELL(menubar
), item
);
536 item
= gtk_menu_item_new_with_mnemonic(_("_AI"));
537 gtk_menu_shell_append(GTK_MENU_SHELL(menubar
), item
);
539 menu
= gtk_menu_new();
540 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item
), menu
);
542 item
= gtk_menu_item_new_with_mnemonic(_("_Toggle AI Mode"));
543 g_signal_connect(item
, "activate",
544 G_CALLBACK(players_ai_toggle_callback
), NULL
);
545 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
547 sep
= gtk_separator_menu_item_new();
548 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), sep
);
550 for (level
= 0; level
< AI_LEVEL_COUNT
; level
++) {
551 if (is_settable_ai_level(level
)) {
552 const char *level_name
= ai_level_translated_name(level
);
554 item
= gtk_menu_item_new_with_label(level_name
);
555 g_signal_connect(item
, "activate",
556 G_CALLBACK(players_ai_skill_callback
),
557 GUINT_TO_POINTER(level
));
558 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
561 gtk_widget_show_all(menu
);
563 gui_dialog_show_all(players_dialog_shell
);
565 real_players_dialog_update();
567 gui_dialog_set_default_response(players_dialog_shell
,
570 gtk_tree_view_focus(GTK_TREE_VIEW(players_list
));
574 /**************************************************************************
576 **************************************************************************/
577 #define MIN_DIMENSION 5
579 /**************************************************************************
580 Builds the flag pixmap. May return NULL if there is not enough memory.
581 You must call g_object_unref on the returned pixbuf when it is no
583 **************************************************************************/
584 GdkPixbuf
*get_flag(const struct nation_type
*nation
)
586 int x0
, y0
, x1
, y1
, w
, h
;
590 flag
= get_nation_flag_sprite(tileset
, nation
);
592 /* calculate the bounding box ... */
593 sprite_get_bounding_box(flag
, &x0
, &y0
, &x1
, &y1
);
595 fc_assert_ret_val(x0
!= -1, NULL
);
596 fc_assert_ret_val(y0
!= -1, NULL
);
597 fc_assert_ret_val(x1
!= -1, NULL
);
598 fc_assert_ret_val(y1
!= -1, NULL
);
603 /* if the flag is smaller then 5 x 5, something is wrong */
604 fc_assert_ret_val(w
>= MIN_DIMENSION
&& h
>= MIN_DIMENSION
, NULL
);
607 im
= gdk_pixbuf_new(GDK_COLORSPACE_RGB
, TRUE
, 8, w
, h
);
609 gdk_pixbuf_copy_area(sprite_get_pixbuf(flag
), x0
, y0
, w
, h
,
613 /* and finaly store the scaled flag pixbuf in the static flags array */
618 /**************************************************************************
619 Fills the player list with the information for 'pplayer' at the row
621 **************************************************************************/
622 static void fill_row(GtkListStore
*store
, GtkTreeIter
*it
,
623 const struct player
*pplayer
)
625 struct player_dlg_column
* pcol
;
627 int style
= PANGO_STYLE_NORMAL
, weight
= PANGO_WEIGHT_NORMAL
;
630 for (k
= 0; k
< num_player_dlg_columns
; k
++) {
631 pcol
= &player_dlg_columns
[k
];
632 switch (pcol
->type
) {
635 gtk_list_store_set(store
, it
, k
, pcol
->func(pplayer
), -1);
638 pixbuf
= get_flag(nation_of_player(pplayer
));
639 if (pixbuf
!= NULL
) {
640 gtk_list_store_set(store
, it
, k
, pixbuf
, -1);
641 g_object_unref(pixbuf
);
645 pixbuf
= create_player_icon(pplayer
);
646 if (pixbuf
!= NULL
) {
647 gtk_list_store_set(store
, it
, k
, pixbuf
, -1);
648 g_object_unref(pixbuf
);
652 gtk_list_store_set(store
, it
, k
, pcol
->bool_func(pplayer
), -1);
657 /* now add some eye candy ... */
658 if (client_has_player()) {
659 switch (player_diplstate_get(client_player(), pplayer
)->type
) {
661 weight
= PANGO_WEIGHT_NORMAL
;
662 style
= PANGO_STYLE_ITALIC
;
666 weight
= PANGO_WEIGHT_BOLD
;
667 style
= PANGO_STYLE_NORMAL
;
673 weight
= PANGO_WEIGHT_NORMAL
;
674 style
= PANGO_STYLE_NORMAL
;
681 gtk_list_store_set(store
, it
,
682 PLR_DLG_COL_STYLE
, style
,
683 PLR_DLG_COL_WEIGHT
, weight
,
684 PLR_DLG_COL_ID
, player_number(pplayer
),
688 /**************************************************************************
689 Return TRUE if the player should be shown in the player list.
690 **************************************************************************/
691 static bool player_should_be_shown(const struct player
*pplayer
)
693 return NULL
!= pplayer
&& (gui_options
.player_dlg_show_dead_players
694 || pplayer
->is_alive
)
695 && (!is_barbarian(pplayer
));
698 /**************************************************************************
699 Clear and refill the entire player list.
700 **************************************************************************/
701 void real_players_dialog_update(void)
707 if (NULL
== players_dialog_shell
) {
711 /* Save the selection. */
712 if (gtk_tree_selection_get_selected(players_selection
, &model
, &iter
)) {
713 gtk_tree_model_get(model
, &iter
, PLR_DLG_COL_ID
, &selected
, -1);
718 gtk_list_store_clear(players_dialog_store
);
719 players_iterate(pplayer
) {
720 if (!player_should_be_shown(pplayer
)) {
723 gtk_list_store_append(players_dialog_store
, &iter
);
724 fill_row(players_dialog_store
, &iter
, pplayer
);
725 if (player_number(pplayer
) == selected
) {
726 /* Restore the selection. */
727 gtk_tree_selection_select_iter(players_selection
, &iter
);
729 } players_iterate_end
;
734 /**************************************************************************
735 Callback for diplomatic meetings button. This button is enabled iff
736 we can meet with the other player.
737 **************************************************************************/
738 void players_meet_callback(GtkMenuItem
*item
, gpointer data
)
743 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
746 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
748 dsend_packet_diplomacy_init_meeting_req(&client
.conn
, plrno
);
752 /**************************************************************************
753 Confirm pact/treaty cancellation.
754 Frees strings passed in.
755 **************************************************************************/
756 static void confirm_cancel_pact(enum clause_type clause
, int plrno
,
757 char *title
, char *question
)
761 shell
= gtk_message_dialog_new(NULL
, 0,
762 GTK_MESSAGE_QUESTION
, GTK_BUTTONS_YES_NO
,
764 gtk_window_set_title(GTK_WINDOW(shell
), title
);
765 setup_dialog(shell
, toplevel
);
766 gtk_dialog_set_default_response(GTK_DIALOG(shell
), GTK_RESPONSE_NO
);
768 if (gtk_dialog_run(GTK_DIALOG(shell
)) == GTK_RESPONSE_YES
) {
769 dsend_packet_diplomacy_cancel_pact(&client
.conn
, plrno
, clause
);
771 gtk_widget_destroy(shell
);
776 /**************************************************************************
777 Pact cancellation requested
778 **************************************************************************/
779 void players_war_callback(GtkMenuItem
*item
, gpointer data
)
784 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
785 struct astring title
= ASTRING_INIT
, question
= ASTRING_INIT
;
787 struct player
*aplayer
;
788 enum diplstate_type oldstate
, newstate
;
790 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
791 aplayer
= player_by_number(plrno
);
792 fc_assert_ret(aplayer
!= NULL
);
794 oldstate
= player_diplstate_get(client_player(), aplayer
)->type
;
795 newstate
= cancel_pact_result(oldstate
);
797 /* TRANS: %s is a diplomatic state: "Cancel Cease-fire" */
798 astr_set(&title
, _("Cancel %s"), diplstate_type_translated_name(oldstate
));
800 if (newstate
== DS_WAR
) {
801 astr_set(&question
, _("Really declare war on the %s?"),
802 nation_plural_for_player(aplayer
));
804 /* TRANS: "Cancel Belgian Alliance? ... will be Armistice." */
805 astr_set(&question
, _("Cancel %s %s? New diplomatic state will be %s."),
806 nation_adjective_for_player(aplayer
),
807 diplstate_type_translated_name(oldstate
),
808 diplstate_type_translated_name(newstate
));
811 /* can be any pact clause */
812 confirm_cancel_pact(CLAUSE_CEASEFIRE
, plrno
,
813 astr_to_str(&title
), astr_to_str(&question
));
817 /**************************************************************************
818 Withdrawing shared vision
819 **************************************************************************/
820 void players_vision_callback(GtkMenuItem
*item
, gpointer data
)
825 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
826 struct astring question
= ASTRING_INIT
;
828 struct player
*aplayer
;
830 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
831 aplayer
= player_by_number(plrno
);
832 fc_assert_ret(aplayer
!= NULL
);
834 /* TRANS: "...from the Belgians?" */
835 astr_set(&question
, _("Withdraw shared vision from the %s?"),
836 nation_plural_for_player(aplayer
));
838 confirm_cancel_pact(CLAUSE_VISION
, plrno
,
839 fc_strdup(_("Withdraw Shared Vision")),
840 astr_to_str(&question
));
844 /**************************************************************************
845 Intelligence report query
846 **************************************************************************/
847 void players_intel_callback(GtkMenuItem
*item
, gpointer data
)
852 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
855 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
857 if (can_intel_with_player(player_by_number(plrno
))) {
858 popup_intel_dialog(player_by_number(plrno
));
863 /**************************************************************************
864 Spaceship query callback
865 **************************************************************************/
866 void players_sship_callback(GtkMenuItem
*item
, gpointer data
)
871 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
874 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
875 popup_spaceship_dialog(player_by_number(plrno
));
879 /**************************************************************************
881 **************************************************************************/
882 static void players_ai_toggle_callback(GtkMenuItem
*item
, gpointer data
)
887 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
890 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
892 send_chat_printf("/aitoggle \"%s\"", player_name(player_by_number(plrno
)));
896 /**************************************************************************
897 AI skill level setting callback.
898 **************************************************************************/
899 static void players_ai_skill_callback(GtkMenuItem
*item
, gpointer data
)
904 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
907 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
909 send_chat_printf("/%s %s",
910 ai_level_cmd(GPOINTER_TO_UINT(data
)),
911 player_name(player_by_number(plrno
)));
915 /**************************************************************************
916 Refresh players dialog views.
917 **************************************************************************/
918 static void update_views(void)
922 for (i
= 0; i
< num_player_dlg_columns
; i
++) {
923 GtkTreeViewColumn
*col
;
925 col
= gtk_tree_view_get_column(GTK_TREE_VIEW(players_list
), i
);
926 gtk_tree_view_column_set_visible(col
, player_dlg_columns
[i
].show
);