Freeciv-3.3
Loading...
Searching...
No Matches
wldlg.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 <stdlib.h>
19#include <string.h>
20
21#include <gtk/gtk.h>
22#include <gdk/gdkkeysyms.h>
23
24/* utility */
25#include "fcintl.h"
26#include "log.h"
27#include "mem.h"
28#include "support.h"
29
30/* common */
31#include "city.h"
32#include "packets.h"
33#include "worklist.h"
34
35/* client */
36#include "citydlg_common.h"
37#include "client_main.h"
38#include "climisc.h"
39#include "global_worklist.h"
40#include "options.h"
41#include "text.h"
42#include "tilespec.h"
43
44/* client/gui-gtk-3.22 */
45#include "canvas.h"
46#include "citydlg.h"
47#include "graphics.h"
48#include "gui_main.h"
49#include "gui_stuff.h"
50#include "helpdlg.h"
51#include "inputdlg.h"
52
53#include "wldlg.h"
54
57
58enum {
63};
64
66
67static int max_unit_height = -1, max_unit_width = -1;
68
70 struct global_worklist *pgwl);
71static void popup_worklist(struct global_worklist *pgwl);
72static void popdown_worklist(struct global_worklist *pgwl);
75
76/************************************************************************/
80{
81 max_unit_height = -1;
82 max_unit_width = -1;
83}
84
85/************************************************************************/
104
105/************************************************************************/
109{
111}
112
113/************************************************************************/
130
131/************************************************************************/
134static void worklists_response(GtkWidget *w, gint response)
135{
136 struct global_worklist *pgwl;
137 int id;
138 GtkTreeSelection *selection;
139 GtkTreeModel *model;
140 GtkTreeIter it;
141
143
144 if (gtk_tree_selection_get_selected(selection, &model, &it)) {
145 gtk_tree_model_get(model, &it, 1, &id, -1);
147 } else {
148 pgwl = NULL;
149 id = -1;
150 }
151
152 switch (response) {
153 case WORKLISTS_NEW:
154 global_worklist_new(_("new"));
156 return;
157
158 case WORKLISTS_DELETE:
159 if (!pgwl) {
160 return;
161 }
162
166 return;
167
169 if (!pgwl) {
170 return;
171 }
172
174 return;
175
176 default:
178 return;
179 }
180}
181
182/************************************************************************/
186 const gchar *spath,
187 const gchar *text, gpointer data)
188{
189 GtkTreePath *path;
190 GtkTreeIter it;
191 struct global_worklist *pgwl;
192 int id;
193
196 gtk_tree_path_free(path);
197
200
201 if (!pgwl) {
203 return;
204 }
205
207 gtk_list_store_set(worklists_store, &it, 0, text, -1);
208}
209
210/************************************************************************/
214{
216 GtkWidget *vbox, *label, *sw;
218
219 shell = gtk_dialog_new_with_buttons(_("Edit worklists"),
220 NULL,
221 0,
222 _("_New"),
224 _("_Delete"),
226 _("_Properties"),
228 _("_Close"),
230 NULL);
233
234 g_signal_connect(shell, "response",
236 g_signal_connect(shell, "destroy",
238
239 vbox = gtk_grid_new();
244
246
250
253
255
257 g_object_set(rend, "editable", TRUE, NULL);
258 g_signal_connect(rend, "edited",
261 rend, "text", 0, NULL);
262
270
272 "use-underline", TRUE,
273 "mnemonic-widget", list,
274 "label", _("_Worklists:"),
275 "xalign", 0.0, "yalign", 0.5, NULL);
276
277 gtk_container_add(GTK_CONTAINER(vbox), label);
280
281 return shell;
282}
283
284/************************************************************************/
297
298
299
300
301/****************************************************************
302...
303*****************************************************************/
321
323
324static void commit_worklist(struct worklist_data *ptr);
325
326
327enum {
330
332 { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP, TARGET_GTK_TREE_MODEL_ROW },
333};
334
335
336/************************************************************************/
345
346/************************************************************************/
350{
351 if (hash) {
353
355 return ret;
356 } else {
357 return NULL;
358 }
359}
360
361/************************************************************************/
371
372/************************************************************************/
381
382/************************************************************************/
416
417/************************************************************************/
431
432/************************************************************************/
436{
437 struct worklist_data *ptr;
438
439 ptr = data;
440
441 if (ptr->global_worklist_id != -1) {
443 }
444
445 free(ptr);
446}
447
448/************************************************************************/
452{
453 struct global_worklist *pgwl;
454 const struct worklist *pwl;
455 size_t i;
456
457 if (NULL == client.conn.playing) {
458 return;
459 }
460
463 if (!pgwl) {
464 return;
465 }
467
468 for (i = 0; i < (size_t) worklist_length(pwl); i++) {
469 GtkTreeIter it;
470 cid id;
471 char buf[8192];
472
473 id = cid_encode(pwl->entries[i]);
474
475 gtk_list_store_append(ptr->dst, &it);
476 gtk_list_store_set(ptr->dst, &it, 0, (gint)id,
477 1, production_help(&(pwl->entries[i]),
478 buf, sizeof(buf)), -1);
479 }
480
481 commit_worklist(ptr);
482}
483
484/************************************************************************/
517
518/************************************************************************/
521static void help_callback(GtkWidget *w, gpointer data)
522{
523 struct worklist_data *ptr;
524 GtkTreeSelection *selection;
525 GtkTreeModel *model;
526 GtkTreeIter it;
527
528 ptr = data;
529 selection = ptr->src_selection;
530
531 if (gtk_tree_selection_get_selected(selection, &model, &it)) {
532 gint id;
533 struct universal target;
534
535 gtk_tree_model_get(model, &it, 0, &id, -1);
536 target = cid_decode(id);
537
538 if (VUT_UTYPE == target.kind) {
540 HELP_UNIT);
541 } else if (is_great_wonder(target.value.building)) {
544 } else {
547 }
548 } else {
550 }
551}
552
553/************************************************************************/
556static void change_callback(GtkWidget *w, gpointer data)
557{
558 struct worklist_data *ptr;
559 GtkTreeSelection *selection;
560 GtkTreeModel *model;
561 GtkTreeIter it;
562
563 ptr = data;
564 selection = ptr->src_selection;
565
566 if (gtk_tree_selection_get_selected(selection, &model, &it)) {
567 gint id;
568 struct universal univ;
569
570 gtk_tree_model_get(model, &it, 0, &id, -1);
571 univ = cid_production(id);
572 city_change_production(ptr->pcity, &univ);
573 }
574}
575
576/************************************************************************/
579static void future_callback(GtkToggleButton *toggle, gpointer data)
580{
581 struct worklist_data *ptr;
582
583 ptr = data;
584 ptr->future = !ptr->future;
585
587}
588
589/************************************************************************/
592static void queue_bubble_up(struct worklist_data *ptr)
593{
594 GtkTreePath *path;
596 GtkTreeModel *model;
597
599 return;
600 }
601
602 model = GTK_TREE_MODEL(ptr->dst);
604 if (path) {
606
607 if (gtk_tree_path_prev(path)) {
608 gtk_tree_model_get_iter(model, &it_prev, path);
609 it = it_prev;
610 gtk_tree_model_iter_next(model, &it);
611
613
615 commit_worklist(ptr);
616 }
617 }
618 gtk_tree_path_free(path);
619}
620
621/************************************************************************/
624static void queue_remove(struct worklist_data *ptr)
625{
626 GtkTreePath *path;
628
630 if (path) {
631 dst_row_callback(GTK_TREE_VIEW(ptr->dst_view), path, col, ptr);
632 gtk_tree_path_free(path);
633 }
634}
635
636/************************************************************************/
639static void queue_bubble_down(struct worklist_data *ptr)
640{
641 GtkTreePath *path;
643 GtkTreeModel *model;
644
646 return;
647 }
648
649 model = GTK_TREE_MODEL(ptr->dst);
651 if (path) {
653
654 gtk_tree_model_get_iter(model, &it, path);
655 it_next = it;
656 if (gtk_tree_model_iter_next(model, &it_next)) {
658
659 gtk_tree_path_next(path);
661 commit_worklist(ptr);
662 }
663 }
664 gtk_tree_path_free(path);
665}
666
667/************************************************************************/
670static void queue_insert(struct worklist_data *ptr, bool prepend)
671{
672 GtkTreeModel *model;
673 GtkTreeIter it;
674 GtkTreePath *path;
675
678 gint i, ncols;
679
681 return;
682 }
683
684 if (!gtk_tree_selection_get_selected(ptr->src_selection, &model, &it)) {
685 return;
686 }
687
688 path = gtk_tree_model_get_path(model, &it);
689
692
694 if (prepend) {
696 } else {
698 }
699
701
702 for (i = 0; i < ncols; i++) {
703 GValue value = { 0, };
704
707 }
708 commit_worklist(ptr);
709
710 gtk_tree_path_free(path);
711}
712
713/************************************************************************/
716static void queue_prepend(struct worklist_data *ptr)
717{
718 queue_insert(ptr, TRUE);
719}
720
721/************************************************************************/
724static void queue_append(struct worklist_data *ptr)
725{
726 queue_insert(ptr, FALSE);
727}
728
729/************************************************************************/
734{
735 struct worklist_data *ptr;
738 gint i, ncols;
739
740 ptr = data;
741
743 return;
744 }
745
748
751
753
754 for (i = 0; i < ncols; i++) {
755 GValue value = { 0, };
756
759 }
760 commit_worklist(ptr);
761}
762
763/************************************************************************/
768{
769 struct worklist_data *ptr;
771 GtkTreeIter it;
772
773 ptr = data;
775
777
779 commit_worklist(ptr);
780}
781
782/************************************************************************/
786 gpointer data)
787{
788 struct worklist_data *ptr;
789
790 ptr = data;
791
793 return FALSE;
794 }
795
796 if ((ev->state & GDK_SHIFT_MASK) && ev->keyval == GDK_KEY_Insert) {
797 queue_prepend(ptr);
798 return TRUE;
799 } else if (ev->keyval == GDK_KEY_Insert) {
800 queue_append(ptr);
801 return TRUE;
802 } else {
803 return FALSE;
804 }
805}
806
807/************************************************************************/
811 gpointer data)
812{
813 GtkTreeModel *model;
814 struct worklist_data *ptr;
815
816 ptr = data;
817 model = GTK_TREE_MODEL(ptr->dst);
818
819 if (ev->keyval == GDK_KEY_Delete) {
821 bool deleted = FALSE;
822
823 if (gtk_tree_model_get_iter_first(model, &it)) {
824 bool more;
825
826 do {
827 it_next = it;
828 more = gtk_tree_model_iter_next(model, &it_next);
829
832 deleted = TRUE;
833 }
834 it = it_next;
835
836 } while (more);
837 }
838
839 if (deleted) {
840 commit_worklist(ptr);
841 }
842 return TRUE;
843
844 } else if ((ev->state & GDK_MOD1_MASK) && ev->keyval == GDK_KEY_Up) {
845 queue_bubble_up(ptr);
846 return TRUE;
847
848 } else if ((ev->state & GDK_MOD1_MASK) && ev->keyval == GDK_KEY_Down) {
850 return TRUE;
851
852 } else {
853 return FALSE;
854 }
855}
856
857/************************************************************************/
861{
862 struct worklist_data *ptr;
863
864 ptr = data;
865
866 /* update widget sensitivity. */
867 if (gtk_tree_selection_get_selected(selection, NULL, NULL)) {
869 && (!ptr->pcity || city_owner(ptr->pcity) == client.conn.playing)) {
870 /* if ptr->pcity is NULL, this is a global worklist */
874 } else {
878 }
880 } else {
885 }
886}
887
888/************************************************************************/
892{
893 struct worklist_data *ptr;
894
895 ptr = data;
896
897 /* update widget sensitivity. */
898 if (gtk_tree_selection_count_selected_rows(selection) > 0) {
899 int num_rows = 0;
900 GtkTreeIter it;
901
905 do {
906 num_rows++;
907 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(ptr->dst), &it));
908 }
909 if (num_rows > 1) {
911 } else {
913 }
914 } else {
918 }
919}
920
921/************************************************************************/
925 struct worklist_data *ptr)
926{
927 commit_worklist(ptr);
928 return FALSE;
929}
930
931/************************************************************************/
935 GtkTreeModel *model, GtkTreeIter *it,
936 gpointer data)
937{
938 gint id;
939 struct universal target;
940
941 gtk_tree_model_get(model, it, 0, &id, -1);
942 target = cid_production(id);
943
945 GdkPixbuf *pix;
946 struct sprite *sprite;
947
948 if (VUT_UTYPE == target.kind) {
953 } else {
955 }
957 g_object_set(rend, "pixbuf", pix, NULL);
959 if (VUT_UTYPE == target.kind) {
961 }
962 } else {
963 struct city **pcity = data;
964 gint column;
965 char *row[4];
966 char buf[4][64];
967 guint i;
968 gboolean useless;
969
970 for (i = 0; i < ARRAY_SIZE(row); i++) {
971 row[i] = buf[i];
972 }
974
975 get_city_dialog_production_row(row, sizeof(buf[0]), &target, *pcity);
976 g_object_set(rend, "text", row[column], NULL);
977
978 if (NULL != *pcity && VUT_IMPROVEMENT == target.kind) {
979 useless = is_improvement_redundant(*pcity, target.value.building);
980 /* Mark building redundant if we are really certain that there is
981 * no use for it. */
982 g_object_set(rend, "strikethrough", useless, NULL);
983 } else {
984 g_object_set(rend, "strikethrough", FALSE, NULL);
985 }
986 }
987}
988
989/************************************************************************/
992static void populate_view(GtkTreeView *view, struct city **ppcity,
994{
995 static const char *titles[] =
996 { N_("Type"), N_("Name"), N_("Info"), N_("Cost"), N_("Turns") };
997
998 static bool titles_done;
999 guint i;
1002
1004
1005 /* Case i == 0 taken out of the loop to workaround gcc-4.2.1 bug
1006 * https://gcc.gnu.org/PR33381
1007 * Some values would 'stick' from i == 0 round. */
1008 i = 0;
1009
1011
1015
1017 if (max_unit_width == -1 || max_unit_height == -1) {
1019 }
1020 } else {
1021 g_object_set(col, "visible", FALSE, NULL);
1022 }
1025 }
1026
1027 for (i = 1; i < ARRAY_SIZE(titles); i++) {
1028 gint pos = i - 1;
1029
1032
1036
1037 if (pos >= 2) {
1038 g_object_set(G_OBJECT(rend), "xalign", 1.0, NULL);
1040 }
1041
1042 if (pos == 3) {
1043 *pcol = col;
1044 }
1047 }
1048 }
1049}
1050
1051/************************************************************************/
1055{
1056 GtkWidget *editor, *table, *sw, *bbox;
1057 GtkWidget *src_view, *dst_view, *label, *button;
1058 GtkWidget *menubar, *item, *menu;
1059 GtkWidget *table2, *arrow, *check;
1060 GtkSizeGroup *group;
1062 struct worklist_data *ptr;
1063
1064 ptr = fc_malloc(sizeof(*ptr));
1065
1068
1069 ptr->global_worklist_id = -1;
1070 ptr->pcity = NULL;
1071 ptr->src = src_store;
1072 ptr->dst = dst_store;
1073 ptr->future = FALSE;
1074
1075 /* create shell. */
1076 editor = gtk_grid_new();
1081 g_object_set_data(G_OBJECT(editor), "data", ptr);
1082
1083 ptr->editor = editor;
1084
1085 /* add source and target lists. */
1086 table = gtk_grid_new();
1088
1090
1096 gtk_grid_attach(GTK_GRID(table), sw, 3, 1, 2, 1);
1097
1103 gtk_widget_set_name(src_view, "small_font");
1105
1108
1110 "use-underline", TRUE,
1111 "mnemonic-widget", src_view,
1112 "label", _("Source _Tasks:"),
1113 "xalign", 0.0, "yalign", 0.5, NULL);
1114 gtk_grid_attach(GTK_GRID(table), label, 3, 0, 1, 1);
1115
1116 check = gtk_check_button_new_with_mnemonic(_("Show _Future Targets"));
1117 gtk_grid_attach(GTK_GRID(table), check, 4, 0, 1, 1);
1119
1120 table2 = gtk_grid_new();
1121 gtk_grid_attach(GTK_GRID(table), table2, 2, 1, 1, 1);
1122
1123 button = gtk_button_new();
1124 gtk_widget_set_margin_top(button, 24);
1125 gtk_widget_set_margin_bottom(button, 24);
1126 ptr->prepend_cmd = button;
1128 gtk_grid_attach(GTK_GRID(table2), button, 0, 0, 1, 1);
1129
1130 arrow = gtk_image_new_from_icon_name("pan-start-symbolic", GTK_ICON_SIZE_MENU);
1131 gtk_container_add(GTK_CONTAINER(button), arrow);
1132 g_signal_connect_swapped(button, "clicked",
1135
1136 button = gtk_button_new();
1137 ptr->up_cmd = button;
1139 gtk_grid_attach(GTK_GRID(table2), button, 0, 1, 1, 1);
1140
1141 arrow = gtk_image_new_from_icon_name("pan-up-symbolic", GTK_ICON_SIZE_MENU);
1142 gtk_container_add(GTK_CONTAINER(button), arrow);
1143 g_signal_connect_swapped(button, "clicked",
1146
1147 button = gtk_button_new();
1148 ptr->down_cmd = button;
1150 gtk_grid_attach(GTK_GRID(table2), button, 0, 2, 1, 1);
1151
1152 arrow = gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_MENU);
1153 gtk_container_add(GTK_CONTAINER(button), arrow);
1154 g_signal_connect_swapped(button, "clicked",
1157
1158 button = gtk_button_new();
1159 gtk_widget_set_margin_top(button, 24);
1160 gtk_widget_set_margin_bottom(button, 24);
1161 ptr->append_cmd = button;
1163 gtk_grid_attach(GTK_GRID(table2), button, 0, 3, 1, 1);
1164
1165 arrow = gtk_image_new_from_icon_name("pan-start-symbolic", GTK_ICON_SIZE_MENU);
1166 gtk_container_add(GTK_CONTAINER(button), arrow);
1167 g_signal_connect_swapped(button, "clicked",
1168 G_CALLBACK(queue_append), ptr);
1170
1171 button = gtk_button_new();
1172 gtk_widget_set_margin_top(button, 24);
1173 gtk_widget_set_margin_bottom(button, 24);
1174 ptr->remove_cmd = button;
1176 gtk_grid_attach(GTK_GRID(table2), button, 0, 4, 1, 1);
1177
1178 arrow = gtk_image_new_from_icon_name("pan-end-symbolic", GTK_ICON_SIZE_MENU);
1179 gtk_container_add(GTK_CONTAINER(button), arrow);
1180 g_signal_connect_swapped(button, "clicked",
1181 G_CALLBACK(queue_remove), ptr);
1183
1189 gtk_grid_attach(GTK_GRID(table), sw, 0, 1, 2, 1);
1190
1196 gtk_widget_set_name(dst_view, "small_font");
1198
1201
1203 "use-underline", TRUE,
1204 "mnemonic-widget", dst_view,
1205 "label", _("Target _Worklist:"),
1206 "xalign", 0.0, "yalign", 0.5, NULL);
1207 gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
1208
1209 /* add bottom menu and buttons. */
1214
1218
1219 menu = gtk_menu_new();
1220
1221 item = gtk_menu_item_new_with_mnemonic(_("_Add Global Worklist"));
1224 g_signal_connect(menu, "show",
1226 ptr->add_cmd = item;
1228
1229 button = icon_label_button_new("help-browser", _("Help"));
1231 g_signal_connect(button, "clicked",
1233 ptr->help_cmd = button;
1235
1236 button = gtk_button_new_with_mnemonic(_("Change Prod_uction"));
1238 g_signal_connect(button, "clicked",
1240 ptr->change_cmd = button;
1242
1243 ptr->src_view = src_view;
1244 ptr->dst_view = dst_view;
1248
1249 /* DND and other state changing callbacks. */
1251 g_signal_connect(dst_view, "drag_end",
1253
1254 g_signal_connect(src_view, "row_activated",
1256 g_signal_connect(src_view, "key_press_event",
1258
1259 g_signal_connect(dst_view, "row_activated",
1261 g_signal_connect(dst_view, "key_press_event",
1263
1264 g_signal_connect(ptr->src_selection, "changed",
1266 g_signal_connect(ptr->dst_selection, "changed",
1268
1269
1272
1273 return editor;
1274}
1275
1276/************************************************************************/
1280{
1281 struct worklist_data *ptr;
1282
1283 ptr = g_object_get_data(G_OBJECT(editor), "data");
1284
1285 ptr->global_worklist_id = -1;
1286 ptr->pcity = pcity;
1287
1290
1291 g_object_set(ptr->src_col, "visible", TRUE, NULL);
1292 g_object_set(ptr->dst_col, "visible", TRUE, NULL);
1293
1299}
1300
1301/************************************************************************/
1305 struct global_worklist *pgwl)
1306{
1307 struct worklist_data *ptr;
1308
1309 ptr = g_object_get_data(G_OBJECT(editor), "data");
1310
1312 ptr->pcity = NULL;
1313
1316
1318 g_object_set(ptr->src_col, "visible", FALSE, NULL);
1319 g_object_set(ptr->dst_col, "visible", FALSE, NULL);
1320
1322}
1323
1324/************************************************************************/
1328{
1329 struct worklist_data *ptr;
1330 struct worklist queue;
1331 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
1332 int i, targets_used;
1333 struct item items[MAX_NUM_PRODUCTION_TARGETS];
1334 bool selected;
1335 gint id;
1336 GtkTreeIter it;
1337 GtkTreePath *path;
1338 GtkTreeModel *model;
1340
1341 ptr = g_object_get_data(G_OBJECT(editor), "data");
1342
1343 /* refresh source tasks. */
1345 gtk_tree_model_get(GTK_TREE_MODEL(ptr->src), &it, 0, &id, -1);
1346 selected = TRUE;
1347 } else {
1348 selected = FALSE;
1349 }
1350
1351 /* These behave just right if ptr->pcity is NULL -> in case of global
1352 * worklist. */
1354 ptr->future);
1355 name_and_sort_items(targets, targets_used, items, FALSE, ptr->pcity);
1356
1357 /* Re-purpose existing items in the list store -- this avoids the
1358 * UI jumping around (especially as the set of source tasks doesn't
1359 * actually change much in practice). */
1360 model = GTK_TREE_MODEL(ptr->src);
1362
1363 path = NULL;
1364 for (i = 0; i < targets_used; i++) {
1365 char buf[8192];
1366
1367 if (!exists) {
1368 gtk_list_store_append(ptr->src, &it);
1369 }
1370
1371 gtk_list_store_set(ptr->src, &it, 0, (gint)cid_encode(items[i].item),
1372 1, production_help(&(items[i].item),
1373 buf, sizeof(buf)), -1);
1374
1375 if (selected && cid_encode(items[i].item) == id) {
1376 path = gtk_tree_model_get_path(GTK_TREE_MODEL(ptr->src), &it);
1377 }
1378
1379 if (exists) {
1380 exists = gtk_tree_model_iter_next(model, &it);
1381 }
1382 }
1383
1384 /* If the list got shorter, delete any excess items. */
1385 if (exists) {
1387 bool more;
1388
1389 do {
1390 it_next = it;
1391 more = gtk_tree_model_iter_next(model, &it_next);
1392
1393 gtk_list_store_remove(ptr->src, &it);
1394 it = it_next;
1395 } while (more);
1396 }
1397
1398 /* Select the same item that was previously selected, if any. */
1399 if (path) {
1401 gtk_tree_path_free(path);
1402 }
1403
1404 /* refresh target worklist. */
1405 model = GTK_TREE_MODEL(ptr->dst);
1407
1408 /* dance around worklist braindamage. */
1409 if (ptr->pcity != NULL) {
1410 city_get_queue(ptr->pcity, &queue);
1411 } else {
1412 const struct global_worklist *pgwl;
1413
1415
1416 fc_assert(NULL != pgwl);
1417
1419 }
1420
1421 for (i = 0; i < worklist_length(&queue); i++) {
1422 struct universal target = queue.entries[i];
1423 char buf[8192];
1424
1425 if (!exists) {
1426 gtk_list_store_append(ptr->dst, &it);
1427 }
1428
1429 gtk_list_store_set(ptr->dst, &it, 0, (gint)cid_encode(target),
1430 1, production_help(&target,
1431 buf, sizeof(buf)), -1);
1432
1433 if (exists) {
1434 exists = gtk_tree_model_iter_next(model, &it);
1435 }
1436 }
1437
1438 if (exists) {
1440 bool more;
1441
1442 do {
1443 it_next = it;
1444 more = gtk_tree_model_iter_next(model, &it_next);
1445
1446 gtk_list_store_remove(ptr->dst, &it);
1447 it = it_next;
1448 } while (more);
1449 }
1450
1451 /* update widget sensitivity. */
1452 if (ptr->pcity) {
1454 && city_owner(ptr->pcity) == client.conn.playing)) {
1457 } else {
1460 }
1461 } else {
1464 }
1465}
1466
1467/************************************************************************/
1470static void commit_worklist(struct worklist_data *ptr)
1471{
1472 struct worklist queue;
1473 GtkTreeModel *model;
1474 GtkTreeIter it;
1475 size_t i;
1476
1477 model = GTK_TREE_MODEL(ptr->dst);
1478
1479 worklist_init(&queue);
1480
1481 i = 0;
1482 if (gtk_tree_model_get_iter_first(model, &it)) {
1483 do {
1484 gint id;
1485 struct universal univ;
1486
1487 /* oops, the player has a worklist longer than what we can store. */
1488 if (i >= MAX_LEN_WORKLIST) {
1489 break;
1490 }
1491
1492 gtk_tree_model_get(model, &it, 0, &id, -1);
1493 univ = cid_production(id);
1494 worklist_append(&queue, &univ);
1495
1496 i++;
1497 } while (gtk_tree_model_iter_next(model, &it));
1498 }
1499
1500 /* dance around worklist braindamage. */
1501 if (ptr->pcity) {
1502 if (!city_set_queue(ptr->pcity, &queue)) {
1503 /* Failed to change worklist. This means worklist visible
1504 * on screen is not true. */
1506 }
1507 } else {
1508 struct global_worklist *pgwl;
1509
1511 if (pgwl) {
1512 global_worklist_set(pgwl, &queue);
1513 }
1514 }
1515}
#define city_owner(_pcity_)
Definition city.h:560
void get_city_dialog_production_row(char *buf[], size_t column_size, struct universal *target, struct city *pcity)
bool city_set_queue(struct city *pcity, const struct worklist *pqueue)
int city_change_production(struct city *pcity, struct universal *target)
void city_get_queue(struct city *pcity, struct worklist *pqueue)
struct civclient client
bool can_client_issue_orders(void)
int collect_eventually_buildable_targets(struct universal *targets, struct city *pcity, bool advanced_tech)
Definition climisc.c:819
void name_and_sort_items(struct universal *targets, int num_targets, struct item *items, bool show_cost, struct city *pcity)
Definition climisc.c:650
cid cid_encode(struct universal target)
Definition climisc.c:483
struct universal cid_decode(cid id)
Definition climisc.c:526
#define MAX_NUM_PRODUCTION_TARGETS
Definition climisc.h:89
#define cid_production
Definition climisc.h:71
int cid
Definition climisc.h:31
static struct fc_sockaddr_list * list
Definition clinet.c:102
char * incite_cost
Definition comments.c:76
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 struct unit struct city * pcity
Definition dialogs_g.h:78
int int id
Definition editgui_g.h:28
static struct editor_state * editor
Definition editor.c:100
#define _(String)
Definition fcintl.h:67
#define N_(String)
Definition fcintl.h:69
struct global_worklist * global_worklist_by_id(int id)
bool global_worklist_set(struct global_worklist *pgwl, const struct worklist *pwl)
const char * global_worklist_name(const struct global_worklist *pgwl)
int global_worklist_id(const struct global_worklist *pgwl)
void global_worklist_destroy(struct global_worklist *pgwl)
const struct worklist * global_worklist_get(const struct global_worklist *pgwl)
struct global_worklist * global_worklist_new(const char *name)
void global_worklist_set_name(struct global_worklist *pgwl, const char *name)
#define global_worklists_iterate(pgwl)
#define global_worklists_iterate_end
static struct tile * pos
Definition finddlg.c:53
GtkWidget * toplevel
Definition gui_main.c:126
#define GUI_GTK_OPTION(optname)
Definition gui_main.h:25
GtkWidget * icon_label_button_new(const gchar *icon_name, const gchar *label_text)
Definition gui_stuff.c:76
GtkWidget * gtk_aux_menu_bar_new(void)
Definition gui_stuff.c:255
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
void intl_slist(int n, const char **s, bool *done)
Definition gui_stuff.c:111
void popup_help_dialog_string(const char *item)
Definition helpdlg.c:212
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:196
static struct gui_dialog * shell
Definition messagedlg.c:39
void free_sprite(struct sprite *s)
Definition sprite.c:278
struct sprite * sprite_scale(struct sprite *src, int new_w, int new_h)
Definition sprite.c:291
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
void sprite_get_bounding_box(struct sprite *sprite, int *start_x, int *start_y, int *end_x, int *end_y)
Definition sprite.c:321
static GHashTable * hash
Definition wldlg.c:322
static gboolean dst_dnd_callback(GtkWidget *w, GdkDragContext *context, struct worklist_data *ptr)
Definition wldlg.c:924
static void dst_selection_callback(GtkTreeSelection *selection, gpointer data)
Definition wldlg.c:891
static void worklists_response(GtkWidget *w, gint response)
Definition wldlg.c:134
void update_worklist_report_dialog(void)
Definition wldlg.c:116
static void queue_remove(struct worklist_data *ptr)
Definition wldlg.c:624
static GtkWidget * get_worklist(int global_worklist_id)
Definition wldlg.c:349
static void reset_global_worklist(GtkWidget *editor, struct global_worklist *pgwl)
Definition wldlg.c:1304
static void future_callback(GtkToggleButton *toggle, gpointer data)
Definition wldlg.c:579
void blank_max_unit_size(void)
Definition wldlg.c:79
@ WORKLISTS_NEW
Definition wldlg.c:59
@ WORKLISTS_CLOSE
Definition wldlg.c:62
@ WORKLISTS_DELETE
Definition wldlg.c:60
@ WORKLISTS_PROPERTIES
Definition wldlg.c:61
static void src_selection_callback(GtkTreeSelection *selection, gpointer data)
Definition wldlg.c:860
static void help_callback(GtkWidget *w, gpointer data)
Definition wldlg.c:521
static GtkTargetEntry wl_dnd_targets[]
Definition wldlg.c:331
static void src_row_callback(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
Definition wldlg.c:732
static void dst_row_callback(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
Definition wldlg.c:766
static void delete_worklist(int global_worklist_id)
Definition wldlg.c:375
void refresh_worklist(GtkWidget *editor)
Definition wldlg.c:1327
void add_worklist_dnd_target(GtkWidget *w)
Definition wldlg.c:339
static gboolean src_key_press_callback(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition wldlg.c:785
static void popdown_worklist(struct global_worklist *pgwl)
Definition wldlg.c:420
static GtkWidget * worklists_shell
Definition wldlg.c:55
@ TARGET_GTK_TREE_MODEL_ROW
Definition wldlg.c:328
static void popup_worklist(struct global_worklist *pgwl)
Definition wldlg.c:385
static GtkWidget * worklists_list
Definition wldlg.c:56
static void queue_bubble_up(struct worklist_data *ptr)
Definition wldlg.c:592
static GtkWidget * create_worklists_report(void)
Definition wldlg.c:213
static void popup_add_menu(GtkMenuShell *menu, gpointer data)
Definition wldlg.c:487
static void cell_edited(GtkCellRendererText *cell, const gchar *spath, const gchar *text, gpointer data)
Definition wldlg.c:185
static void cell_render_func(GtkTreeViewColumn *col, GtkCellRenderer *rend, GtkTreeModel *model, GtkTreeIter *it, gpointer data)
Definition wldlg.c:934
static gboolean dst_key_press_callback(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition wldlg.c:810
static void worklist_destroy(GtkWidget *editor, gpointer data)
Definition wldlg.c:435
static void worklists_destroy_callback(GtkWidget *w, gpointer data)
Definition wldlg.c:108
static void change_callback(GtkWidget *w, gpointer data)
Definition wldlg.c:556
void reset_city_worklist(GtkWidget *editor, struct city *pcity)
Definition wldlg.c:1279
static void queue_insert(struct worklist_data *ptr, bool prepend)
Definition wldlg.c:670
static void menu_item_callback(GtkMenuItem *item, struct worklist_data *ptr)
Definition wldlg.c:451
static void populate_view(GtkTreeView *view, struct city **ppcity, GtkTreeViewColumn **pcol)
Definition wldlg.c:992
static void insert_worklist(int global_worklist_id, GtkWidget *editor)
Definition wldlg.c:364
static void queue_append(struct worklist_data *ptr)
Definition wldlg.c:724
GtkWidget * create_worklist(void)
Definition wldlg.c:1054
static void commit_worklist(struct worklist_data *ptr)
Definition wldlg.c:1470
static void queue_bubble_down(struct worklist_data *ptr)
Definition wldlg.c:639
static int max_unit_width
Definition wldlg.c:67
static int max_unit_height
Definition wldlg.c:67
static void update_max_unit_size(void)
Definition wldlg.c:88
static void queue_prepend(struct worklist_data *ptr)
Definition wldlg.c:716
static GtkListStore * worklists_store
Definition wldlg.c:65
void popup_worklists_report(void)
Definition wldlg.c:287
#define HELP_WORKLIST_EDITOR_ITEM
@ HELP_IMPROVEMENT
Definition helpdlg_g.h:20
@ HELP_UNIT
Definition helpdlg_g.h:20
@ HELP_WONDER
Definition helpdlg_g.h:21
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define fc_assert(condition)
Definition log.h:177
#define fc_malloc(sz)
Definition mem.h:34
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MAX(x, y)
Definition shared.h:54
Definition city.h:317
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:151
Definition climisc.h:82
enum universals_n kind
Definition fc_types.h:608
universals_u value
Definition fc_types.h:607
GtkWidget * add_cmd
Definition wldlg.c:316
GtkWidget * prepend_cmd
Definition wldlg.c:317
GActionGroup * group
Definition wldlg.c:311
GtkWidget * dst_view
Definition wldlg.c:311
GtkTreeViewColumn * dst_col
Definition wldlg.c:314
GtkTreeSelection * dst_selection
Definition wldlg.c:312
GtkWidget * src_view
Definition wldlg.c:311
GtkWidget * up_cmd
Definition wldlg.c:317
bool future
Definition wldlg.c:319
GtkTreeSelection * src_selection
Definition wldlg.c:312
GtkListStore * src
Definition wldlg.c:310
GtkTreeViewColumn * src_col
Definition wldlg.c:314
GtkWidget * remove_cmd
Definition wldlg.c:317
GtkListStore * dst
Definition wldlg.c:310
GtkWidget * editor
Definition wldlg.c:308
int global_worklist_id
Definition wldlg.c:305
GtkWidget * append_cmd
Definition wldlg.c:317
GtkWidget * help_cmd
Definition wldlg.c:316
struct city * pcity
Definition wldlg.c:306
GMenu * menu
Definition wldlg.c:309
GtkWidget * down_cmd
Definition wldlg.c:317
GtkWidget * change_cmd
Definition wldlg.c:316
struct universal entries[MAX_LEN_WORKLIST]
Definition worklist.h:30
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char * production_help(const struct universal *uni, char *buf, size_t bufsize)
Definition text.c:2137
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:7007
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:7029
const struct unit_type * utype
Definition fc_types.h:553
const struct impr_type * building
Definition fc_types.h:546
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1566
#define unit_type_iterate(_p)
Definition unittype.h:862
#define unit_type_iterate_end
Definition unittype.h:869
void worklist_copy(struct worklist *dst, const struct worklist *src)
Definition worklist.c:112
void worklist_init(struct worklist *pwl)
Definition worklist.c:38
bool worklist_append(struct worklist *pwl, const struct universal *prod)
Definition worklist.c:147
int worklist_length(const struct worklist *pwl)
Definition worklist.c:57
#define MAX_LEN_WORKLIST
Definition worklist.h:24