Freeciv-3.2
Loading...
Searching...
No Matches
dialogs.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 <stdarg.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include <gtk/gtk.h>
24#include <gdk/gdkkeysyms.h>
25
26/* utility */
27#include "astring.h"
28#include "bitvector.h"
29#include "fcintl.h"
30#include "log.h"
31#include "mem.h"
32#include "rand.h"
33#include "support.h"
34
35/* common */
36#include "game.h"
37#include "government.h"
38#include "map.h"
39#include "packets.h"
40#include "player.h"
41#include "sex.h"
42
43/* client */
44#include "client_main.h"
45#include "climisc.h"
46#include "connectdlg_common.h"
47#include "control.h"
48#include "helpdata.h" /* for helptext_nation() */
49#include "goto.h"
50#include "options.h"
51#include "packhand.h"
52#include "text.h"
53#include "tilespec.h"
54
55/* client/gui-gtk-4.0 */
56#include "chatline.h"
57#include "choice_dialog.h"
58#include "citydlg.h"
59#include "editprop.h"
60#include "graphics.h"
61#include "gui_main.h"
62#include "gui_stuff.h"
63#include "mapview.h"
64#include "plrdlg.h"
65#include "wldlg.h"
66#include "unitselect.h"
67#include "unitselextradlg.h"
68
69#include "dialogs.h"
70
71/******************************************************************/
75/* One entry per nation group, plus one at the end for 'all nations' */
83
84static void create_races_dialog(struct player *pplayer);
85static void races_response(GtkWidget *w, gint response, gpointer data);
86static void races_nation_callback(GtkTreeSelection *select, gpointer data);
87static void races_leader_callback(void);
88static void races_sex_callback(GtkWidget *w, gpointer data);
89static void races_style_callback(GtkTreeSelection *select, gpointer data);
91 GtkTreeModel *model, GtkTreePath *path,
92 gboolean selected, gpointer data);
93
94static int selected_nation;
95static int selected_sex;
96static int selected_style;
97
99
100/**********************************************************************/
103void popup_notify_dialog(const char *caption, const char *headline,
104 const char *lines)
105{
106 static struct gui_dialog *shell;
108 int grid_row = 0;
109
112
113 gui_dialog_add_button(shell, "window-close", _("_Close"),
115
121
124 gtk_widget_set_name(headline_label, "notify_label");
125
129
138
139 gtk_widget_set_name(label, "notify_label");
143
144 gtk_grid_attach(GTK_GRID(vgrid), sw, 0, grid_row++, 1, 1);
145
147
150
151 shell = NULL;
152}
153
154/**********************************************************************/
158static void notify_goto_response(GtkWidget *w, gint response)
159{
160 struct city *pcity = NULL;
161 struct tile *ptile = g_object_get_data(G_OBJECT(w), "tile");
162
163 switch (response) {
164 case 1:
166 break;
167 case 2:
168 pcity = tile_city(ptile);
169
172 }
173
174 if (pcity) {
175 popup_city_dialog(pcity);
176 }
177 break;
178 }
179
181}
182
183/**********************************************************************/
187{
189}
190
191/**********************************************************************/
196void popup_notify_goto_dialog(const char *headline, const char *lines,
197 const struct text_tag_list *tags,
198 struct tile *ptile)
199{
201
202 if (ptile == NULL) {
204 _("_Close"), GTK_RESPONSE_CLOSE,
205 NULL);
206 } else {
207 struct city *pcity = tile_city(ptile);
208
209 if (pcity != NULL && city_owner(pcity) == client.conn.playing) {
211 _("Goto _Location"), 1,
212 _("I_nspect City"), 2,
213 _("_Close"), GTK_RESPONSE_CLOSE,
214 NULL);
215 } else {
217 _("Goto _Location"), 1,
218 _("_Close"), GTK_RESPONSE_CLOSE,
219 NULL);
220 }
221 }
224
225 label = gtk_label_new(lines);
227 label);
229
230 g_object_set_data(G_OBJECT(shell), "tile", ptile);
231
234}
235
236/**********************************************************************/
261
262/**********************************************************************/
265static void revolution_response(GtkWidget *w, gint response, gpointer data)
266{
267 struct government *government = data;
268
269 if (response == GTK_RESPONSE_YES) {
270 if (!government) {
272 } else {
274 }
275 }
276 if (w) {
278 }
279}
280
281/**********************************************************************/
285{
286 static GtkWidget *shell = NULL;
287
289 if (!shell) {
291 0,
294 _("You say you wanna revolution?"));
295 gtk_window_set_title(GTK_WINDOW(shell), _("Revolution!"));
297
298 g_signal_connect(shell, "destroy",
300 }
301 g_signal_connect(shell, "response",
303
305 } else {
307 }
308}
309
310/**********************************************************************/
313static void pillage_callback(GtkWidget *dlg, gint arg)
314{
316
317 if (arg == GTK_RESPONSE_YES) {
319 "actor"));
321
323 "target"));
325
326 if (actor && tgt_extra) {
328 tgt_extra);
329 }
330 }
331
333}
334
335/**********************************************************************/
339{
341 /* Possibly legal target extras. */
342 bv_extras alternative;
343 /* Selected by default. */
345 /* Current target to check. */
346 struct extra_type *tgt;
347
349
350 BV_CLR_ALL(alternative);
352
353 while ((tgt = get_preferred_pillage(extras))) {
354 int what;
355
356 what = extra_index(tgt);
358 BV_SET(alternative, what);
359 }
360
362 /* TRANS: Pillage dialog title. */
363 _("What To Pillage"),
364 /* TRANS: Pillage dialog actor text. */
365 _("Looking for target extra:"),
366 /* TRANS: Pillage dialog target text. */
367 _("Select what to pillage:"),
368 /* TRANS: Pillage dialog do button text. */
369 _("Pillage"), G_CALLBACK(pillage_callback));
370 }
371}
372
373/**********************************************************************/
378{
380}
381
382/**********************************************************************/
390
391/**************************************************************************
392 NATION SELECTION DIALOG
393**************************************************************************/
394/**********************************************************************/
401{
402 if (nation == -1 || list == NULL) {
403 return NULL;
404 } else {
407 GtkTreePath *path = NULL;
408
410 do {
411 int nation_of_row;
412
413 gtk_tree_model_get(model, &iter, 0, &nation_of_row, -1);
414 if (nation == nation_of_row) {
415 path = gtk_tree_model_get_path(model, &iter);
416 break;
417 }
418 } while (gtk_tree_model_iter_next(model, &iter));
419 return path;
420 }
421}
422
423/**********************************************************************/
429static void select_nation_on_tab(GtkWidget *tab_list, int nation)
430{
431 /* tab_list is a GtkTreeView (not its enclosing GtkScrolledWindow). */
434 GtkTreePath *path = path_to_nation_on_list(nation, list);
435
436 /* Suppress normal effects of selection change to avoid loops. */
438 if (path) {
439 /* Found nation on this list. */
440 /* Avoid disturbing tabs that already have the correct selection. */
441 if (!gtk_tree_selection_path_is_selected(select, path)) {
442 /* Set cursor -- this will cause the nation to be selected */
444 /* Make sure selected nation is visible in list */
446 }
447 } else {
448 /* Either no nation was selected, or the nation is not mentioned in
449 * this tab. Either way we want to end up with no selection. */
451
452 /* If there is no cursor, Gtk tends to focus and select the first row
453 * at the first opportunity, disturbing any existing state. We want to
454 * allow the no-rows-selected state, so detect this case and defuse
455 * it by setting a cursor. */
457 /* Set the cursor in the case above, or if there was a previous
458 * selection */
462 }
465 }
466 gtk_tree_path_free(path);
467 /* Re-enable selection change side-effects */
469}
470
471/**********************************************************************/
474static void sync_tabs_to_nation(int nation)
475{
476 /* Ensure that all tabs are in sync with the new selection */
477 int i;
478
479 for (i = 0; i <= nation_group_count(); i++) {
480 if (races_nation_list[i]) {
482 }
483 }
484}
485
486/**********************************************************************/
509
510/**********************************************************************/
516static void select_nation(int nation,
517 const char *leadername, bool is_male,
518 int style_id)
519{
521
522 selected_nation = nation;
523
524 /* Refresh the available leaders. */
526
527 if (selected_nation != -1) {
528
529 /* Select leader name and sex. */
530 if (leadername) {
532 /* Assume is_male is valid too. */
534 TRUE);
535 } else {
538
540 /* This also updates the leader sex, eventually. */
541 }
542
543 /* Select the appropriate city style entry. */
544 {
545 int i;
546 int j = 0;
547 GtkTreePath *path;
548
551
552 if (i >= 0 && i < style_id) {
553 j++;
554 } else {
555 break;
556 }
558
559 path = gtk_tree_path_new();
562 NULL, FALSE);
563 gtk_tree_path_free(path);
564 }
565
566 /* Update nation description. */
567 {
568 char buf[4096];
569
570 helptext_nation(buf, sizeof(buf),
573 }
574
576 /* Once we've made a nation selection, allow user to ok */
579 } else {
580 /* No nation selected. Blank properties and make controls insensitive. */
581 /* Leader name */
582 gtk_entry_buffer_set_text(buffer, "", -1);
583 /* Leader sex (*shrug*) */
585 /* City style */
586 {
587 GtkTreeSelection* select
589
591 }
592 /* Nation description */
594
596 /* Don't allow OK without a selection
597 * (user can still do "Random Nation") */
600 }
601
602 /* Update notebook to reflect the current selection */
604}
605
606/**********************************************************************/
613 int index)
614{
615 GtkWidget *sw = NULL;
616 GtkListStore *store = NULL;
618
619 /* Populate nation list store. */
620 nations_iterate(pnation) {
621 bool used;
622 GdkPixbuf *img;
623 GtkTreeIter it;
624 GValue value = { 0, };
625
626 if (!is_nation_playable(pnation) || !is_nation_pickable(pnation)) {
627 continue;
628 }
629
630 if (NULL != group && !nation_is_in_group(pnation, group)) {
631 continue;
632 }
633
634 /* Only create tab on demand -- we don't want it if there aren't any
635 * currently pickable nations in this group. */
636 if (sw == NULL) {
637 GtkTreeSelection *select;
638 GtkCellRenderer *render;
640
645
649 gtk_widget_add_css_class(GTK_WIDGET(list), "large-pixbufs");
652 g_object_unref(store);
653
656 NULL);
658 NULL, NULL);
659
665
668 "pixbuf", 2, NULL);
672 "text", 3, "strikethrough", 1, NULL);
674 }
675
676 gtk_list_store_append(store, &it);
677
678 used = (pnation->player != NULL && pnation->player != races_player);
679 gtk_list_store_set(store, &it, 0, nation_number(pnation), 1, used, -1);
680 img = get_flag(pnation);
681 if (img != NULL) {
682 gtk_list_store_set(store, &it, 2, img, -1);
684 }
685
688 gtk_list_store_set_value(store, &it, 3, &value);
689 g_value_unset(&value);
691
692 races_nation_list[index] = list;
693 return sw;
694}
695
696/**********************************************************************/
700{
703 int i;
704
705 for (i = 0; i < nation_group_count(); i++) {
706 struct nation_group *group = (nation_group_by_number(i));
707
708 if (is_nation_group_hidden(group)) {
710 continue;
711 }
713 if (nation_list) {
717 }
718 }
719
721 /* Even this list can be empty if there are no pickable nations (due to
722 * a combination of start position and nationset restrictions). */
723 if (nation_list) {
727 }
728}
729
730/**********************************************************************/
734void races_update_pickable(bool nationset_change)
735{
736 int tab, groupidx;
737
738 if (!races_shell) {
739 return;
740 }
741
742 /* Save selected tab */
744 if (tab != -1) {
745 int i = 0;
746
747 groupidx = 0;
748 /* Turn tab index into a nation group index (they're not always equal,
749 * as some groups may not currently have tabs). */
750 do {
751 while (groupidx <= nation_group_count()
753 groupidx++;
754 }
756 /* Nation group 'groupidx' is what's displayed on the i'th tab */
757 if (i == tab) {
758 break;
759 }
760 i++;
761 groupidx++;
762 } while (TRUE);
763 } else {
764 /* No tabs currently */
765 groupidx = -1;
766 }
767
768 /* selected_nation already contains currently selected nation; however,
769 * it may no longer be a valid choice */
770 if (selected_nation != -1
772 select_nation(-1, NULL, FALSE, 0);
773 }
774
775 /* Delete all list stores, treeviews, tabs */
778 }
779
780 /* (Re)create all of them */
782
783 /* Can't set current tab before child widget is visible */
785
786 /* Restore selected tab */
787 if (groupidx != -1 && races_nation_list[groupidx] != NULL) {
788 int i;
789
790 tab = 0;
791 for (i = 0; i < groupidx; i++) {
792 if (races_nation_list[i] != NULL) {
793 tab++;
794 }
795 }
797 }
798
799 /* Restore selected nation */
801}
802
803/**********************************************************************/
806void nationset_sync_to_server(const char *nationset)
807{
808 if (nationsets_chooser) {
809 struct nation_set *set = nation_set_by_setting_value(nationset);
810
812 nation_set_index(set));
813 }
814}
815
816/**********************************************************************/
820{
822
824 struct option *poption = optset_option_by_name(server_optset, "nationset");
825 gchar *rule_name;
826
828 0, &rule_name, -1);
829 /* Suppress propagation of an option value equivalent to the current
830 * server state, after canonicalisation, to avoid loops from
831 * nationset_sync_to_server().
832 * (HACK: relies on local Gtk "changed" signal getting here before
833 * server response.) */
835 != nation_set_by_rule_name(rule_name)) {
836 option_str_set(poption, rule_name);
837 }
838 FC_FREE(rule_name);
839 }
840}
841
842/**********************************************************************/
845static void create_races_dialog(struct player *pplayer)
846{
848 GtkWidget *cmd;
849 GtkWidget *group;
851 GtkWidget *frame, *label, *combo;
852 GtkWidget *text;
853 GtkWidget *notebook;
854 GtkWidget *sw;
856 GtkListStore *store;
857 GtkCellRenderer *render;
859 int i;
860 char *title;
861
862 /* Init. */
863 selected_nation = -1;
864
865 if (C_S_RUNNING == client_state()) {
866 title = _("Edit Nation");
867 } else if (NULL != pplayer && pplayer == client.conn.playing) {
868 title = _("What Nation Will You Be?");
869 } else {
870 title = _("Pick Nation");
871 }
872
874 NULL,
875 0,
876 _("_Cancel"),
878 _("_Random Nation"),
879 GTK_RESPONSE_NO, /* Arbitrary */
880 _("_OK"),
882 NULL);
884 races_player = pplayer;
886
888
889 frame = gtk_frame_new(_("Select a nation"));
891
897
899
900 /* Left side: nation list */
901 {
903
905
907
908 /* Nationset selector dropdown */
909 /* Only present this if there is more than one choice.
910 * (If ruleset is changed, possibly changing the number of available sets
911 * and invalidating this decision, then dialog will be popped down.) */
912 if (nation_set_count() > 1) {
917 GtkCellRenderer *renderer;
918
920 /* Index in list store must match nation_set_index(). */
921 gchar *escaped;
922 struct astring s = ASTRING_INIT;
923 int num_nations = 0;
924
925 nations_iterate(pnation) {
926 if (is_nation_playable(pnation) && nation_is_in_set(pnation, pset)) {
927 num_nations++;
928 }
931 /* TRANS: nation set name followed by number of playable nations;
932 * <b> and </b> are Pango markup and should be left alone */
933 astr_set(&s, PL_("<b>%s</b> (%d nation)",
934 "<b>%s</b> (%d nations)", num_nations),
935 escaped, num_nations);
936 g_free(escaped);
938 /* While in principle it would be better to get Gtk to wrap the
939 * drop-down (e.g. via "wrap-width" property), there's no way
940 * to specify the indentation we want. So we do it ourselves. */
941 char *desc = fc_strdup(_(nation_set_description(pset)));
942 char *p = desc;
943
944 fc_break_lines(desc, 70);
945 astr_add(&s, "\n");
946 while (*p) {
947 int len = strcspn(p, "\n");
948
949 if (p[len] == '\n') {
950 len++;
951 }
952 escaped = g_markup_escape_text(p, len);
953 astr_add(&s, "\t%s", escaped);
954 g_free(escaped);
955 p += len;
956 }
957 FC_FREE(desc);
958 }
961 1, astr_str(&s),
963 -1);
964 astr_free(&s);
966
967 /* We want a combo box where the button displays just the set name,
968 * but the dropdown displays the expanded description. */
972 {
973 /* Do our best to turn the text-entry widget into something more
974 * like a cell-view: disable editing, and focusing (which removes
975 * the caret). */
977
980 }
981 /* The entry displays the set name. */
983 2);
984 /* The dropdown displays the marked-up description. */
985 renderer = gtk_cell_renderer_text_new();
988 renderer, TRUE);
990 renderer, "markup", 1, NULL);
995 {
996 /* Populate initially from client's view of server setting */
998 "nationset");
999 if (poption) {
1001 }
1002 }
1003
1005 "use-underline", TRUE,
1006 "label", _("_Nation Set:"),
1007 "xalign", 0.0,
1008 "yalign", 0.5,
1009 NULL);
1011
1014 0, 0, 1, 1);
1016 1, 0, 1, 1);
1017 }
1018
1022 0, 2, 2, 1);
1023
1024 /* Suppress notebook tabs if there will be only one ("All") */
1025 {
1026 bool show_groups = FALSE;
1027
1030 show_groups = TRUE;
1031 break;
1032 }
1034 if (!show_groups) {
1036 } else {
1038 "use-underline", TRUE,
1039 "label", _("Nation _Groups:"),
1040 "xalign", 0.0,
1041 "yalign", 0.5,
1042 NULL);
1045 0, 1, 2, 1);
1047 }
1048 }
1049
1050 /* Populate treeview */
1052
1054 }
1055
1056 /* Right side. */
1057 notebook = gtk_notebook_new();
1059 gtk_box_append(GTK_BOX(hbox), notebook);
1060
1061 /* Properties pane. */
1062 label = gtk_label_new_with_mnemonic(_("_Properties"));
1063
1065 g_signal_connect(table, "destroy",
1072 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
1073
1074 /* Leader. */
1075 {
1077
1080 g_object_unref(G_OBJECT(model));
1081 }
1082 races_leader = combo;
1084 "use-underline", TRUE,
1085 "mnemonic-widget", GTK_COMBO_BOX(combo),
1086 "label", _("_Leader:"),
1087 "xalign", 0.0,
1088 "yalign", 0.5,
1089 NULL);
1091 gtk_widget_set_margin_end(label, 12);
1092 gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 2);
1093 gtk_grid_attach(GTK_GRID(table), combo, 1, 0, 2, 1);
1094
1096 "_"));
1098 races_sex[0] = cmd;
1099 gtk_grid_attach(GTK_GRID(table), cmd, 1, 1, 1, 1);
1100 group = cmd;
1101
1103 "_"));
1105 GTK_CHECK_BUTTON(group));
1107 races_sex[1] = cmd;
1108 gtk_grid_attach(GTK_GRID(table), cmd, 2, 1, 1, 1);
1109
1110 /* City style. */
1111 store = gtk_list_store_new(3, G_TYPE_INT,
1113
1117 gtk_widget_add_css_class(GTK_WIDGET(list), "large-pixbufs");
1119 g_object_unref(store);
1123
1130 gtk_grid_attach(GTK_GRID(table), sw, 1, 2, 2, 2);
1131
1133 "use-underline", TRUE,
1134 "mnemonic-widget", list,
1135 "label", _("City _Styles:"),
1136 "xalign", 0.0,
1137 "yalign", 0.5,
1138 NULL);
1139 gtk_widget_set_margin_top(label, 6);
1140 gtk_widget_set_margin_end(label, 12);
1141 gtk_grid_attach(GTK_GRID(table), label, 0, 2, 1, 1);
1142
1145 "pixbuf", 1, NULL);
1147 render = gtk_cell_renderer_text_new();
1149 "text", 2, NULL);
1151
1152 /* Populate style store. */
1154 GdkPixbuf *img;
1155 struct sprite *s;
1156 GtkTreeIter it;
1157
1159
1160 if (i >= 0) {
1161 gtk_list_store_append(store, &it);
1162
1165 free_sprite(s);
1166 gtk_list_store_set(store, &it, 0, i, 1, img, 2,
1169 }
1171
1172 /* Legend pane. */
1173 label = gtk_label_new_with_mnemonic(_("_Description"));
1174
1175 text = gtk_text_view_new();
1188
1189 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), text, label);
1190
1191 /* Signals. */
1192 g_signal_connect(shell, "destroy",
1194 g_signal_connect(shell, "response",
1196
1199
1200 g_signal_connect(races_sex[0], "toggled",
1202 g_signal_connect(races_sex[1], "toggled",
1204
1205 /* Finish up. */
1207
1208 /* You can't assign NO_NATION during a running game. */
1209 if (C_S_RUNNING == client_state()) {
1211 FALSE);
1212 }
1213
1215 TRUE);
1216
1217 /* Select player's current nation in UI, if any */
1218 if (races_player->nation) {
1223 /* Make sure selected nation is visible
1224 * (last page, "All", will certainly contain it) */
1227 } else {
1228 select_nation(-1, NULL, FALSE, 0);
1229 }
1230}
1231
1232/**********************************************************************/
1235void popup_races_dialog(struct player *pplayer)
1236{
1237 if (!pplayer) {
1238 return;
1239 }
1240
1241 if (!races_shell) {
1242 create_races_dialog(pplayer);
1244 }
1245}
1246
1247/**********************************************************************/
1251{
1252 if (races_shell) {
1254 }
1255
1256 /* We're probably starting a new game, maybe with a new ruleset.
1257 So we warn the worklist dialog. */
1259}
1260
1261/**********************************************************************/
1266{
1267 int i;
1268
1269 if (!races_shell) {
1270 return;
1271 }
1272
1273 for (i = 0; i <= nation_group_count(); i++) {
1274 if (races_nation_list[i]) {
1278 GtkTreeIter it;
1280
1281 /* Update 'chosen' column in model */
1282 if (gtk_tree_model_get_iter_first(model, &it)) {
1283 do {
1284 int nation_no;
1285 struct nation_type *nation;
1286
1287 gtk_tree_model_get(model, &it, 0, &nation_no, -1);
1288 nation = nation_by_number(nation_no);
1289
1290 chosen = !is_nation_pickable(nation)
1291 || (nation->player && nation->player != races_player);
1292
1293 gtk_list_store_set(GTK_LIST_STORE(model), &it, 1, chosen, -1);
1294
1295 } while (gtk_tree_model_iter_next(model, &it));
1296 }
1297
1298 /* If our selection is now invalid, deselect it */
1299 if (gtk_tree_selection_get_selected(select, &model, &it)) {
1300 gtk_tree_model_get(model, &it, 1, &chosen, -1);
1301
1302 if (chosen) {
1304 }
1305 }
1306 }
1307 }
1308}
1309
1310/**********************************************************************/
1314{
1315 GtkTreeModel *model;
1316 GtkTreeIter it;
1317
1318 if (gtk_tree_selection_get_selected(select, &model, &it)) {
1320 int newnation;
1321
1322 gtk_tree_model_get(model, &it, 0, &newnation, 1, &chosen, -1);
1323
1324 /* Only allow nations not chosen by another player */
1325 if (!chosen) {
1326 if (newnation != selected_nation) {
1327 /* Choose a random leader */
1330 }
1331 return;
1332 }
1333 }
1334
1335 /* Fall-through if no valid nation selected */
1336 select_nation(-1, NULL, FALSE, 0);
1337}
1338
1339/**********************************************************************/
1358
1359/**********************************************************************/
1363{
1365}
1366
1367/**********************************************************************/
1371 GtkTreeModel *model, GtkTreePath *path,
1372 gboolean selected, gpointer data)
1373{
1374 GtkTreeIter it;
1376
1377 gtk_tree_model_get_iter(model, &it, path);
1378 gtk_tree_model_get(model, &it, 1, &chosen, -1);
1379 return (!chosen || selected);
1380}
1381
1382/**********************************************************************/
1386{
1387 GtkTreeModel *model;
1388 GtkTreeIter it;
1389
1390 if (gtk_tree_selection_get_selected(select, &model, &it)) {
1391 gtk_tree_model_get(model, &it, 0, &selected_style, -1);
1392 } else {
1393 selected_style = -1;
1394 }
1395}
1396
1397/**********************************************************************/
1400static void races_response(GtkWidget *w, gint response, gpointer data)
1401{
1402 if (response == GTK_RESPONSE_ACCEPT) {
1403 const char *s;
1404
1405 /* This shouldn't be possible but... */
1406 if (selected_nation == -1) {
1407 return;
1408 }
1409
1410 if (selected_sex == -1) {
1411 output_window_append(ftc_client, _("You must select your sex."));
1412 return;
1413 }
1414
1415 if (selected_style == -1) {
1416 output_window_append(ftc_client, _("You must select your style."));
1417 return;
1418 }
1419
1422
1423 /* Perform a minimum of sanity test on the name. */
1424 /* This could call is_allowed_player_name if it were available. */
1425 if (strlen(s) == 0) {
1426 output_window_append(ftc_client, _("You must type a legal name."));
1427 return;
1428 }
1429
1432 selected_sex, s,
1434 } else if (response == GTK_RESPONSE_NO) {
1437 -1, FALSE, "", 0);
1438 }
1439
1441}
1442
1443/**********************************************************************/
1456
1457/**********************************************************************/
1470
1471/**********************************************************************/
1474void popup_upgrade_dialog(struct unit_list *punits)
1475{
1477 char buf[512];
1478
1479 if (!punits || unit_list_size(punits) == 0) {
1480 return;
1481 }
1482
1483 if (!get_units_upgrade_info(buf, sizeof(buf), punits)) {
1486 "%s", buf);
1487 gtk_window_set_title(GTK_WINDOW(shell), _("Upgrade Unit!"));
1490 NULL);
1492 } else {
1495 "%s", buf);
1496 gtk_window_set_title(GTK_WINDOW(shell), _("Upgrade Obsolete Units"));
1499
1500 /* FIXME: Should not block */
1505 }
1507 }
1508}
1509
1510/**********************************************************************/
1513void popup_disband_dialog(struct unit_list *punits)
1514{
1516 char buf[512];
1517
1518 if (!punits || unit_list_size(punits) == 0) {
1519 return;
1520 }
1521
1522 if (!get_units_disband_info(buf, sizeof(buf), punits)) {
1525 "%s", buf);
1526 gtk_window_set_title(GTK_WINDOW(shell), _("Disband Units"));
1529 NULL);
1531 } else {
1534 "%s", buf);
1535 gtk_window_set_title(GTK_WINDOW(shell), _("Disband Units"));
1538
1539 /* FIXME: Should not block */
1544 }
1546 }
1548 }
1549}
1550
1551/**********************************************************************/
1561
1562/**********************************************************************/
1576
1577/**********************************************************************/
1581void show_tileset_error(bool fatal, const char *tset_name, const char *msg)
1582{
1583 if (is_gui_up()) {
1584 GtkWidget *dialog;
1585
1586 if (tset_name != NULL) {
1589 _("Tileset \"%s\" problem, "
1590 "it's probably incompatible with "
1591 "the ruleset:\n%s"),
1592 tset_name, msg);
1593 } else {
1596 _("Tileset problem, "
1597 "it's probably incompatible with "
1598 "the ruleset:\n%s"),
1599 msg);
1600 }
1601
1602 setup_dialog(dialog, toplevel);
1603
1604 blocking_dialog(dialog);
1605
1607 }
1608}
1609
1610/**********************************************************************/
1615{
1616 /* Just tell the client common code to handle this. */
1617 return FALSE;
1618}
1619
1620/**********************************************************************/
1624void popup_combat_info(int attacker_unit_id, int defender_unit_id,
1625 int attacker_hp, int defender_hp,
1626 bool make_att_veteran, bool make_def_veteran)
1627{
1628}
1629
1630/**********************************************************************/
1633static void act_conf_response(GtkWidget *dialog, gint response,
1634 gpointer data)
1635{
1637
1638 if (response == GTK_RESPONSE_YES) {
1640 } else {
1642 }
1643}
1644
1645/**********************************************************************/
1648void request_action_confirmation(const char *expl,
1649 struct act_confirmation_data *data)
1650{
1651 GtkWidget *dialog;
1652 char buf[1024];
1653
1654 if (expl != NULL) {
1655 fc_snprintf(buf, sizeof(buf), _("Are you sure you want to do %s?\n%s"),
1656 action_id_name_translation(data->act), expl);
1657 } else {
1658 fc_snprintf(buf, sizeof(buf), _("Are you sure you want to do %s?"),
1660 }
1661
1663 0,
1666 "%s", buf);
1667 setup_dialog(dialog, toplevel);
1668
1669 g_signal_connect(dialog, "response",
1671
1673}
1674
1675/**********************************************************************/
1678void popup_image(const char *tag)
1679{
1680 struct sprite *spr = load_popup_sprite(tag);
1681
1682 if (spr != NULL) {
1684 GtkWidget *win = gtk_window_new();
1686 int width, height;
1687
1691 gtk_widget_show(win);
1692
1694 } else {
1695 log_error(_("No image for tag \"%s\", requested by the server."), tag);
1696 }
1697}
const char * action_id_name_translation(action_id act_id)
Definition actions.c:2011
void astr_free(struct astring *astr)
Definition astring.c:153
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
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
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_CLR(bv, bit)
Definition bitvector.h:86
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
void output_window_append(const struct ft_color color, const char *featured_text)
const char * city_style_name_translation(const int style)
Definition city.c:1756
#define city_owner(_pcity_)
Definition city.h:563
void popup_city_dialog(struct city *pcity)
struct civclient client
enum client_states client_state(void)
@ C_S_RUNNING
Definition client_main.h:47
void common_taxrates_callback(int idx, bool reverse)
Definition climisc.c:1193
static struct fc_sockaddr_list * list
Definition clinet.c:102
char * incite_cost
Definition comments.c:75
void request_unit_disband(struct unit *punit)
Definition control.c:2087
void request_new_unit_activity_targeted(struct unit *punit, enum unit_activity act, struct extra_type *tgt)
Definition control.c:1950
void action_confirmation(struct act_confirmation_data *data, bool confirm)
Definition control.c:1778
void request_unit_upgrade(struct unit *punit)
Definition control.c:2118
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 int const struct action *paction show_tileset_error
Definition dialogs_g.h:85
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit * actor
Definition dialogs_g.h:73
const char * caption
Definition dialogs_g.h:37
const char const char * headline
Definition dialogs_g.h:38
popup_notify_dialog
Definition dialogs_g.h:37
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 int const struct action *paction bool fatal
Definition dialogs_g.h:86
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
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 int const struct action *paction bool const char * tset_name
Definition dialogs_g.h:86
struct extra_type * extra_by_number(int id)
Definition extras.c:183
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
#define extra_index(_e_)
Definition extras.h:183
int Tech_type_id
Definition fc_types.h:377
int Nation_type_id
Definition fc_types.h:380
#define MAX_NUM_NATION_GROUPS
Definition fc_types.h:58
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const struct ft_color ftc_client
struct civ_game game
Definition game.c:62
struct unit * game_unit_by_number(int id)
Definition game.c:116
static GtkWidget * races_properties
Definition dialogs.c:78
static gboolean races_selection_func(GtkTreeSelection *select, GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data)
Definition dialogs.c:1350
static GtkWidget * races_shell
Definition dialogs.c:72
static void select_nation(int nation, const char *leadername, bool is_male, int style_id)
Definition dialogs.c:513
static void sync_tabs_to_nation(int nation)
Definition dialogs.c:471
static GtkWidget * races_style_list
Definition dialogs.c:81
static void revolution_response(GtkWidget *w, gint response, gpointer data)
Definition dialogs.c:265
static void races_leader_callback(void)
Definition dialogs.c:1322
static int selected_style
Definition dialogs.c:96
static void create_nation_selection_lists(void)
Definition dialogs.c:696
static int is_showing_pillage_dialog
Definition dialogs.c:98
static void create_races_dialog(struct player *pplayer)
Definition dialogs.c:839
static GtkWidget * races_leader
Definition dialogs.c:79
static GtkWidget * races_nation_list[MAX_NUM_NATION_GROUPS+1]
Definition dialogs.c:76
static void populate_leader_list(void)
Definition dialogs.c:487
void unit_select_dialog_popup(struct tile *ptile)
Definition dialogs.c:377
void popup_upgrade_dialog(struct unit_list *punits)
Definition dialogs.c:1435
void races_update_pickable(bool nationset_change)
Definition dialogs.c:731
static void notify_connect_msg_response(GtkWidget *w, gint response)
Definition dialogs.c:186
static void races_sex_callback(GtkWidget *w, gpointer data)
Definition dialogs.c:1342
static void pillage_callback(GtkWidget *dlg, gint arg)
Definition dialogs.c:313
void popup_notify_goto_dialog(const char *headline, const char *lines, const struct text_tag_list *tags, struct tile *ptile)
Definition dialogs.c:196
void show_tech_gained_dialog(Tech_type_id tech)
Definition dialogs.c:1524
static GtkWidget * races_sex[2]
Definition dialogs.c:80
void popup_races_dialog(struct player *pplayer)
Definition dialogs.c:1215
void popup_disband_dialog(struct unit_list *punits)
Definition dialogs.c:1473
static GtkTreePath * path_to_nation_on_list(Nation_type_id nation, GtkTreeView *list)
Definition dialogs.c:399
void popdown_races_dialog(void)
Definition dialogs.c:1230
static int selected_nation
Definition dialogs.c:94
static GtkWidget * races_notebook
Definition dialogs.c:77
void popup_pillage_dialog(struct unit *punit, bv_extras extras)
Definition dialogs.c:338
static void races_response(GtkWidget *w, gint response, gpointer data)
Definition dialogs.c:1380
static void act_conf_response(GtkWidget *dialog, gint response, gpointer data)
Definition dialogs.c:1592
static void notify_goto_response(GtkWidget *w, gint response)
Definition dialogs.c:159
static void races_nation_callback(GtkTreeSelection *select, gpointer data)
Definition dialogs.c:1293
void popup_connect_msg(const char *headline, const char *message)
Definition dialogs.c:239
bool handmade_scenario_warning(void)
Definition dialogs.c:1573
void unit_select_dialog_update_real(void *unused)
Definition dialogs.c:386
static void nationset_callback(GtkComboBox *b, gpointer data)
Definition dialogs.c:814
void races_toggles_set_sensitive(void)
Definition dialogs.c:1245
static void races_style_callback(GtkTreeSelection *select, gpointer data)
Definition dialogs.c:1365
void popup_combat_info(int attacker_unit_id, int defender_unit_id, int attacker_hp, int defender_hp, bool make_att_veteran, bool make_def_veteran)
Definition dialogs.c:1583
static int selected_sex
Definition dialogs.c:95
struct player * races_player
Definition dialogs.c:74
static GtkWidget * nationsets_chooser
Definition dialogs.c:73
void request_action_confirmation(const char *expl, struct act_confirmation_data *data)
Definition dialogs.c:1607
static GtkTextBuffer * races_text
Definition dialogs.c:82
void nationset_sync_to_server(const char *nationset)
Definition dialogs.c:801
gboolean taxrates_callback(GtkWidget *w, GdkEventButton *ev, gpointer data)
Definition dialogs.c:1425
static GtkWidget * create_list_of_nations_in_group(struct nation_group *group, int index)
Definition dialogs.c:609
void popup_image(const char *tag)
Definition dialogs.c:1636
static void select_nation_on_tab(GtkWidget *tab_list, int nation)
Definition dialogs.c:427
void popdown_all_game_dialogs(void)
Definition dialogs.c:1514
struct property_editor * editprop_get_property_editor(void)
Definition editprop.c:6244
void property_editor_popdown(struct property_editor *pe)
Definition editprop.c:6309
GtkWidget * bottom_notebook
Definition gui_main.c:129
bool is_gui_up(void)
Definition gui_main.c:2057
GtkWidget * toplevel
Definition gui_main.c:125
#define GUI_GTK_OPTION(optname)
Definition gui_main.h:32
void gui_dialog_present(struct gui_dialog *dlg)
Definition gui_stuff.c:835
void gui_dialog_new(struct gui_dialog **pdlg, GtkNotebook *notebook, gpointer user_data, bool check_top)
Definition gui_stuff.c:517
void gui_dialog_show_all(struct gui_dialog *dlg)
Definition gui_stuff.c:795
void gui_dialog_set_title(struct gui_dialog *dlg, const char *title)
Definition gui_stuff.c:935
void gui_dialog_set_default_size(struct gui_dialog *dlg, int width, int height)
Definition gui_stuff.c:919
void gui_dialog_destroy_all(void)
Definition gui_stuff.c:974
GtkWidget * gui_dialog_add_button(struct gui_dialog *dlg, const char *icon_name, const char *text, int response)
Definition gui_stuff.c:706
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:197
static struct gui_dialog * shell
Definition messagedlg.c:39
GdkPixbuf * get_flag(const struct nation_type *nation)
Definition plrdlg.c:607
const char * title
Definition repodlgs.c:1314
void free_sprite(struct sprite *s)
Definition sprite.c:278
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
struct sprite * crop_blankspace(struct sprite *s)
Definition sprite.c:386
void unit_select_dialog_popup_main(struct tile *ptile, bool create)
Definition unitselect.c:186
void unit_select_dialog_popdown(void)
Definition unitselect.c:207
bool select_tgt_extra(struct unit *actor, struct tile *ptile, bv_extras potential_tgt_extras, struct extra_type *suggested_tgt_extra, const gchar *dlg_title, const gchar *actor_label, const gchar *tgt_label, const gchar *do_label, GCallback do_callback)
void blank_max_unit_size(void)
Definition wldlg.c:79
gboolean reverse_taxrates_callback(GtkGestureClick *gesture, int n_press, double x, double y)
Definition dialogs.c:1460
gint blocking_dialog(GtkWidget *dlg)
Definition gui_stuff.c:1135
void gui_dialog_add_content_widget(struct gui_dialog *dlg, GtkWidget *wdg)
Definition gui_stuff.c:1104
void widget_destroyed(GtkWidget *wdg, void *data)
Definition gui_stuff.c:1154
static char * leader_name
Definition dialogs.c:97
void popup_revolution_dialog(void)
Definition dialogs.c:112
void helptext_nation(char *buf, size_t bufsz, struct nation_type *pnation, const char *user_text)
Definition helpdata.c:5099
@ HELP_TECH
Definition helpdlg_g.h:21
const char * name
Definition inputfile.c:127
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_error(message,...)
Definition log.h:103
void center_tile_mapcanvas(const struct tile *ptile)
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:486
struct nation_leader * nation_leader_by_name(const struct nation_type *pnation, const char *name)
Definition nation.c:267
bool nation_leader_is_male(const struct nation_leader *pleader)
Definition nation.c:290
const char * nation_adjective_translation(const struct nation_type *pnation)
Definition nation.c:149
struct nation_type * nation_by_number(const Nation_type_id nation)
Definition nation.c:475
int nation_set_index(const struct nation_set *pset)
Definition nation.c:699
bool is_nation_pickable(const struct nation_type *nation)
Definition nation.c:188
const struct nation_leader_list * nation_leaders(const struct nation_type *pnation)
Definition nation.c:230
const char * nation_set_name_translation(const struct nation_set *pset)
Definition nation.c:818
bool is_nation_playable(const struct nation_type *nation)
Definition nation.c:200
bool nation_is_in_group(const struct nation_type *pnation, const struct nation_group *pgroup)
Definition nation.c:1099
bool nation_is_in_set(const struct nation_type *pnation, const struct nation_set *pset)
Definition nation.c:837
const char * nation_set_description(const struct nation_set *pset)
Definition nation.c:828
const char * nation_group_name_translation(const struct nation_group *pgroup)
Definition nation.c:1090
int nation_set_count(void)
Definition nation.c:691
struct nation_group * nation_group_by_number(int id)
Definition nation.c:1004
struct nation_set * nation_set_by_rule_name(const char *name)
Definition nation.c:779
bool is_nation_group_hidden(struct nation_group *pgroup)
Definition nation.c:1057
struct nation_set * nation_set_by_setting_value(const char *setting)
Definition nation.c:859
const char * nation_leader_name(const struct nation_leader *pleader)
Definition nation.c:281
int nation_group_count(void)
Definition nation.c:935
const char * nation_set_rule_name(const struct nation_set *pset)
Definition nation.c:807
struct nation_style * style_of_nation(const struct nation_type *pnation)
Definition nation.c:672
#define nation_leader_list_iterate(leaderlist, pleader)
Definition nation.h:57
#define nation_sets_iterate_end
Definition nation.h:305
#define nation_sets_iterate(NAME_pset)
Definition nation.h:301
#define nations_iterate_end
Definition nation.h:336
#define nations_iterate(NAME_pnation)
Definition nation.h:333
#define nation_leader_list_iterate_end
Definition nation.h:59
#define nation_groups_iterate(NAME_pgroup)
Definition nation.h:311
#define nation_groups_iterate_end
Definition nation.h:315
const struct option_set * server_optset
Definition options.c:4020
bool option_str_set(struct option *poption, const char *str)
Definition options.c:930
const char * option_str_get(const struct option *poption)
Definition options.c:897
struct client_options gui_options
Definition options.c:72
struct option * optset_option_by_name(const struct option_set *poptset, const char *name)
Definition options.c:435
@ GUI_POPUP_TECH_HELP_RULESET
Definition options.h:77
@ GUI_POPUP_TECH_HELP_ENABLED
Definition options.h:75
int dsend_packet_nation_select_req(struct connection *pc, int player_no, Nation_type_id nation_no, bool is_male, const char *name, int style)
void start_revolution(void)
Definition packhand.c:2385
void set_government_choice(struct government *government)
Definition packhand.c:2372
char * lines
Definition packhand.c:131
int len
Definition packhand.c:127
int player_number(const struct player *pplayer)
Definition player.c:837
const char * player_name(const struct player *pplayer)
Definition player.c:895
#define fc_rand(_size)
Definition rand.h:56
const char * sex_name_mnemonic(sex_t kind, const char *mnemonic)
Definition sex.c:74
@ SEX_FEMALE
Definition sex.h:22
@ SEX_MALE
Definition sex.h:23
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
struct sprite int int int int struct sprite int int float bool smooth get_sprite_dimensions
Definition sprite_g.h:36
Definition city.h:320
struct packet_ruleset_control control
Definition game.h:83
struct connection conn
Definition client_main.h:96
bool center_when_popup_city
Definition options.h:161
struct player * playing
Definition connection.h:151
GtkWidget * label
Definition gui_stuff.h:87
Definition mapimg.c:367
struct player * player
Definition nation.h:118
bool is_male
Definition player.h:255
int revolution_finishes
Definition player.h:271
struct nation_type * nation
Definition player.h:258
struct nation_style * style
Definition player.h:277
Definition tile.h:50
char * label
Definition tile.h:65
Definition unit.h:138
int style_number(const struct nation_style *pstyle)
Definition style.c:68
int basic_city_style_for_style(struct nation_style *pstyle)
Definition style.c:210
#define styles_iterate(_p)
Definition style.h:46
#define styles_iterate_end
Definition style.h:52
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
int fc_break_lines(char *str, size_t desired_len)
Definition support.c:1149
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char * advance_name_translation(const struct advance *padvance)
Definition tech.c:290
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
struct extra_type * get_preferred_pillage(bv_extras extras)
Definition terrain.c:550
bool get_units_upgrade_info(char *buf, size_t bufsz, struct unit_list *punits)
Definition text.c:1263
bool get_units_disband_info(char *buf, size_t bufsz, struct unit_list *punits)
Definition text.c:1329
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
struct sprite * load_popup_sprite(const char *tag)
Definition tilespec.c:7589
struct sprite * get_sample_city_sprite(const struct tileset *t, int style_idx)
Definition tilespec.c:6862
void unload_popup_sprite(const char *tag)
Definition tilespec.c:7597
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:367
#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