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 <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include <X11/Intrinsic.h>
23 #include <X11/Shell.h>
24 #include <X11/StringDefs.h>
25 #include <X11/Xaw/AsciiText.h>
26 #include <X11/Xaw/Command.h>
27 #include <X11/Xaw/Form.h>
28 #include <X11/Xaw/Label.h>
29 #include <X11/Xaw/List.h>
30 #include <X11/Xaw/MenuButton.h>
31 #include <X11/Xaw/SimpleMenu.h>
32 #include <X11/Xaw/SmeBSB.h>
33 #include <X11/Xaw/Toggle.h>
34 #include <X11/Xaw/Viewport.h>
35 
36 /* utility */
37 #include "fcintl.h"
38 #include "log.h"
39 #include "shared.h"
40 #include "support.h"
41 
42 /* common */
43 #include "city.h"
44 #include "game.h"
45 #include "government.h"
46 #include "packets.h"
47 #include "research.h"
48 #include "unitlist.h"
49 
50 /* client */
51 #include "chatline_common.h" /* for send_chat() */
52 #include "client_main.h"
53 #include "climisc.h"
54 #include "text.h"
55 
56 /* client/gui-xaw */
57 #include "cityrep.h"
58 #include "dialogs.h"
59 #include "gui_main.h"
60 #include "gui_stuff.h"
61 #include "helpdlg.h"
62 #include "optiondlg.h"
63 
64 #include "repodlgs_common.h"
65 #include "repodlgs.h"
66 
67 /******************************************************************/
68 static Widget science_dialog_shell;
69 static Widget science_label;
70 static Widget science_current_label, science_goal_label;
71 static Widget science_change_menu_button, science_goal_menu_button;
72 static Widget science_list, science_help_toggle;
73 static Widget science_help_note;
74 static Widget popupmenu, goalmenu;
75 static int science_dialog_shell_is_modal;
76 
77 void create_science_dialog(bool make_modal);
78 void science_close_callback(Widget w, XtPointer client_data,
79 			    XtPointer call_data);
80 void science_help_callback(Widget w, XtPointer client_data,
81 			   XtPointer call_data);
82 void science_change_callback(Widget w, XtPointer client_data,
83 			     XtPointer call_data);
84 void science_goal_callback(Widget w, XtPointer client_data,
85 			   XtPointer call_data);
86 
87 
88 /******************************************************************/
89 static Widget economy_dialog_shell;
90 static Widget economy_label, economy_label2;
91 static Widget economy_list, economy_list_label;
92 static Widget sellall_command, sellredundant_command;
93 static int economy_dialog_shell_is_modal;
94 static struct impr_type *economy_improvement_type[B_LAST];
95 static bool economy_improvement_redundant[B_LAST];
96 
97 void create_economy_report_dialog(bool make_modal);
98 void economy_close_callback(Widget w, XtPointer client_data,
99 			 XtPointer call_data);
100 void economy_selloff_callback(Widget w, XtPointer client_data,
101                             XtPointer call_data);
102 void economy_list_callback(Widget w, XtPointer client_data,
103                          XtPointer call_data);
104 
105 /******************************************************************/
106 static Widget activeunits_dialog_shell;
107 static Widget activeunits_label, activeunits_label2;
108 static Widget activeunits_list, activeunits_list_label;
109 static Widget upgrade_command;
110 static int activeunits_dialog_shell_is_modal;
111 static int activeunits_type[U_LAST];
112 
113 void create_activeunits_report_dialog(bool make_modal);
114 void activeunits_close_callback(Widget w, XtPointer client_data,
115 			 XtPointer call_data);
116 void activeunits_upgrade_callback(Widget w, XtPointer client_data,
117 			 XtPointer call_data);
118 void activeunits_refresh_callback(Widget w, XtPointer client_data,
119 			 XtPointer call_data);
120 void activeunits_list_callback(Widget w, XtPointer client_data,
121                            XtPointer call_data);
122 
123 /****************************************************************
124 ...
125 ****************************************************************/
get_centered_report_title(const char * report_name)126 const char *get_centered_report_title(const char *report_name)
127 {
128   return create_centered_string(get_report_title(report_name));
129 }
130 
131 /****************************************************************
132 ...
133 ****************************************************************/
get_report_title_plus(const char * report_name,const char * additional)134 static const char *get_report_title_plus(const char *report_name,
135 					 const char *additional)
136 {
137   char buf[512];
138 
139   fc_snprintf(buf, sizeof(buf), "%s\n%s", get_report_title(report_name),
140 	      additional);
141 
142   return create_centered_string(buf);
143 }
144 
145 /****************************************************************
146 ...
147 ************************ ***************************************/
science_report_dialog_popup(bool make_modal)148 void science_report_dialog_popup(bool make_modal)
149 {
150   if (!science_dialog_shell && NULL != client.conn.playing) {
151     Position x, y;
152     Dimension width, height;
153 
154     science_dialog_shell_is_modal=make_modal;
155 
156     if(make_modal)
157       XtSetSensitive(main_form, FALSE);
158 
159     create_science_dialog(make_modal);
160 
161     XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
162 
163     XtTranslateCoords(toplevel, (Position) width/10, (Position) height/10,
164 		      &x, &y);
165     XtVaSetValues(science_dialog_shell, XtNx, x, XtNy, y, NULL);
166 
167     XtPopup(science_dialog_shell, XtGrabNone);
168   }
169 }
170 
171 /****************************************************************
172   Closes the science dialog.
173 *****************************************************************/
science_report_dialog_popdown(void)174 void science_report_dialog_popdown(void)
175 {
176   if (science_dialog_shell) {
177     if (science_dialog_shell_is_modal) {
178       XtSetSensitive(main_form, TRUE);
179     }
180     XtDestroyWidget(science_dialog_shell);
181     science_dialog_shell = 0;
182   }
183 }
184 
185 /****************************************************************
186 ...
187 *****************************************************************/
create_science_dialog(bool make_modal)188 void create_science_dialog(bool make_modal)
189 {
190   Widget science_form;
191   Widget  close_command;
192   static const char *tech_list_names_ptrs[A_LAST + 1];
193   Dimension width;
194   char rate_text[128];
195   char current_text[512];
196   char goal_text[512];
197   const char *report_title;
198   int num_list, j = 0, flag = 0;
199 
200   if (NULL != client.conn.playing) {
201     struct research *research = research_get(client_player());
202 
203     if (research->researching == A_UNSET) {
204       fc_snprintf(current_text, sizeof(current_text),
205 		  _("Researching %s: %d/%s"),
206 		  advance_name_translation(advance_by_number(A_NONE)),
207 		  research->bulbs_researched,
208 		  _("unknown"));
209     } else {
210       fc_snprintf(current_text, sizeof(current_text),
211 		  _("Researching %s: %d/%d"),
212                   research_advance_name_translation(research,
213                                                     research->researching),
214                   research->bulbs_researched,
215                   research->client.researching_cost);
216     }
217 
218     if (research->tech_goal == A_UNSET) {
219       fc_snprintf(goal_text, sizeof(goal_text),
220 		  _("Goal: %s (%d steps)"),
221 		  advance_name_translation(advance_by_number(A_NONE)),
222 		  0);
223     } else {
224       fc_snprintf(goal_text, sizeof(goal_text),
225 		  _("Goal: %s (%d steps)"),
226 		  advance_name_translation(advance_by_number(research->tech_goal)),
227                   research_goal_unknown_techs(research,
228                                               research->tech_goal));
229     }
230 
231     advance_index_iterate(A_FIRST, i) {
232       if (TECH_KNOWN == research_invention_state(research, i)) {
233 	tech_list_names_ptrs[j] = advance_name_translation(advance_by_number(i));
234 	j++;
235       }
236     } advance_index_iterate_end;
237     tech_list_names_ptrs[j] = 0;
238     qsort(tech_list_names_ptrs, j, sizeof(char *), compare_strings_ptrs);
239     num_list = j;
240 
241     science_dialog_shell =
242       I_T(XtVaCreatePopupShell("sciencepopup",
243 			       (make_modal ? transientShellWidgetClass :
244 			        topLevelShellWidgetClass),
245 			        toplevel, NULL));
246 
247     science_form = XtVaCreateManagedWidget("scienceform",
248 					   formWidgetClass,
249 					   science_dialog_shell,
250 					   NULL);
251     fc_snprintf(rate_text, sizeof(rate_text), "\ntext not set yet");
252     /* TRANS: Research report title */
253     report_title = get_report_title_plus(_("Research"), rate_text);
254     science_label = XtVaCreateManagedWidget("sciencelabel",
255 					    labelWidgetClass,
256 					    science_form,
257 					    XtNlabel, report_title,
258 					    NULL);
259     free((void *) report_title);
260 
261     science_current_label =
262       XtVaCreateManagedWidget("sciencecurrentlabel",
263 			      labelWidgetClass,
264 			      science_form,
265 			      XtNlabel, current_text,
266 			      NULL);
267 
268     science_goal_label =
269       XtVaCreateManagedWidget("sciencegoallabel",
270 			      labelWidgetClass,
271 			      science_form,
272 			      XtNlabel, goal_text,
273 			      NULL);
274 
275     science_change_menu_button =
276       I_L(XtVaCreateManagedWidget("sciencechangemenubutton",
277 				  menuButtonWidgetClass,
278 				  science_form, NULL));
279 
280     science_goal_menu_button =
281       I_L(XtVaCreateManagedWidget("sciencegoalmenubutton",
282 				  menuButtonWidgetClass,
283 				  science_form, NULL));
284 
285     science_help_note =
286       I_L(XtVaCreateManagedWidget("sciencehelpnote",
287 				  labelWidgetClass,
288 				  science_form, NULL));
289 
290     science_help_toggle =
291       XtVaCreateManagedWidget("sciencehelptoggle",
292 			      toggleWidgetClass,
293 			      science_form,
294 			      NULL);
295 
296     science_list =
297       XtVaCreateManagedWidget("sciencelist",
298 			      listWidgetClass,
299 			      science_form,
300 			      XtNlist, tech_list_names_ptrs,
301 			      NULL);
302 
303     close_command =
304       I_L(XtVaCreateManagedWidget("scienceclosecommand",
305 				  commandWidgetClass,
306 				  science_form, NULL));
307 
308     popupmenu =
309       XtVaCreatePopupShell("menu",
310 			   simpleMenuWidgetClass,
311 			   science_change_menu_button,
312 			   NULL);
313 
314     goalmenu =
315       XtVaCreatePopupShell("menu",
316 			   simpleMenuWidgetClass,
317 			   science_goal_menu_button,
318 			   NULL);
319 
320     advance_index_iterate(A_FIRST, i) {
321       if (TECH_PREREQS_KNOWN ==
322             research_invention_state(research, i)) {
323 	Widget entry =
324 	  XtVaCreateManagedWidget(advance_name_translation(advance_by_number(i)),
325 				  smeBSBObjectClass,
326 				  popupmenu,
327 				  NULL);
328 	XtAddCallback(entry, XtNcallback, science_change_callback,
329 		      INT_TO_XTPOINTER(i));
330       flag = 1;
331       }
332     } advance_index_iterate_end;
333 
334     if (!flag) {
335       XtSetSensitive(science_change_menu_button, FALSE);
336     }
337 
338     flag = 0;
339     advance_index_iterate(A_FIRST, i) {
340       if (research_invention_reachable(research, i)
341           && TECH_KNOWN != research_invention_state(research, i)
342           && (11 > research_goal_unknown_techs(research, i)
343 	      || i == research->tech_goal)) {
344 	Widget entry =
345 	  XtVaCreateManagedWidget(advance_name_translation(advance_by_number(i)),
346 				  smeBSBObjectClass,
347 				  goalmenu,
348 				  NULL);
349 	XtAddCallback(entry, XtNcallback, science_goal_callback,
350 		      INT_TO_XTPOINTER(i));
351 	flag = 1;
352       }
353     } advance_index_iterate_end;
354 
355     if (!flag) {
356       XtSetSensitive(science_goal_menu_button, FALSE);
357     }
358 
359     XtAddCallback(close_command, XtNcallback, science_close_callback, NULL);
360     XtAddCallback(science_list, XtNcallback, science_help_callback, NULL);
361     XtAddCallback(science_help_toggle, XtNcallback, toggle_callback, NULL);
362 
363     if (num_list > 60) {
364       int ncol;
365       XtVaGetValues(science_list, XtNdefaultColumns, &ncol, NULL);
366       XtVaSetValues(science_list, XtNdefaultColumns, ncol+1, NULL);
367     }
368 
369     XtRealizeWidget(science_dialog_shell);
370 
371     if (!make_modal) {
372       XSetWMProtocols(display, XtWindow(science_dialog_shell),
373 		      &wm_delete_window, 1);
374       XtOverrideTranslations(science_dialog_shell,
375         XtParseTranslationTable("<Message>WM_PROTOCOLS: msg-close-science-report()"));
376     }
377 
378     width = 500;
379     XtVaSetValues(science_label, XtNwidth, &width, NULL);
380 
381     toggle_callback(science_help_toggle, NULL, NULL);
382     real_science_report_dialog_update(NULL);
383   }
384 }
385 
386 
387 /****************************************************************
388 ...
389 *****************************************************************/
science_change_callback(Widget w,XtPointer client_data,XtPointer call_data)390 void science_change_callback(Widget w, XtPointer client_data,
391 			     XtPointer call_data)
392 {
393   size_t to = (size_t) client_data;
394   Boolean b;
395 
396   XtVaGetValues(science_help_toggle, XtNstate, &b, NULL);
397   if (b == TRUE) {
398     popup_help_dialog_typed(advance_name_translation(advance_by_number(to)),
399                             HELP_TECH);
400   } else {
401     dsend_packet_player_research(&client.conn, to);
402   }
403 }
404 
405 /****************************************************************
406 ...
407 *****************************************************************/
science_goal_callback(Widget w,XtPointer client_data,XtPointer call_data)408 void science_goal_callback(Widget w, XtPointer client_data,
409 			   XtPointer call_data)
410 {
411   size_t to = (size_t) client_data;
412   Boolean b;
413 
414   XtVaGetValues(science_help_toggle, XtNstate, &b, NULL);
415   if (b == TRUE) {
416     popup_help_dialog_typed(advance_name_translation(advance_by_number(to)),
417                             HELP_TECH);
418   } else {
419     dsend_packet_player_tech_goal(&client.conn, to);
420   }
421 }
422 
423 
424 /****************************************************************
425 ...
426 *****************************************************************/
science_close_callback(Widget w,XtPointer client_data,XtPointer call_data)427 void science_close_callback(Widget w, XtPointer client_data,
428 			    XtPointer call_data)
429 {
430   science_report_dialog_popdown();
431 }
432 
433 
434 /****************************************************************
435 ...
436 *****************************************************************/
sciencereport_msg_close(Widget w)437 void sciencereport_msg_close(Widget w)
438 {
439   science_close_callback(w, NULL, NULL);
440 }
441 
442 
443 /****************************************************************
444 ...
445 *****************************************************************/
science_help_callback(Widget w,XtPointer client_data,XtPointer call_data)446 void science_help_callback(Widget w, XtPointer client_data,
447 			    XtPointer call_data)
448 {
449   XawListReturnStruct *ret=XawListShowCurrent(science_list);
450   Boolean b;
451 
452   XtVaGetValues(science_help_toggle, XtNstate, &b, NULL);
453   if (b == TRUE)
454     {
455       if(ret->list_index!=XAW_LIST_NONE)
456 	popup_help_dialog_typed(ret->string, HELP_TECH);
457       else
458 	popup_help_dialog_string(HELP_TECHS_ITEM);
459     }
460 }
461 
462 
463 /****************************************************************
464 ...
465 *****************************************************************/
real_science_report_dialog_update(void * unused)466 void real_science_report_dialog_update(void *unused)
467 {
468   if(science_dialog_shell) {
469     char text[512];
470     static const char *tech_list_names_ptrs[A_LAST + 1];
471     int j, flag;
472     const char *report_title;
473     struct research *research = research_get(client_player());
474 
475     /* TRANS: Research report title */
476     report_title = get_report_title_plus(_("Research"), science_dialog_text());
477     xaw_set_label(science_label, report_title);
478     free((void *) report_title);
479 
480     if (research->researching == A_UNSET) {
481       fc_snprintf(text, sizeof(text),
482 		  _("Researching %s: %d/%s"),
483 		  advance_name_translation(advance_by_number(A_NONE)),
484 		  research->bulbs_researched,
485 		  _("unknown"));
486     } else {
487       fc_snprintf(text, sizeof(text),
488 		  _("Researching %s: %d/%d"),
489                   research_advance_name_translation(research,
490                                                     research->researching),
491                   research->bulbs_researched,
492                   research->client.researching_cost);
493     }
494 
495     xaw_set_label(science_current_label, text);
496 
497     if (research->tech_goal == A_UNSET) {
498       fc_snprintf(text, sizeof(text),
499 		  _("Goal: %s (%d steps)"),
500 		  advance_name_translation(advance_by_number(A_NONE)),
501 		  0);
502     } else {
503       fc_snprintf(text, sizeof(text),
504 		  _("Goal: %s (%d steps)"),
505 		  advance_name_translation(advance_by_number(research->tech_goal)),
506                   research_goal_unknown_techs(research,
507                                               research->tech_goal));
508     }
509 
510     xaw_set_label(science_goal_label, text);
511 
512     j=0;
513     advance_index_iterate(A_FIRST, i) {
514       if (TECH_KNOWN == research_invention_state(research, i)) {
515 	tech_list_names_ptrs[j]=advance_name_translation(advance_by_number(i));
516 	j++;
517       }
518     } advance_index_iterate_end;
519     tech_list_names_ptrs[j]=0;
520     qsort(tech_list_names_ptrs, j, sizeof(char *), compare_strings_ptrs);
521 
522     XawListChange(science_list,
523                   (CONST_FOR_XAW_LIST_CHANGE char **)tech_list_names_ptrs,
524                   0/*j*/, 0, 1);
525 
526     XtDestroyWidget(popupmenu);
527 
528     popupmenu=XtVaCreatePopupShell("menu",
529 				   simpleMenuWidgetClass,
530 				   science_change_menu_button,
531 				   NULL);
532 
533     flag=0;
534     advance_index_iterate(A_FIRST, i) {
535       if (TECH_PREREQS_KNOWN ==
536             research_invention_state(research, i)) {
537 	Widget entry=
538 	  XtVaCreateManagedWidget(advance_name_translation(advance_by_number(i)),
539 				  smeBSBObjectClass,
540 				  popupmenu,
541 				  NULL);
542 	XtAddCallback(entry, XtNcallback, science_change_callback,
543 		      INT_TO_XTPOINTER(i));
544 	flag=1;
545       }
546     } advance_index_iterate_end;
547     if(!flag)
548       XtSetSensitive(science_change_menu_button, FALSE);
549 
550     XtDestroyWidget(goalmenu);
551 
552     goalmenu=XtVaCreatePopupShell("menu",
553 				  simpleMenuWidgetClass,
554 				  science_goal_menu_button,
555 				  NULL);
556 
557     flag=0;
558     advance_index_iterate(A_FIRST, i) {
559       if (research_invention_reachable(research, i)
560           && TECH_KNOWN != research_invention_state(research, i)
561           && (11 > research_goal_unknown_techs(research, i)
562 	      || i == research->tech_goal)) {
563 	Widget entry=
564 	  XtVaCreateManagedWidget(advance_name_translation(advance_by_number(i)),
565 				  smeBSBObjectClass,
566 				  goalmenu,
567 				  NULL);
568 	XtAddCallback(entry, XtNcallback, science_goal_callback,
569 		      INT_TO_XTPOINTER(i));
570 	flag=1;
571       }
572     } advance_index_iterate_end;
573 
574     if(!flag)
575       XtSetSensitive(science_goal_menu_button, FALSE);
576 
577   }
578 
579 }
580 
581 /****************************************************************************
582   Resize and redraw the requirement tree.
583 ****************************************************************************/
science_report_dialog_redraw(void)584 void science_report_dialog_redraw(void)
585 {
586   /* No requirement tree yet. */
587 }
588 
589 
590 /****************************************************************
591 
592                       ECONOMY REPORT DIALOG
593 
594 ****************************************************************/
595 
596 /****************************************************************
597 ...
598 ****************************************************************/
economy_report_dialog_popup(bool make_modal)599 void economy_report_dialog_popup(bool make_modal)
600 {
601   if(!economy_dialog_shell) {
602       Position x, y;
603       Dimension width, height;
604 
605       economy_dialog_shell_is_modal=make_modal;
606 
607       if(make_modal)
608 	XtSetSensitive(main_form, FALSE);
609 
610       create_economy_report_dialog(make_modal);
611 
612       XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
613 
614       XtTranslateCoords(toplevel, (Position) width/10, (Position) height/10,
615 			&x, &y);
616       XtVaSetValues(economy_dialog_shell, XtNx, x, XtNy, y, NULL);
617 
618       XtPopup(economy_dialog_shell, XtGrabNone);
619    }
620 }
621 
622 /****************************************************************
623   Closes the economy report.
624 ****************************************************************/
economy_report_dialog_popdown(void)625 void economy_report_dialog_popdown(void)
626 {
627   if (economy_dialog_shell) {
628     if (economy_dialog_shell_is_modal) {
629       XtSetSensitive(main_form, TRUE);
630     }
631     XtDestroyWidget(economy_dialog_shell);
632     economy_dialog_shell = 0;
633   }
634 }
635 
636 /****************************************************************
637 ...
638 *****************************************************************/
create_economy_report_dialog(bool make_modal)639 void create_economy_report_dialog(bool make_modal)
640 {
641   Widget economy_form;
642   Widget close_command;
643   const char *report_title;
644 
645   economy_dialog_shell =
646     I_T(XtVaCreatePopupShell("reporteconomypopup",
647 			     (make_modal ? transientShellWidgetClass :
648 			      topLevelShellWidgetClass),
649 			     toplevel, NULL));
650 
651   economy_form = XtVaCreateManagedWidget("reporteconomyform",
652 					 formWidgetClass,
653 					 economy_dialog_shell,
654 					 NULL);
655 
656   report_title=get_centered_report_title(_("Economy"));
657   economy_label = XtVaCreateManagedWidget("reporteconomylabel",
658 				       labelWidgetClass,
659 				       economy_form,
660 				       XtNlabel, report_title,
661 				       NULL);
662   free((void *) report_title);
663 
664   economy_list_label =
665     I_L(XtVaCreateManagedWidget("reporteconomylistlabel", labelWidgetClass,
666 				economy_form, NULL));
667 
668   economy_list
669     = XtVaCreateManagedWidget("reporteconomylist", listWidgetClass,
670 			      economy_form, NULL);
671 
672   economy_label2
673     = XtVaCreateManagedWidget("reporteconomylabel2", labelWidgetClass,
674 			      economy_form, NULL);
675 
676   close_command =
677     I_L(XtVaCreateManagedWidget("reporteconomyclosecommand", commandWidgetClass,
678 				economy_form, NULL));
679 
680   sellredundant_command =
681     I_L(XtVaCreateManagedWidget("reporteconomysellredundantcommand",
682 				commandWidgetClass,
683 				economy_form,
684 				XtNsensitive, False,
685 				NULL));
686 
687   sellall_command  =
688     I_L(XtVaCreateManagedWidget("reporteconomysellallcommand",
689 				commandWidgetClass,
690 				economy_form,
691 				XtNsensitive, False,
692 				NULL));
693 
694   XtAddCallback(economy_list, XtNcallback, economy_list_callback, NULL);
695   XtAddCallback(close_command, XtNcallback, economy_close_callback, NULL);
696   XtAddCallback(sellredundant_command, XtNcallback, economy_selloff_callback, (XtPointer)0);
697   XtAddCallback(sellall_command, XtNcallback, economy_selloff_callback, (XtPointer)1);
698   XtRealizeWidget(economy_dialog_shell);
699 
700   if(!make_modal)  {
701     XSetWMProtocols(display, XtWindow(economy_dialog_shell),
702 		    &wm_delete_window, 1);
703     XtOverrideTranslations(economy_dialog_shell,
704       XtParseTranslationTable("<Message>WM_PROTOCOLS: msg-close-economy-report()"));
705   }
706 
707   real_economy_report_dialog_update(NULL);
708 }
709 
710 
711 
712 /****************************************************************
713   Called when a building type is selected in the economy list.
714 *****************************************************************/
economy_list_callback(Widget w,XtPointer client_data,XtPointer call_data)715 void economy_list_callback(Widget w, XtPointer client_data,
716 			 XtPointer call_data)
717 {
718   XawListReturnStruct *ret = XawListShowCurrent(economy_list);
719 
720   if (ret->list_index != XAW_LIST_NONE) {
721     /* The user has selected an improvement type. */
722     struct impr_type *pimprove = economy_improvement_type[ret->list_index];
723     bool is_sellable = can_sell_building(pimprove);
724 
725     XtSetSensitive(sellredundant_command, is_sellable
726                    && economy_improvement_redundant[ret->list_index]);
727     XtSetSensitive(sellall_command, is_sellable);
728   } else {
729     /* No selection has been made. */
730     XtSetSensitive(sellredundant_command, FALSE);
731     XtSetSensitive(sellall_command, FALSE);
732   }
733 }
734 
735 /****************************************************************
736 ...
737 *****************************************************************/
economy_close_callback(Widget w,XtPointer client_data,XtPointer call_data)738 void economy_close_callback(Widget w, XtPointer client_data,
739 			 XtPointer call_data)
740 {
741   economy_report_dialog_popdown();
742 }
743 
744 /****************************************************************
745 ...
746 *****************************************************************/
economyreport_msg_close(Widget w)747 void economyreport_msg_close(Widget w)
748 {
749   economy_close_callback(w, NULL, NULL);
750 }
751 
752 /****************************************************************
753 ...
754 *****************************************************************/
economy_selloff_callback(Widget w,XtPointer client_data,XtPointer call_data)755 void economy_selloff_callback(Widget w, XtPointer client_data,
756 			    XtPointer call_data)
757 {
758   char str[1024];
759   XawListReturnStruct *ret = XawListShowCurrent(economy_list);
760 
761   if (ret->list_index == XAW_LIST_NONE) {
762     return;
763   }
764 
765   sell_all_improvements(economy_improvement_type[ret->list_index],
766 			client_data == NULL, str, sizeof(str));
767   popup_notify_dialog(_("Sell-Off:"), _("Results"), str);
768 }
769 
770 /****************************************************************
771 ...
772 *****************************************************************/
real_economy_report_dialog_update(void * unused)773 void real_economy_report_dialog_update(void *unused)
774 {
775   if(economy_dialog_shell) {
776     int i, entries_used, tax, total;
777     Dimension width;
778     static CONST_FOR_XAW_LIST_CHANGE char *economy_list_names_ptrs[B_LAST + 1];
779     static char economy_list_names[B_LAST][200];
780     const char *report_title;
781     char economy_total[48];
782     struct improvement_entry entries[B_LAST];
783 
784     report_title=get_centered_report_title(_("Economy"));
785     xaw_set_label(economy_label, report_title);
786     free((void *) report_title);
787 
788     get_economy_report_data(entries, &entries_used, &total, &tax);
789 
790     for (i = 0; i < entries_used; i++) {
791       struct improvement_entry *p = &entries[i];
792 
793       fc_snprintf(economy_list_names[i], sizeof(economy_list_names[i]),
794 		  "%-20s%5d%5d%6d",
795 		  improvement_name_translation(p->type),
796 		  p->count, p->cost, p->total_cost);
797       economy_list_names_ptrs[i] = economy_list_names[i];
798       economy_improvement_type[i] = p->type;
799       economy_improvement_redundant[i] = (p->redundant > 0);
800     }
801 
802     if (entries_used == 0) {
803       sz_strlcpy(economy_list_names[0],
804 		 "                                          ");
805       economy_list_names_ptrs[0] = economy_list_names[0];
806       entries_used = 1;
807     }
808     economy_list_names_ptrs[entries_used] = NULL;
809 
810     fc_snprintf(economy_total, sizeof(economy_total),
811 		_("Income:%6d    Total Costs: %6d"), tax, total);
812     xaw_set_label(economy_label2, economy_total);
813 
814     XawListChange(economy_list, economy_list_names_ptrs, 0, 0, 1);
815 
816     XtVaGetValues(economy_list, XtNwidth, &width, NULL);
817     XtVaSetValues(economy_list_label, XtNwidth, width, NULL);
818 
819     XtVaSetValues(economy_label2, XtNwidth, width, NULL);
820 
821     XtVaSetValues(economy_label, XtNwidth, width, NULL);
822 
823   }
824 
825 }
826 
827 /****************************************************************
828 
829                       ACTIVE UNITS REPORT DIALOG
830 
831 ****************************************************************/
832 
833 /****************************************************************
834 ...
835 ****************************************************************/
units_report_dialog_popup(bool make_modal)836 void units_report_dialog_popup(bool make_modal)
837 {
838   if(!activeunits_dialog_shell) {
839       Position x, y;
840       Dimension width, height;
841 
842       activeunits_dialog_shell_is_modal=make_modal;
843 
844       if(make_modal)
845 	XtSetSensitive(main_form, FALSE);
846 
847       create_activeunits_report_dialog(make_modal);
848 
849       XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
850 
851       XtTranslateCoords(toplevel, (Position) width/10, (Position) height/10,
852 			&x, &y);
853       XtVaSetValues(activeunits_dialog_shell, XtNx, x, XtNy, y, NULL);
854 
855       XtPopup(activeunits_dialog_shell, XtGrabNone);
856    }
857 }
858 
859 /****************************************************************
860   Closes the active units report.
861 *****************************************************************/
units_report_dialog_popdown(void)862 void units_report_dialog_popdown(void)
863 {
864   if (activeunits_dialog_shell) {
865     if (activeunits_dialog_shell_is_modal) {
866       XtSetSensitive(main_form, TRUE);
867     }
868     XtDestroyWidget(activeunits_dialog_shell);
869     activeunits_dialog_shell = 0;
870   }
871 }
872 
873 /****************************************************************
874 ...
875 *****************************************************************/
create_activeunits_report_dialog(bool make_modal)876 void create_activeunits_report_dialog(bool make_modal)
877 {
878   Widget activeunits_form;
879   Widget close_command, refresh_command;
880   const char *report_title;
881 
882   activeunits_dialog_shell =
883     I_T(XtVaCreatePopupShell("reportactiveunitspopup",
884 			     (make_modal ? transientShellWidgetClass :
885 			      topLevelShellWidgetClass),
886 			     toplevel, NULL));
887 
888   activeunits_form = XtVaCreateManagedWidget("reportactiveunitsform",
889 					 formWidgetClass,
890 					 activeunits_dialog_shell,
891 					 NULL);
892 
893   report_title=get_centered_report_title(_("Units"));
894   activeunits_label = XtVaCreateManagedWidget("reportactiveunitslabel",
895 				       labelWidgetClass,
896 				       activeunits_form,
897 				       XtNlabel, report_title,
898 				       NULL);
899   free((void *) report_title);
900 
901   activeunits_list_label =
902     I_L(XtVaCreateManagedWidget("reportactiveunitslistlabel",
903 				labelWidgetClass,
904 				activeunits_form,
905 				NULL));
906 
907   activeunits_list = XtVaCreateManagedWidget("reportactiveunitslist",
908 				      listWidgetClass,
909 				      activeunits_form,
910 				      NULL);
911 
912   activeunits_label2 = XtVaCreateManagedWidget("reportactiveunitslabel2",
913 				       labelWidgetClass,
914 				       activeunits_form,
915                                        XtNlabel,
916 				       _("Totals: ..."),
917 				       NULL);
918 
919   close_command =
920     I_L(XtVaCreateManagedWidget("reportactiveunitsclosecommand",
921 				commandWidgetClass,
922 				activeunits_form,
923 				NULL));
924 
925   upgrade_command =
926     I_L(XtVaCreateManagedWidget("reportactiveunitsupgradecommand",
927 				commandWidgetClass,
928 				activeunits_form,
929 				XtNsensitive, False,
930 				NULL));
931 
932   refresh_command =
933     I_L(XtVaCreateManagedWidget("reportactiveunitsrefreshcommand",
934 				commandWidgetClass,
935 				activeunits_form,
936 				NULL));
937 
938   XtAddCallback(activeunits_list, XtNcallback, activeunits_list_callback, NULL);
939   XtAddCallback(close_command, XtNcallback, activeunits_close_callback, NULL);
940   XtAddCallback(upgrade_command, XtNcallback, activeunits_upgrade_callback, NULL);
941   XtAddCallback(refresh_command, XtNcallback, activeunits_refresh_callback, NULL);
942 
943   XtRealizeWidget(activeunits_dialog_shell);
944 
945   if(!make_modal)  {
946     XSetWMProtocols(display, XtWindow(activeunits_dialog_shell),
947 		    &wm_delete_window, 1);
948     XtOverrideTranslations(activeunits_dialog_shell,
949       XtParseTranslationTable("<Message>WM_PROTOCOLS: msg-close-units-report()"));
950   }
951 
952   real_units_report_dialog_update(NULL);
953 }
954 
955 /****************************************************************
956 ...
957 *****************************************************************/
activeunits_list_callback(Widget w,XtPointer client_data,XtPointer call_data)958 void activeunits_list_callback(Widget w, XtPointer client_data,
959 			 XtPointer call_data)
960 {
961   XawListReturnStruct *ret;
962   int inx;
963   int may_upgrade;
964 
965   ret = XawListShowCurrent (activeunits_list);
966   inx = ret->list_index;
967 
968   may_upgrade =
969     ((inx != XAW_LIST_NONE) &&
970      (can_upgrade_unittype(client.conn.playing,
971        utype_by_number(activeunits_type[inx])) != NULL));
972 
973   XtSetSensitive (upgrade_command, may_upgrade);
974 }
975 
976 /****************************************************************
977 ...
978 *****************************************************************/
upgrade_callback_yes(Widget w,XtPointer client_data,XtPointer call_data)979 static void upgrade_callback_yes(Widget w, XtPointer client_data,
980                                  XtPointer call_data)
981 {
982   dsend_packet_unit_type_upgrade(&client.conn, (size_t) client_data);
983   destroy_message_dialog(w);
984 }
985 
986 /****************************************************************
987 ...
988 *****************************************************************/
upgrade_callback_no(Widget w,XtPointer client_data,XtPointer call_data)989 static void upgrade_callback_no(Widget w, XtPointer client_data,
990                                 XtPointer call_data)
991 {
992   destroy_message_dialog(w);
993 }
994 
995 /****************************************************************
996 ...
997 *****************************************************************/
activeunits_upgrade_callback(Widget w,XtPointer client_data,XtPointer call_data)998 void activeunits_upgrade_callback(Widget w, XtPointer client_data,
999 			 XtPointer call_data)
1000 {
1001   char buf[512];
1002   struct unit_type *punittype1, *punittype2;
1003 
1004   XawListReturnStruct *ret;
1005   ret=XawListShowCurrent(activeunits_list);
1006 
1007   if (ret->list_index != XAW_LIST_NONE) {
1008     char tbuf[512];
1009     int price;
1010     punittype1 = utype_by_number(activeunits_type[ret->list_index]);
1011     punittype2 = can_upgrade_unittype(client_player(), punittype1);
1012     price = unit_upgrade_price(client_player(), punittype1, punittype2);
1013 
1014     fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
1015                                             "Treasury contains %d gold.",
1016                                             client_player()->economic.gold),
1017                 client_player()->economic.gold);
1018 
1019     fc_snprintf(buf, sizeof(buf),
1020                 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1021                 PL_("Upgrade as many %s to %s as possible for %d gold "
1022                     "each?\n%s",
1023                     "Upgrade as many %s to %s as possible for %d gold "
1024                     "each?\n%s", price),
1025                 utype_name_translation(punittype1),
1026                 utype_name_translation(punittype2),
1027                 price, tbuf);
1028 
1029     popup_message_dialog(toplevel, "upgradedialog", buf,
1030 			 upgrade_callback_yes,
1031 			 INT_TO_XTPOINTER(activeunits_type[ret->list_index]),
1032 			 0, upgrade_callback_no, 0, 0, NULL);
1033   }
1034 }
1035 
1036 /****************************************************************
1037 ...
1038 *****************************************************************/
activeunits_close_callback(Widget w,XtPointer client_data,XtPointer call_data)1039 void activeunits_close_callback(Widget w, XtPointer client_data,
1040 			 XtPointer call_data)
1041 {
1042   units_report_dialog_popdown();
1043 }
1044 
1045 /****************************************************************
1046 ...
1047 *****************************************************************/
activeunits_refresh_callback(Widget w,XtPointer client_data,XtPointer call_data)1048 void activeunits_refresh_callback(Widget w, XtPointer client_data,
1049 				  XtPointer call_data)
1050 {
1051   real_units_report_dialog_update(NULL);
1052 }
1053 
1054 /****************************************************************
1055 ...
1056 *****************************************************************/
activeunits_msg_close(Widget w)1057 void activeunits_msg_close(Widget w)
1058 {
1059   activeunits_close_callback(w, NULL, NULL);
1060 }
1061 
1062 /****************************************************************
1063 ...
1064 *****************************************************************/
real_units_report_dialog_update(void * unused)1065 void real_units_report_dialog_update(void *unused)
1066 {
1067   struct repoinfo {
1068     int active_count;
1069     int upkeep[O_LAST];
1070     int building_count;
1071   };
1072 
1073   if (NULL == client.conn.playing) {
1074     return;
1075   }
1076 
1077   if (activeunits_dialog_shell) {
1078     int k;
1079     Dimension width;
1080     static CONST_FOR_XAW_LIST_CHANGE char *activeunits_list_names_ptrs[U_LAST + 1];
1081     static char activeunits_list_names[U_LAST][200];
1082     struct repoinfo unitarray[U_LAST];
1083     struct repoinfo unittotals;
1084     const char *report_title;
1085     char activeunits_total[100];
1086     Unit_type_id i;
1087 
1088     report_title = get_centered_report_title(_("Units"));
1089     xaw_set_label(activeunits_label, report_title);
1090     free((void *) report_title);
1091 
1092     memset(unitarray, '\0', sizeof(unitarray));
1093 
1094     unit_list_iterate(client.conn.playing->units, punit) {
1095       Unit_type_id uti = utype_index(unit_type_get(punit));
1096 
1097       (unitarray[uti].active_count)++;
1098       if (punit->homecity) {
1099 	output_type_iterate(o) {
1100 	  unitarray[uti].upkeep[o] += punit->upkeep[o];
1101 	} output_type_iterate_end;
1102       }
1103     } unit_list_iterate_end;
1104 
1105     city_list_iterate(client.conn.playing->cities,pcity) {
1106       if (VUT_UTYPE == pcity->production.kind) {
1107         struct unit_type *punittype = pcity->production.value.utype;
1108         int num_units;
1109         /* Account for build slots in city */
1110         (void) city_production_build_units(pcity, TRUE, &num_units);
1111         /* Unit is in progress even if it won't be done this turn */
1112         num_units = MAX(num_units, 1);
1113         (unitarray[utype_index(punittype)].building_count) += num_units;
1114       }
1115     }
1116     city_list_iterate_end;
1117 
1118     k = 0;
1119     memset(&unittotals, '\0', sizeof(unittotals));
1120     unit_type_iterate(punittype) {
1121       i = utype_index(punittype);
1122       if ((unitarray[i].active_count > 0) || (unitarray[i].building_count > 0)) {
1123 	fc_snprintf
1124 	  (
1125 	   activeunits_list_names[k],
1126 	   sizeof(activeunits_list_names[k]),
1127 	   "%-27s%c%9d%9d%9d%9d",
1128 	   utype_name_translation(punittype),
1129 	   can_upgrade_unittype(client.conn.playing, punittype) != NULL ? '*': '-',
1130 	   unitarray[i].building_count,
1131 	   unitarray[i].active_count,
1132            unitarray[i].upkeep[O_SHIELD],
1133            unitarray[i].upkeep[O_FOOD]
1134            /* TODO: add upkeep[O_GOLD] here */
1135 	  );
1136 	activeunits_list_names_ptrs[k]=activeunits_list_names[k];
1137 	activeunits_type[k]=(unitarray[i].active_count > 0) ? i : U_LAST;
1138 	k++;
1139 	unittotals.active_count += unitarray[i].active_count;
1140         output_type_iterate(o) {
1141           unittotals.upkeep[o] = unitarray[i].upkeep[o];
1142         } output_type_iterate_end;
1143 	unittotals.building_count += unitarray[i].building_count;
1144       }
1145     } unit_type_iterate_end;
1146 
1147     if (k==0) {
1148       sz_strlcpy(activeunits_list_names[0], "                                ");
1149       activeunits_list_names_ptrs[0]=activeunits_list_names[0];
1150       k=1;
1151     }
1152 
1153     fc_snprintf(activeunits_total, sizeof(activeunits_total),
1154 	    _("Totals:                     %9d%9d%9d%9d"),
1155 	    unittotals.building_count, unittotals.active_count,
1156            unittotals.upkeep[O_SHIELD], unittotals.upkeep[O_FOOD]);
1157             /* TODO: add upkeep[O_GOLD] here */
1158     xaw_set_label(activeunits_label2, activeunits_total);
1159 
1160     activeunits_list_names_ptrs[k]=0;
1161     XawListChange(activeunits_list, activeunits_list_names_ptrs, 0, 0, 1);
1162 
1163     XtVaGetValues(activeunits_list, XtNwidth, &width, NULL);
1164     XtVaSetValues(activeunits_list_label, XtNwidth, width, NULL);
1165     XtVaSetValues(activeunits_label2, XtNwidth, width, NULL);
1166     XtVaSetValues(activeunits_label, XtNwidth, width, NULL);
1167 
1168     activeunits_list_callback(NULL, NULL, NULL);
1169   }
1170 }
1171 
1172 static char eg_buffer[150 * MAX_NUM_PLAYERS];
1173 static int eg_player_count = 0;
1174 static int eg_players_received = 0;
1175 
1176 /****************************************************************
1177   Show a dialog with player statistics at endgame.
1178   TODO: Display all statistics in packet_endgame_report.
1179 *****************************************************************/
endgame_report_dialog_start(const struct packet_endgame_report * packet)1180 void endgame_report_dialog_start(const struct packet_endgame_report *packet)
1181 {
1182   eg_buffer[0] = '\0';
1183   eg_player_count = packet->player_num;
1184   eg_players_received = 0;
1185 }
1186 
1187 /****************************************************************
1188   Received endgame report information about single player
1189 *****************************************************************/
endgame_report_dialog_player(const struct packet_endgame_player * packet)1190 void endgame_report_dialog_player(const struct packet_endgame_player *packet)
1191 {
1192   const struct player *pplayer = player_by_number(packet->player_id);
1193 
1194   eg_players_received++;
1195 
1196   cat_snprintf(eg_buffer, sizeof(eg_buffer),
1197                PL_("%2d: The %s ruler %s scored %d point\n",
1198                    "%2d: The %s ruler %s scored %d points\n",
1199                    packet->score),
1200                eg_players_received, nation_adjective_for_player(pplayer),
1201                player_name(pplayer), packet->score);
1202 
1203   if (eg_players_received == eg_player_count) {
1204     popup_notify_dialog(_("Final Report:"),
1205                         _("The Greatest Civilizations in the world."),
1206                         eg_buffer);
1207   }
1208 }
1209