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-5.0 */
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
56
57enum {
62};
63
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#define FC_TYPE_WORKLIST_ROW (fc_worklist_row_get_type())
77
79
87
92
94
95
96#define FC_TYPE_WLMETA_ROW (fc_wlmeta_row_get_type())
97
99
107
112
114
115/**********************************************************************/
118static void
122
123/**********************************************************************/
126static void
130
131/**********************************************************************/
134#if 0
136{
137 FcWorklistRow *result;
138
139 result = g_object_new(FC_TYPE_WORKLIST_ROW, nullptr);
140
141 return result;
142}
143#endif
144
145/**********************************************************************/
148static void
152
153/**********************************************************************/
156static void
160
161/**********************************************************************/
165{
166 FcWlmetaRow *result;
167
168 result = g_object_new(FC_TYPE_WLMETA_ROW, nullptr);
169
170 return result;
171}
172
173/************************************************************************/
177{
178 max_unit_height = -1;
179 max_unit_width = -1;
180}
181
182/************************************************************************/
201
202/************************************************************************/
206{
208}
209
210/************************************************************************/
229
230/************************************************************************/
233static void worklists_response(GtkWidget *w, gint response)
234{
235 struct global_worklist *pgwl;
237
238 if (row != nullptr) {
240 } else {
241 pgwl = nullptr;
242 }
243
244 switch (response) {
245 case WORKLISTS_NEW:
246 global_worklist_new(_("new"));
248 return;
249
250 case WORKLISTS_DELETE:
251 if (!pgwl) {
252 return;
253 }
254
258 return;
259
261 if (!pgwl) {
262 return;
263 }
264
266 return;
267
268 default:
270 return;
271 }
272}
273
274/************************************************************************/
278{
279 int id = GPOINTER_TO_INT(data);
280 struct global_worklist *pgwl;
281
283
284 if (pgwl != nullptr) {
286
288 }
289}
290
291/**********************************************************************/
308
309/**********************************************************************/
318
319/************************************************************************/
323{
325 GtkWidget *vbox, *label;
329
330 shell = gtk_dialog_new_with_buttons(_("Edit worklists"),
331 NULL,
332 0,
333 _("_New"),
335 _("_Delete"),
337 _("_Properties"),
339 _("_Close"),
341 NULL);
343
344 g_signal_connect(shell, "response",
346 g_signal_connect(shell, "destroy",
348
351 vbox);
352
354
357
360 nullptr);
362 nullptr);
363
366
368 "use-underline", TRUE,
369 "mnemonic-widget", list,
370 "label", _("_Worklists:"),
371 "xalign", 0.0, "yalign", 0.5, NULL);
372
373 gtk_box_append(GTK_BOX(vbox), label);
376
377 return shell;
378}
379
380/************************************************************************/
393
394/****************************************************************
395 ...
396*****************************************************************/
397struct worklist_data {
399 struct city *pcity;
400
402
405 GMenu *menu;
406 int menu_size;
409
411
414
415 bool future;
416};
417
419
420static void commit_worklist(struct worklist_data *ptr);
421
422/************************************************************************/
439
440/************************************************************************/
444{
445 if (hash) {
447
449 return ret;
450 } else {
451 return NULL;
452 }
453}
454
455/************************************************************************/
465
466/************************************************************************/
475
476/************************************************************************/
508
509/************************************************************************/
523
524/************************************************************************/
528{
529 struct worklist_data *ptr;
530
531 ptr = data;
532
533 if (ptr->global_worklist_id != -1) {
535 }
536
537 free(ptr);
538}
539
540/************************************************************************/
544 gpointer data)
545{
546 struct global_worklist *pgwl;
547 const struct worklist *pwl;
548 struct worklist_data *ptr = (struct worklist_data *)data;
549 size_t i;
550
551 if (NULL == client.conn.playing) {
552 return;
553 }
554
557 if (pgwl == NULL) {
558 return;
559 }
560
562
563 for (i = 0; i < (size_t) worklist_length(pwl); i++) {
564 GtkTreeIter it;
565 cid id;
566 char buf[8192];
567
568 id = cid_encode(pwl->entries[i]);
569
571 gtk_list_store_set(ptr->dst_depr, &it, 0, (gint)id,
572 1, production_help(&(pwl->entries[i]),
573 buf, sizeof(buf)), -1);
574 }
575
576 commit_worklist(ptr);
577}
578
579/************************************************************************/
583{
584 GSimpleAction *act;
585 int current_size = 0;
586
587 if (ptr->menu == NULL) {
588 ptr->menu = g_menu_new();
589 ptr->menu_size = 0;
590 }
591
593 int id = global_worklist_id(pgwl);
594 char act_name[60];
595
596 fc_snprintf(act_name, sizeof(act_name), "wl%d", id);
598
599 g_object_set_data(G_OBJECT(act), "id",
602 g_signal_connect(act, "activate", G_CALLBACK(menu_item_callback), ptr);
603
604 fc_snprintf(act_name, sizeof(act_name), "win.wl%d", id);
605
606 if (ptr->menu_size > current_size) {
608 }
612
613 act = g_simple_action_new("wledit", NULL);
615 g_signal_connect(act, "activate",
617
618 if (ptr->menu_size > current_size) {
620 }
621
623 g_menu_item_new(_("Edit Global _Worklists"), "win.wledit"));
624
625 if (ptr->menu_size < current_size) {
626 ptr->menu_size = current_size;
627 } else {
628 while (ptr->menu_size > current_size) {
629 g_menu_remove(ptr->menu, --ptr->menu_size);
630 }
631 }
632
633 return ptr->menu;
634}
635
636/************************************************************************/
640{
641 gint id;
642 struct universal target;
643
644 gtk_tree_model_get(model, it, 0, &id, -1);
645 target = cid_decode(id);
646
647 if (VUT_UTYPE == target.kind) {
649 HELP_UNIT);
650 } else if (is_great_wonder(target.value.building)) {
653 } else {
656 }
657}
658
659/************************************************************************/
662static void help_callback(GtkWidget *w, gpointer data)
663{
664 struct worklist_data *ptr;
666 GtkTreeModel *model;
667 GtkTreeIter it;
668
669 ptr = data;
671
673 wl_help_from_iter(model, &it);
674 } else {
676 }
677}
678
679/************************************************************************/
682static void change_callback(GtkWidget *w, gpointer data)
683{
684 struct worklist_data *ptr;
686 GtkTreeModel *model;
687 GtkTreeIter it;
688
689 ptr = data;
691
693 gint id;
694 struct universal univ;
695
696 gtk_tree_model_get(model, &it, 0, &id, -1);
697 univ = cid_production(id);
698 city_change_production(ptr->pcity, &univ);
699 }
700}
701
702/************************************************************************/
705static void future_callback(GtkToggleButton *toggle, gpointer data)
706{
707 struct worklist_data *ptr;
708
709 ptr = data;
710 ptr->future = !ptr->future;
711
713}
714
715/************************************************************************/
718static void queue_bubble_up(struct worklist_data *ptr)
719{
720 GtkTreePath *path;
722 GtkTreeModel *model;
723
725 return;
726 }
727
728 model = GTK_TREE_MODEL(ptr->dst_depr);
730 if (path) {
732
733 if (gtk_tree_path_prev(path)) {
734 gtk_tree_model_get_iter(model, &it_prev, path);
735 it = it_prev;
736 gtk_tree_model_iter_next(model, &it);
737
739
741 commit_worklist(ptr);
742 }
743 }
744 gtk_tree_path_free(path);
745}
746
747/************************************************************************/
750static void queue_remove(struct worklist_data *ptr)
751{
752 GtkTreePath *path;
754
756 if (path) {
758 gtk_tree_path_free(path);
759 }
760}
761
762/************************************************************************/
765static void queue_bubble_down(struct worklist_data *ptr)
766{
767 GtkTreePath *path;
769 GtkTreeModel *model;
770
772 return;
773 }
774
775 model = GTK_TREE_MODEL(ptr->dst_depr);
777 if (path) {
779
780 gtk_tree_model_get_iter(model, &it, path);
781 it_next = it;
782 if (gtk_tree_model_iter_next(model, &it_next)) {
784
785 gtk_tree_path_next(path);
787 commit_worklist(ptr);
788 }
789 }
790 gtk_tree_path_free(path);
791}
792
793/************************************************************************/
796static void queue_insert(struct worklist_data *ptr, bool prepend)
797{
798 GtkTreeModel *model;
799 GtkTreeIter it;
800 GtkTreePath *path;
803 gint i, ncols;
804
806 return;
807 }
808
809 if (!gtk_tree_selection_get_selected(ptr->src_selection_depr, &model, &it)) {
810 return;
811 }
812
813 path = gtk_tree_model_get_path(model, &it);
814
817
819 if (prepend) {
821 } else {
823 }
824
826
827 for (i = 0; i < ncols; i++) {
828 GValue value = { 0, };
829
832 }
833 commit_worklist(ptr);
834
835 gtk_tree_path_free(path);
836}
837
838/************************************************************************/
841static void queue_prepend(struct worklist_data *ptr)
842{
843 queue_insert(ptr, TRUE);
844}
845
846/************************************************************************/
849static void queue_append(struct worklist_data *ptr)
850{
851 queue_insert(ptr, FALSE);
852}
853
854/************************************************************************/
887
888/************************************************************************/
906
907/************************************************************************/
912 GdkModifierType state, gpointer data)
913{
914 struct worklist_data *ptr;
915
916 ptr = data;
917
919 return FALSE;
920 }
921
922 if ((state & GDK_SHIFT_MASK) && keyval == GDK_KEY_Insert) {
923 queue_prepend(ptr);
924 return TRUE;
925 } else if (keyval == GDK_KEY_Insert) {
926 queue_append(ptr);
927 return TRUE;
928 } else {
929 return FALSE;
930 }
931}
932
933/************************************************************************/
938 GdkModifierType state, gpointer data)
939{
941 struct worklist_data *ptr;
942
943 ptr = data;
945
946 if (keyval == GDK_KEY_Delete) {
948 bool deleted = FALSE;
949
951 bool more;
952
953 do {
954 it_next = it;
956
959 deleted = TRUE;
960 }
961 it = it_next;
962
963 } while (more);
964 }
965
966 if (deleted) {
967 commit_worklist(ptr);
968 }
969
970 return TRUE;
971 } else if ((state & GDK_ALT_MASK) && keyval == GDK_KEY_Up) {
972 queue_bubble_up(ptr);
973
974 return TRUE;
975 } else if ((state & GDK_ALT_MASK) && keyval == GDK_KEY_Down) {
977
978 return TRUE;
979 } else {
980 return FALSE;
981 }
982}
983
984/************************************************************************/
988{
989 struct worklist_data *ptr;
990
991 ptr = data;
992
993 /* Update widget sensitivity. */
994 if (gtk_tree_selection_get_selected(selection, NULL, NULL)) {
996 && (!ptr->pcity || city_owner(ptr->pcity) == client.conn.playing)) {
997 /* If ptr->pcity is NULL, this is a global worklist */
1001 } else {
1005 }
1007 } else {
1012 }
1013}
1014
1015/************************************************************************/
1019{
1020 struct worklist_data *ptr;
1021
1022 ptr = data;
1023
1024 /* Update widget sensitivity. */
1025 if (gtk_tree_selection_count_selected_rows(selection) > 0) {
1026 int num_rows = 0;
1027 GtkTreeIter it;
1028
1032 do {
1033 num_rows++;
1034 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(ptr->dst_depr), &it));
1035 }
1036 if (num_rows > 1) {
1038 } else {
1040 }
1041 } else {
1045 }
1046}
1047
1048/************************************************************************/
1052 GtkTreeModel *model, GtkTreeIter *it,
1053 gpointer data)
1054{
1055 gint id;
1056 struct universal target;
1057
1058 gtk_tree_model_get(model, it, 0, &id, -1);
1059 target = cid_production(id);
1060
1062 GdkPixbuf *pix;
1063 struct sprite *sprite;
1064
1065 if (VUT_UTYPE == target.kind) {
1070 } else {
1072 }
1074 g_object_set(rend, "pixbuf", pix, NULL);
1076 if (VUT_UTYPE == target.kind) {
1078 }
1079 } else {
1080 struct city **pcity = data;
1081 gint column;
1082 char *row[4];
1083 char buf[4][64];
1084 guint i;
1085 gboolean useless;
1086
1087 for (i = 0; i < ARRAY_SIZE(row); i++) {
1088 row[i] = buf[i];
1089 }
1091
1092 get_city_dialog_production_row(row, sizeof(buf[0]), &target, *pcity);
1093 g_object_set(rend, "text", row[column], NULL);
1094
1095 if (NULL != *pcity && VUT_IMPROVEMENT == target.kind) {
1096 useless = is_improvement_redundant(*pcity, target.value.building);
1097 /* Mark building redundant if we are really certain that there is
1098 * no use for it. */
1099 g_object_set(rend, "strikethrough", useless, NULL);
1100 } else {
1101 g_object_set(rend, "strikethrough", FALSE, NULL);
1102 }
1103 }
1104}
1105
1106/************************************************************************/
1111{
1112 static const char *titles[] =
1113 { N_("Type"), N_("Name"), N_("Info"), N_("Cost"), N_("Turns") };
1114
1115 static bool titles_done;
1116 guint i;
1119
1121
1122 /* Case i == 0 taken out of the loop to workaround gcc-4.2.1 bug
1123 * https://gcc.gnu.org/PR33381
1124 * Some values would 'stick' from i == 0 round. */
1125 i = 0;
1126
1128
1132
1134 if (max_unit_width == -1 || max_unit_height == -1) {
1136 }
1137 } else {
1138 g_object_set(col, "visible", FALSE, NULL);
1139 }
1142 }
1143
1144 for (i = 1; i < ARRAY_SIZE(titles); i++) {
1145 gint pos = i - 1;
1146
1149
1151 i, titles[i], rend,
1154
1155 if (pos >= 2) {
1156 g_object_set(G_OBJECT(rend), "xalign", 1.0, NULL);
1158 }
1159
1160 if (pos == 3) {
1161 *pcol = col;
1162 }
1165 }
1166 }
1167}
1168
1169/************************************************************************/
1173 int n_press,
1174 double x, double y)
1175{
1179 GtkTreePath *path;
1180 int bx, by;
1181
1183
1186
1187 if (gtk_tree_model_get_iter(model, &iter, path)) {
1188 wl_help_from_iter(model, &iter);
1189 }
1190 }
1191
1192 return TRUE;
1193}
1194
1195/************************************************************************/
1198static gboolean drag_drop(GtkDropTarget *target, const GValue *value,
1199 double x, double y, gpointer data)
1200{
1201 struct worklist_data *ptr = (struct worklist_data *)data;
1202 GtkTreeIter it;
1203 char buf[8192];
1204 cid id = g_value_get_int(value);
1205 struct universal univ;
1206
1207 univ = cid_production(id);
1209 gtk_list_store_set(ptr->dst_depr, &it, 0, id, 1,
1210 production_help(&univ, buf, sizeof(buf)), -1);
1211
1212 commit_worklist(ptr);
1213
1214 return TRUE;
1215}
1216
1217/**********************************************************************/
1231
1232/**********************************************************************/
1241
1242/************************************************************************/
1246{
1247 GtkWidget *editor, *table, *sw, *bbox;
1248 GtkWidget *src_view_depr, *dst_view_depr, *label, *button;
1250 GMenu *menu;
1251 GtkWidget *table2, *arrow, *check;
1255 struct worklist_data *ptr;
1256 int editor_row = 0;
1260
1261 ptr = fc_malloc(sizeof(*ptr));
1262
1265
1266 ptr->global_worklist_id = -1;
1267 ptr->pcity = NULL;
1268 ptr->src_depr = src_store_depr;
1269 ptr->dst_depr = dst_store_depr;
1270 ptr->future = FALSE;
1271
1274 nullptr);
1276 nullptr);
1277
1278 /* Create shell. */
1279 editor = gtk_grid_new();
1284 g_object_set_data(G_OBJECT(editor), "data", ptr);
1285
1286 ptr->editor = editor;
1287
1288 /* Add source and target lists. */
1289 table = gtk_grid_new();
1291
1293
1298 gtk_grid_attach(GTK_GRID(table), sw, 3, 1, 2, 1);
1299
1305 gtk_widget_set_name(src_view_depr, "small_font");
1307
1311 g_signal_connect(controller, "pressed",
1314
1317
1319 "use-underline", TRUE,
1320 "mnemonic-widget", src_view_depr,
1321 "label", _("Source _Tasks:"),
1322 "xalign", 0.0, "yalign", 0.5, NULL);
1323 gtk_grid_attach(GTK_GRID(table), label, 3, 0, 1, 1);
1324
1325 check = gtk_check_button_new_with_mnemonic(_("Show _Future Targets"));
1326 gtk_grid_attach(GTK_GRID(table), check, 4, 0, 1, 1);
1328
1329 table2 = gtk_grid_new();
1330 gtk_grid_attach(GTK_GRID(table), table2, 2, 1, 1, 1);
1331
1332 button = gtk_button_new();
1333 gtk_widget_set_margin_top(button, 24);
1334 gtk_widget_set_margin_bottom(button, 24);
1335 ptr->prepend_cmd = button;
1337 gtk_grid_attach(GTK_GRID(table2), button, 0, 0, 1, 1);
1338
1339 arrow = gtk_image_new_from_icon_name("pan-start-symbolic");
1340 gtk_button_set_child(GTK_BUTTON(button), arrow);
1341 g_signal_connect_swapped(button, "clicked",
1344
1345 button = gtk_button_new();
1346 ptr->up_cmd = button;
1348 gtk_grid_attach(GTK_GRID(table2), button, 0, 1, 1, 1);
1349
1350 arrow = gtk_image_new_from_icon_name("pan-up-symbolic");
1351 gtk_button_set_child(GTK_BUTTON(button), arrow);
1352 g_signal_connect_swapped(button, "clicked",
1355
1356 button = gtk_button_new();
1357 ptr->down_cmd = button;
1359 gtk_grid_attach(GTK_GRID(table2), button, 0, 2, 1, 1);
1360
1361 arrow = gtk_image_new_from_icon_name("pan-down-symbolic");
1362 gtk_button_set_child(GTK_BUTTON(button), arrow);
1363 g_signal_connect_swapped(button, "clicked",
1366
1367 button = gtk_button_new();
1368 gtk_widget_set_margin_top(button, 24);
1369 gtk_widget_set_margin_bottom(button, 24);
1370 ptr->append_cmd = button;
1372 gtk_grid_attach(GTK_GRID(table2), button, 0, 3, 1, 1);
1373
1374 arrow = gtk_image_new_from_icon_name("pan-start-symbolic");
1375 gtk_button_set_child(GTK_BUTTON(button), arrow);
1376 g_signal_connect_swapped(button, "clicked",
1377 G_CALLBACK(queue_append), ptr);
1379
1380 button = gtk_button_new();
1381 gtk_widget_set_margin_top(button, 24);
1382 gtk_widget_set_margin_bottom(button, 24);
1383 ptr->remove_cmd = button;
1385 gtk_grid_attach(GTK_GRID(table2), button, 0, 4, 1, 1);
1386
1387 arrow = gtk_image_new_from_icon_name("pan-end-symbolic");
1388 gtk_button_set_child(GTK_BUTTON(button), arrow);
1389 g_signal_connect_swapped(button, "clicked",
1390 G_CALLBACK(queue_remove), ptr);
1392
1397 gtk_grid_attach(GTK_GRID(table), sw, 0, 1, 2, 1);
1398
1404 gtk_widget_set_name(dst_view_depr, "small_font");
1406
1410 g_signal_connect(controller, "pressed",
1413
1416
1418 "use-underline", TRUE,
1419 "mnemonic-widget", dst_view_depr,
1420 "label", _("Target _Worklist:"),
1421 "xalign", 0.0, "yalign", 0.5, NULL);
1422 gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
1423
1424 /* Add bottom menu and buttons. */
1428
1429 ptr->menu = NULL;
1432 menu = create_wl_menu(ptr);
1434
1437
1438 button = icon_label_button_new("help-browser", _("Help"));
1439 gtk_box_append(GTK_BOX(bbox), button);
1440 g_signal_connect(button, "clicked",
1442 ptr->help_cmd = button;
1444
1445 button = gtk_button_new_with_mnemonic(_("Change Prod_uction"));
1446 gtk_box_append(GTK_BOX(bbox), button);
1447 g_signal_connect(button, "clicked",
1449 ptr->change_cmd = button;
1451
1457
1458 /* DND and other state changing callbacks. */
1460
1462
1465
1467 g_signal_connect(controller, "key-pressed",
1470
1472 g_signal_connect(controller, "key-pressed",
1475
1476 g_signal_connect(src_view_depr, "row_activated",
1478
1479 g_signal_connect(dst_view_depr, "row_activated",
1481
1482 g_signal_connect(ptr->src_selection_depr, "changed",
1484 g_signal_connect(ptr->dst_selection_depr, "changed",
1486
1487
1490
1491 return editor;
1492}
1493
1494/************************************************************************/
1498 double x, double y,
1499 gpointer data)
1500{
1501 GtkTreeIter it;
1502 struct worklist_data *ptr = (struct worklist_data *)data;
1503
1505 gint id;
1507
1508 gtk_tree_model_get(GTK_TREE_MODEL(ptr->src_depr), &it, 0, &id, -1);
1509
1511
1513
1514 return provider;
1515 }
1516
1517 return NULL;
1518}
1519
1520/************************************************************************/
1524 gpointer *data)
1525{
1527 GValue val = { 0, };
1529 cid id;
1530 struct universal target;
1531 struct sprite *sprite;
1532 GdkPixbuf *pix;
1533 GtkWidget *img;
1534
1535 g_value_init(&val, G_TYPE_INT);
1536 if (gdk_content_provider_get_value(content, &val, NULL)) {
1537 id = g_value_get_int(&val);
1538 target = cid_production(id);
1539
1540 if (VUT_UTYPE == target.kind) {
1545 } else {
1547 }
1550
1552
1555 }
1556}
1557
1558/************************************************************************/
1562{
1563 struct worklist_data *ptr;
1565
1566 ptr = g_object_get_data(G_OBJECT(editor), "data");
1567
1568 ptr->global_worklist_id = -1;
1569 ptr->pcity = pcity;
1570
1573
1574 g_object_set(ptr->src_col, "visible", TRUE, NULL);
1575 g_object_set(ptr->dst_col, "visible", TRUE, NULL);
1576
1578
1580 g_signal_connect(dnd_src, "drag-begin", G_CALLBACK(drag_begin), ptr);
1581
1584}
1585
1586/************************************************************************/
1590 struct global_worklist *pgwl)
1591{
1592 struct worklist_data *ptr;
1593
1594 ptr = g_object_get_data(G_OBJECT(editor), "data");
1595
1597 ptr->pcity = nullptr;
1598
1601
1603 g_object_set(ptr->src_col, "visible", FALSE, NULL);
1604 g_object_set(ptr->dst_col, "visible", FALSE, NULL);
1605
1607}
1608
1609/************************************************************************/
1613{
1614 struct worklist_data *ptr;
1615 struct worklist queue;
1616 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
1617 int i, targets_used;
1618 struct item items[MAX_NUM_PRODUCTION_TARGETS];
1619 bool selected;
1620 gint id;
1621 GtkTreeIter it;
1622 GtkTreePath *path;
1625
1626 ptr = g_object_get_data(G_OBJECT(editor), "data");
1627
1628 /* Refresh source tasks. */
1630 gtk_tree_model_get(GTK_TREE_MODEL(ptr->src_depr), &it, 0, &id, -1);
1631 selected = TRUE;
1632 } else {
1633 selected = FALSE;
1634 }
1635
1636 /* These behave just right if ptr->pcity is NULL -> in case of global
1637 * worklist. */
1639 ptr->future);
1640 name_and_sort_items(targets, targets_used, items, FALSE, ptr->pcity);
1641
1642 /* Re-purpose existing items in the list store -- this avoids the
1643 * UI jumping around (especially as the set of source tasks doesn't
1644 * actually change much in practice). */
1647
1648 path = NULL;
1649 for (i = 0; i < targets_used; i++) {
1650 char buf[8192];
1651
1652 if (!exists) {
1654 }
1655
1656 gtk_list_store_set(ptr->src_depr, &it, 0, (gint)cid_encode(items[i].item),
1657 1, production_help(&(items[i].item),
1658 buf, sizeof(buf)), -1);
1659
1660 if (selected && cid_encode(items[i].item) == id) {
1662 }
1663
1664 if (exists) {
1666 }
1667 }
1668
1669 /* If the list got shorter, delete any excess items. */
1670 if (exists) {
1672 bool more;
1673
1674 do {
1675 it_next = it;
1677
1679 it = it_next;
1680 } while (more);
1681 }
1682
1683 /* Select the same item that was previously selected, if any. */
1684 if (path) {
1686 gtk_tree_path_free(path);
1687 }
1688
1689 /* Refresh target worklist. */
1692
1693 /* Dance around worklist braindamage. */
1694 if (ptr->pcity != NULL) {
1695 city_get_queue(ptr->pcity, &queue);
1696 } else {
1697 const struct global_worklist *pgwl;
1698
1700
1701 fc_assert(NULL != pgwl);
1702
1704 }
1705
1706 for (i = 0; i < worklist_length(&queue); i++) {
1707 struct universal target = queue.entries[i];
1708 char buf[8192];
1709
1710 if (!exists) {
1712 }
1713
1714 gtk_list_store_set(ptr->dst_depr, &it, 0, (gint)cid_encode(target),
1715 1, production_help(&target,
1716 buf, sizeof(buf)), -1);
1717
1718 if (exists) {
1720 }
1721 }
1722
1723 if (exists) {
1725 bool more;
1726
1727 do {
1728 it_next = it;
1730
1732 it = it_next;
1733 } while (more);
1734 }
1735
1736 create_wl_menu(ptr);
1737
1738 /* Update widget sensitivity. */
1739 if (ptr->pcity) {
1741 && city_owner(ptr->pcity) == client.conn.playing)) {
1743 } else {
1745 }
1746 } else {
1748 }
1749}
1750
1751/************************************************************************/
1754static void commit_worklist(struct worklist_data *ptr)
1755{
1756 struct worklist queue;
1758 GtkTreeIter it;
1759 size_t i;
1760
1762
1763 worklist_init(&queue);
1764
1765 i = 0;
1767 do {
1768 gint id;
1769 struct universal univ;
1770
1771 /* Oops, the player has a worklist longer than what we can store. */
1772 if (i >= MAX_LEN_WORKLIST) {
1773 break;
1774 }
1775
1776 gtk_tree_model_get(model_depr, &it, 0, &id, -1);
1777 univ = cid_production(id);
1778 worklist_append(&queue, &univ);
1779
1780 i++;
1781 } while (gtk_tree_model_iter_next(model_depr, &it));
1782 }
1783
1784 /* Dance around worklist braindamage. */
1785 if (ptr->pcity) {
1786 if (!city_set_queue(ptr->pcity, &queue)) {
1787 /* Failed to change worklist. This means worklist visible
1788 * on screen is not true. */
1790 }
1791 } else {
1792 struct global_worklist *pgwl;
1793
1795 if (pgwl) {
1796 global_worklist_set(pgwl, &queue);
1797 }
1798 }
1799}
#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)
static struct ai_type * self
Definition classicai.c:46
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
static GtkWidget * source
Definition gotodlg.c:58
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
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 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 help_callback(GtkWidget *w, gpointer data)
Definition wldlg.c:521
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
static void popup_worklist(struct global_worklist *pgwl)
Definition wldlg.c:385
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 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
void refresh_all_city_worklists(void)
Definition citydlg.c:3735
GtkWidget * aux_menu_new(void)
Definition gui_stuff.c:244
#define menu_item_insert_unref(menu, index, item)
Definition gui_stuff.h:142
static void drag_begin(GtkDragSource *source, GdkDrag *drag, gpointer *data)
Definition wldlg.c:1395
static gboolean wl_right_button_up(GtkGestureClick *gesture, int n_press, double x, double y)
Definition wldlg.c:1076
static void wl_help_from_iter(GtkTreeModel *model, GtkTreeIter *it)
Definition wldlg.c:543
static GMenu * create_wl_menu(struct worklist_data *ptr)
Definition wldlg.c:486
static GdkContentProvider * drag_prepare(GtkDragSource *source, double x, double y, gpointer data)
Definition wldlg.c:1369
static gboolean drag_drop(GtkDropTarget *target, const GValue *value, double x, double y, gpointer data)
Definition wldlg.c:1102
static void dst_row_callback_depr(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
Definition wldlg.c:891
static GtkSingleSelection * worklists_selection
Definition wldlg.c:65
static void fc_wlmeta_row_init(FcWlmetaRow *self)
Definition wldlg.c:157
static void src_row_callback_depr(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
Definition wldlg.c:857
static void fc_worklist_row_class_init(FcWorklistRowClass *klass)
Definition wldlg.c:119
static void src_selection_callback_depr(GtkTreeSelection *selection, gpointer data)
Definition wldlg.c:987
#define FC_TYPE_WORKLIST_ROW
Definition wldlg.c:76
static void fc_worklist_row_init(FcWorklistRow *self)
Definition wldlg.c:127
static FcWlmetaRow * fc_wlmeta_row_new(void)
Definition wldlg.c:164
static void wlmeta_factory_setup(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition wldlg.c:312
static void wlmeta_factory_bind(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition wldlg.c:294
static void fc_wlmeta_row_class_init(FcWlmetaRowClass *klass)
Definition wldlg.c:149
#define FC_TYPE_WLMETA_ROW
Definition wldlg.c:96
static void worklist_factory_setup(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition wldlg.c:1235
static void dst_selection_callback_depr(GtkTreeSelection *selection, gpointer data)
Definition wldlg.c:1018
static void worklist_factory_bind(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition wldlg.c:1220
#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
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
GObjectClass parent_class
Definition wldlg.c:110
GObject parent_instance
Definition wldlg.c:102
const char * name
Definition wldlg.c:104
GObjectClass parent_class
Definition wldlg.c:90
char * name
Definition wldlg.c:84
GObject parent_instance
Definition wldlg.c:82
Definition city.h:317
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:151
Definition mapimg.c:367
Definition climisc.h:82
enum universals_n kind
Definition fc_types.h:608
universals_u value
Definition fc_types.h:607
GtkListStore * dst_depr
Definition wldlg.c:403
GtkWidget * prepend_cmd
Definition wldlg.c:317
GActionGroup * group
Definition wldlg.c:311
GtkTreeSelection * dst_selection_depr
Definition wldlg.c:408
GtkWidget * src_view_depr
Definition wldlg.c:404
GtkTreeViewColumn * dst_col
Definition wldlg.c:314
int menu_size
Definition wldlg.c:310
GtkWidget * up_cmd
Definition wldlg.c:317
bool future
Definition wldlg.c:319
GtkTreeViewColumn * src_col
Definition wldlg.c:314
GtkWidget * dst_view_depr
Definition wldlg.c:404
GtkTreeSelection * src_selection_depr
Definition wldlg.c:408
GtkWidget * remove_cmd
Definition wldlg.c:317
GtkWidget * editor
Definition wldlg.c:308
GtkListStore * src_depr
Definition wldlg.c:403
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
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#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