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-4.0 */
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 GtkDrawingArea *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_left_button_up(GtkGestureClick *gesture,
90 int n_press,
91 double x, double y);
92static gboolean science_diagram_right_button_up(GtkGestureClick *gesture,
93 int n_press,
94 double x, double y);
95
96static void science_diagram_update(GtkDrawingArea *widget, cairo_t *cr,
97 int width, int height, gpointer data);
98static GtkWidget *science_diagram_new(void);
99static void science_diagram_data(GtkWidget *widget, bool show_all);
100static void science_diagram_center(GtkWidget *diagram, Tech_type_id tech);
101static void science_report_redraw(struct science_report *preport);
102static gint cmp_func(gconstpointer a_p, gconstpointer b_p);
103static void science_report_update(struct science_report *preport);
104static void science_report_current_callback(GtkComboBox *combo,
105 gpointer data);
106static void science_report_show_all_callback(GtkComboBox *combo,
107 gpointer data);
108static void science_report_goal_callback(GtkComboBox *combo, gpointer data);
109static void science_report_init(struct science_report *preport);
110static void science_report_free(struct science_report *preport);
111
112static struct science_report science_report = { NULL, };
114
115/* Those values must match the function science_report_store_new(). */
119
120 /* Not visible. */
121 SRD_COL_ID, /* Tech_type_id */
122
125
126/************************************************************************/
129static GtkListStore *science_report_store_new(void)
130{
131 return gtk_list_store_new(SRD_COL_NUM,
132 G_TYPE_STRING, /* SRD_COL_NAME */
133 G_TYPE_INT, /* SRD_COL_STEPS */
134 G_TYPE_INT); /* SRD_COL_ID */
135}
136
137/************************************************************************/
140static inline void science_report_store_set(GtkListStore *store,
141 GtkTreeIter *iter,
142 Tech_type_id tech)
143{
144 const struct research *presearch = research_get(client_player());
145
146 gtk_list_store_set(store, iter,
148 research_advance_name_translation(presearch, tech),
150 research_goal_unknown_techs(presearch, tech),
151 SRD_COL_ID, tech,
152 -1);
153}
154
155/************************************************************************/
158static bool science_report_combo_get_active(GtkComboBox *combo,
159 Tech_type_id *tech,
160 char **name)
161{
162 GtkTreeIter iter;
163
165 || !gtk_combo_box_get_active_iter(combo, &iter)) {
166 return FALSE;
167 }
168
169 gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter,
171 SRD_COL_ID, tech,
172 -1);
173
174 return TRUE;
175}
176
177/************************************************************************/
180static void science_report_combo_set_active(GtkComboBox *combo,
181 Tech_type_id tech)
182{
183 ITree iter;
184 Tech_type_id iter_tech;
185
186 for (itree_begin(gtk_combo_box_get_model(combo), &iter);
187 !itree_end(&iter); itree_next(&iter)) {
188 itree_get(&iter, SRD_COL_ID, &iter_tech, -1);
189 if (iter_tech == tech) {
191 gtk_combo_box_set_active_iter(combo, &iter.it);
193 return;
194 }
195 }
196 log_error("%s(): Tech %d not found in the combo.", __FUNCTION__, tech);
197}
198
199/************************************************************************/
202static gboolean science_diagram_left_button_up(GtkGestureClick *gesture,
203 int n_press,
204 double x, double y)
205{
206 GtkEventController *controller = GTK_EVENT_CONTROLLER(gesture);
207 GtkWidget *w = gtk_event_controller_get_widget(controller);
208 struct reqtree *reqtree = g_object_get_data(G_OBJECT(w), "reqtree");
209 Tech_type_id tech;
210
211 tech = get_tech_on_reqtree(reqtree, x, y);
212
213 if (tech == A_NONE) {
214 return TRUE;
215 }
216
218 /* Set research or research goal */
220 tech)) {
221 case TECH_PREREQS_KNOWN:
223 break;
224 case TECH_UNKNOWN:
226 break;
227 case TECH_KNOWN:
228 break;
229 }
230 }
231
232 return TRUE;
233}
234
235/************************************************************************/
238static gboolean science_diagram_right_button_up(GtkGestureClick *gesture,
239 int n_press,
240 double x, double y)
241{
242 const struct research *presearch;
243 GtkEventController *controller = GTK_EVENT_CONTROLLER(gesture);
244 GtkWidget *w = gtk_event_controller_get_widget(controller);
245 struct reqtree *reqtree = g_object_get_data(G_OBJECT(w), "reqtree");
246 Tech_type_id tech;
247
248 tech = get_tech_on_reqtree(reqtree, x, y);
249
250 if (tech == A_NONE) {
251 return TRUE;
252 }
253
254 presearch = research_get(client_player());
255
256 /* Open help */
258 tech),
259 HELP_TECH);
260
261 return TRUE;
262}
263
264/************************************************************************/
267static void science_diagram_update(GtkDrawingArea *widget, cairo_t *cr,
268 int width, int height, gpointer data)
269{
270 /* FIXME: this currently redraws everything! */
272 struct reqtree *reqtree = g_object_get_data(G_OBJECT(widget), "reqtree");
273 int rtwidth, rtheight;
274 GtkAdjustment *hadjustment;
275 GtkAdjustment *vadjustment;
276 gint hadjustment_value;
277 gint vadjustment_value;
278 GtkViewport *vp;
279
281 return;
282 }
283
284 get_reqtree_dimensions(reqtree, &rtwidth, &rtheight);
285 gtk_widget_set_size_request(GTK_WIDGET(widget), rtwidth, rtheight);
286
287 vp = GTK_VIEWPORT(gtk_widget_get_parent(GTK_WIDGET(widget)));
288 hadjustment = gtk_scrollable_get_hadjustment(GTK_SCROLLABLE(vp));
289 vadjustment = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vp));
290
291 hadjustment_value = (gint)gtk_adjustment_get_value(hadjustment);
292 vadjustment_value = (gint)gtk_adjustment_get_value(vadjustment);
293
294 cairo_translate(cr, -hadjustment_value, -vadjustment_value);
295
296 canvas.drawable = cr;
297
298 draw_reqtree(reqtree, &canvas, 0, 0, 0, 0, rtwidth, rtheight);
299}
300
301/************************************************************************/
305static GtkWidget *science_diagram_new(void)
306{
307 GtkWidget *diagram;
308 GtkEventController *controller;
309 GtkGesture *gesture;
310
311 diagram = gtk_drawing_area_new();
312 gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(diagram),
313 science_diagram_update, NULL, NULL);
314
315 controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
316 g_signal_connect(controller, "released",
317 G_CALLBACK(science_diagram_left_button_up), NULL);
318 gtk_widget_add_controller(diagram, controller);
319 gesture = gtk_gesture_click_new();
320 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 3);
321 controller = GTK_EVENT_CONTROLLER(gesture);
322 g_signal_connect(controller, "released",
323 G_CALLBACK(science_diagram_right_button_up), NULL);
324 gtk_widget_add_controller(diagram, controller);
325
326 return diagram;
327}
328
329/************************************************************************/
332static void science_diagram_data(GtkWidget *widget, bool show_all)
333{
334 struct reqtree *reqtree;
335
336 if (can_conn_edit(&client.conn)) {
337 /* Show all techs in editor mode, not only currently reachable ones */
338 reqtree = create_reqtree(NULL, TRUE);
339 } else {
340 /* Show only at some point reachable techs */
341 reqtree = create_reqtree(client_player(), show_all);
342 }
343
344 g_object_set_data_full(G_OBJECT(widget), "reqtree", reqtree,
345 (GDestroyNotify) destroy_reqtree);
346}
347
348/************************************************************************/
351static void science_diagram_center(GtkWidget *diagram, Tech_type_id tech)
352{
353 GtkViewport *vp = GTK_VIEWPORT(gtk_widget_get_parent(diagram));
354 struct reqtree *reqtree;
355 int x, y, width, height;
356
357 reqtree = g_object_get_data(G_OBJECT(diagram), "reqtree");
359 if (find_tech_on_reqtree(reqtree, tech, &x, &y, NULL, NULL)) {
360 GtkAdjustment *adjust = NULL;
361 gdouble value;
362
363 adjust = gtk_scrollable_get_hadjustment(GTK_SCROLLABLE(vp));
364 value = (gtk_adjustment_get_lower(adjust)
365 + gtk_adjustment_get_upper(adjust)
366 - gtk_adjustment_get_page_size(adjust)) / width * x;
367 gtk_adjustment_set_value(adjust, value);
368
369 adjust = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vp));
370 value = (gtk_adjustment_get_lower(adjust)
371 + gtk_adjustment_get_upper(adjust)
372 - gtk_adjustment_get_page_size(adjust)) / height * y;
373 gtk_adjustment_set_value(adjust, value);
374 }
375}
376
377/************************************************************************/
380static void science_report_redraw(struct science_report *preport)
381{
382 Tech_type_id researching;
383
384 fc_assert_ret(NULL != preport);
385
386 science_diagram_data(GTK_WIDGET(preport->drawing_area),
387 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
388 preport->button_show_all)));
389
390 if (client_has_player()) {
391 researching = research_get(client_player())->researching;
392 } else {
393 researching = A_UNSET;
394 }
395 science_diagram_center(GTK_WIDGET(preport->drawing_area), researching);
396
397 gtk_widget_queue_draw(GTK_WIDGET(preport->drawing_area));
398}
399
400/************************************************************************/
403static gint cmp_func(gconstpointer a_p, gconstpointer b_p)
404{
405 const gchar *a_str, *b_str;
406 gint a = GPOINTER_TO_INT(a_p), b = GPOINTER_TO_INT(b_p);
407 const struct research *presearch = research_get(client_player());
408
409 a_str = research_advance_name_translation(presearch, a);
410 b_str = research_advance_name_translation(presearch, b);
411
412 return fc_strcoll(a_str, b_str);
413}
414
415/************************************************************************/
418static void science_report_update(struct science_report *preport)
419{
420 GtkListStore *store;
421 GtkTreeIter iter;
422 GList *sorting_list, *item;
423 struct research *presearch = research_get(client_player());
424 const char *text;
425 double pct;
426 Tech_type_id tech;
427
428 fc_assert_ret(NULL != preport);
429 fc_assert_ret(NULL != presearch);
430
431 /* Disable callbacks. */
433
434 gtk_widget_queue_draw(GTK_WIDGET(preport->drawing_area));
435
436 gtk_label_set_text(preport->main_label, science_dialog_text());
437
438 /* Update the progress bar. */
439 text = get_science_target_text(&pct);
440 gtk_progress_bar_set_text(preport->progress_bar, text);
441 gtk_progress_bar_set_fraction(preport->progress_bar, pct);
442 /* Work around GTK refresh bug? */
443 gtk_widget_queue_resize(GTK_WIDGET(preport->progress_bar));
444
445 /* Update reachable techs. */
446 store = GTK_LIST_STORE(gtk_combo_box_get_model(preport->reachable_techs));
447 gtk_list_store_clear(store);
448 sorting_list = NULL;
449
450 /* Collect all techs which are reachable in the next step. */
452 if (TECH_PREREQS_KNOWN == presearch->inventions[i].state) {
453 sorting_list = g_list_prepend(sorting_list, GINT_TO_POINTER(i));
454 }
456
457 if (sorting_list != NULL) {
458 if (A_UNSET == presearch->researching
459 || is_future_tech(presearch->researching)) {
460 gtk_list_store_append(store, &iter);
461 science_report_store_set(store, &iter, presearch->researching);
462 gtk_combo_box_set_active_iter(preport->reachable_techs, &iter);
463 }
464
465 /* Sort the list, append it to the store. */
466 sorting_list = g_list_sort(sorting_list, cmp_func);
467 for (item = sorting_list; NULL != item; item = g_list_next(item)) {
468 tech = GPOINTER_TO_INT(item->data);
469 gtk_list_store_append(store, &iter);
470 science_report_store_set(store, &iter, tech);
471 if (tech == presearch->researching) {
472 gtk_combo_box_set_active_iter(preport->reachable_techs, &iter);
473 }
474 }
475
476 /* Free, re-init. */
477 g_list_free(sorting_list);
478 sorting_list = NULL;
479 } else {
480 /* No reachable normal techs. Can we select Future Tech? */
481 Tech_type_id next;
482
483 gtk_list_store_append(store, &iter);
484 if (research_future_next(presearch)) {
485 next = A_FUTURE;
486 } else {
487 next = presearch->researching;
488 }
489 science_report_store_set(store, &iter, next);
490
491 gtk_combo_box_set_active_iter(preport->reachable_techs, &iter);
492 }
493
494 store = GTK_LIST_STORE(gtk_combo_box_get_model(preport->reachable_goals));
495 gtk_list_store_clear(store);
496
497 /* Update the tech goal. */
498 gtk_label_set_text(preport->goal_label,
499 get_science_goal_text(presearch->tech_goal));
500
501 /* Collect all techs which are reachable in next 10 steps. */
503 if (research_invention_reachable(presearch, i)
504 && TECH_KNOWN != presearch->inventions[i].state
505 && (i == presearch->tech_goal
506 || 10 >= presearch->inventions[i].num_required_techs)) {
507 sorting_list = g_list_prepend(sorting_list, GINT_TO_POINTER(i));
508 }
510
511 if (sorting_list != NULL) {
512 if (A_UNSET == presearch->tech_goal) {
513 gtk_list_store_append(store, &iter);
514 science_report_store_set(store, &iter, A_UNSET);
515 gtk_combo_box_set_active_iter(preport->reachable_goals, &iter);
516 }
517
518 /* Sort the list, append it to the store. */
519 sorting_list = g_list_sort(sorting_list, cmp_func);
520 for (item = sorting_list; NULL != item; item = g_list_next(item)) {
521 tech = GPOINTER_TO_INT(item->data);
522 gtk_list_store_append(store, &iter);
523 science_report_store_set(store, &iter, tech);
524 if (tech == presearch->tech_goal) {
525 gtk_combo_box_set_active_iter(preport->reachable_goals, &iter);
526 }
527 }
528
529 /* Free. */
530 g_list_free(sorting_list);
531 } else {
532 /* No reachable normal techs. Can we select Future Tech? */
533 Tech_type_id goal;
534
535 gtk_list_store_append(store, &iter);
536
537 if (research_future_next(presearch)) {
538 goal = A_FUTURE;
539 } else {
540 goal = A_UNSET;
541 }
542
543 science_report_store_set(store, &iter, goal);
544 gtk_combo_box_set_active_iter(preport->reachable_goals, &iter);
545 }
546
547 /* Re-enable callbacks. */
549}
550
551/************************************************************************/
554static void science_report_current_callback(GtkComboBox *combo,
555 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_check_button_get_active(GTK_CHECK_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. */
574}
575
576/************************************************************************/
579static void science_report_show_all_callback(GtkComboBox *combo,
580 gpointer data)
581{
582 struct science_report *preport = (struct science_report *) data;
583
584 science_report_redraw(preport);
585}
586
587/************************************************************************/
590static void science_report_goal_callback(GtkComboBox *combo, gpointer data)
591{
592 Tech_type_id tech;
593 char *tech_name;
594
595 if (!science_report_combo_get_active(combo, &tech, &tech_name)) {
596 return;
597 }
598
599 if (gtk_check_button_get_active(GTK_CHECK_BUTTON(data))) {
601 } else if (can_client_issue_orders()) {
603 }
604
605 free(tech_name);
606 /* Revert, or we will not be in sync with the server. */
608 (client_player())->tech_goal);
609}
610
611/************************************************************************/
614static void science_report_init(struct science_report *preport)
615{
616 GtkWidget *frame, *table, *help_button, *show_all_button, *sw, *w;
617 GtkSizeGroup *group;
618 GtkListStore *store;
619 GtkCellRenderer *renderer;
620
621 fc_assert_ret(NULL != preport);
622
623 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), NULL, TRUE);
624 /* TRANS: Research report title */
625 gui_dialog_set_title(preport->shell, _("Research"));
626
627 gui_dialog_add_button(preport->shell, "window-close", _("_Close"),
628 GTK_RESPONSE_CLOSE);
629
630 group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
631
632 w = gtk_label_new(NULL);
634 preport->main_label = GTK_LABEL(w);
635
636 /* Current research target line. */
637 frame = gtk_frame_new(_("Researching"));
638 gui_dialog_add_content_widget(preport->shell, frame);
639
640 table = gtk_grid_new();
641 gtk_grid_set_column_spacing(GTK_GRID(table), 4);
642 gtk_frame_set_child(GTK_FRAME(frame), table);
643
644 help_button = gtk_check_button_new_with_label(_("Help"));
645 gtk_grid_attach(GTK_GRID(table), help_button, 5, 0, 1, 1);
646
647 store = science_report_store_new();
648 w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
649 gtk_size_group_add_widget(group, w);
650 g_object_unref(G_OBJECT(store));
651 renderer = gtk_cell_renderer_text_new();
652 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), renderer, TRUE);
653 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(w), renderer, "text",
654 SRD_COL_NAME, NULL);
655 gtk_widget_set_sensitive(w, can_client_issue_orders());
656 g_signal_connect(w, "changed", G_CALLBACK(science_report_current_callback),
657 help_button);
658 gtk_grid_attach(GTK_GRID(table), w, 0, 0, 1, 1);
659 preport->reachable_techs = GTK_COMBO_BOX(w);
660
661 w = gtk_progress_bar_new();
662 gtk_widget_set_hexpand(w, TRUE);
663 gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(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->progress_bar = GTK_PROGRESS_BAR(w);
667
668 /* Research goal line. */
669 frame = gtk_frame_new( _("Goal"));
670 gui_dialog_add_content_widget(preport->shell, frame);
671
672 table = gtk_grid_new();
673 gtk_grid_set_column_spacing(GTK_GRID(table), 4);
674 gtk_frame_set_child(GTK_FRAME(frame), table);
675
676 store = science_report_store_new();
677 w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
678 gtk_size_group_add_widget(group, w);
679 g_object_unref(G_OBJECT(store));
680 renderer = gtk_cell_renderer_text_new();
681 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), renderer, TRUE);
682 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(w), renderer, "text",
683 SRD_COL_NAME, NULL);
684 renderer = gtk_cell_renderer_text_new();
685 gtk_cell_layout_pack_end(GTK_CELL_LAYOUT(w), renderer, FALSE);
686 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(w), renderer, "text",
687 SRD_COL_STEPS, NULL);
688 gtk_widget_set_sensitive(w, can_client_issue_orders());
689 g_signal_connect(w, "changed", G_CALLBACK(science_report_goal_callback),
690 help_button);
691 gtk_grid_attach(GTK_GRID(table), w, 0, 0, 1, 1);
692 preport->reachable_goals = GTK_COMBO_BOX(w);
693
694 w = gtk_label_new(NULL);
695 gtk_widget_set_hexpand(w, TRUE);
696 gtk_grid_attach(GTK_GRID(table), w, 2, 0, 1, 1);
697 gtk_widget_set_size_request(w, -1, 25);
698 preport->goal_label = GTK_LABEL(w);
699
700 /* Toggle "Show All" button. */
701 /* TRANS: As in 'Show all (even not reachable) techs'. */
702 show_all_button = gtk_toggle_button_new_with_label(_("Show all"));
703 gtk_grid_attach(GTK_GRID(table), show_all_button, 5, 0, 1, 1);
704 g_signal_connect(show_all_button, "toggled",
705 G_CALLBACK(science_report_show_all_callback), preport);
706 gtk_widget_set_sensitive(show_all_button, can_client_issue_orders()
708 preport->button_show_all = show_all_button;
709
710 /* Science diagram. */
711 sw = gtk_scrolled_window_new();
712 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
713 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
715
717 gtk_widget_set_hexpand(w, TRUE);
718 gtk_widget_set_vexpand(w, TRUE);
719 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), w);
720 preport->drawing_area = GTK_DRAWING_AREA(w);
721
722 science_report_update(preport);
723 gui_dialog_show_all(preport->shell);
724 gtk_widget_queue_draw(GTK_WIDGET(preport->drawing_area));
725 g_object_unref(group);
726
727 /* This must be _after_ the dialog is drawn to really center it ... */
728 science_report_redraw(preport);
729}
730
731/************************************************************************/
734static void science_report_free(struct science_report *preport)
735{
736 fc_assert_ret(NULL != preport);
737
738 gui_dialog_destroy(preport->shell);
739 fc_assert(NULL == preport->shell);
740
741 memset(preport, 0, sizeof(*preport));
742}
743
744/************************************************************************/
748{
749 struct research *presearch = research_get(client_player());
750
751 if (NULL == science_report.shell) {
753 }
754
755 if (NULL != presearch
756 && A_UNSET == presearch->tech_goal
757 && A_UNSET == presearch->researching) {
759 } else {
761 }
762
763 if (raise) {
765 }
766}
767
768/************************************************************************/
778
779/************************************************************************/
783{
784 if (NULL != science_report.shell) {
786 }
787}
788
789/************************************************************************/
793{
794 if (NULL != science_report.shell) {
796 }
797}
798
799
800/****************************************************************************
801 ECONOMY REPORT DIALOG
802****************************************************************************/
803struct economy_report {
804 struct gui_dialog *shell;
805 GtkTreeView *tree_view;
806 GtkLabel *label;
807};
808
809static struct economy_report economy_report = { NULL, NULL, NULL };
810
816
817/* Those values must match the functions economy_report_store_new() and
818 * economy_report_column_name(). */
834
835/************************************************************************/
838static GtkListStore *economy_report_store_new(void)
839{
840 return gtk_list_store_new(ERD_COL_NUM,
841 GDK_TYPE_PIXBUF, /* ERD_COL_SPRITE */
842 G_TYPE_STRING, /* ERD_COL_NAME */
843 G_TYPE_INT, /* ERD_COL_REDUNDANT */
844 G_TYPE_INT, /* ERD_COL_COUNT */
845 G_TYPE_INT, /* ERD_COL_COST */
846 G_TYPE_INT, /* ERD_COL_TOTAL_COST */
847 G_TYPE_STRING, /* ERD_COL_EMPTY */
848 G_TYPE_BOOLEAN, /* ERD_COL_IS_IMPROVEMENT */
849 G_TYPE_INT, /* ERD_COL_UNI_KIND */
850 G_TYPE_INT); /* ERD_COL_UNI_VALUE_ID */
851}
852
853/************************************************************************/
856static const char *
858{
859 switch (col) {
860 case ERD_COL_SPRITE:
861 /* TRANS: Image header */
862 return _("Type");
863 case ERD_COL_NAME:
864 return Q_("?Building or Unit type:Name");
866 return _("Redundant");
867 case ERD_COL_COUNT:
868 return _("Count");
869 case ERD_COL_COST:
870 return _("Cost");
872 /* TRANS: Upkeep total, count*cost. */
873 return _("U Total");
874 case ERD_COL_EMPTY:
875 /* empty space for scrollbar*/
876 return " ";
878 case ERD_COL_CID:
879 case ERD_COL_NUM:
880 break; /* no more columns will be displayed after reaching this */
881 }
882
883 return NULL;
884}
885
886/************************************************************************/
889static void economy_report_update(struct economy_report *preport)
890{
891 GtkTreeSelection *selection;
892 GtkTreeModel *model;
893 GtkListStore *store;
894 GtkTreeIter iter;
895 GdkPixbuf *pix;
896 struct improvement_entry building_entries[B_LAST];
897 struct unit_entry unit_entries[U_LAST];
898 int entries_used, building_total, unit_total, tax, i;
899 char buf[256];
900 cid selected;
901
902 fc_assert_ret(NULL != preport);
903
904 /* Save the selection. */
905 selection = gtk_tree_view_get_selection(preport->tree_view);
906 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
907 gtk_tree_model_get(model, &iter, ERD_COL_CID, &selected, -1);
908 } else {
909 selected = -1;
910 }
911
912 model = gtk_tree_view_get_model(preport->tree_view);
913 store = GTK_LIST_STORE(model);
914 gtk_list_store_clear(store);
915
916 /* Buildings. */
917 get_economy_report_data(building_entries, &entries_used,
918 &building_total, &tax);
919 for (i = 0; i < entries_used; i++) {
920 struct improvement_entry *pentry = building_entries + i;
921 struct impr_type *pimprove = pentry->type;
922 struct sprite *sprite = get_building_sprite(tileset, pimprove);
923 cid id = cid_encode_building(pimprove);
924
926 gtk_list_store_append(store, &iter);
927 gtk_list_store_set(store, &iter,
928 ERD_COL_SPRITE, pix,
931 ERD_COL_COUNT, pentry->count,
932 ERD_COL_COST, pentry->cost,
934 ERD_COL_EMPTY, " ",
936 ERD_COL_CID, id,
937 -1);
938 g_object_unref(G_OBJECT(pix));
939 if (selected == id) {
940 /* Restore the selection. */
941 gtk_tree_selection_select_iter(selection, &iter);
942 }
943 }
944
945 /* Units. */
946 get_economy_report_units_data(unit_entries, &entries_used, &unit_total);
947 for (i = 0; i < entries_used; i++) {
948 struct unit_entry *pentry = unit_entries + i;
949 struct unit_type *putype = pentry->type;
950 struct sprite *sprite = get_unittype_sprite(tileset, putype,
951 direction8_invalid());
952 cid id = cid_encode_unit(putype);
953
955 gtk_list_store_append(store, &iter);
956 gtk_list_store_set(store, &iter,
957 ERD_COL_SPRITE, pix,
960 ERD_COL_COUNT, pentry->count,
961 ERD_COL_COST, pentry->cost,
963 ERD_COL_EMPTY, " ",
965 ERD_COL_CID, id,
966 -1);
967 g_object_unref(G_OBJECT(pix));
968 if (selected == id) {
969 /* Restore the selection. */
970 gtk_tree_selection_select_iter(selection, &iter);
971 }
972 }
973
974 /* Update the label. */
975 fc_snprintf(buf, sizeof(buf), _("Income: %d Total Costs: %d"),
976 tax, building_total + unit_total);
977 gtk_label_set_text(preport->label, buf);
978}
979
980/************************************************************************/
983static void economy_report_command_callback(struct gui_dialog *pdialog,
984 int response,
985 gpointer data)
986{
987 struct economy_report *preport = data;
988 GtkTreeSelection *selection = gtk_tree_view_get_selection(preport->tree_view);
989 GtkTreeModel *model;
990 GtkTreeIter iter;
991 GtkWidget *shell;
992 struct universal selected;
993 cid id;
994 char buf[256] = "";
995
996 switch (response) {
998 case ERD_RES_SELL_ALL:
1000 break;
1001 default:
1002 gui_dialog_destroy(pdialog);
1003 return;
1004 }
1005
1007 || !gtk_tree_selection_get_selected(selection, &model, &iter)) {
1008 return;
1009 }
1010
1011 gtk_tree_model_get(model, &iter, ERD_COL_CID, &id, -1);
1012 selected = cid_decode(id);
1013
1014 switch (selected.kind) {
1015 case VUT_IMPROVEMENT:
1016 {
1017 const struct impr_type *pimprove = selected.value.building;
1018
1019 if (can_sell_building(pimprove)
1020 && (ERD_RES_SELL_ALL == response
1021 || (ERD_RES_SELL_REDUNDANT == response))) {
1022 bool redundant = (ERD_RES_SELL_REDUNDANT == response);
1023 gint count;
1024 gtk_tree_model_get(model, &iter,
1025 redundant ? ERD_COL_REDUNDANT : ERD_COL_COUNT,
1026 &count, -1);
1027 if (count == 0) {
1028 break;
1029 }
1030 shell = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL
1031 | GTK_DIALOG_DESTROY_WITH_PARENT,
1032 GTK_MESSAGE_QUESTION,
1033 GTK_BUTTONS_YES_NO,
1034 redundant
1035 /* TRANS: %s is an improvement */
1036 ? _("Do you really wish to sell "
1037 "every redundant %s (%d total)?")
1038 /* TRANS: %s is an improvement */
1039 : _("Do you really wish to sell "
1040 "every %s (%d total)?"),
1042 count);
1044 gtk_window_set_title(GTK_WINDOW(shell), _("Sell Improvements"));
1045
1046 if (GTK_RESPONSE_YES == blocking_dialog(shell)) {
1047 sell_all_improvements(pimprove, redundant, buf, sizeof(buf));
1048 }
1049 gtk_window_destroy(GTK_WINDOW(shell));
1050 }
1051 }
1052 break;
1053 case VUT_UTYPE:
1054 {
1055 if (ERD_RES_DISBAND_UNITS == response) {
1056 const struct unit_type *putype = selected.value.utype;
1057 gint count;
1058
1059 gtk_tree_model_get(model, &iter, ERD_COL_COUNT, &count, -1);
1060
1061 shell = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL
1062 | GTK_DIALOG_DESTROY_WITH_PARENT,
1063 GTK_MESSAGE_QUESTION,
1064 GTK_BUTTONS_YES_NO,
1065 /* TRANS: %s is a unit */
1066 _("Do you really wish to disband "
1067 "every %s (%d total)?"),
1068 utype_name_translation(putype),
1069 count);
1071 gtk_window_set_title(GTK_WINDOW(shell), _("Disband Units"));
1072
1073 if (GTK_RESPONSE_YES == blocking_dialog(shell)) {
1074 disband_all_units(putype, FALSE, buf, sizeof(buf));
1075 }
1076 gtk_window_destroy(GTK_WINDOW(shell));
1077 }
1078 }
1079 break;
1080 default:
1081 log_error("Not supported type: %d.", selected.kind);
1082 }
1083
1084 if ('\0' != buf[0]) {
1085 shell = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
1086 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
1087 "%s", buf);
1089 g_signal_connect(shell, "response", G_CALLBACK(gtk_window_destroy),
1090 NULL);
1091 gtk_window_set_title(GTK_WINDOW(shell), _("Sell-Off: Results"));
1092 gtk_window_present(GTK_WINDOW(shell));
1093 }
1094}
1095
1096/************************************************************************/
1099static void economy_report_selection_callback(GtkTreeSelection *selection,
1100 gpointer data)
1101{
1102 struct gui_dialog *pdialog = ((struct economy_report *)data)->shell;
1103 GtkTreeModel *model;
1104 GtkTreeIter iter;
1105
1107 && gtk_tree_selection_get_selected(selection, &model, &iter)) {
1108 struct universal selected;
1109 cid id;
1110
1111 gtk_tree_model_get(model, &iter, ERD_COL_CID, &id, -1);
1112 selected = cid_decode(id);
1113 switch (selected.kind) {
1114 case VUT_IMPROVEMENT:
1115 {
1116 bool can_sell = can_sell_building(selected.value.building);
1117 gint redundant;
1118 gtk_tree_model_get(model, &iter, ERD_COL_REDUNDANT, &redundant, -1);
1119
1121 can_sell && redundant > 0);
1124 FALSE);
1125 }
1126 return;
1127 case VUT_UTYPE:
1129 FALSE);
1132 TRUE);
1133 return;
1134 default:
1135 log_error("Not supported type: %d.", selected.kind);
1136 break;
1137 }
1138 }
1139
1143}
1144
1145/************************************************************************/
1148static void economy_report_init(struct economy_report *preport)
1149{
1150 GtkWidget *view, *sw, *label, *button;
1151 GtkListStore *store;
1152 GtkTreeSelection *selection;
1153 const char *title;
1155
1156 fc_assert_ret(NULL != preport);
1157
1158 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), preport, TRUE);
1159 gui_dialog_set_title(preport->shell, _("Economy"));
1160
1161 sw = gtk_scrolled_window_new();
1162 gtk_widget_set_halign(sw, GTK_ALIGN_CENTER);
1163 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
1164 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1165 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1167
1168 store = economy_report_store_new();
1169 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1170 gtk_widget_set_vexpand(view, TRUE);
1171 g_object_unref(store);
1172 gtk_widget_set_name(view, "small_font");
1173 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(view));
1174 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
1175 preport->tree_view = GTK_TREE_VIEW(view);
1176
1177 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1178 g_signal_connect(selection, "changed",
1179 G_CALLBACK(economy_report_selection_callback), preport);
1180
1181 for (i = 0; (title = economy_report_column_name(i)); i++) {
1182 GtkCellRenderer *renderer;
1183 GtkTreeViewColumn *col;
1184 GType type = gtk_tree_model_get_column_type(GTK_TREE_MODEL(store), i);
1185
1186 if (GDK_TYPE_PIXBUF == type) {
1187 renderer = gtk_cell_renderer_pixbuf_new();
1188 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1189 "pixbuf", i, NULL);
1190#if 0
1191 } else if (G_TYPE_BOOLEAN == type) {
1192 renderer = gtk_cell_renderer_toggle_new();
1193 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1194 "active", i, NULL);
1195#endif
1196 } else {
1197 bool is_redundant = (i == ERD_COL_REDUNDANT);
1198 renderer = gtk_cell_renderer_text_new();
1199 if (is_redundant) {
1200 /* Special treatment: hide "Redundant" column for units */
1201 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1202 "text", i,
1203 "visible",
1205 NULL);
1206 } else {
1207 col = gtk_tree_view_column_new_with_attributes(title, renderer,
1208 "text", i, NULL);
1209 }
1210 }
1211
1212 if (i > 1) {
1213 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
1214 gtk_tree_view_column_set_alignment(col, 1.0);
1215 }
1216
1217 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1218 }
1219
1220 label = gtk_label_new(NULL);
1221 gui_dialog_add_content_widget(preport->shell, label);
1222 gtk_widget_set_margin_start(label, 5);
1223 gtk_widget_set_margin_end(label, 5);
1224 gtk_widget_set_margin_top(label, 5);
1225 gtk_widget_set_margin_bottom(label, 5);
1226 preport->label = GTK_LABEL(label);
1227
1228 gui_dialog_add_button(preport->shell, "window-close", _("_Close"),
1229 GTK_RESPONSE_CLOSE);
1230
1231 button = gui_dialog_add_button(preport->shell, NULL, _("_Disband"),
1233 gtk_widget_set_sensitive(button, FALSE);
1234
1235 button = gui_dialog_add_button(preport->shell, NULL, _("Sell _All"),
1237 gtk_widget_set_sensitive(button, FALSE);
1238
1239 button = gui_dialog_add_button(preport->shell, NULL, _("Sell _Redundant"),
1241 gtk_widget_set_sensitive(button, FALSE);
1242
1245
1246 gui_dialog_set_default_size(preport->shell, -1, 350);
1247 gui_dialog_show_all(preport->shell);
1248
1249 economy_report_update(preport);
1250
1251 gtk_tree_view_focus(GTK_TREE_VIEW(view));
1252}
1253
1254/************************************************************************/
1257static void economy_report_free(struct economy_report *preport)
1258{
1259 fc_assert_ret(NULL != preport);
1260
1261 gui_dialog_destroy(preport->shell);
1262 fc_assert(NULL == preport->shell);
1263
1264 memset(preport, 0, sizeof(*preport));
1265}
1266
1267/************************************************************************/
1271{
1272 if (NULL == economy_report.shell) {
1274 }
1275
1277 if (raise) {
1279 }
1280}
1281
1282/************************************************************************/
1286{
1287 if (NULL != economy_report.shell) {
1289 }
1290}
1291
1292/************************************************************************/
1296{
1297 if (NULL != economy_report.shell) {
1299 }
1300}
1301
1302
1303/****************************************************************************
1304 UNITS REPORT DIALOG
1305****************************************************************************/
1306struct units_report {
1307 struct gui_dialog *shell;
1308 GtkTreeView *tree_view;
1309};
1310
1311static struct units_report units_report = { NULL, NULL };
1312
1317
1318/* Those values must match the order of unit_report_columns[]. */
1338
1339static const struct {
1340 GType type;
1341 const char *title;
1342 const char *tooltip;
1345} unit_report_columns[] = {
1346 { /* URD_COL_UTYPE_NAME */ G_TYPE_STRING, N_("Unit Type"),
1347 NULL, FALSE, -1 },
1348 { /* URD_COL_UPGRADABLE */ G_TYPE_BOOLEAN, N_("?Upgradable unit [short]:U"),
1349 N_("Upgradable"), TRUE, URD_COL_UPG_VISIBLE },
1350 { /* URD_COL_N_UPGRADABLE */ G_TYPE_INT, "" /* merge with previous col */,
1351 NULL, TRUE, URD_COL_NUPG_VISIBLE },
1352 /* TRANS: "In progress" abbreviation. */
1353 { /* URD_COL_IN_PROGRESS */ G_TYPE_INT, N_("In-Prog"),
1354 N_("In progress"), TRUE, -1 },
1355 { /* URD_COL_ACTIVE */ G_TYPE_INT, N_("Active"),
1356 NULL, TRUE, -1 },
1357 { /* URD_COL_SHIELD */ G_TYPE_INT, N_("Shield"),
1358 N_("Total shield upkeep"), TRUE, -1 },
1359 { /* URD_COL_FOOD */ G_TYPE_INT, N_("Food"),
1360 N_("Total food upkeep"), TRUE, -1 },
1361 { /* URD_COL_GOLD */ G_TYPE_INT, N_("Gold"),
1362 N_("Total gold upkeep"), TRUE, -1 },
1363 { /* URD_COL_EMPTY */ G_TYPE_STRING, " ",
1364 " ", TRUE, -1 },
1365
1366 { /* URD_COL_TEXT_WEIGHT */ G_TYPE_INT, NULL /* ... */ },
1367 { /* URD_COL_UPG_VISIBLE */ G_TYPE_BOOLEAN, NULL /* ... */ },
1368 { /* URD_COL_NUPG_VISIBLE */ G_TYPE_BOOLEAN, NULL /* ... */ },
1369 { /* URD_COL_UTYPE_ID */ G_TYPE_INT, NULL /* ... */ }
1371
1372/************************************************************************/
1375static GtkListStore *units_report_store_new(void)
1376{
1377 int i;
1378 GType cols[URD_COL_NUM];
1380
1381 for (i=0; i<URD_COL_NUM; i++) {
1382 cols[i] = unit_report_columns[i].type;
1383 }
1384
1385 return gtk_list_store_newv(URD_COL_NUM, cols);
1386}
1387
1388/************************************************************************/
1391static void units_report_update(struct units_report *preport)
1392{
1393 struct urd_info {
1394 int active_count;
1395 int building_count;
1396 int upkeep[O_LAST];
1397 };
1398
1399 struct urd_info unit_array[utype_count()];
1400 struct urd_info unit_totals;
1401 struct urd_info *info;
1402 int total_upgradable_count = 0;
1403 GtkTreeSelection *selection;
1404 GtkTreeModel *model;
1405 GtkListStore *store;
1406 GtkTreeIter iter;
1407 Unit_type_id selected, utype_id;
1408
1409 fc_assert_ret(NULL != preport);
1410
1411 memset(unit_array, '\0', sizeof(unit_array));
1412 memset(&unit_totals, '\0', sizeof(unit_totals));
1413
1414 /* Count units. */
1415 players_iterate(pplayer) {
1416 if (client_has_player() && pplayer != client_player()) {
1417 continue;
1418 }
1419
1420 unit_list_iterate(pplayer->units, punit) {
1421 info = unit_array + utype_index(unit_type_get(punit));
1422
1423 if (0 != punit->homecity) {
1425 info->upkeep[o] += punit->upkeep[o];
1427 }
1428 info->active_count++;
1430 city_list_iterate(pplayer->cities, pcity) {
1431 if (VUT_UTYPE == pcity->production.kind) {
1432 int num_units;
1433 info = unit_array + utype_index(pcity->production.value.utype);
1434 /* Account for build slots in city */
1435 (void) city_production_build_units(pcity, TRUE, &num_units);
1436 /* Unit is in progress even if it won't be done this turn */
1437 num_units = MAX(num_units, 1);
1438 info->building_count += num_units;
1439 }
1442
1443 /* Save selection. */
1444 selection = gtk_tree_view_get_selection(preport->tree_view);
1445 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
1446 gtk_tree_model_get(model, &iter, URD_COL_UTYPE_ID, &selected, -1);
1447 } else {
1448 selected = -1;
1449 }
1450
1451 /* Make the store. */
1452 model = gtk_tree_view_get_model(preport->tree_view);
1453 store = GTK_LIST_STORE(model);
1454 gtk_list_store_clear(store);
1455
1456 unit_type_iterate(utype) {
1457 bool upgradable;
1458
1459 utype_id = utype_index(utype);
1460 info = unit_array + utype_id;
1461
1462 if (0 == info->active_count && 0 == info->building_count) {
1463 continue; /* We don't need a row for this type. */
1464 }
1465
1466 upgradable = client_has_player()
1467 && NULL != can_upgrade_unittype(client_player(), utype);
1468
1469 gtk_list_store_append(store, &iter);
1470 gtk_list_store_set(store, &iter,
1472 URD_COL_UPGRADABLE, upgradable,
1473 URD_COL_N_UPGRADABLE, 0, /* never displayed */
1474 URD_COL_IN_PROGRESS, info->building_count,
1475 URD_COL_ACTIVE, info->active_count,
1476 URD_COL_SHIELD, info->upkeep[O_SHIELD],
1477 URD_COL_FOOD, info->upkeep[O_FOOD],
1478 URD_COL_GOLD, info->upkeep[O_GOLD],
1479 URD_COL_EMPTY, " ",
1480 URD_COL_TEXT_WEIGHT, PANGO_WEIGHT_NORMAL,
1483 URD_COL_UTYPE_ID, utype_id,
1484 -1);
1485 if (selected == utype_id) {
1486 /* Restore the selection. */
1487 gtk_tree_selection_select_iter(selection, &iter);
1488 }
1489
1490 /* Update totals. */
1491 unit_totals.active_count += info->active_count;
1493 unit_totals.upkeep[o] += info->upkeep[o];
1495 unit_totals.building_count += info->building_count;
1496 if (upgradable) {
1497 total_upgradable_count += info->active_count;
1498 }
1500
1501 /* Add the total row. */
1502 gtk_list_store_append(store, &iter);
1503 gtk_list_store_set(store, &iter,
1504 URD_COL_UTYPE_NAME, _("Totals:"),
1505 URD_COL_UPGRADABLE, FALSE, /* never displayed */
1506 URD_COL_N_UPGRADABLE, total_upgradable_count,
1507 URD_COL_IN_PROGRESS, unit_totals.building_count,
1508 URD_COL_ACTIVE, unit_totals.active_count,
1509 URD_COL_SHIELD, unit_totals.upkeep[O_SHIELD],
1510 URD_COL_FOOD, unit_totals.upkeep[O_FOOD],
1511 URD_COL_GOLD, unit_totals.upkeep[O_GOLD],
1512 URD_COL_EMPTY, " ",
1513 URD_COL_TEXT_WEIGHT, PANGO_WEIGHT_BOLD,
1517 -1);
1518 if (selected == U_LAST) {
1519 /* Restore the selection. */
1520 gtk_tree_selection_select_iter(selection, &iter);
1521 }
1522}
1523
1524/************************************************************************/
1527static void units_report_selection_callback(GtkTreeSelection *selection,
1528 gpointer data)
1529{
1530 struct units_report *preport = data;
1531 GtkTreeModel *model;
1532 GtkTreeIter it;
1533 int active_count;
1534 struct unit_type *utype = NULL;
1535
1536 if (gtk_tree_selection_get_selected(selection, &model, &it)) {
1537 int ut;
1538
1539 gtk_tree_model_get(model, &it,
1540 URD_COL_ACTIVE, &active_count,
1541 URD_COL_UTYPE_ID, &ut,
1542 -1);
1543 if (0 < active_count) {
1544 utype = utype_by_number(ut);
1545 }
1546 }
1547
1548 if (NULL == utype) {
1550 FALSE);
1552 FALSE);
1553 } else {
1557 && action_ever_possible(ACTION_UPGRADE_UNIT)
1558 && NULL != can_upgrade_unittype(client_player(), utype)));
1559 }
1560}
1561
1562/************************************************************************/
1565static struct unit *find_nearest_unit(const struct unit_type *utype,
1566 struct tile *ptile)
1567{
1568 struct unit *best_candidate = NULL;
1569 int best_dist = FC_INFINITY, dist;
1570
1571 players_iterate(pplayer) {
1572 if (client_has_player() && pplayer != client_player()) {
1573 continue;
1574 }
1575
1576 unit_list_iterate(pplayer->units, punit) {
1577 if (utype == unit_type_get(punit)
1579 && 0 < punit->moves_left
1580 && !punit->done_moving
1581 && punit->ssa_controller == SSA_NONE) {
1582 dist = sq_map_distance(unit_tile(punit), ptile);
1583 if (dist < best_dist) {
1584 best_candidate = punit;
1585 best_dist = dist;
1586 }
1587 }
1590
1591 return best_candidate;
1592}
1593
1594/************************************************************************/
1597static void units_report_command_callback(struct gui_dialog *pdialog,
1598 int response,
1599 gpointer data)
1600{
1601 struct units_report *preport = data;
1602 struct unit_type *utype = NULL;
1603 GtkTreeSelection *selection;
1604 GtkTreeModel *model;
1605 GtkTreeIter it;
1606
1607 switch (response) {
1608 case URD_RES_NEAREST:
1609 case URD_RES_UPGRADE:
1610 break;
1611 default:
1612 gui_dialog_destroy(pdialog);
1613 return;
1614 }
1615
1616 /* Nearest & upgrade commands. */
1617 selection = gtk_tree_view_get_selection(preport->tree_view);
1618 if (gtk_tree_selection_get_selected(selection, &model, &it)) {
1619 int ut;
1620
1621 gtk_tree_model_get(model, &it, URD_COL_UTYPE_ID, &ut, -1);
1622 utype = utype_by_number(ut);
1623 }
1624
1625 if (response == URD_RES_NEAREST) {
1626 struct tile *ptile;
1627 struct unit *punit;
1628
1629 ptile = get_center_tile_mapcanvas();
1630 if ((punit = find_nearest_unit(utype, ptile))) {
1632
1633 if (ACTIVITY_IDLE == punit->activity
1634 || ACTIVITY_SENTRY == punit->activity) {
1635 if (can_unit_do_activity_client(punit, ACTIVITY_IDLE)) {
1637 }
1638 }
1639 }
1640 } else if (can_client_issue_orders()) {
1641 GtkWidget *shell;
1642 const struct unit_type *upgrade = can_upgrade_unittype(client_player(), utype);
1643 char buf[1024];
1644 int price = unit_upgrade_price(client_player(), utype, upgrade);
1645
1646 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Treasury contains %d gold.",
1647 "Treasury contains %d gold.",
1648 client_player()->economic.gold),
1649 client_player()->economic.gold);
1650
1651 shell = gtk_message_dialog_new(NULL,
1652 GTK_DIALOG_MODAL
1653 | GTK_DIALOG_DESTROY_WITH_PARENT,
1654 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1655 /* TRANS: Last %s is pre-pluralised
1656 * "Treasury contains %d gold." */
1657 PL_("Upgrade as many %s to %s as possible "
1658 "for %d gold each?\n%s",
1659 "Upgrade as many %s to %s as possible "
1660 "for %d gold each?\n%s", price),
1662 utype_name_translation(upgrade),
1663 price, buf);
1665
1666 gtk_window_set_title(GTK_WINDOW(shell), _("Upgrade Obsolete Units"));
1667
1668 if (GTK_RESPONSE_YES == blocking_dialog(shell)) {
1670 }
1671
1672 gtk_window_destroy(GTK_WINDOW(shell));
1673 }
1674}
1675
1676/************************************************************************/
1679static void units_report_init(struct units_report *preport)
1680{
1681 GtkWidget *view, *sw, *button;
1682 GtkListStore *store;
1683 GtkTreeSelection *selection;
1684 GtkTreeViewColumn *col = NULL;
1685 enum units_report_columns i;
1686
1687 fc_assert_ret(NULL != preport);
1688
1689 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), preport, TRUE);
1690 gui_dialog_set_title(preport->shell, _("Units"));
1691
1692 sw = gtk_scrolled_window_new();
1693 gtk_widget_set_halign(sw, GTK_ALIGN_CENTER);
1694 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
1695 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1696 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1698
1699 store = units_report_store_new();
1700 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1701 gtk_widget_set_vexpand(view, TRUE);
1702 g_object_unref(store);
1703 gtk_widget_set_name(view, "small_font");
1704 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(view));
1705 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
1706 preport->tree_view = GTK_TREE_VIEW(view);
1707
1708 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1709 g_signal_connect(selection, "changed",
1710 G_CALLBACK(units_report_selection_callback), preport);
1711
1712 for (i = 0; unit_report_columns[i].title != NULL; i++) {
1713 GtkCellRenderer *renderer;
1714
1715 if (strlen(unit_report_columns[i].title) > 0) {
1716 GtkWidget *header = gtk_label_new(Q_(unit_report_columns[i].title));
1718 gtk_widget_set_tooltip_text(header,
1720 }
1721 gtk_widget_show(header);
1722 col = gtk_tree_view_column_new();
1723 gtk_tree_view_column_set_widget(col, header);
1725 gtk_tree_view_column_set_alignment(col, 1.0);
1726 }
1727 gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
1728 } /* else add new renderer to previous TreeViewColumn */
1729
1730 fc_assert(col != NULL);
1731 if (G_TYPE_BOOLEAN == unit_report_columns[i].type) {
1732 renderer = gtk_cell_renderer_toggle_new();
1733 gtk_tree_view_column_pack_start(col, renderer, FALSE);
1734 gtk_tree_view_column_add_attribute(col, renderer, "active", i);
1735 } else {
1736 renderer = gtk_cell_renderer_text_new();
1737 gtk_tree_view_column_pack_start(col, renderer, TRUE);
1738 gtk_tree_view_column_add_attribute(col, renderer, "text", i);
1739 gtk_tree_view_column_add_attribute(col, renderer,
1740 "weight", URD_COL_TEXT_WEIGHT);
1741 }
1742
1743 if (unit_report_columns[i].visible_col >= 0) {
1744 gtk_tree_view_column_add_attribute(col, renderer, "visible",
1746 }
1747
1749 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
1750 }
1751 }
1752
1753 gui_dialog_add_button(preport->shell, "window-close", _("_Close"),
1754 GTK_RESPONSE_CLOSE);
1755
1756 button = gui_dialog_add_button(preport->shell, NULL, _("_Upgrade"),
1758 gtk_widget_set_sensitive(button, FALSE);
1759
1760 button = gui_dialog_add_button(preport->shell, "edit-find",
1761 _("Find _Nearest"), URD_RES_NEAREST);
1762 gtk_widget_set_sensitive(button, FALSE);
1763
1766
1767 gui_dialog_set_default_size(preport->shell, -1, 350);
1768 gui_dialog_show_all(preport->shell);
1769
1770 units_report_update(preport);
1771 gtk_tree_view_focus(GTK_TREE_VIEW(view));
1772}
1773
1774/************************************************************************/
1777static void units_report_free(struct units_report *preport)
1778{
1779 fc_assert_ret(NULL != preport);
1780
1781 gui_dialog_destroy(preport->shell);
1782 fc_assert(NULL == preport->shell);
1783
1784 memset(preport, 0, sizeof(*preport));
1785}
1786
1787/************************************************************************/
1791{
1792 if (NULL == units_report.shell) {
1794 }
1795
1797 if (raise) {
1799 }
1800}
1801
1802/************************************************************************/
1806{
1807 if (NULL != units_report.shell) {
1809 fc_assert(NULL == units_report.shell);
1810 }
1811}
1812
1813/************************************************************************/
1817{
1818 if (NULL != units_report.shell) {
1820 }
1821}
1822
1823
1824/****************************************************************************
1825 FINAL REPORT DIALOG
1826****************************************************************************/
1827struct endgame_report {
1828 struct gui_dialog *shell;
1829 GtkTreeView *tree_view;
1830 GtkListStore *store;
1831 int player_count;
1832 int players_received;
1833};
1834
1843
1844static struct endgame_report endgame_report = { NULL, NULL };
1845
1846/************************************************************************/
1849static const char *
1851{
1852 switch (col) {
1853 case FRD_COL_PLAYER:
1854 return _("Player\n");
1855 case FRD_COL_NATION:
1856 return _("Nation\n");
1857 case FRD_COL_SCORE:
1858 return _("Score\n");
1859 case FRD_COL_TOOLTIP:
1860 case FRD_COL_NUM:
1861 break;
1862 }
1863
1864 return NULL;
1865}
1866
1867/************************************************************************/
1870static void endgame_report_update(struct endgame_report *preport,
1871 const struct packet_endgame_report *packet)
1872{
1873 const size_t col_num = packet->category_num + FRD_COL_NUM;
1874 GType col_types[col_num];
1875 GtkListStore *store;
1876 GtkTreeViewColumn *col;
1877 int i;
1878
1879 fc_assert_ret(NULL != preport);
1880
1881 /* Remove the old columns. */
1882 while ((col = gtk_tree_view_get_column(preport->tree_view, 0))) {
1883 gtk_tree_view_remove_column(preport->tree_view, col);
1884 }
1885
1886 /* Create the new model. */
1887 col_types[FRD_COL_PLAYER] = G_TYPE_STRING;
1888 col_types[FRD_COL_NATION] = GDK_TYPE_PIXBUF;
1889 col_types[FRD_COL_SCORE] = G_TYPE_INT;
1890 col_types[FRD_COL_TOOLTIP] = G_TYPE_STRING;
1891 for (i = FRD_COL_NUM; (guint)i < col_num; i++) {
1892 col_types[i] = G_TYPE_INT;
1893 }
1894 store = gtk_list_store_newv(col_num, col_types);
1895 gtk_tree_view_set_model(preport->tree_view, GTK_TREE_MODEL(store));
1896 g_object_unref(G_OBJECT(store));
1897
1898 /* Create the new columns. */
1899 for (i = 0; (guint)i < col_num; i++) {
1900 GtkCellRenderer *renderer;
1901 const char *title;
1902 const char *attribute;
1903
1904 if (GDK_TYPE_PIXBUF == col_types[i]) {
1905 renderer = gtk_cell_renderer_pixbuf_new();
1906 attribute = "pixbuf";
1907 } else {
1908 renderer = gtk_cell_renderer_text_new();
1909 attribute = "text";
1910 }
1911
1912 if (i < FRD_COL_NUM) {
1914 } else {
1915 title = packet->category_name[i - FRD_COL_NUM];
1916 }
1917
1918 if (title != NULL) {
1919 col = gtk_tree_view_column_new_with_attributes(Q_(title), renderer,
1920 attribute, i, NULL);
1921 gtk_tree_view_append_column(preport->tree_view, col);
1922 if (GDK_TYPE_PIXBUF != col_types[i]) {
1923 gtk_tree_view_column_set_sort_column_id(col, i);
1924 }
1925 }
1926 }
1927
1928 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(preport->tree_view),
1930
1931 preport->store = store;
1932 preport->player_count = packet->player_num;
1933 preport->players_received = 0;
1934}
1935
1936/************************************************************************/
1940{
1941 /* Fill the model with player stats. */
1942 struct endgame_report *preport = &endgame_report;
1943 const struct player *pplayer = player_by_number(packet->player_id);
1944 GtkTreeIter iter;
1945 int i;
1946
1947 gtk_list_store_append(preport->store, &iter);
1948 gtk_list_store_set(preport->store, &iter,
1949 FRD_COL_PLAYER, player_name(pplayer),
1951 FRD_COL_SCORE, packet->score,
1952 FRD_COL_TOOLTIP, score_tooltip(pplayer, packet->score),
1953 -1);
1954 for (i = 0; i < packet->category_num; i++) {
1955 gtk_list_store_set(preport->store, &iter,
1956 i + FRD_COL_NUM, packet->category_score[i],
1957 -1);
1958 }
1959
1960 preport->players_received++;
1961
1962 if (preport->players_received == preport->player_count) {
1963 gui_dialog_present(preport->shell);
1964 }
1965}
1966
1967/************************************************************************/
1970static void endgame_report_init(struct endgame_report *preport)
1971{
1972 GtkWidget *sw, *view;
1973
1974 fc_assert_ret(NULL != preport);
1975
1976 gui_dialog_new(&preport->shell, GTK_NOTEBOOK(top_notebook), NULL, TRUE);
1977 gui_dialog_set_title(preport->shell, _("Score"));
1978
1979 gui_dialog_set_default_size(preport->shell, 700, 420);
1980
1981 /* Setup the layout. */
1982 sw = gtk_scrolled_window_new();
1983 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
1984 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
1985 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
1987
1988 view = gtk_tree_view_new();
1989 gtk_widget_set_name(view, "small_font");
1990 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view);
1991 preport->tree_view = GTK_TREE_VIEW(view);
1992
1993 if (preport->shell->type == GUI_DIALOG_TAB) {
1994 gtk_widget_set_hexpand(GTK_WIDGET(view), TRUE);
1995 gtk_widget_set_vexpand(GTK_WIDGET(view), TRUE);
1996 }
1997
1998 gui_dialog_show_all(preport->shell);
1999}
2000
2001/************************************************************************/
2005{
2006 if (NULL == endgame_report.shell) {
2008 }
2010}
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
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 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 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
gint blocking_dialog(GtkWidget *dlg)
Definition gui_stuff.c:1126
void gui_dialog_add_content_widget(struct gui_dialog *dlg, GtkWidget *wdg)
Definition gui_stuff.c:1095
static gboolean science_diagram_left_button_up(GtkGestureClick *gesture, int n_press, double x, double y)
Definition repodlgs.c:202
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
static gboolean science_diagram_right_button_up(GtkGestureClick *gesture, int n_press, double x, double y)
Definition repodlgs.c:238
@ 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
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
GtkDrawingArea * drawing_area
Definition repodlgs.c:77
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