Freeciv-3.1
Loading...
Searching...
No Matches
repodlgs.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 <math.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include <gtk/gtk.h>
24#include <gdk/gdkkeysyms.h>
25
26/* utility */
27#include "fcintl.h"
28#include "log.h"
29#include "shared.h"
30#include "support.h"
31
32/* common */
33#include "fc_types.h" /* LINE_BREAK */
34#include "game.h"
35#include "government.h"
36#include "packets.h"
37#include "research.h"
38#include "tech.h"
39#include "unitlist.h"
40
41/* client */
42#include "chatline_common.h"
43#include "client_main.h"
44#include "climisc.h"
45#include "control.h"
46#include "mapview_common.h"
47#include "options.h"
48#include "packhand_gen.h"
49#include "control.h"
50#include "reqtree.h"
51#include "text.h"
52
53/* client/gui-gtk-3.22 */
54#include "canvas.h"
55#include "cityrep.h"
56#include "dialogs.h"
57#include "gui_main.h"
58#include "gui_stuff.h"
59#include "helpdlg.h"
60#include "plrdlg.h"
61#include "sprite.h"
62
63#include "repodlgs.h"
64
65
66/****************************************************************************
67 RESEARCH REPORT DIALOG
68****************************************************************************/
69struct science_report {
70 struct gui_dialog *shell;
71 GtkComboBox *reachable_techs;
72 GtkComboBox *reachable_goals;
73 GtkWidget *button_show_all;
74 GtkLabel *main_label; /* Gets science_dialog_text(). */
75 GtkProgressBar *progress_bar;
76 GtkLabel *goal_label;
77 GtkLayout *drawing_area;
78};
79
80static GtkListStore *science_report_store_new(void);
81static inline void science_report_store_set(GtkListStore *store,
82 GtkTreeIter *iter,
83 Tech_type_id tech);
84static bool science_report_combo_get_active(GtkComboBox *combo,
85 Tech_type_id *tech,
86 char **name);
87static void science_report_combo_set_active(GtkComboBox *combo,
88 Tech_type_id tech);
89static gboolean science_diagram_button_release_callback(GtkWidget *widget,
90 GdkEventButton *event, gpointer data);
91static gboolean science_diagram_update(GtkWidget *widget,
92 cairo_t *cr,
93 gpointer data);
94static GtkWidget *science_diagram_new(void);
95static void science_diagram_data(GtkWidget *widget, bool show_all);
96static void science_diagram_center(GtkWidget *diagram, Tech_type_id tech);
97static void science_report_redraw(struct science_report *preport);
98static gint cmp_func(gconstpointer a_p, gconstpointer b_p);
99static void science_report_update(struct science_report *preport);
100static void science_report_current_callback(GtkComboBox *combo,
101 gpointer data);
102static void science_report_show_all_callback(GtkComboBox *combo,
103 gpointer data);
104static void science_report_goal_callback(GtkComboBox *combo, gpointer data);
105static void science_report_init(struct science_report *preport);
106static void science_report_free(struct science_report *preport);
107
108static struct science_report science_report = { NULL, };
110
111/* Those values must match the function science_report_store_new(). */
115
116 /* Not visible. */
117 SRD_COL_ID, /* Tech_type_id */
118
121
122/************************************************************************/
125static GtkListStore *science_report_store_new(void)
126{
127 return gtk_list_store_new(SRD_COL_NUM,
128 G_TYPE_STRING, /* SRD_COL_NAME */
129 G_TYPE_INT, /* SRD_COL_STEPS */
130 G_TYPE_INT); /* SRD_COL_ID */
131}
132
133/************************************************************************/
136static inline void science_report_store_set(GtkListStore *store,
137 GtkTreeIter *iter,
138 Tech_type_id tech)
139{
140 const struct research *presearch = research_get(client_player());
141
142 gtk_list_store_set(store, iter,
144 research_advance_name_translation(presearch, tech),
146 research_goal_unknown_techs(presearch, tech),
147 SRD_COL_ID, tech,
148 -1);
149}
150
151/************************************************************************/
154static bool science_report_combo_get_active(GtkComboBox *combo,
155 Tech_type_id *tech,
156 char **name)
157{
158 GtkTreeIter iter;
159
161 || !gtk_combo_box_get_active_iter(combo, &iter)) {
162 return FALSE;
163 }
164
165 gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter,
167 SRD_COL_ID, tech,
168 -1);
169 return TRUE;
170}
171
172/************************************************************************/
175static void science_report_combo_set_active(GtkComboBox *combo,
176 Tech_type_id tech)
177{
178 ITree iter;
179 Tech_type_id iter_tech;
180
181 for (itree_begin(gtk_combo_box_get_model(combo), &iter);
182 !itree_end(&iter); itree_next(&iter)) {
183 itree_get(&iter, SRD_COL_ID, &iter_tech, -1);
184 if (iter_tech == tech) {
186 gtk_combo_box_set_active_iter(combo, &iter.it);
188 return;
189 }
190 }
191 log_error("%s(): Tech %d not found in the combo.", __FUNCTION__, tech);
192}
193
194/************************************************************************/
198 GdkEventButton *event, gpointer data)
199{
200 const struct research *presearch = research_get(client_player());
201 struct reqtree *reqtree = g_object_get_data(G_OBJECT(widget), "reqtree");
203
204 if (tech == A_NONE) {
205 return TRUE;
206 }
207
208 if (event->button == 3) {
209 /* RMB: get help */
211 tech),
212 HELP_TECH);
213 } else {
214 if (event->button == 1 && can_client_issue_orders()) {
215 /* LMB: set research or research goal */
217 tech)) {
218 case TECH_PREREQS_KNOWN:
220 break;
221 case TECH_UNKNOWN:
223 break;
224 case TECH_KNOWN:
225 break;
226 }
227 }
228 }
229 return TRUE;
230}
231
232/************************************************************************/
235static gboolean science_diagram_update(GtkWidget *widget, cairo_t *cr, gpointer data)
236{
237 /* FIXME: this currently redraws everything! */
239 struct reqtree *reqtree = g_object_get_data(G_OBJECT(widget), "reqtree");
240 int width, height;
241 GtkAdjustment *hadjustment;
242 GtkAdjustment *vadjustment;
243 gint hadjustment_value;
244 gint vadjustment_value;
245
247 return TRUE;
248 }
249
250 hadjustment = gtk_scrollable_get_hadjustment(GTK_SCROLLABLE(widget));
251 vadjustment = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(widget));
252
253 hadjustment_value = (gint)gtk_adjustment_get_value(hadjustment);
254 vadjustment_value = (gint)gtk_adjustment_get_value(vadjustment);
255
256 cairo_translate(cr, -hadjustment_value, -vadjustment_value);
257
258 canvas.drawable = cr;
259
261 draw_reqtree(reqtree, &canvas, 0, 0, 0, 0, width, height);
262
263 return TRUE;
264}
265
266/************************************************************************/
270static GtkWidget *science_diagram_new(void)
271{
272 GtkWidget *diagram;
273
274 diagram = gtk_layout_new(NULL, NULL);
275 gtk_widget_add_events(diagram,
276 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
277 | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK);
278 g_signal_connect(diagram, "draw",
279 G_CALLBACK(science_diagram_update), NULL);
280 g_signal_connect(diagram, "button-release-event",
282 NULL);
283
284 return diagram;
285}
286
287/************************************************************************/
290static void science_diagram_data(GtkWidget *widget, bool show_all)
291{
292 struct reqtree *reqtree;
293 int width, height;
294
295 if (can_conn_edit(&client.conn)) {
296 /* Show all techs in editor mode, not only currently reachable ones */
297 reqtree = create_reqtree(NULL, TRUE);
298 } else {
299 /* Show only at some point reachable techs */
300 reqtree = create_reqtree(client_player(), show_all);
301 }
302
304 gtk_layout_set_size(GTK_LAYOUT(widget), width, height);
305 g_object_set_data_full(G_OBJECT(widget), "reqtree", reqtree,
306 (GDestroyNotify) destroy_reqtree);
307}
308
309/************************************************************************/
312static void science_diagram_center(GtkWidget *diagram, Tech_type_id tech)
313{
314 GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW(gtk_widget_get_parent(diagram));
315 struct reqtree *reqtree;
316 int x, y, width, height;
317
318 if (!GTK_IS_SCROLLED_WINDOW(sw)) {
319 return;
320 }
321
322 reqtree = g_object_get_data(G_OBJECT(diagram), "reqtree");
324 if (find_tech_on_reqtree(reqtree, tech, &x, &y, NULL, NULL)) {
325 GtkAdjustment *adjust = NULL;
326 gdouble value;
327
328 adjust = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(sw));
329 value = (gtk_adjustment_get_lower(adjust)
330 + gtk_adjustment_get_upper(adjust)
331 - gtk_adjustment_get_page_size(adjust)) / width * x;
332 gtk_adjustment_set_value(adjust, value);
333
334 adjust = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(sw));
335 value = (gtk_adjustment_get_lower(adjust)
336 + gtk_adjustment_get_upper(adjust)
337 - gtk_adjustment_get_page_size(adjust)) / height * y;
338 gtk_adjustment_set_value(adjust, value);
339 }
340}
341
342/************************************************************************/
345static void science_report_redraw(struct science_report *preport)
346{
347 Tech_type_id researching;
348
349 fc_assert_ret(NULL != preport);
350
351 science_diagram_data(GTK_WIDGET(preport->drawing_area),
352 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
353 preport->button_show_all)));
354
355 if (client_has_player()) {
356 researching = research_get(client_player())->researching;
357 } else {
358 researching = A_UNSET;
359 }
360 science_diagram_center(GTK_WIDGET(preport->drawing_area), researching);
361
362 gtk_widget_queue_draw(GTK_WIDGET(preport->drawing_area));
363}
364
365/************************************************************************/
368static gint cmp_func(gconstpointer a_p, gconstpointer b_p)
369{
370 const gchar *a_str, *b_str;
371 gint a = GPOINTER_TO_INT(a_p), b = GPOINTER_TO_INT(b_p);
372 const struct research *presearch = research_get(client_player());
373
374 a_str = research_advance_name_translation(presearch, a);
375 b_str = research_advance_name_translation(presearch, b);
376
377 return fc_strcoll(a_str, b_str);
378}
379
380/************************************************************************/
383static void science_report_update(struct science_report *preport)
384{
385 GtkListStore *store;
386 GtkTreeIter iter;
387 GList *sorting_list, *item;
388 struct research *presearch = research_get(client_player());
389 const char *text;
390 double pct;
391 Tech_type_id tech;
392
393 fc_assert_ret(NULL != preport);
394 fc_assert_ret(NULL != presearch);
395
396 /* Disable callbacks. */
398
399 gtk_widget_queue_draw(GTK_WIDGET(preport->drawing_area));
400
401 gtk_label_set_text(preport->main_label, science_dialog_text());
402
403 /* Update the progress bar. */
404 text = get_science_target_text(&pct);
405 gtk_progress_bar_set_text(preport->progress_bar, text);
406 gtk_progress_bar_set_fraction(preport->progress_bar, pct);
407 /* Work around GTK+ refresh bug? */
408 gtk_widget_queue_resize(GTK_WIDGET(preport->progress_bar));
409
410 /* Update reachable techs. */
411 store = GTK_LIST_STORE(gtk_combo_box_get_model(preport->reachable_techs));
412 gtk_list_store_clear(store);
413 sorting_list = NULL;
414
415 /* Collect all techs which are reachable in the next step. */
417 if (TECH_PREREQS_KNOWN == presearch->inventions[i].state) {
418 sorting_list = g_list_prepend(sorting_list, GINT_TO_POINTER(i));
419 }
421
422 if (sorting_list != NULL) {
423 if (A_UNSET == presearch->researching
424 || is_future_tech(presearch->researching)) {
425 gtk_list_store_append(store, &iter);
426 science_report_store_set(store, &iter, presearch->researching);
427 gtk_combo_box_set_active_iter(preport->reachable_techs, &iter);
428 }
429
430 /* Sort the list, append it to the store. */
431 sorting_list = g_list_sort(sorting_list, cmp_func);
432 for (item = sorting_list; NULL != item; item = g_list_next(item)) {
433 tech = GPOINTER_TO_INT(item->data);
434 gtk_list_store_append(store, &iter);
435 science_report_store_set(store, &iter, tech);
436 if (tech == presearch->researching) {
437 gtk_combo_box_set_active_iter(preport->reachable_techs, &iter);
438 }
439 }
440
441 /* Free, re-init. */
442 g_list_free(sorting_list);
443 sorting_list = NULL;
444 } else {
445 /* No reachable normal techs. Can we select Future Tech? */
446 Tech_type_id next;
447
448 gtk_list_store_append(store, &iter);
449 if (research_future_next(presearch)) {
450 next = A_FUTURE;
451 } else {
452 next = presearch->researching;
453 }
454 science_report_store_set(store, &iter, next);
455
456 gtk_combo_box_set_active_iter(preport->reachable_techs, &iter);
457 }
458
459 store = GTK_LIST_STORE(gtk_combo_box_get_model(preport->reachable_goals));
460 gtk_list_store_clear(store);
461
462 /* Update the tech goal. */
463 gtk_label_set_text(preport->goal_label,
464 get_science_goal_text(presearch->tech_goal));
465
466 /* Collect all techs which are reachable in next 10 steps. */
468 if (research_invention_reachable(presearch, i)
469 && TECH_KNOWN != presearch->inventions[i].state
470 && (i == presearch->tech_goal
471 || 10 >= presearch->inventions[i].num_required_techs)) {
472 sorting_list = g_list_prepend(sorting_list, GINT_TO_POINTER(i));
473 }
475
476 if (sorting_list != NULL) {
477 if (A_UNSET == presearch->tech_goal) {
478 gtk_list_store_append(store, &iter);
479 science_report_store_set(store, &iter, A_UNSET);
480 gtk_combo_box_set_active_iter(preport->reachable_goals, &iter);
481 }
482
483 /* Sort the list, append it to the store. */
484 sorting_list = g_list_sort(sorting_list, cmp_func);
485 for (item = sorting_list; NULL != item; item = g_list_next(item)) {
486 tech = GPOINTER_TO_INT(item->data);
487 gtk_list_store_append(store, &iter);
488 science_report_store_set(store, &iter, tech);
489 if (tech == presearch->tech_goal) {
490 gtk_combo_box_set_active_iter(preport->reachable_goals, &iter);
491 }
492 }
493
494 /* Free. */
495 g_list_free(sorting_list);
496 } else {
497 /* No reachable normal techs. Can we select Future Tech? */
498 Tech_type_id goal;
499
500 gtk_list_store_append(store, &iter);
501
502 if (research_future_next(presearch)) {
503 goal = A_FUTURE;
504 } else {
505 goal = A_UNSET;
506 }
507
508 science_report_store_set(store, &iter, goal);
509 gtk_combo_box_set_active_iter(preport->reachable_goals, &iter);
510 }
511
512 /* Re-enable callbacks. */
514}
515
516/************************************************************************/
519static void science_report_current_callback(GtkComboBox *combo,
520 gpointer data)
521{
522 Tech_type_id tech;
523 char *tech_name;
524
525 if (!science_report_combo_get_active(combo, &tech, &tech_name)) {
526 return;
527 }
528
529 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data))) {
531 } else if (can_client_issue_orders()) {
533 }
534
535 free(tech_name);
536 /* Revert, or we will not be in sync with the server. */
539}
540
541/************************************************************************/
544static void science_report_show_all_callback(GtkComboBox *combo,
545 gpointer data)
546{
547 struct science_report *preport = (struct science_report *) data;
548
549 science_report_redraw(preport);
550}
551
552/************************************************************************/
555static void science_report_goal_callback(GtkComboBox *combo, gpointer data)
556{
557 Tech_type_id tech;
558 char *tech_name;
559
560 if (!science_report_combo_get_active(combo, &tech, &tech_name)) {
561 return;
562 }
563
564 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data))) {
566 } else if (can_client_issue_orders()) {
568 }
569
570 free(tech_name);
571 /* Revert, or we will not be in sync with the server. */
573 (client_player())->tech_goal);
574}
575
576/************************************************************************/
579static void science_report_init(struct science_report *preport)
580{
581 GtkWidget *frame, *table, *help_button, *show_all_button, *sw, *w;
582 GtkSizeGroup *group;
583 GtkContainer *vbox;
584 GtkListStore *store;
585 GtkCellRenderer *renderer;
586
587 fc_assert_ret(NULL != preport);
588
589 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), NULL, TRUE);
590 /* TRANS: Research report title */
591 gui_dialog_set_title(preport->shell, _("Research"));
592
593 gui_dialog_add_button(preport->shell, "window-close", _("_Close"),
594 GTK_RESPONSE_CLOSE);
595 gui_dialog_set_default_response(preport->shell, GTK_RESPONSE_CLOSE);
596
597 vbox = GTK_CONTAINER(preport->shell->vbox);
598 group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
599
600 w = gtk_label_new(NULL);
601 gtk_container_add(vbox, w);
602 preport->main_label = GTK_LABEL(w);
603
604 /* Current research target line. */
605 frame = gtk_frame_new(_("Researching"));
606 gtk_container_add(vbox, frame);
607
608 table = gtk_grid_new();
609 gtk_grid_set_column_spacing(GTK_GRID(table), 4);
610 gtk_container_add(GTK_CONTAINER(frame), table);
611
612 help_button = gtk_check_button_new_with_label(_("Help"));
613 gtk_grid_attach(GTK_GRID(table), help_button, 5, 0, 1, 1);
614
615 store = science_report_store_new();
616 w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
617 gtk_size_group_add_widget(group, w);
618 g_object_unref(G_OBJECT(store));
619 renderer = gtk_cell_renderer_text_new();
620 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), renderer, TRUE);
621 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(w), renderer, "text",
622 SRD_COL_NAME, NULL);
623 gtk_widget_set_sensitive(w, can_client_issue_orders());
624 g_signal_connect(w, "changed", G_CALLBACK(science_report_current_callback),
625 help_button);
626 gtk_grid_attach(GTK_GRID(table), w, 0, 0, 1, 1);
627 preport->reachable_techs = GTK_COMBO_BOX(w);
628
629 w = gtk_progress_bar_new();
630 gtk_widget_set_hexpand(w, TRUE);
631 gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(w), TRUE);
632 gtk_grid_attach(GTK_GRID(table), w, 2, 0, 1, 1);
633 gtk_widget_set_size_request(w, -1, 25);
634 preport->progress_bar = GTK_PROGRESS_BAR(w);
635
636 /* Research goal line. */
637 frame = gtk_frame_new( _("Goal"));
638 gtk_container_add(vbox, frame);
639
640 table = gtk_grid_new();
641 gtk_grid_set_column_spacing(GTK_GRID(table), 4);
642 gtk_container_add(GTK_CONTAINER(frame),table);
643
644 store = science_report_store_new();
645 w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
646 gtk_size_group_add_widget(group, w);
647 g_object_unref(G_OBJECT(store));
648 renderer = gtk_cell_renderer_text_new();
649 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), renderer, TRUE);
650 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(w), renderer, "text",
651 SRD_COL_NAME, NULL);
652 renderer = gtk_cell_renderer_text_new();
653 gtk_cell_layout_pack_end(GTK_CELL_LAYOUT(w), renderer, FALSE);
654 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(w), renderer, "text",
655 SRD_COL_STEPS, NULL);
656 gtk_widget_set_sensitive(w, can_client_issue_orders());
657 g_signal_connect(w, "changed", G_CALLBACK(science_report_goal_callback),
658 help_button);
659 gtk_grid_attach(GTK_GRID(table), w, 0, 0, 1, 1);
660 preport->reachable_goals = GTK_COMBO_BOX(w);
661
662 w = gtk_label_new(NULL);
663 gtk_widget_set_hexpand(w, TRUE);
664 gtk_grid_attach(GTK_GRID(table), w, 2, 0, 1, 1);
665 gtk_widget_set_size_request(w, -1, 25);
666 preport->goal_label = GTK_LABEL(w);
667
668 /* Toggle "Show All" button. */
669 /* TRANS: As in 'Show all (even not reachable) techs'. */
670 show_all_button = gtk_toggle_button_new_with_label(_("Show all"));
671 gtk_grid_attach(GTK_GRID(table), show_all_button, 5, 0, 1, 1);
672 g_signal_connect(show_all_button, "toggled",
673 G_CALLBACK(science_report_show_all_callback), preport);
674 gtk_widget_set_sensitive(show_all_button, can_client_issue_orders()
676 preport->button_show_all = show_all_button;
677
678 /* Science diagram. */
679 sw = gtk_scrolled_window_new(NULL, NULL);
680 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
681 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
682 gtk_container_add(vbox, sw);
683
685 gtk_widget_set_hexpand(w, TRUE);
686 gtk_widget_set_vexpand(w, TRUE);
687 gtk_container_add(GTK_CONTAINER(sw), w);
688 preport->drawing_area = GTK_LAYOUT(w);
689
690 science_report_update(preport);
691 gui_dialog_show_all(preport->shell);
692 gtk_widget_queue_draw(GTK_WIDGET(preport->drawing_area));
693 g_object_unref(group);
694
695 /* This must be _after_ the dialog is drawn to really center it ... */
696 science_report_redraw(preport);
697}
698
699/************************************************************************/
702static void science_report_free(struct science_report *preport)
703{
704 fc_assert_ret(NULL != preport);
705
706 gui_dialog_destroy(preport->shell);
707 fc_assert(NULL == preport->shell);
708
709 memset(preport, 0, sizeof(*preport));
710}
711
712/************************************************************************/
716{
717 struct research *presearch = research_get(client_player());
718
719 if (NULL == science_report.shell) {
721 }
722
723 if (NULL != presearch
724 && A_UNSET == presearch->tech_goal
725 && A_UNSET == presearch->researching) {
727 } else {
729 }
730
731 if (raise) {
733 }
734}
735
736/************************************************************************/
746
747/************************************************************************/
751{
752 if (NULL != science_report.shell) {
754 }
755}
756
757/************************************************************************/
761{
762 if (NULL != science_report.shell) {
764 }
765}
766
767
768/****************************************************************************
769 ECONOMY REPORT DIALOG
770****************************************************************************/
771struct economy_report {
772 struct gui_dialog *shell;
773 GtkTreeView *tree_view;
774 GtkLabel *label;
775};
776
777static struct economy_report economy_report = { NULL, NULL, NULL };
778
784
785/* Those values must match the functions economy_report_store_new() and
786 * economy_report_column_name(). */
802
803/************************************************************************/
806static GtkListStore *economy_report_store_new(void)
807{
808 return gtk_list_store_new(ERD_COL_NUM,
809 GDK_TYPE_PIXBUF, /* ERD_COL_SPRITE */
810 G_TYPE_STRING, /* ERD_COL_NAME */
811 G_TYPE_INT, /* ERD_COL_REDUNDANT */
812 G_TYPE_INT, /* ERD_COL_COUNT */
813 G_TYPE_INT, /* ERD_COL_COST */
814 G_TYPE_INT, /* ERD_COL_TOTAL_COST */
815 G_TYPE_STRING, /* ERD_COL_EMPTY */
816 G_TYPE_BOOLEAN, /* ERD_COL_IS_IMPROVEMENT */
817 G_TYPE_INT, /* ERD_COL_UNI_KIND */
818 G_TYPE_INT); /* ERD_COL_UNI_VALUE_ID */
819}
820
821/************************************************************************/
824static const char *
826{
827 switch (col) {
828 case ERD_COL_SPRITE:
829 /* TRANS: Image header */
830 return _("Type");
831 case ERD_COL_NAME:
832 return Q_("?Building or Unit type:Name");
834 return _("Redundant");
835 case ERD_COL_COUNT:
836 return _("Count");
837 case ERD_COL_COST:
838 return _("Cost");
840 /* TRANS: Upkeep total, count*cost. */
841 return _("U Total");
842 case ERD_COL_EMPTY:
843 /* empty space for scrollbar*/
844 return " ";
846 case ERD_COL_CID:
847 case ERD_COL_NUM:
848 break; /* no more columns will be displayed after reaching this */
849 }
850
851 return NULL;
852}
853
854/************************************************************************/
857static void economy_report_update(struct economy_report *preport)
858{
859 GtkTreeSelection *selection;
860 GtkTreeModel *model;
861 GtkListStore *store;
862 GtkTreeIter iter;
863 GdkPixbuf *pix;
864 struct improvement_entry building_entries[B_LAST];
865 struct unit_entry unit_entries[U_LAST];
866 int entries_used, building_total, unit_total, tax, i;
867 char buf[256];
868 cid selected;
869
870 fc_assert_ret(NULL != preport);
871
872 /* Save the selection. */
873 selection = gtk_tree_view_get_selection(preport->tree_view);
874 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
875 gtk_tree_model_get(model, &iter, ERD_COL_CID, &selected, -1);
876 } else {
877 selected = -1;
878 }
879
880 model = gtk_tree_view_get_model(preport->tree_view);
881 store = GTK_LIST_STORE(model);
882 gtk_list_store_clear(store);
883
884 /* Buildings. */
885 get_economy_report_data(building_entries, &entries_used,
886 &building_total, &tax);
887 for (i = 0; i < entries_used; i++) {
888 struct improvement_entry *pentry = building_entries + i;
889 struct impr_type *pimprove = pentry->type;
890 struct sprite *sprite = get_building_sprite(tileset, pimprove);
891 cid id = cid_encode_building(pimprove);
892
894 gtk_list_store_append(store, &iter);
895 gtk_list_store_set(store, &iter,
896 ERD_COL_SPRITE, pix,
899 ERD_COL_COUNT, pentry->count,
900 ERD_COL_COST, pentry->cost,
902 ERD_COL_EMPTY, " ",
904 ERD_COL_CID, id,
905 -1);
906 g_object_unref(G_OBJECT(pix));
907 if (selected == id) {
908 /* Restore the selection. */
909 gtk_tree_selection_select_iter(selection, &iter);
910 }
911 }
912
913 /* Units. */
914 get_economy_report_units_data(unit_entries, &entries_used, &unit_total);
915 for (i = 0; i < entries_used; i++) {
916 struct unit_entry *pentry = unit_entries + i;
917 struct unit_type *putype = pentry->type;
918 struct sprite *sprite = get_unittype_sprite(tileset, putype,
919 direction8_invalid());
920 cid id = cid_encode_unit(putype);
921
923 gtk_list_store_append(store, &iter);
924 gtk_list_store_set(store, &iter,
925 ERD_COL_SPRITE, pix,
928 ERD_COL_COUNT, pentry->count,
929 ERD_COL_COST, pentry->cost,
931 ERD_COL_EMPTY, " ",
933 ERD_COL_CID, id,
934 -1);
935 g_object_unref(G_OBJECT(pix));
936 if (selected == id) {
937 /* Restore the selection. */
938 gtk_tree_selection_select_iter(selection, &iter);
939 }
940 }
941
942 /* Update the label. */
943 fc_snprintf(buf, sizeof(buf), _("Income: %d Total Costs: %d"),
944 tax, building_total + unit_total);
945 gtk_label_set_text(preport->label, buf);
946}
947
948/************************************************************************/
951static void economy_report_command_callback(struct gui_dialog *pdialog,
952 int response,
953 gpointer data)
954{
955 struct economy_report *preport = data;
956 GtkTreeSelection *selection = gtk_tree_view_get_selection(preport->tree_view);
957 GtkTreeModel *model;
958 GtkTreeIter iter;
959 GtkWidget *shell;
960 struct universal selected;
961 cid id;
962 char buf[256] = "";
963
964 switch (response) {
966 case ERD_RES_SELL_ALL:
968 break;
969 default:
970 gui_dialog_destroy(pdialog);
971 return;
972 }
973
975 || !gtk_tree_selection_get_selected(selection, &model, &iter)) {
976 return;
977 }
978
979 gtk_tree_model_get(model, &iter, ERD_COL_CID, &id, -1);
980 selected = cid_decode(id);
981
982 switch (selected.kind) {
983 case VUT_IMPROVEMENT:
984 {
985 const struct impr_type *pimprove = selected.value.building;
986
987 if (can_sell_building(pimprove)
988 && (ERD_RES_SELL_ALL == response
989 || (ERD_RES_SELL_REDUNDANT == response))) {
990 bool redundant = (ERD_RES_SELL_REDUNDANT == response);
991 gint count;
992 gtk_tree_model_get(model, &iter,
993 redundant ? ERD_COL_REDUNDANT : ERD_COL_COUNT,
994 &count, -1);
995 if (count == 0) {
996 break;
997 }
998 shell = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL
999 | GTK_DIALOG_DESTROY_WITH_PARENT,
1000 GTK_MESSAGE_QUESTION,
1001 GTK_BUTTONS_YES_NO,
1002 redundant
1003 /* TRANS: %s is an improvement */
1004 ? _("Do you really wish to sell "
1005 "every redundant %s (%d total)?")
1006 /* TRANS: %s is an improvement */
1007 : _("Do you really wish to sell "
1008 "every %s (%d total)?"),
1010 count);
1012 gtk_window_set_title(GTK_WINDOW(shell), _("Sell Improvements"));
1013
1014 if (GTK_RESPONSE_YES == gtk_dialog_run(GTK_DIALOG(shell))) {
1015 sell_all_improvements(pimprove, redundant, buf, sizeof(buf));
1016 }
1017 gtk_widget_destroy(shell);
1018 }
1019 }
1020 break;
1021 case VUT_UTYPE:
1022 {
1023 if (ERD_RES_DISBAND_UNITS == response) {
1024 const struct unit_type *putype = selected.value.utype;
1025 gint count;
1026 gtk_tree_model_get(model, &iter, ERD_COL_COUNT, &count, -1);
1027
1028 shell = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL
1029 | GTK_DIALOG_DESTROY_WITH_PARENT,
1030 GTK_MESSAGE_QUESTION,
1031 GTK_BUTTONS_YES_NO,
1032 /* TRANS: %s is a unit */
1033 _("Do you really wish to disband "
1034 "every %s (%d total)?"),
1035 utype_name_translation(putype),
1036 count);
1038 gtk_window_set_title(GTK_WINDOW(shell), _("Disband Units"));
1039
1040 if (GTK_RESPONSE_YES == gtk_dialog_run(GTK_DIALOG(shell))) {
1041 disband_all_units(putype, FALSE, buf, sizeof(buf));
1042 }
1043 gtk_widget_destroy(shell);
1044 }
1045 }
1046 break;
1047 default:
1048 log_error("Not supported type: %d.", selected.kind);
1049 }
1050
1051 if ('\0' != buf[0]) {
1052 shell = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
1053 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
1054 "%s", buf);
1056 g_signal_connect(shell, "response", G_CALLBACK(gtk_widget_destroy),
1057 NULL);
1058 gtk_window_set_title(GTK_WINDOW(shell), _("Sell-Off: Results"));
1059 gtk_window_present(GTK_WINDOW(shell));
1060 }
1061}
1062
1063/************************************************************************/
1066static void economy_report_selection_callback(GtkTreeSelection *selection,
1067 gpointer data)
1068{
1069 struct gui_dialog *pdialog = ((struct economy_report *)data)->shell;
1070 GtkTreeModel *model;
1071 GtkTreeIter iter;
1072
1074 && gtk_tree_selection_get_selected(selection, &model, &iter)) {
1075 struct universal selected;
1076 cid id;
1077
1078 gtk_tree_model_get(model, &iter, ERD_COL_CID, &id, -1);
1079 selected = cid_decode(id);
1080 switch (selected.kind) {
1081 case VUT_IMPROVEMENT:
1082 {
1083 bool can_sell = can_sell_building(selected.value.building);
1084 gint redundant;
1085 gtk_tree_model_get(model, &iter, ERD_COL_REDUNDANT, &redundant, -1);
1086
1088 can_sell && redundant > 0);
1091 FALSE);
1092 }
1093 return;
1094 case VUT_UTYPE:
1096 FALSE);
1099 TRUE);
1100 return;
1101 default:
1102 log_error("Not supported type: %d.", selected.kind);
1103 break;
1104 }
1105 }
1106
1110}
1111
1112/************************************************************************/
1115static void economy_report_init(struct economy_report *preport)
1116{
1117 GtkWidget *view, *sw, *label, *button;
1118 GtkListStore *store;
1119 GtkTreeSelection *selection;
1120 GtkContainer *vbox;
1121 const char *title;
1123
1124 fc_assert_ret(NULL != preport);
1125
1126 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), preport, TRUE);
1127 gui_dialog_set_title(preport->shell, _("Economy"));
1128 vbox = GTK_CONTAINER(preport->shell->vbox);
1129
1130 sw = gtk_scrolled_window_new(NULL, NULL);
1131 gtk_widget_set_halign(sw, GTK_ALIGN_CENTER);
1132 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
1133 GTK_SHADOW_ETCHED_IN);
1134 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1135 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1136 gtk_container_add(GTK_CONTAINER(vbox), sw);
1137
1138 store = economy_report_store_new();
1139 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1140 gtk_widget_set_vexpand(view, TRUE);
1141 g_object_unref(store);
1142 gtk_widget_set_name(view, "small_font");
1143 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(view));
1144 gtk_container_add(GTK_CONTAINER(sw), view);
1145 preport->tree_view = GTK_TREE_VIEW(view);
1146
1147 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1148 g_signal_connect(selection, "changed",
1149 G_CALLBACK(economy_report_selection_callback), preport);
1150
1151 for (i = 0; (title = economy_report_column_name(i)); i++) {
1152 GtkCellRenderer *renderer;
1153 GtkTreeViewColumn *col;
1154 GType type = gtk_tree_model_get_column_type(GTK_TREE_MODEL(store), i);
1155
1156 if (GDK_TYPE_PIXBUF == type) {
1157 renderer = gtk_cell_renderer_pixbuf_new();
1158 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1159 "pixbuf", i, NULL);
1160#if 0
1161 } else if (G_TYPE_BOOLEAN == type) {
1162 renderer = gtk_cell_renderer_toggle_new();
1163 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1164 "active", i, NULL);
1165#endif
1166 } else {
1167 bool is_redundant = (i == ERD_COL_REDUNDANT);
1168 renderer = gtk_cell_renderer_text_new();
1169 if (is_redundant) {
1170 /* Special treatment: hide "Redundant" column for units */
1171 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1172 "text", i,
1173 "visible",
1175 NULL);
1176 } else {
1177 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1178 "text", i, NULL);
1179 }
1180 }
1181
1182 if (i > 1) {
1183 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
1184 gtk_tree_view_column_set_alignment(col, 1.0);
1185 }
1186
1187 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1188 }
1189
1190 label = gtk_label_new(NULL);
1191 gtk_container_add(vbox, label);
1192 gtk_widget_set_margin_start(label, 5);
1193 gtk_widget_set_margin_end(label, 5);
1194 gtk_widget_set_margin_top(label, 5);
1195 gtk_widget_set_margin_bottom(label, 5);
1196 preport->label = GTK_LABEL(label);
1197
1198 gui_dialog_add_button(preport->shell, "window-close", _("_Close"),
1199 GTK_RESPONSE_CLOSE);
1200
1201 button = gui_dialog_add_button(preport->shell, NULL, _("_Disband"),
1203 gtk_widget_set_sensitive(button, FALSE);
1204
1205 button = gui_dialog_add_button(preport->shell, NULL, _("Sell _All"),
1207 gtk_widget_set_sensitive(button, FALSE);
1208
1209 button = gui_dialog_add_button(preport->shell, NULL, _("Sell _Redundant"),
1211 gtk_widget_set_sensitive(button, FALSE);
1212
1213 gui_dialog_set_default_response(preport->shell, GTK_RESPONSE_CLOSE);
1216
1217 gui_dialog_set_default_size(preport->shell, -1, 350);
1218 gui_dialog_show_all(preport->shell);
1219
1220 economy_report_update(preport);
1221
1222 gtk_tree_view_focus(GTK_TREE_VIEW(view));
1223}
1224
1225/************************************************************************/
1228static void economy_report_free(struct economy_report *preport)
1229{
1230 fc_assert_ret(NULL != preport);
1231
1232 gui_dialog_destroy(preport->shell);
1233 fc_assert(NULL == preport->shell);
1234
1235 memset(preport, 0, sizeof(*preport));
1236}
1237
1238/************************************************************************/
1242{
1243 if (NULL == economy_report.shell) {
1245 }
1246
1248 if (raise) {
1250 }
1251}
1252
1253/************************************************************************/
1257{
1258 if (NULL != economy_report.shell) {
1260 }
1261}
1262
1263/************************************************************************/
1267{
1268 if (NULL != economy_report.shell) {
1270 }
1271}
1272
1273
1274/****************************************************************************
1275 UNITS REPORT DIALOG
1276****************************************************************************/
1277struct units_report {
1278 struct gui_dialog *shell;
1279 GtkTreeView *tree_view;
1280};
1281
1282static struct units_report units_report = { NULL, NULL };
1283
1288
1289/* Those values must match the order of unit_report_columns[]. */
1309
1310static const struct {
1311 GType type;
1312 const char *title;
1313 const char *tooltip;
1316} unit_report_columns[] = {
1317 { /* URD_COL_UTYPE_NAME */ G_TYPE_STRING, N_("Unit Type"),
1318 NULL, FALSE, -1 },
1319 { /* URD_COL_UPGRADABLE */ G_TYPE_BOOLEAN, N_("?Upgradable unit [short]:U"),
1320 N_("Upgradable"), TRUE, URD_COL_UPG_VISIBLE },
1321 { /* URD_COL_N_UPGRADABLE */ G_TYPE_INT, "" /* merge with previous col */,
1322 NULL, TRUE, URD_COL_NUPG_VISIBLE },
1323 /* TRANS: "In progress" abbreviation. */
1324 { /* URD_COL_IN_PROGRESS */ G_TYPE_INT, N_("In-Prog"),
1325 N_("In progress"), TRUE, -1 },
1326 { /* URD_COL_ACTIVE */ G_TYPE_INT, N_("Active"),
1327 NULL, TRUE, -1 },
1328 { /* URD_COL_SHIELD */ G_TYPE_INT, N_("Shield"),
1329 N_("Total shield upkeep"), TRUE, -1 },
1330 { /* URD_COL_FOOD */ G_TYPE_INT, N_("Food"),
1331 N_("Total food upkeep"), TRUE, -1 },
1332 { /* URD_COL_GOLD */ G_TYPE_INT, N_("Gold"),
1333 N_("Total gold upkeep"), TRUE, -1 },
1334 { /* URD_COL_EMPTY */ G_TYPE_STRING, " ",
1335 " ", TRUE, -1 },
1336
1337 { /* URD_COL_TEXT_WEIGHT */ G_TYPE_INT, NULL /* ... */ },
1338 { /* URD_COL_UPG_VISIBLE */ G_TYPE_BOOLEAN, NULL /* ... */ },
1339 { /* URD_COL_NUPG_VISIBLE */ G_TYPE_BOOLEAN, NULL /* ... */ },
1340 { /* URD_COL_UTYPE_ID */ G_TYPE_INT, NULL /* ... */ }
1342
1343/************************************************************************/
1346static GtkListStore *units_report_store_new(void)
1347{
1348 int i;
1349 GType cols[URD_COL_NUM];
1351
1352 for (i=0; i<URD_COL_NUM; i++) {
1353 cols[i] = unit_report_columns[i].type;
1354 }
1355
1356 return gtk_list_store_newv(URD_COL_NUM, cols);
1357}
1358
1359/************************************************************************/
1362static void units_report_update(struct units_report *preport)
1363{
1364 struct urd_info {
1365 int active_count;
1366 int building_count;
1367 int upkeep[O_LAST];
1368 };
1369
1370 struct urd_info unit_array[utype_count()];
1371 struct urd_info unit_totals;
1372 struct urd_info *info;
1373 int total_upgradable_count = 0;
1374 GtkTreeSelection *selection;
1375 GtkTreeModel *model;
1376 GtkListStore *store;
1377 GtkTreeIter iter;
1378 Unit_type_id selected, utype_id;
1379
1380 fc_assert_ret(NULL != preport);
1381
1382 memset(unit_array, '\0', sizeof(unit_array));
1383 memset(&unit_totals, '\0', sizeof(unit_totals));
1384
1385 /* Count units. */
1386 players_iterate(pplayer) {
1387 if (client_has_player() && pplayer != client_player()) {
1388 continue;
1389 }
1390
1391 unit_list_iterate(pplayer->units, punit) {
1392 info = unit_array + utype_index(unit_type_get(punit));
1393
1394 if (0 != punit->homecity) {
1396 info->upkeep[o] += punit->upkeep[o];
1398 }
1399 info->active_count++;
1401 city_list_iterate(pplayer->cities, pcity) {
1402 if (VUT_UTYPE == pcity->production.kind) {
1403 int num_units;
1404 info = unit_array + utype_index(pcity->production.value.utype);
1405 /* Account for build slots in city */
1406 (void) city_production_build_units(pcity, TRUE, &num_units);
1407 /* Unit is in progress even if it won't be done this turn */
1408 num_units = MAX(num_units, 1);
1409 info->building_count += num_units;
1410 }
1413
1414 /* Save selection. */
1415 selection = gtk_tree_view_get_selection(preport->tree_view);
1416 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
1417 gtk_tree_model_get(model, &iter, URD_COL_UTYPE_ID, &selected, -1);
1418 } else {
1419 selected = -1;
1420 }
1421
1422 /* Make the store. */
1423 model = gtk_tree_view_get_model(preport->tree_view);
1424 store = GTK_LIST_STORE(model);
1425 gtk_list_store_clear(store);
1426
1427 unit_type_iterate(utype) {
1428 bool upgradable;
1429
1430 utype_id = utype_index(utype);
1431 info = unit_array + utype_id;
1432
1433 if (0 == info->active_count && 0 == info->building_count) {
1434 continue; /* We don't need a row for this type. */
1435 }
1436
1437 upgradable = client_has_player()
1438 && NULL != can_upgrade_unittype(client_player(), utype);
1439
1440 gtk_list_store_append(store, &iter);
1441 gtk_list_store_set(store, &iter,
1443 URD_COL_UPGRADABLE, upgradable,
1444 URD_COL_N_UPGRADABLE, 0, /* never displayed */
1445 URD_COL_IN_PROGRESS, info->building_count,
1446 URD_COL_ACTIVE, info->active_count,
1447 URD_COL_SHIELD, info->upkeep[O_SHIELD],
1448 URD_COL_FOOD, info->upkeep[O_FOOD],
1449 URD_COL_GOLD, info->upkeep[O_GOLD],
1450 URD_COL_EMPTY, " ",
1451 URD_COL_TEXT_WEIGHT, PANGO_WEIGHT_NORMAL,
1454 URD_COL_UTYPE_ID, utype_id,
1455 -1);
1456 if (selected == utype_id) {
1457 /* Restore the selection. */
1458 gtk_tree_selection_select_iter(selection, &iter);
1459 }
1460
1461 /* Update totals. */
1462 unit_totals.active_count += info->active_count;
1464 unit_totals.upkeep[o] += info->upkeep[o];
1466 unit_totals.building_count += info->building_count;
1467 if (upgradable) {
1468 total_upgradable_count += info->active_count;
1469 }
1471
1472 /* Add the total row. */
1473 gtk_list_store_append(store, &iter);
1474 gtk_list_store_set(store, &iter,
1475 URD_COL_UTYPE_NAME, _("Totals:"),
1476 URD_COL_UPGRADABLE, FALSE, /* never displayed */
1477 URD_COL_N_UPGRADABLE, total_upgradable_count,
1478 URD_COL_IN_PROGRESS, unit_totals.building_count,
1479 URD_COL_ACTIVE, unit_totals.active_count,
1480 URD_COL_SHIELD, unit_totals.upkeep[O_SHIELD],
1481 URD_COL_FOOD, unit_totals.upkeep[O_FOOD],
1482 URD_COL_GOLD, unit_totals.upkeep[O_GOLD],
1483 URD_COL_EMPTY, " ",
1484 URD_COL_TEXT_WEIGHT, PANGO_WEIGHT_BOLD,
1488 -1);
1489 if (selected == U_LAST) {
1490 /* Restore the selection. */
1491 gtk_tree_selection_select_iter(selection, &iter);
1492 }
1493}
1494
1495/************************************************************************/
1498static void units_report_selection_callback(GtkTreeSelection *selection,
1499 gpointer data)
1500{
1501 struct units_report *preport = data;
1502 GtkTreeModel *model;
1503 GtkTreeIter it;
1504 int active_count;
1505 struct unit_type *utype = NULL;
1506
1507 if (gtk_tree_selection_get_selected(selection, &model, &it)) {
1508 int ut;
1509
1510 gtk_tree_model_get(model, &it,
1511 URD_COL_ACTIVE, &active_count,
1512 URD_COL_UTYPE_ID, &ut,
1513 -1);
1514 if (0 < active_count) {
1515 utype = utype_by_number(ut);
1516 }
1517 }
1518
1519 if (NULL == utype) {
1521 FALSE);
1523 FALSE);
1524 } else {
1528 && action_ever_possible(ACTION_UPGRADE_UNIT)
1529 && NULL != can_upgrade_unittype(client_player(), utype)));
1530 }
1531}
1532
1533/************************************************************************/
1536static struct unit *find_nearest_unit(const struct unit_type *utype,
1537 struct tile *ptile)
1538{
1539 struct unit *best_candidate = NULL;
1540 int best_dist = FC_INFINITY, dist;
1541
1542 players_iterate(pplayer) {
1543 if (client_has_player() && pplayer != client_player()) {
1544 continue;
1545 }
1546
1547 unit_list_iterate(pplayer->units, punit) {
1548 if (utype == unit_type_get(punit)
1550 && 0 < punit->moves_left
1551 && !punit->done_moving
1552 && punit->ssa_controller == SSA_NONE) {
1553 dist = sq_map_distance(unit_tile(punit), ptile);
1554 if (dist < best_dist) {
1555 best_candidate = punit;
1556 best_dist = dist;
1557 }
1558 }
1561
1562 return best_candidate;
1563}
1564
1565/************************************************************************/
1568static void units_report_command_callback(struct gui_dialog *pdialog,
1569 int response,
1570 gpointer data)
1571{
1572 struct units_report *preport = data;
1573 struct unit_type *utype = NULL;
1574 GtkTreeSelection *selection;
1575 GtkTreeModel *model;
1576 GtkTreeIter it;
1577
1578 switch (response) {
1579 case URD_RES_NEAREST:
1580 case URD_RES_UPGRADE:
1581 break;
1582 default:
1583 gui_dialog_destroy(pdialog);
1584 return;
1585 }
1586
1587 /* Nearest & upgrade commands. */
1588 selection = gtk_tree_view_get_selection(preport->tree_view);
1589 if (gtk_tree_selection_get_selected(selection, &model, &it)) {
1590 int ut;
1591
1592 gtk_tree_model_get(model, &it, URD_COL_UTYPE_ID, &ut, -1);
1593 utype = utype_by_number(ut);
1594 }
1595
1596 if (response == URD_RES_NEAREST) {
1597 struct tile *ptile;
1598 struct unit *punit;
1599
1600 ptile = get_center_tile_mapcanvas();
1601 if ((punit = find_nearest_unit(utype, ptile))) {
1603
1604 if (ACTIVITY_IDLE == punit->activity
1605 || ACTIVITY_SENTRY == punit->activity) {
1606 if (can_unit_do_activity_client(punit, ACTIVITY_IDLE)) {
1608 }
1609 }
1610 }
1611 } else if (can_client_issue_orders()) {
1612 GtkWidget *shell;
1613 const struct unit_type *upgrade = can_upgrade_unittype(client_player(), utype);
1614 char buf[1024];
1615 int price = unit_upgrade_price(client_player(), utype, upgrade);
1616
1617 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Treasury contains %d gold.",
1618 "Treasury contains %d gold.",
1619 client_player()->economic.gold),
1620 client_player()->economic.gold);
1621
1622 shell = gtk_message_dialog_new(NULL,
1623 GTK_DIALOG_MODAL
1624 | GTK_DIALOG_DESTROY_WITH_PARENT,
1625 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1626 /* TRANS: Last %s is pre-pluralised
1627 * "Treasury contains %d gold." */
1628 PL_("Upgrade as many %s to %s as possible "
1629 "for %d gold each?\n%s",
1630 "Upgrade as many %s to %s as possible "
1631 "for %d gold each?\n%s", price),
1633 utype_name_translation(upgrade),
1634 price, buf);
1636
1637 gtk_window_set_title(GTK_WINDOW(shell), _("Upgrade Obsolete Units"));
1638
1639 if (GTK_RESPONSE_YES == gtk_dialog_run(GTK_DIALOG(shell))) {
1641 }
1642
1643 gtk_widget_destroy(shell);
1644 }
1645}
1646
1647/************************************************************************/
1650static void units_report_init(struct units_report *preport)
1651{
1652 GtkWidget *view, *sw, *button;
1653 GtkListStore *store;
1654 GtkTreeSelection *selection;
1655 GtkContainer *vbox;
1656 GtkTreeViewColumn *col = NULL;
1657 enum units_report_columns i;
1658
1659 fc_assert_ret(NULL != preport);
1660
1661 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), preport, TRUE);
1662 gui_dialog_set_title(preport->shell, _("Units"));
1663 vbox = GTK_CONTAINER(preport->shell->vbox);
1664
1665 sw = gtk_scrolled_window_new(NULL,NULL);
1666 gtk_widget_set_halign(sw, GTK_ALIGN_CENTER);
1667 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
1668 GTK_SHADOW_ETCHED_IN);
1669 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1670 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1671 gtk_container_add(GTK_CONTAINER(vbox), sw);
1672
1673 store = units_report_store_new();
1674 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1675 gtk_widget_set_vexpand(view, TRUE);
1676 g_object_unref(store);
1677 gtk_widget_set_name(view, "small_font");
1678 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(view));
1679 gtk_container_add(GTK_CONTAINER(sw), view);
1680 preport->tree_view = GTK_TREE_VIEW(view);
1681
1682 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1683 g_signal_connect(selection, "changed",
1684 G_CALLBACK(units_report_selection_callback), preport);
1685
1686 for (i = 0; unit_report_columns[i].title != NULL; i++) {
1687 GtkCellRenderer *renderer;
1688
1689 if (strlen(unit_report_columns[i].title) > 0) {
1690 GtkWidget *header = gtk_label_new(Q_(unit_report_columns[i].title));
1692 gtk_widget_set_tooltip_text(header,
1694 }
1695 gtk_widget_show(header);
1696 col = gtk_tree_view_column_new();
1697 gtk_tree_view_column_set_widget(col, header);
1699 gtk_tree_view_column_set_alignment(col, 1.0);
1700 }
1701 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1702 } /* else add new renderer to previous TreeViewColumn */
1703
1704 fc_assert(col != NULL);
1705 if (G_TYPE_BOOLEAN == unit_report_columns[i].type) {
1706 renderer = gtk_cell_renderer_toggle_new();
1707 gtk_tree_view_column_pack_start(col, renderer, FALSE);
1708 gtk_tree_view_column_add_attribute(col, renderer, "active", i);
1709 } else {
1710 renderer = gtk_cell_renderer_text_new();
1711 gtk_tree_view_column_pack_start(col, renderer, TRUE);
1712 gtk_tree_view_column_add_attribute(col, renderer, "text", i);
1713 gtk_tree_view_column_add_attribute(col, renderer,
1714 "weight", URD_COL_TEXT_WEIGHT);
1715 }
1716
1717 if (unit_report_columns[i].visible_col >= 0) {
1718 gtk_tree_view_column_add_attribute(col, renderer, "visible",
1720 }
1721
1723 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
1724 }
1725 }
1726
1727 gui_dialog_add_button(preport->shell, "window-close", _("_Close"),
1728 GTK_RESPONSE_CLOSE);
1729
1730 button = gui_dialog_add_button(preport->shell, NULL, _("_Upgrade"),
1732 gtk_widget_set_sensitive(button, FALSE);
1733
1734 button = gui_dialog_add_button(preport->shell, "edit-find",
1735 _("Find _Nearest"), URD_RES_NEAREST);
1736 gtk_widget_set_sensitive(button, FALSE);
1737
1738 gui_dialog_set_default_response(preport->shell, GTK_RESPONSE_CLOSE);
1741
1742 gui_dialog_set_default_size(preport->shell, -1, 350);
1743 gui_dialog_show_all(preport->shell);
1744
1745 units_report_update(preport);
1746 gtk_tree_view_focus(GTK_TREE_VIEW(view));
1747}
1748
1749/************************************************************************/
1752static void units_report_free(struct units_report *preport)
1753{
1754 fc_assert_ret(NULL != preport);
1755
1756 gui_dialog_destroy(preport->shell);
1757 fc_assert(NULL == preport->shell);
1758
1759 memset(preport, 0, sizeof(*preport));
1760}
1761
1762/************************************************************************/
1766{
1767 if (NULL == units_report.shell) {
1769 }
1770
1772 if (raise) {
1774 }
1775}
1776
1777/************************************************************************/
1781{
1782 if (NULL != units_report.shell) {
1784 fc_assert(NULL == units_report.shell);
1785 }
1786}
1787
1788/************************************************************************/
1792{
1793 if (NULL != units_report.shell) {
1795 }
1796}
1797
1798
1799/****************************************************************************
1800 FINAL REPORT DIALOG
1801****************************************************************************/
1802struct endgame_report {
1803 struct gui_dialog *shell;
1804 GtkTreeView *tree_view;
1805 GtkListStore *store;
1806 int player_count;
1807 int players_received;
1808};
1809
1818
1819static struct endgame_report endgame_report = { NULL, NULL };
1820
1821/************************************************************************/
1824static const char *
1826{
1827 switch (col) {
1828 case FRD_COL_PLAYER:
1829 return _("Player\n");
1830 case FRD_COL_NATION:
1831 return _("Nation\n");
1832 case FRD_COL_SCORE:
1833 return _("Score\n");
1834 case FRD_COL_TOOLTIP:
1835 case FRD_COL_NUM:
1836 break;
1837 }
1838
1839 return NULL;
1840}
1841
1842/************************************************************************/
1845static void endgame_report_update(struct endgame_report *preport,
1846 const struct packet_endgame_report *packet)
1847{
1848 const size_t col_num = packet->category_num + FRD_COL_NUM;
1849 GType col_types[col_num];
1850 GtkListStore *store;
1851 GtkTreeViewColumn *col;
1852 int i;
1853
1854 fc_assert_ret(NULL != preport);
1855
1856 /* Remove the old columns. */
1857 while ((col = gtk_tree_view_get_column(preport->tree_view, 0))) {
1858 gtk_tree_view_remove_column(preport->tree_view, col);
1859 }
1860
1861 /* Create the new model. */
1862 col_types[FRD_COL_PLAYER] = G_TYPE_STRING;
1863 col_types[FRD_COL_NATION] = GDK_TYPE_PIXBUF;
1864 col_types[FRD_COL_SCORE] = G_TYPE_INT;
1865 col_types[FRD_COL_TOOLTIP] = G_TYPE_STRING;
1866 for (i = FRD_COL_NUM; (guint)i < col_num; i++) {
1867 col_types[i] = G_TYPE_INT;
1868 }
1869 store = gtk_list_store_newv(col_num, col_types);
1870 gtk_tree_view_set_model(preport->tree_view, GTK_TREE_MODEL(store));
1871 g_object_unref(G_OBJECT(store));
1872
1873 /* Create the new columns. */
1874 for (i = 0; (guint)i < col_num; i++) {
1875 GtkCellRenderer *renderer;
1876 const char *title;
1877 const char *attribute;
1878
1879 if (GDK_TYPE_PIXBUF == col_types[i]) {
1880 renderer = gtk_cell_renderer_pixbuf_new();
1881 attribute = "pixbuf";
1882 } else {
1883 renderer = gtk_cell_renderer_text_new();
1884 attribute = "text";
1885 }
1886
1887 if (i < FRD_COL_NUM) {
1889 } else {
1890 title = packet->category_name[i - FRD_COL_NUM];
1891 }
1892
1893 if (title != NULL) {
1894 col = gtk_tree_view_column_new_with_attributes(Q_(title), renderer,
1895 attribute, i, NULL);
1896 gtk_tree_view_append_column(preport->tree_view, col);
1897 if (GDK_TYPE_PIXBUF != col_types[i]) {
1898 gtk_tree_view_column_set_sort_column_id(col, i);
1899 }
1900 }
1901 }
1902
1903 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(preport->tree_view),
1905
1906 preport->store = store;
1907 preport->player_count = packet->player_num;
1908 preport->players_received = 0;
1909}
1910
1911/************************************************************************/
1915{
1916 /* Fill the model with player stats. */
1917 struct endgame_report *preport = &endgame_report;
1918 const struct player *pplayer = player_by_number(packet->player_id);
1919 GtkTreeIter iter;
1920 int i;
1921
1922 gtk_list_store_append(preport->store, &iter);
1923 gtk_list_store_set(preport->store, &iter,
1924 FRD_COL_PLAYER, player_name(pplayer),
1926 FRD_COL_SCORE, packet->score,
1927 FRD_COL_TOOLTIP, score_tooltip(pplayer, packet->score),
1928 -1);
1929 for (i = 0; i < packet->category_num; i++) {
1930 gtk_list_store_set(preport->store, &iter,
1931 i + FRD_COL_NUM, packet->category_score[i],
1932 -1);
1933 }
1934
1935 preport->players_received++;
1936
1937 if (preport->players_received == preport->player_count) {
1938 gui_dialog_present(preport->shell);
1939 }
1940}
1941
1942/************************************************************************/
1945static void endgame_report_init(struct endgame_report *preport)
1946{
1947 GtkWidget *sw, *view;
1948
1949 fc_assert_ret(NULL != preport);
1950
1951 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), NULL, TRUE);
1952 gui_dialog_set_title(preport->shell, _("Score"));
1953
1954 gui_dialog_set_default_size(preport->shell, 700, 420);
1955
1956 /* Setup the layout. */
1957 sw = gtk_scrolled_window_new(NULL, NULL);
1958 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
1959 GTK_SHADOW_ETCHED_IN);
1960 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1961 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
1962 gtk_container_add(GTK_CONTAINER(preport->shell->vbox), sw);
1963
1964 view = gtk_tree_view_new();
1965 gtk_widget_set_name(view, "small_font");
1966 gtk_container_add(GTK_CONTAINER(sw), view);
1967 preport->tree_view = GTK_TREE_VIEW(view);
1968
1969 if (preport->shell->type == GUI_DIALOG_TAB) {
1970 gtk_widget_set_hexpand(GTK_WIDGET(view), TRUE);
1971 gtk_widget_set_vexpand(GTK_WIDGET(view), TRUE);
1972 }
1973
1974 gui_dialog_show_all(preport->shell);
1975}
1976
1977/************************************************************************/
1981{
1982 if (NULL == endgame_report.shell) {
1984 }
1986}
bool action_ever_possible(action_id action)
Definition actions.c:9305
int entries_used
Definition agents.c:74
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
bool city_production_build_units(const struct city *pcity, bool add_production, int *num_units)
Definition city.c:732
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define output_type_iterate(output)
Definition city.h:821
#define city_list_iterate_end
Definition city.h:490
#define output_type_iterate_end
Definition city.h:827
bool client_is_global_observer(void)
struct civclient client
bool can_client_issue_orders(void)
bool client_has_player(void)
#define client_player()
cid cid_encode_building(const struct impr_type *pimprove)
Definition climisc.c:498
struct universal cid_decode(cid id)
Definition climisc.c:519
cid cid_encode_unit(const struct unit_type *punittype)
Definition climisc.c:486
int cid
Definition climisc.h:31
bool can_conn_edit(const struct connection *pconn)
Definition connection.c:510
void unit_focus_set_and_select(struct unit *punit)
Definition control.c:637
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:40
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
int int id
Definition editgui_g.h:28
enum event_type event
Definition events.c:81
int Tech_type_id
Definition fc_types.h:347
int Unit_type_id
Definition fc_types.h:352
@ O_SHIELD
Definition fc_types.h:91
@ O_FOOD
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
@ O_LAST
Definition fc_types.h:91
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
#define N_(String)
Definition fcintl.h:69
#define FC_STATIC_CANVAS_INIT
Definition canvas.h:27
GtkWidget * top_notebook
Definition gui_main.c:128
void gtk_tree_view_focus(GtkTreeView *view)
Definition gui_stuff.c:230
void gui_dialog_destroy(struct gui_dialog *dlg)
Definition gui_stuff.c:951
void gui_dialog_present(struct gui_dialog *dlg)
Definition gui_stuff.c:834
void gui_dialog_set_default_response(struct gui_dialog *dlg, int response)
Definition gui_stuff.c:733
void itree_get(ITree *it,...)
Definition gui_stuff.c:158
void gui_dialog_raise(struct gui_dialog *dlg)
Definition gui_stuff.c:864
void gui_dialog_new(struct gui_dialog **pdlg, GtkNotebook *notebook, gpointer user_data, bool check_top)
Definition gui_stuff.c:504
void gui_dialog_response_set_callback(struct gui_dialog *dlg, GUI_DIALOG_RESPONSE_FUN fun)
Definition gui_stuff.c:985
void itree_begin(GtkTreeModel *model, ITree *it)
Definition gui_stuff.c:121
GtkWidget * gui_dialog_add_button(struct gui_dialog *dlg, const char *text, int response)
Definition gui_stuff.c:706
void gui_dialog_show_all(struct gui_dialog *dlg)
Definition gui_stuff.c:794
void gui_dialog_set_title(struct gui_dialog *dlg, const char *title)
Definition gui_stuff.c:932
void gui_dialog_set_default_size(struct gui_dialog *dlg, int width, int height)
Definition gui_stuff.c:916
void gui_dialog_alert(struct gui_dialog *dlg)
Definition gui_stuff.c:887
void itree_next(ITree *it)
Definition gui_stuff.c:138
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:281
void gui_dialog_set_response_sensitive(struct gui_dialog *dlg, int response, bool setting)
Definition gui_stuff.c:759
GtkWidget * gui_dialog_get_toplevel(struct gui_dialog *dlg)
Definition gui_stuff.c:786
gboolean itree_end(ITree *it)
Definition gui_stuff.c:130
@ GUI_DIALOG_TAB
Definition gui_stuff.h:61
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:195
static struct gui_dialog * shell
Definition messagedlg.c:39
GdkPixbuf * get_flag(const struct nation_type *nation)
Definition plrdlg.c:609
static struct endgame_report endgame_report
Definition repodlgs.c:1819
static void units_report_init(struct units_report *preport)
Definition repodlgs.c:1651
void units_report_dialog_popdown(void)
Definition repodlgs.c:1780
static GtkListStore * units_report_store_new(void)
Definition repodlgs.c:1347
void science_report_dialog_popup(bool raise)
Definition repodlgs.c:716
static void science_report_store_set(GtkListStore *store, GtkTreeIter *iter, Tech_type_id tech)
Definition repodlgs.c:136
static void economy_report_init(struct economy_report *preport)
Definition repodlgs.c:1117
static void science_report_update(struct science_report *preport)
Definition repodlgs.c:385
static void units_report_update(struct units_report *preport)
Definition repodlgs.c:1363
static bool science_report_combo_get_active(GtkComboBox *combo, Tech_type_id *tech, char **name)
Definition repodlgs.c:154
void endgame_report_dialog_start(const struct packet_endgame_report *packet)
Definition repodlgs.c:1980
static void science_diagram_center(GtkWidget *diagram, Tech_type_id tech)
Definition repodlgs.c:312
units_report_response
Definition repodlgs.c:1285
@ URD_RES_UPGRADE
Definition repodlgs.c:1287
@ URD_RES_NEAREST
Definition repodlgs.c:1286
static void endgame_report_update(struct endgame_report *preport, const struct packet_endgame_report *packet)
Definition repodlgs.c:1845
void real_units_report_dialog_update(void *unused)
Definition repodlgs.c:1791
void real_economy_report_dialog_update(void *unused)
Definition repodlgs.c:1267
const char * tooltip
Definition repodlgs.c:1314
void economy_report_dialog_popdown(void)
Definition repodlgs.c:1257
static gboolean science_diagram_update(GtkWidget *widget, cairo_t *cr, gpointer data)
Definition repodlgs.c:235
static gboolean science_diagram_button_release_callback(GtkWidget *widget, GdkEventButton *event, gpointer data)
Definition repodlgs.c:197
static const char * endgame_report_column_name(enum endgame_report_columns col)
Definition repodlgs.c:1825
void economy_report_dialog_popup(bool raise)
Definition repodlgs.c:1242
static void endgame_report_init(struct endgame_report *preport)
Definition repodlgs.c:1945
static void science_report_combo_set_active(GtkComboBox *combo, Tech_type_id tech)
Definition repodlgs.c:175
const char * title
Definition repodlgs.c:1313
static void science_diagram_data(GtkWidget *widget, bool show_all)
Definition repodlgs.c:290
static void science_report_free(struct science_report *preport)
Definition repodlgs.c:703
static bool science_report_no_combo_callback
Definition repodlgs.c:109
static const struct @155 unit_report_columns[]
void units_report_dialog_popup(bool raise)
Definition repodlgs.c:1765
static void economy_report_command_callback(struct gui_dialog *pdialog, int response, gpointer data)
Definition repodlgs.c:952
GType type
Definition repodlgs.c:1312
static void units_report_command_callback(struct gui_dialog *pdialog, int response, gpointer data)
Definition repodlgs.c:1569
static void units_report_selection_callback(GtkTreeSelection *selection, gpointer data)
Definition repodlgs.c:1499
static void economy_report_update(struct economy_report *preport)
Definition repodlgs.c:858
void science_report_dialog_redraw(void)
Definition repodlgs.c:761
units_report_columns
Definition repodlgs.c:1291
@ URD_COL_NUM
Definition repodlgs.c:1308
@ URD_COL_UPG_VISIBLE
Definition repodlgs.c:1304
@ URD_COL_ACTIVE
Definition repodlgs.c:1296
@ URD_COL_IN_PROGRESS
Definition repodlgs.c:1295
@ URD_COL_TEXT_WEIGHT
Definition repodlgs.c:1303
@ URD_COL_GOLD
Definition repodlgs.c:1299
@ URD_COL_UPGRADABLE
Definition repodlgs.c:1293
@ URD_COL_FOOD
Definition repodlgs.c:1298
@ URD_COL_N_UPGRADABLE
Definition repodlgs.c:1294
@ URD_COL_NUPG_VISIBLE
Definition repodlgs.c:1305
@ URD_COL_UTYPE_NAME
Definition repodlgs.c:1292
@ URD_COL_UTYPE_ID
Definition repodlgs.c:1306
@ URD_COL_SHIELD
Definition repodlgs.c:1297
@ URD_COL_EMPTY
Definition repodlgs.c:1300
science_report_columns
Definition repodlgs.c:112
@ SRD_COL_ID
Definition repodlgs.c:117
@ SRD_COL_NAME
Definition repodlgs.c:113
@ SRD_COL_NUM
Definition repodlgs.c:119
@ SRD_COL_STEPS
Definition repodlgs.c:114
static const char * economy_report_column_name(enum economy_report_columns col)
Definition repodlgs.c:826
static GtkWidget * science_diagram_new(void)
Definition repodlgs.c:270
int visible_col
Definition repodlgs.c:1316
static void science_report_show_all_callback(GtkComboBox *combo, gpointer data)
Definition repodlgs.c:546
economy_report_columns
Definition repodlgs.c:788
@ ERD_COL_NUM
Definition repodlgs.c:801
@ ERD_COL_SPRITE
Definition repodlgs.c:789
@ ERD_COL_IS_IMPROVEMENT
Definition repodlgs.c:798
@ ERD_COL_CID
Definition repodlgs.c:799
@ ERD_COL_NAME
Definition repodlgs.c:790
@ ERD_COL_EMPTY
Definition repodlgs.c:795
@ ERD_COL_REDUNDANT
Definition repodlgs.c:791
@ ERD_COL_TOTAL_COST
Definition repodlgs.c:794
@ ERD_COL_COUNT
Definition repodlgs.c:792
@ ERD_COL_COST
Definition repodlgs.c:793
void science_report_dialog_popdown(void)
Definition repodlgs.c:740
bool rightalign
Definition repodlgs.c:1315
static GtkListStore * economy_report_store_new(void)
Definition repodlgs.c:807
static struct unit * find_nearest_unit(const struct unit_type *utype, struct tile *ptile)
Definition repodlgs.c:1537
endgame_report_columns
Definition repodlgs.c:1810
@ FRD_COL_NUM
Definition repodlgs.c:1816
@ FRD_COL_TOOLTIP
Definition repodlgs.c:1814
@ FRD_COL_NATION
Definition repodlgs.c:1812
@ FRD_COL_PLAYER
Definition repodlgs.c:1811
@ FRD_COL_SCORE
Definition repodlgs.c:1813
economy_report_response
Definition repodlgs.c:780
@ ERD_RES_SELL_REDUNDANT
Definition repodlgs.c:781
@ ERD_RES_SELL_ALL
Definition repodlgs.c:782
@ ERD_RES_DISBAND_UNITS
Definition repodlgs.c:783
static gint cmp_func(gconstpointer a_p, gconstpointer b_p)
Definition repodlgs.c:370
static void economy_report_selection_callback(GtkTreeSelection *selection, gpointer data)
Definition repodlgs.c:1068
static void science_report_goal_callback(GtkComboBox *combo, gpointer data)
Definition repodlgs.c:557
static void economy_report_free(struct economy_report *preport)
Definition repodlgs.c:1229
static void science_report_init(struct science_report *preport)
Definition repodlgs.c:581
static void science_report_current_callback(GtkComboBox *combo, gpointer data)
Definition repodlgs.c:521
void real_science_report_dialog_update(void *unused)
Definition repodlgs.c:751
static void units_report_free(struct units_report *preport)
Definition repodlgs.c:1752
static GtkListStore * science_report_store_new(void)
Definition repodlgs.c:125
static void science_report_redraw(struct science_report *preport)
Definition repodlgs.c:347
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
Definition sprite.c:402
const char * tooltip
Definition repodlgs.c:1342
const char * title
Definition repodlgs.c:1341
GType type
Definition repodlgs.c:1340
int visible_col
Definition repodlgs.c:1344
bool rightalign
Definition repodlgs.c:1343
@ HELP_TECH
Definition helpdlg_g.h:21
bool can_sell_building(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define log_error(message,...)
Definition log.h:103
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:639
struct tile * get_center_tile_mapcanvas(void)
void center_tile_mapcanvas(const struct tile *ptile)
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
int dsend_packet_player_tech_goal(struct connection *pc, int tech)
int dsend_packet_player_research(struct connection *pc, int tech)
int dsend_packet_unit_type_upgrade(struct connection *pc, Unit_type_id type)
const char * science_dialog_text(void)
Definition text.c:774
struct player * player_by_number(const int player_id)
Definition player.c:840
const char * player_name(const struct player *pplayer)
Definition player.c:886
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
void get_economy_report_units_data(struct unit_entry *entries, int *num_entries_used, int *total_cost)
void get_economy_report_data(struct improvement_entry *entries, int *num_entries_used, int *total_cost, int *total_income)
void sell_all_improvements(const struct impr_type *pimprove, bool redundant_only, char *message, size_t message_sz)
void disband_all_units(const struct unit_type *punittype, bool in_cities_only, char *message, size_t message_sz)
endgame_report_dialog_player
Definition repodlgs_g.h:33
void draw_reqtree(struct reqtree *tree, struct canvas *pcanvas, int canvas_x, int canvas_y, int tt_x, int tt_y, int w, int h)
Definition reqtree.c:1033
void get_reqtree_dimensions(struct reqtree *reqtree, int *width, int *height)
Definition reqtree.c:867
Tech_type_id get_tech_on_reqtree(struct reqtree *tree, int x, int y)
Definition reqtree.c:1170
bool find_tech_on_reqtree(struct reqtree *tree, Tech_type_id tech, int *x, int *y, int *w, int *h)
Definition reqtree.c:1193
void destroy_reqtree(struct reqtree *tree)
Definition reqtree.c:470
struct reqtree * create_reqtree(struct player *pplayer, bool show_all)
Definition reqtree.c:836
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:747
bool research_invention_reachable(const struct research *presearch, const Tech_type_id tech)
Definition research.c:665
bool research_future_next(const struct research *presearch)
Definition research.c:1335
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:271
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
#define ARRAY_SIZE(x)
Definition shared.h:85
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
GtkTreeIter it
Definition gui_stuff.h:34
cairo_t * drawable
Definition canvas.h:23
struct connection conn
Definition client_main.h:96
GtkLabel * label
Definition repodlgs.c:775
GtkTreeView * tree_view
Definition repodlgs.c:774
struct gui_dialog * shell
Definition repodlgs.c:773
GtkListStore * store
Definition repodlgs.c:1805
GtkTreeView * tree_view
Definition repodlgs.c:1804
struct gui_dialog * shell
Definition repodlgs.c:1803
GtkWidget * vbox
Definition gui_stuff.h:71
enum gui_dialog_type type
Definition gui_stuff.h:76
int cost
struct impr_type * type
int total_cost
int count
int redundant
Definition climisc.h:82
char category_name[32][MAX_LEN_NAME]
Definition packets_gen.h:90
enum tech_state state
Definition research.h:73
Tech_type_id researching
Definition research.h:52
Tech_type_id tech_goal
Definition research.h:85
struct research::research_invention inventions[A_ARRAY_SIZE]
struct gui_dialog * shell
Definition repodlgs.c:70
GtkLayout * drawing_area
Definition repodlgs.c:77
GtkProgressBar * progress_bar
Definition repodlgs.c:75
GtkComboBox * reachable_techs
Definition repodlgs.c:71
GtkComboBox * reachable_goals
Definition repodlgs.c:72
GtkLabel * goal_label
Definition repodlgs.c:76
GtkLabel * main_label
Definition repodlgs.c:74
GtkWidget * button_show_all
Definition repodlgs.c:73
Definition tile.h:49
int total_cost
struct unit_type * type
int count
int cost
Definition unit.h:138
int upkeep[O_LAST]
Definition unit.h:148
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
struct unit::@80::@82 client
int homecity
Definition unit.h:146
bool done_moving
Definition unit.h:181
const struct unit_type * utype
Definition unit.h:139
enum unit_focus_status focus_status
Definition unit.h:211
enum server_side_agent ssa_controller
Definition unit.h:172
GtkTreeView * tree_view
Definition repodlgs.c:1280
struct gui_dialog * shell
Definition repodlgs.c:1279
enum universals_n kind
Definition fc_types.h:758
universals_u value
Definition fc_types.h:757
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
int fc_strcoll(const char *str0, const char *str1)
Definition support.c:472
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
#define A_FUTURE
Definition tech.h:46
#define advance_index_iterate_end
Definition tech.h:248
#define A_FIRST
Definition tech.h:44
#define A_NONE
Definition tech.h:43
#define A_UNSET
Definition tech.h:48
#define advance_index_iterate(_start, _index)
Definition tech.h:244
const char * score_tooltip(const struct player *pplayer, int score)
Definition text.c:2157
const char * get_science_target_text(double *percent)
Definition text.c:853
const char * get_science_goal_text(Tech_type_id goal)
Definition text.c:899
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:6494
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum direction8 facing)
Definition tilespec.c:6516
bool tileset_is_fully_loaded(void)
Definition tilespec.c:7203
const struct unit_type * utype
Definition fc_types.h:604
const struct impr_type * building
Definition fc_types.h:598
#define unit_tile(_pu)
Definition unit.h:395
@ FOCUS_AVAIL
Definition unit.h:53
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1755
Unit_type_id utype_count(void)
Definition unittype.c:80
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1783
#define unit_type_iterate(_p)
Definition unittype.h:841
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:848