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"
37 #include "client_main.h"
39 #include "connectdlg_common.h"
46 /* client/gui-gtk-3.0 */
50 #include "gui_stuff.h"
52 #include "spaceshipdlg.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
);
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
111 May return NULL if the player has no color yet.
112 ***************************************************************************/
113 GdkPixbuf
*create_player_icon(const struct player
*plr
)
117 cairo_surface_t
*surface
;
121 if (!player_has_color(tileset
, plr
)) {
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
);
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);
143 tmp
= surface_get_pixbuf(surface
, width
, height
);
144 cairo_surface_destroy(surface
);
149 /**************************************************************************
151 **************************************************************************/
152 static void update_players_menu(void)
157 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
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
);
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
))
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
));
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
) {
212 gtk_tree_view_get_cursor(view
, &path
, NULL
);
214 GtkTreeModel
*model
= gtk_tree_view_get_model(view
);
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
);
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
;
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)
267 GType model_types
[num_player_dlg_columns
+ 3];
270 for (i
= 0; i
< num_player_dlg_columns
; i
++) {
271 switch (player_dlg_columns
[i
].type
) {
273 model_types
[i
] = GDK_TYPE_PIXBUF
;
276 model_types
[i
] = GDK_TYPE_PIXBUF
;
279 model_types
[i
] = G_TYPE_BOOLEAN
;
283 model_types
[i
] = G_TYPE_STRING
;
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
);
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
),
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
));
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
;
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
;
383 /**************************************************************************
384 Create 'show' menu for player dialog
385 **************************************************************************/
386 static GtkWidget
* create_show_menu(void)
389 GtkWidget
*menu
= gtk_menu_new();
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
);
415 /**************************************************************************
416 Create all of player dialog
417 **************************************************************************/
418 void create_players_dialog(void)
422 GtkWidget
*menubar
, *menu
, *item
, *vbox
;
425 gui_dialog_new(&players_dialog_shell
, GTK_NOTEBOOK(top_notebook
), NULL
,
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
];
458 switch (pcol
->type
) {
460 renderer
= gtk_cell_renderer_pixbuf_new();
462 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
,
463 renderer
, "pixbuf", i
, NULL
);
466 renderer
= gtk_cell_renderer_toggle_new();
468 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
, renderer
,
472 renderer
= gtk_cell_renderer_pixbuf_new();
474 col
= gtk_tree_view_column_new_with_attributes(pcol
->title
, renderer
,
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
,
483 "style", PLR_DLG_COL_STYLE
,
484 "weight", PLR_DLG_COL_WEIGHT
,
486 gtk_tree_view_column_set_sort_column_id(col
, i
);
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
,
494 "style", PLR_DLG_COL_STYLE
,
495 "weight", PLR_DLG_COL_WEIGHT
,
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);
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
,
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
595 **************************************************************************/
596 GdkPixbuf
*get_flag(const struct nation_type
*nation
)
598 int x0
, y0
, x1
, y1
, w
, h
;
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
);
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
);
619 im
= gdk_pixbuf_new(GDK_COLORSPACE_RGB
, TRUE
, 8, w
, h
);
621 GdkPixbuf
*pixbuf
= sprite_get_pixbuf(flag
);
623 gdk_pixbuf_copy_area(pixbuf
, x0
, y0
, w
, h
,
625 g_object_unref(G_OBJECT(pixbuf
));
628 /* and finally store the scaled flag pixbuf in the static flags array */
633 /**************************************************************************
634 Fills the player list with the information for 'pplayer' at the row
636 **************************************************************************/
637 static void fill_row(GtkListStore
*store
, GtkTreeIter
*it
,
638 const struct player
*pplayer
)
640 struct player_dlg_column
* pcol
;
642 int style
= PANGO_STYLE_NORMAL
, weight
= PANGO_WEIGHT_NORMAL
;
645 for (k
= 0; k
< num_player_dlg_columns
; k
++) {
646 pcol
= &player_dlg_columns
[k
];
647 switch (pcol
->type
) {
650 gtk_list_store_set(store
, it
, k
, pcol
->func(pplayer
), -1);
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
);
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
);
667 gtk_list_store_set(store
, it
, k
, pcol
->bool_func(pplayer
), -1);
672 /* now add some eye candy ... */
673 if (client_has_player()) {
674 switch (player_diplstate_get(client_player(), pplayer
)->type
) {
676 weight
= PANGO_WEIGHT_NORMAL
;
677 style
= PANGO_STYLE_ITALIC
;
681 weight
= PANGO_WEIGHT_BOLD
;
682 style
= PANGO_STYLE_NORMAL
;
688 weight
= PANGO_WEIGHT_NORMAL
;
689 style
= PANGO_STYLE_NORMAL
;
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
),
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)
722 if (NULL
== players_dialog_shell
) {
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);
733 gtk_list_store_clear(players_dialog_store
);
734 players_iterate(pplayer
) {
735 if (!player_should_be_shown(pplayer
)) {
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
;
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
)
758 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
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
)
776 shell
= gtk_message_dialog_new(NULL
, 0,
777 GTK_MESSAGE_QUESTION
, GTK_BUTTONS_YES_NO
,
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
);
791 /**************************************************************************
792 Pact cancellation requested
793 **************************************************************************/
794 void players_war_callback(GtkMenuItem
*item
, gpointer data
)
799 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
800 struct astring title
= ASTRING_INIT
, question
= ASTRING_INIT
;
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
));
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
)
840 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
841 struct astring question
= ASTRING_INIT
;
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
)
867 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
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
)
886 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
889 gtk_tree_model_get(model
, &it
, PLR_DLG_COL_ID
, &plrno
, -1);
890 popup_spaceship_dialog(player_by_number(plrno
));
894 /**************************************************************************
896 **************************************************************************/
897 static void players_ai_toggle_callback(GtkMenuItem
*item
, gpointer data
)
902 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
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
)
919 if (gtk_tree_selection_get_selected(players_selection
, &model
, &it
)) {
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)
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
);