Freeciv-3.4
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/gdk.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);
1075 if (pix != NULL) {
1077 }
1078 if (VUT_UTYPE == target.kind) {
1080 }
1081 } else {
1082 struct city **pcity = data;
1083 gint column;
1084 char *row[4];
1085 char buf[4][64];
1086 guint i;
1087 gboolean useless;
1088
1089 for (i = 0; i < ARRAY_SIZE(row); i++) {
1090 row[i] = buf[i];
1091 }
1093
1094 get_city_dialog_production_row(row, sizeof(buf[0]), &target, *pcity);
1095 g_object_set(rend, "text", row[column], NULL);
1096
1097 if (NULL != *pcity && VUT_IMPROVEMENT == target.kind) {
1098 useless = is_improvement_redundant(*pcity, target.value.building);
1099 /* Mark building redundant if we are really certain that there is
1100 * no use for it. */
1101 g_object_set(rend, "strikethrough", useless, NULL);
1102 } else {
1103 g_object_set(rend, "strikethrough", FALSE, NULL);
1104 }
1105 }
1106}
1107
1108/************************************************************************/
1113{
1114 static const char *titles[] =
1115 { N_("Type"), N_("Name"), N_("Info"), N_("Cost"), N_("Turns") };
1116
1117 static bool titles_done;
1118 guint i;
1121
1123
1124 /* Case i == 0 taken out of the loop to workaround gcc-4.2.1 bug
1125 * https://gcc.gnu.org/PR33381
1126 * Some values would 'stick' from i == 0 round. */
1127 i = 0;
1128
1130
1134
1136 if (max_unit_width == -1 || max_unit_height == -1) {
1138 }
1139 } else {
1140 g_object_set(col, "visible", FALSE, NULL);
1141 }
1144 }
1145
1146 for (i = 1; i < ARRAY_SIZE(titles); i++) {
1147 gint pos = i - 1;
1148
1151
1153 i, titles[i], rend,
1156
1157 if (pos >= 2) {
1158 g_object_set(G_OBJECT(rend), "xalign", 1.0, NULL);
1160 }
1161
1162 if (pos == 3) {
1163 *pcol = col;
1164 }
1167 }
1168 }
1169}
1170
1171/************************************************************************/
1175 int n_press,
1176 double x, double y)
1177{
1181 GtkTreePath *path;
1182 int bx, by;
1183
1185
1188
1189 if (gtk_tree_model_get_iter(model, &iter, path)) {
1190 wl_help_from_iter(model, &iter);
1191 }
1192 }
1193
1194 return TRUE;
1195}
1196
1197/************************************************************************/
1200static gboolean drag_drop(GtkDropTarget *target, const GValue *value,
1201 double x, double y, gpointer data)
1202{
1203 struct worklist_data *ptr = (struct worklist_data *)data;
1204 GtkTreeIter it;
1205 char buf[8192];
1206 cid id = g_value_get_int(value);
1207 struct universal univ;
1208
1209 univ = cid_production(id);
1211 gtk_list_store_set(ptr->dst_depr, &it, 0, id, 1,
1212 production_help(&univ, buf, sizeof(buf)), -1);
1213
1214 commit_worklist(ptr);
1215
1216 return TRUE;
1217}
1218
1219/**********************************************************************/
1233
1234/**********************************************************************/
1243
1244/************************************************************************/
1248{
1249 GtkWidget *editor, *table, *sw, *bbox;
1250 GtkWidget *src_view_depr, *dst_view_depr, *label, *button;
1252 GMenu *menu;
1253 GtkWidget *table2, *arrow, *check;
1257 struct worklist_data *ptr;
1258 int editor_row = 0;
1262
1263 ptr = fc_malloc(sizeof(*ptr));
1264
1267
1268 ptr->global_worklist_id = -1;
1269 ptr->pcity = NULL;
1270 ptr->src_depr = src_store_depr;
1271 ptr->dst_depr = dst_store_depr;
1272 ptr->future = FALSE;
1273
1276 nullptr);
1278 nullptr);
1279
1280 /* Create shell. */
1281 editor = gtk_grid_new();
1286 g_object_set_data(G_OBJECT(editor), "data", ptr);
1287
1288 ptr->editor = editor;
1289
1290 /* Add source and target lists. */
1291 table = gtk_grid_new();
1293
1295
1300 gtk_grid_attach(GTK_GRID(table), sw, 3, 1, 2, 1);
1301
1308 gtk_widget_set_name(src_view_depr, "small_font");
1310
1314 g_signal_connect(controller, "pressed",
1317
1320
1322 "use-underline", TRUE,
1323 "mnemonic-widget", src_view_depr,
1324 "label", _("Source _Tasks:"),
1325 "xalign", 0.0, "yalign", 0.5, NULL);
1326 gtk_grid_attach(GTK_GRID(table), label, 3, 0, 1, 1);
1327
1328 check = gtk_check_button_new_with_mnemonic(_("Show _Future Targets"));
1329 gtk_grid_attach(GTK_GRID(table), check, 4, 0, 1, 1);
1331
1332 table2 = gtk_grid_new();
1333 gtk_grid_attach(GTK_GRID(table), table2, 2, 1, 1, 1);
1334
1335 button = gtk_button_new();
1336 gtk_widget_set_margin_top(button, 24);
1337 gtk_widget_set_margin_bottom(button, 24);
1338 ptr->prepend_cmd = button;
1340 gtk_grid_attach(GTK_GRID(table2), button, 0, 0, 1, 1);
1341
1342 arrow = gtk_image_new_from_icon_name("pan-start-symbolic");
1343 gtk_button_set_child(GTK_BUTTON(button), arrow);
1344 g_signal_connect_swapped(button, "clicked",
1347
1348 button = gtk_button_new();
1349 ptr->up_cmd = button;
1351 gtk_grid_attach(GTK_GRID(table2), button, 0, 1, 1, 1);
1352
1353 arrow = gtk_image_new_from_icon_name("pan-up-symbolic");
1354 gtk_button_set_child(GTK_BUTTON(button), arrow);
1355 g_signal_connect_swapped(button, "clicked",
1358
1359 button = gtk_button_new();
1360 ptr->down_cmd = button;
1362 gtk_grid_attach(GTK_GRID(table2), button, 0, 2, 1, 1);
1363
1364 arrow = gtk_image_new_from_icon_name("pan-down-symbolic");
1365 gtk_button_set_child(GTK_BUTTON(button), arrow);
1366 g_signal_connect_swapped(button, "clicked",
1369
1370 button = gtk_button_new();
1371 gtk_widget_set_margin_top(button, 24);
1372 gtk_widget_set_margin_bottom(button, 24);
1373 ptr->append_cmd = button;
1375 gtk_grid_attach(GTK_GRID(table2), button, 0, 3, 1, 1);
1376
1377 arrow = gtk_image_new_from_icon_name("pan-start-symbolic");
1378 gtk_button_set_child(GTK_BUTTON(button), arrow);
1379 g_signal_connect_swapped(button, "clicked",
1380 G_CALLBACK(queue_append), ptr);
1382
1383 button = gtk_button_new();
1384 gtk_widget_set_margin_top(button, 24);
1385 gtk_widget_set_margin_bottom(button, 24);
1386 ptr->remove_cmd = button;
1388 gtk_grid_attach(GTK_GRID(table2), button, 0, 4, 1, 1);
1389
1390 arrow = gtk_image_new_from_icon_name("pan-end-symbolic");
1391 gtk_button_set_child(GTK_BUTTON(button), arrow);
1392 g_signal_connect_swapped(button, "clicked",
1393 G_CALLBACK(queue_remove), ptr);
1395
1400 gtk_grid_attach(GTK_GRID(table), sw, 0, 1, 2, 1);
1401
1408 gtk_widget_set_name(dst_view_depr, "small_font");
1410
1414 g_signal_connect(controller, "pressed",
1417
1420
1422 "use-underline", TRUE,
1423 "mnemonic-widget", dst_view_depr,
1424 "label", _("Target _Worklist:"),
1425 "xalign", 0.0, "yalign", 0.5, NULL);
1426 gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
1427
1428 /* Add bottom menu and buttons. */
1432
1433 ptr->menu = NULL;
1436 menu = create_wl_menu(ptr);
1438
1441
1442 button = icon_label_button_new("help-browser", _("Help"));
1443 gtk_box_append(GTK_BOX(bbox), button);
1444 g_signal_connect(button, "clicked",
1446 ptr->help_cmd = button;
1448
1449 button = gtk_button_new_with_mnemonic(_("Change Prod_uction"));
1450 gtk_box_append(GTK_BOX(bbox), button);
1451 g_signal_connect(button, "clicked",
1453 ptr->change_cmd = button;
1455
1461
1462 /* DND and other state changing callbacks. */
1464
1466
1469
1471 g_signal_connect(controller, "key-pressed",
1474
1476 g_signal_connect(controller, "key-pressed",
1479
1480 g_signal_connect(src_view_depr, "row_activated",
1482
1483 g_signal_connect(dst_view_depr, "row_activated",
1485
1486 g_signal_connect(ptr->src_selection_depr, "changed",
1488 g_signal_connect(ptr->dst_selection_depr, "changed",
1490
1491
1494
1495 return editor;
1496}
1497
1498/************************************************************************/
1502 double x, double y,
1503 gpointer data)
1504{
1505 GtkTreeIter it;
1506 struct worklist_data *ptr = (struct worklist_data *)data;
1507
1509 gint id;
1511
1512 gtk_tree_model_get(GTK_TREE_MODEL(ptr->src_depr), &it, 0, &id, -1);
1513
1515
1517
1518 return provider;
1519 }
1520
1521 return NULL;
1522}
1523
1524/************************************************************************/
1528 gpointer *data)
1529{
1531 GValue val = { 0, };
1533 cid id;
1534 struct universal target;
1535 struct sprite *sprite;
1536 GdkPixbuf *pix;
1537 GtkWidget *img;
1538
1539 g_value_init(&val, G_TYPE_INT);
1540 if (gdk_content_provider_get_value(content, &val, NULL)) {
1541 id = g_value_get_int(&val);
1542 target = cid_production(id);
1543
1544 if (VUT_UTYPE == target.kind) {
1549 } else {
1551 }
1554
1556
1559 }
1560}
1561
1562/************************************************************************/
1566{
1567 struct worklist_data *ptr;
1569
1570 ptr = g_object_get_data(G_OBJECT(editor), "data");
1571
1572 ptr->global_worklist_id = -1;
1573 ptr->pcity = pcity;
1574
1577
1578 g_object_set(ptr->src_col, "visible", TRUE, NULL);
1579 g_object_set(ptr->dst_col, "visible", TRUE, NULL);
1580
1582
1584 g_signal_connect(dnd_src, "drag-begin", G_CALLBACK(drag_begin), ptr);
1585
1588}
1589
1590/************************************************************************/
1594 struct global_worklist *pgwl)
1595{
1596 struct worklist_data *ptr;
1597
1598 ptr = g_object_get_data(G_OBJECT(editor), "data");
1599
1601 ptr->pcity = nullptr;
1602
1605
1607 g_object_set(ptr->src_col, "visible", FALSE, NULL);
1608 g_object_set(ptr->dst_col, "visible", FALSE, NULL);
1609
1611}
1612
1613/************************************************************************/
1617{
1618 struct worklist_data *ptr;
1619 struct worklist queue;
1620 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
1621 int i, targets_used;
1622 struct item items[MAX_NUM_PRODUCTION_TARGETS];
1623 bool selected;
1624 gint id;
1625 GtkTreeIter it;
1626 GtkTreePath *path;
1629
1630 ptr = g_object_get_data(G_OBJECT(editor), "data");
1631
1632 /* Refresh source tasks. */
1634 gtk_tree_model_get(GTK_TREE_MODEL(ptr->src_depr), &it, 0, &id, -1);
1635 selected = TRUE;
1636 } else {
1637 selected = FALSE;
1638 }
1639
1640 /* These behave just right if ptr->pcity is NULL -> in case of global
1641 * worklist. */
1643 ptr->future);
1644 name_and_sort_items(targets, targets_used, items, FALSE, ptr->pcity);
1645
1646 /* Re-purpose existing items in the list store -- this avoids the
1647 * UI jumping around (especially as the set of source tasks doesn't
1648 * actually change much in practice). */
1651
1652 path = NULL;
1653 for (i = 0; i < targets_used; i++) {
1654 char buf[8192];
1655
1656 if (!exists) {
1658 }
1659
1660 gtk_list_store_set(ptr->src_depr, &it, 0, (gint)cid_encode(items[i].item),
1661 1, production_help(&(items[i].item),
1662 buf, sizeof(buf)), -1);
1663
1664 if (selected && cid_encode(items[i].item) == id) {
1666 }
1667
1668 if (exists) {
1670 }
1671 }
1672
1673 /* If the list got shorter, delete any excess items. */
1674 if (exists) {
1676 bool more;
1677
1678 do {
1679 it_next = it;
1681
1683 it = it_next;
1684 } while (more);
1685 }
1686
1687 /* Select the same item that was previously selected, if any. */
1688 if (path) {
1690 gtk_tree_path_free(path);
1691 }
1692
1693 /* Refresh target worklist. */
1696
1697 /* Dance around worklist braindamage. */
1698 if (ptr->pcity != NULL) {
1699 city_get_queue(ptr->pcity, &queue);
1700 } else {
1701 const struct global_worklist *pgwl;
1702
1704
1705 fc_assert(NULL != pgwl);
1706
1708 }
1709
1710 for (i = 0; i < worklist_length(&queue); i++) {
1711 struct universal target = queue.entries[i];
1712 char buf[8192];
1713
1714 if (!exists) {
1716 }
1717
1718 gtk_list_store_set(ptr->dst_depr, &it, 0, (gint)cid_encode(target),
1719 1, production_help(&target,
1720 buf, sizeof(buf)), -1);
1721
1722 if (exists) {
1724 }
1725 }
1726
1727 if (exists) {
1729 bool more;
1730
1731 do {
1732 it_next = it;
1734
1736 it = it_next;
1737 } while (more);
1738 }
1739
1740 create_wl_menu(ptr);
1741
1742 /* Update widget sensitivity. */
1743 if (ptr->pcity) {
1745 && city_owner(ptr->pcity) == client.conn.playing)) {
1747 } else {
1749 }
1750 } else {
1752 }
1753}
1754
1755/************************************************************************/
1758static void commit_worklist(struct worklist_data *ptr)
1759{
1760 struct worklist queue;
1762 GtkTreeIter it;
1763 size_t i;
1764
1766
1767 worklist_init(&queue);
1768
1769 i = 0;
1771 do {
1772 gint id;
1773 struct universal univ;
1774
1775 /* Oops, the player has a worklist longer than what we can store. */
1776 if (i >= MAX_LEN_WORKLIST) {
1777 break;
1778 }
1779
1780 gtk_tree_model_get(model_depr, &it, 0, &id, -1);
1781 univ = cid_production(id);
1782 worklist_append(&queue, &univ);
1783
1784 i++;
1785 } while (gtk_tree_model_iter_next(model_depr, &it));
1786 }
1787
1788 /* Dance around worklist braindamage. */
1789 if (ptr->pcity) {
1790 if (!city_set_queue(ptr->pcity, &queue)) {
1791 /* Failed to change worklist. This means worklist visible
1792 * on screen is not true. */
1794 }
1795 } else {
1796 struct global_worklist *pgwl;
1797
1799 if (pgwl) {
1800 global_worklist_set(pgwl, &queue);
1801 }
1802 }
1803}
#define city_owner(_pcity_)
Definition city.h:564
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:47
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:821
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:77
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:77
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:32
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
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
@ 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 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:3792
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:1399
static gboolean wl_right_button_up(GtkGestureClick *gesture, int n_press, double x, double y)
Definition wldlg.c:1078
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:1373
static gboolean drag_drop(GtkDropTarget *target, const GValue *value, double x, double y, gpointer data)
Definition wldlg.c:1104
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:1237
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:1222
#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:318
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:595
universals_u value
Definition fc_types.h:594
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:925
#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:2169
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:7033
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:7055
const struct unit_type * utype
Definition fc_types.h:536
const struct impr_type * building
Definition fc_types.h:529
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1586
#define unit_type_iterate(_p)
Definition unittype.h:865
#define unit_type_iterate_end
Definition unittype.h:872
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