Removed silencing of gtk warning logs from gtk3.22-client.
[freeciv.git] / client / gui-xaw / cityrep.c
blob3abe7bfe47b869966c14d576366a0c767600fa36
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdio.h>
19 #include <stdlib.h>
21 #include <X11/Intrinsic.h>
22 #include <X11/StringDefs.h>
23 #include <X11/Xaw/Form.h>
24 #include <X11/Xaw/Label.h>
25 #include <X11/Xaw/Command.h>
26 #include <X11/Xaw/List.h>
27 #include <X11/Xaw/MenuButton.h>
28 #include <X11/Xaw/SimpleMenu.h>
29 #include <X11/Xaw/SmeBSB.h>
30 #include <X11/Xaw/Toggle.h>
31 #include <X11/Xaw/Viewport.h>
33 /* utility */
34 #include "fcintl.h"
35 #include "log.h"
36 #include "mem.h"
37 #include "shared.h"
38 #include "support.h"
40 /* common */
41 #include "city.h"
42 #include "packets.h"
43 #include "unit.h"
45 /* client */
46 #include "client_main.h"
47 #include "climisc.h"
49 /* gui-xaw */
50 #include "chatline.h"
51 #include "citydlg.h"
52 #include "cityrepdata.h"
53 #include "gui_main.h"
54 #include "gui_stuff.h"
55 #include "mapview.h"
56 #include "optiondlg.h"
57 #include "options.h"
58 #include "repodlgs.h"
59 #include "text.h"
61 #include "cityrep.h"
63 /******************************************************************/
64 static void popup_chgall_dialog (Widget parent);
66 /******************************************************************/
67 static Widget config_shell;
68 static Widget *config_toggle;
70 void create_city_report_config_dialog(void);
71 void popup_city_report_config_dialog(void);
72 void config_ok_command_callback(Widget w, XtPointer client_data,
73 XtPointer call_data);
76 /******************************************************************/
77 void create_city_report_dialog(bool make_modal);
78 void city_close_callback(Widget w, XtPointer client_data,
79 XtPointer call_data);
80 void city_center_callback(Widget w, XtPointer client_data,
81 XtPointer call_data);
82 void city_popup_callback(Widget w, XtPointer client_data,
83 XtPointer call_data);
84 void city_buy_callback(Widget w, XtPointer client_data,
85 XtPointer call_data);
86 void city_chgall_callback(Widget w, XtPointer client_data,
87 XtPointer call_data);
88 void city_refresh_callback(Widget w, XtPointer client_data,
89 XtPointer call_data);
90 void city_change_callback(Widget w, XtPointer client_data,
91 XtPointer call_data);
92 void city_list_callback(Widget w, XtPointer client_data,
93 XtPointer call_data);
94 void city_config_callback(Widget w, XtPointer client_data,
95 XtPointer call_data);
97 static Widget city_form;
98 static Widget city_dialog_shell;
99 static Widget city_label;
100 static Widget city_viewport;
101 static Widget city_list, city_list_label;
102 static Widget city_center_command, city_popup_command, city_buy_command,
103 city_chgall_command, city_refresh_command, city_config_command;
104 static Widget city_change_command, city_popupmenu;
106 static int city_dialog_shell_is_modal;
107 static struct city **cities_in_list = NULL;
109 static char *dummy_city_list[]={
111 " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
112 " ", " ", " ", 0
116 /****************************************************************
117 Create the text for a line in the city report; n is size of buffer
118 *****************************************************************/
119 static void get_city_text(struct city *pcity, char *text, int n)
121 struct city_report_spec *spec;
122 int i;
124 text[0] = '\0'; /* init for strcat */
125 for(i=0, spec=city_report_specs; i<NUM_CREPORT_COLS; i++, spec++) {
126 if(!spec->show) continue;
128 if(spec->space>0)
129 cat_snprintf(text, n, "%*s", spec->space, " ");
131 cat_snprintf(text, n, "%*s", spec->width,
132 (spec->func)(pcity, spec->data));
136 /****************************************************************
137 Return text line for the column headers for the city report
138 *****************************************************************/
139 static char *get_city_table_header(void)
141 static char text[400];
142 struct city_report_spec *spec;
143 int i, j;
145 text[0] = '\0'; /* init for strcat */
146 for(j=0; j<=1; j++) {
147 for(i=0, spec=city_report_specs; i<NUM_CREPORT_COLS; i++, spec++) {
148 if(!spec->show) continue;
150 if(spec->space>0)
151 cat_snprintf(text, sizeof(text), "%*s", spec->space, " ");
153 cat_snprintf(text, sizeof(text), "%*s", spec->width,
154 (j ? (spec->title2 ? spec->title2 : "")
155 : (spec->title1 ? spec->title1 : "")));
157 if (j==0) sz_strlcat(text, "\n");
159 return text;
162 /****************************************************************
164 CITY REPORT DIALOG
166 ****************************************************************/
168 /****************************************************************
170 ****************************************************************/
171 void city_report_dialog_popup(bool make_modal)
173 if(!city_dialog_shell) {
174 Position x, y;
175 Dimension width, height;
177 city_dialog_shell_is_modal=make_modal;
179 if(make_modal)
180 XtSetSensitive(main_form, FALSE);
182 create_city_report_dialog(make_modal);
184 XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
186 XtTranslateCoords(toplevel, (Position) width/10, (Position) height/10,
187 &x, &y);
188 XtVaSetValues(city_dialog_shell, XtNx, x, XtNy, y, NULL);
190 XtPopup(city_dialog_shell, XtGrabNone);
192 /* force refresh of viewport so the scrollbar is added.
193 * Buggy sun athena requires this */
194 XtVaSetValues(city_viewport, XtNforceBars, True, NULL);
198 /****************************************************************
199 Closes the cityrep dialog.
200 ****************************************************************/
201 void city_report_dialog_popdown(void)
203 if (city_dialog_shell) {
204 if (city_dialog_shell_is_modal) {
205 XtSetSensitive(main_form, TRUE);
207 XtDestroyWidget(city_dialog_shell);
208 city_dialog_shell = 0;
212 /****************************************************************
214 *****************************************************************/
215 void create_city_report_dialog(bool make_modal)
217 Widget close_command;
218 const char *report_title;
220 city_dialog_shell =
221 I_T(XtVaCreatePopupShell("reportcitypopup",
222 (make_modal ? transientShellWidgetClass :
223 topLevelShellWidgetClass),
224 toplevel, NULL));
226 city_form = XtVaCreateManagedWidget("reportcityform",
227 formWidgetClass,
228 city_dialog_shell,
229 NULL);
231 report_title=get_centered_report_title(_("Cities"));
232 city_label = XtVaCreateManagedWidget("reportcitylabel",
233 labelWidgetClass,
234 city_form,
235 XtNlabel,
236 report_title,
237 NULL);
238 free((void *) report_title);
239 city_list_label = XtVaCreateManagedWidget("reportcitylistlabel",
240 labelWidgetClass,
241 city_form,
242 XtNlabel,
243 get_city_table_header(),
244 NULL);
245 city_viewport = XtVaCreateManagedWidget("reportcityviewport",
246 viewportWidgetClass,
247 city_form,
248 NULL);
250 city_list = XtVaCreateManagedWidget("reportcitylist",
251 listWidgetClass,
252 city_viewport,
253 XtNlist,
254 (XtArgVal)dummy_city_list,
255 NULL);
257 close_command =
258 I_L(XtVaCreateManagedWidget("reportcityclosecommand", commandWidgetClass,
259 city_form, NULL));
261 city_center_command =
262 I_L(XtVaCreateManagedWidget("reportcitycentercommand", commandWidgetClass,
263 city_form, NULL));
265 city_popup_command =
266 I_L(XtVaCreateManagedWidget("reportcitypopupcommand", commandWidgetClass,
267 city_form, NULL));
269 city_popupmenu = 0;
271 city_buy_command =
272 I_L(XtVaCreateManagedWidget("reportcitybuycommand", commandWidgetClass,
273 city_form, NULL));
275 city_change_command =
276 I_L(XtVaCreateManagedWidget("reportcitychangemenubutton",
277 menuButtonWidgetClass,
278 city_form, NULL));
280 city_chgall_command =
281 I_L(XtVaCreateManagedWidget("reportcitychgallcommand",
282 commandWidgetClass,
283 city_form, NULL));
285 city_refresh_command =
286 I_L(XtVaCreateManagedWidget("reportcityrefreshcommand",
287 commandWidgetClass,
288 city_form, NULL));
290 city_config_command =
291 I_L(XtVaCreateManagedWidget("reportcityconfigcommand",
292 commandWidgetClass,
293 city_form, NULL));
295 XtAddCallback(close_command, XtNcallback, city_close_callback, NULL);
296 XtAddCallback(city_center_command, XtNcallback, city_center_callback, NULL);
297 XtAddCallback(city_popup_command, XtNcallback, city_popup_callback, NULL);
298 XtAddCallback(city_buy_command, XtNcallback, city_buy_callback, NULL);
299 XtAddCallback(city_chgall_command, XtNcallback, city_chgall_callback, NULL);
300 XtAddCallback(city_refresh_command, XtNcallback, city_refresh_callback, NULL);
301 XtAddCallback(city_config_command, XtNcallback, city_config_callback, NULL);
302 XtAddCallback(city_list, XtNcallback, city_list_callback, NULL);
304 XtRealizeWidget(city_dialog_shell);
306 if (!make_modal) { /* ?? dwp */
307 XSetWMProtocols(display, XtWindow(city_dialog_shell),
308 &wm_delete_window, 1);
309 XtOverrideTranslations(city_dialog_shell,
310 XtParseTranslationTable("<Message>WM_PROTOCOLS: msg-close-city-report()"));
313 real_city_report_dialog_update();
316 /****************************************************************
318 *****************************************************************/
319 void city_list_callback(Widget w, XtPointer client_data,
320 XtPointer call_data)
322 XawListReturnStruct *ret=XawListShowCurrent(city_list);
323 struct city *pcity;
325 if(ret->list_index!=XAW_LIST_NONE &&
326 (pcity=cities_in_list[ret->list_index])) {
327 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
328 struct item items[MAX_NUM_PRODUCTION_TARGETS];
329 int targets_used = 0;
330 size_t i;
332 XtSetSensitive(city_change_command, TRUE);
333 XtSetSensitive(city_center_command, TRUE);
334 XtSetSensitive(city_popup_command, TRUE);
335 XtSetSensitive(city_buy_command, city_can_buy(pcity));
336 if (city_popupmenu)
337 XtDestroyWidget(city_popupmenu);
339 city_popupmenu=XtVaCreatePopupShell("menu",
340 simpleMenuWidgetClass,
341 city_change_command,
342 NULL);
344 improvement_iterate(pimprove) {
345 if (can_city_build_improvement_now(pcity, pimprove)) {
346 targets[targets_used].kind = VUT_IMPROVEMENT;
347 targets[targets_used].value.building = pimprove;
348 targets_used++;
350 } improvement_iterate_end;
352 unit_type_iterate(punittype) {
353 if (can_city_build_unit_now(pcity, punittype)) {
354 targets[targets_used].kind = VUT_UTYPE;
355 targets[targets_used].value.utype = punittype;
356 targets_used++;
358 } unit_type_iterate_end;
360 name_and_sort_items(targets, targets_used, items, TRUE, NULL);
362 for (i = 0; i < targets_used; i++) {
363 Widget entry =
364 XtVaCreateManagedWidget(items[i].descr, smeBSBObjectClass,
365 city_popupmenu, NULL);
366 XtAddCallback(entry, XtNcallback, city_change_callback,
367 INT_TO_XTPOINTER(cid_encode(items[i].item)));
370 if (targets_used == 0)
371 XtSetSensitive(city_change_command, FALSE);
372 } else {
373 XtSetSensitive(city_change_command, FALSE);
374 XtSetSensitive(city_center_command, FALSE);
375 XtSetSensitive(city_popup_command, FALSE);
376 XtSetSensitive(city_buy_command, FALSE);
380 /****************************************************************
382 *****************************************************************/
383 void city_change_callback(Widget w, XtPointer client_data,
384 XtPointer call_data)
386 XawListReturnStruct *ret = XawListShowCurrent(city_list);
387 struct city *pcity;
388 struct universal production;
390 if (ret->list_index != XAW_LIST_NONE
391 && (pcity=cities_in_list[ret->list_index])) {
392 cid my_cid = (cid) XTPOINTER_TO_INT(client_data);
394 production = cid_decode(my_cid);
396 city_change_production(pcity, &production);
400 /****************************************************************
402 *****************************************************************/
403 void city_buy_callback(Widget w, XtPointer client_data, XtPointer call_data)
405 XawListReturnStruct *ret = XawListShowCurrent(city_list);
407 if (ret->list_index != XAW_LIST_NONE) {
408 struct city *pcity = cities_in_list[ret->list_index];
409 if (pcity) {
410 cityrep_buy(pcity);
415 /****************************************************************
417 *****************************************************************/
418 void city_chgall_callback(Widget w, XtPointer client_data,
419 XtPointer call_data)
421 popup_chgall_dialog (XtParent (w));
424 /****************************************************************
426 *****************************************************************/
427 void city_refresh_callback(Widget w, XtPointer client_data,
428 XtPointer call_data)
430 /* added by Syela - I find this very useful */
431 XawListReturnStruct *ret = XawListShowCurrent(city_list);
433 if (ret->list_index != XAW_LIST_NONE) {
434 struct city *pcity = cities_in_list[ret->list_index];
436 if (pcity) {
437 dsend_packet_city_refresh(&client.conn, pcity->id);
439 } else {
440 dsend_packet_city_refresh(&client.conn, 0);
444 /****************************************************************
446 *****************************************************************/
447 void city_close_callback(Widget w, XtPointer client_data,
448 XtPointer call_data)
450 city_report_dialog_popdown();
453 /****************************************************************
455 *****************************************************************/
456 void cityrep_msg_close(Widget w)
458 city_close_callback(w, NULL, NULL);
461 /****************************************************************
463 *****************************************************************/
464 void city_center_callback(Widget w, XtPointer client_data,
465 XtPointer call_data)
467 XawListReturnStruct *ret=XawListShowCurrent(city_list);
469 if(ret->list_index!=XAW_LIST_NONE) {
470 struct city *pcity;
471 if((pcity=cities_in_list[ret->list_index]))
472 center_tile_mapcanvas(pcity->tile);
476 /****************************************************************
478 *****************************************************************/
479 void city_popup_callback(Widget w, XtPointer client_data,
480 XtPointer call_data)
482 XawListReturnStruct *ret=XawListShowCurrent(city_list);
484 if (ret->list_index!=XAW_LIST_NONE) {
485 struct city *pcity;
487 if ((pcity = cities_in_list[ret->list_index])) {
488 if (gui_options.center_when_popup_city) {
489 center_tile_mapcanvas(pcity->tile);
491 popup_city_dialog(pcity);
496 /****************************************************************
498 *****************************************************************/
499 void city_config_callback(Widget w, XtPointer client_data,
500 XtPointer call_data)
502 popup_city_report_config_dialog();
505 #define MAX_LEN_CITY_TEXT 200
506 /****************************************************************
508 *****************************************************************/
509 void real_city_report_dialog_update(void)
511 if (!client_has_player()) {
512 return;
515 if(city_dialog_shell) {
516 int i=0, n;
517 Dimension width;
518 static int n_alloc = 0;
519 static char **city_list_text = NULL;
520 const char *report_title;
522 n = city_list_size(client.conn.playing->cities);
523 log_debug("%d cities in report", n);
524 if(n_alloc == 0 || n > n_alloc) {
525 int j, n_prev = n_alloc;
527 n_alloc *= 2;
528 if (!n_alloc || n_alloc < n) n_alloc = n + 1;
529 log_debug("city report n_alloc increased to %d", n_alloc);
530 cities_in_list = fc_realloc(cities_in_list,
531 n_alloc*sizeof(*cities_in_list));
532 city_list_text = fc_realloc(city_list_text, n_alloc*sizeof(char*));
533 for(j=n_prev; j<n_alloc; j++) {
534 city_list_text[j] = fc_malloc(MAX_LEN_CITY_TEXT);
538 report_title=get_centered_report_title(_("Cities"));
539 xaw_set_label(city_label, report_title);
540 free((void *) report_title);
542 xaw_set_label(city_list_label, get_city_table_header());
544 if (city_popupmenu) {
545 XtDestroyWidget(city_popupmenu);
546 city_popupmenu = 0;
549 /* Only sort once, in case any cities have duplicate/truncated names.
550 * Plus this should be much faster than sorting on ids which means
551 * having to find city corresponding to id for each comparison.
553 i=0;
554 city_list_iterate(client.conn.playing->cities, pcity) {
555 cities_in_list[i++] = pcity;
556 } city_list_iterate_end;
557 fc_assert(i==n);
558 qsort(cities_in_list, n, sizeof(struct city*), city_name_compare);
559 for(i=0; i<n; i++) {
560 get_city_text(cities_in_list[i], city_list_text[i], MAX_LEN_CITY_TEXT);
562 i = n;
563 if(!n) {
564 fc_strlcpy(city_list_text[0],
565 " ",
566 MAX_LEN_CITY_TEXT);
567 i=1;
568 cities_in_list[0]=NULL;
571 XawFormDoLayout(city_form, False);
572 XawListChange(city_list, city_list_text, i, 0, True);
574 XtVaGetValues(city_list, XtNlongest, &i, NULL);
575 width=i+10;
576 /* I don't know the proper way to set the width of this viewport widget.
577 Someone who knows is more than welcome to fix this */
578 XtVaSetValues(city_viewport, XtNwidth, width+15, NULL);
579 XtVaSetValues(city_list_label, XtNwidth, width, NULL);
580 XtVaSetValues(city_label, XtNwidth, width+15, NULL);
581 XawFormDoLayout(city_form, True);
583 XtSetSensitive(city_change_command, FALSE);
584 XtSetSensitive(city_center_command, FALSE);
585 XtSetSensitive(city_popup_command, FALSE);
586 XtSetSensitive(city_buy_command, FALSE);
590 /****************************************************************
591 Update the text for a single city in the city report
592 *****************************************************************/
593 void real_city_report_update_city(struct city *pcity)
595 int i;
597 if (!city_dialog_shell) {
598 return;
601 for(i=0; cities_in_list[i]; i++) {
602 if(cities_in_list[i]==pcity) {
603 int n;
604 String *list;
605 Dimension w;
606 char new_city_line[MAX_LEN_CITY_TEXT];
608 XtVaGetValues(city_list, XtNnumberStrings, &n, XtNlist, &list, NULL);
609 if (0 != strcmp(city_name_get(pcity), list[i])) {
610 break;
612 get_city_text(pcity, new_city_line, sizeof(new_city_line));
614 if (strcmp(new_city_line, list[i]) == 0) {
615 return; /* no change */
618 fc_strlcpy(list[i], new_city_line, MAX_LEN_CITY_TEXT);
620 /* It seems really inefficient to regenerate the whole list just to
621 change one line. It's also annoying to have to set the size
622 of each widget explicitly, since Xt is supposed to handle that. */
623 XawFormDoLayout(city_form, False);
624 XawListChange(city_list, list, n, 0, False);
625 XtVaGetValues(city_list, XtNlongest, &n, NULL);
626 w=n+10;
627 XtVaSetValues(city_viewport, XtNwidth, w+15, NULL);
628 XtVaSetValues(city_list_label, XtNwidth, w, NULL);
629 XtVaSetValues(city_label, XtNwidth, w+15, NULL);
630 XawFormDoLayout(city_form, True);
631 return;
634 real_city_report_dialog_update();
637 /****************************************************************
638 After a selection rectangle is defined, make the cities that
639 are hilited on the canvas exclusively hilited in the
640 City List window.
641 *****************************************************************/
642 void hilite_cities_from_canvas(void)
644 /* PORTME */
647 /****************************************************************
648 Toggle a city's hilited status.
649 *****************************************************************/
650 void toggle_city_hilite(struct city *pcity, bool on_off)
652 /* PORTME */
655 /****************************************************************
657 CITY REPORT CONFIGURE DIALOG
659 ****************************************************************/
661 /****************************************************************
662 ...
663 *****************************************************************/
664 void popup_city_report_config_dialog(void)
666 int i;
668 if(config_shell)
669 return;
671 create_city_report_config_dialog();
673 for(i=1; i<NUM_CREPORT_COLS; i++) {
674 XtVaSetValues(config_toggle[i],
675 XtNstate, city_report_specs[i].show,
676 XtNlabel, city_report_specs[i].show?_("Yes"):_("No"), NULL);
679 xaw_set_relative_position(city_dialog_shell, config_shell, 25, 25);
680 XtPopup(config_shell, XtGrabNone);
681 /* XtSetSensitive(main_form, FALSE); */
684 /****************************************************************
686 *****************************************************************/
687 void create_city_report_config_dialog(void)
689 Widget config_form, config_label, config_ok_command;
690 Widget config_optlabel=0, above;
691 struct city_report_spec *spec;
692 char buf[64];
693 int i;
695 config_shell = I_T(XtCreatePopupShell("cityconfig",
696 transientShellWidgetClass,
697 toplevel, NULL, 0));
699 config_form = XtVaCreateManagedWidget("cityconfigform",
700 formWidgetClass,
701 config_shell, NULL);
703 config_label = I_L(XtVaCreateManagedWidget("cityconfiglabel",
704 labelWidgetClass,
705 config_form, NULL));
707 config_toggle = fc_realloc(config_toggle,
708 NUM_CREPORT_COLS * sizeof(*config_toggle));
709 for(i=0, spec=city_report_specs+i; i<NUM_CREPORT_COLS; i++, spec++) {
710 fc_snprintf(buf, sizeof(buf), "%-32s", spec->explanation);
711 above = (i==1)?config_label:config_optlabel;
713 config_optlabel = XtVaCreateManagedWidget("cityconfiglabel",
714 labelWidgetClass,
715 config_form,
716 XtNlabel, buf,
717 XtNfromVert, above,
718 NULL);
720 config_toggle[i] = XtVaCreateManagedWidget("cityconfigtoggle",
721 toggleWidgetClass,
722 config_form,
723 XtNfromVert, above,
724 XtNfromHoriz, config_optlabel,
725 NULL);
728 config_ok_command =
729 I_L(XtVaCreateManagedWidget("cityconfigokcommand",
730 commandWidgetClass,
731 config_form,
732 XtNfromVert, config_optlabel,
733 NULL));
735 XtAddCallback(config_ok_command, XtNcallback,
736 config_ok_command_callback, NULL);
738 for(i=1; i<NUM_CREPORT_COLS; i++)
739 XtAddCallback(config_toggle[i], XtNcallback, toggle_callback, NULL);
741 XtRealizeWidget(config_shell);
743 xaw_horiz_center(config_label);
746 /**************************************************************************
748 **************************************************************************/
749 void config_ok_command_callback(Widget w, XtPointer client_data,
750 XtPointer call_data)
752 struct city_report_spec *spec;
753 int i;
755 XtDestroyWidget(config_shell);
757 for(i=0, spec=city_report_specs+i; i<NUM_CREPORT_COLS; i++, spec++) {
758 Boolean b;
760 XtVaGetValues(config_toggle[i], XtNstate, &b, NULL);
761 spec->show = (bool) b;
763 config_shell=0;
764 real_city_report_dialog_update();
767 /**************************************************************************
769 CHANGE ALL DIALOG
771 **************************************************************************/
773 struct chgall_data
775 struct
777 Widget shell;
778 Widget fr;
779 Widget to;
780 Widget change;
781 Widget refresh;
782 Widget cancel;
783 } w;
785 int fr_count;
786 char *fr_list[U_LAST + B_LAST];
787 cid fr_cids[U_LAST + B_LAST];
789 int to_count;
790 char *to_list[U_LAST + B_LAST];
791 cid to_cids[U_LAST + B_LAST];
793 int fr_index;
794 int to_index;
795 int may_change;
798 static struct chgall_data *chgall_state = NULL;
800 static void chgall_accept_action (Widget w, XEvent *event,
801 String *params, Cardinal *num_params);
802 static void chgall_cancel_action (Widget w, XEvent *event,
803 String *params, Cardinal *num_params);
805 static void chgall_shell_destroy (Widget w, XtPointer client_data,
806 XtPointer call_data);
807 static void chgall_fr_list_callback (Widget w, XtPointer client_data,
808 XtPointer call_data);
809 static void chgall_to_list_callback (Widget w, XtPointer client_data,
810 XtPointer call_data);
811 static void chgall_change_command_callback (Widget w, XtPointer client_data,
812 XtPointer call_data);
813 static void chgall_refresh_command_callback (Widget w, XtPointer client_data,
814 XtPointer call_data);
815 static void chgall_cancel_command_callback (Widget w, XtPointer client_data,
816 XtPointer call_data);
818 static void chgall_update_widgets_state (struct chgall_data *state);
820 /**************************************************************************
822 **************************************************************************/
823 static void popup_chgall_dialog(Widget parent)
825 struct chgall_data *state;
826 Widget shell;
827 Widget chgall_main;
828 Widget fr_viewport;
829 Widget to_viewport;
830 Position x, y;
831 Dimension width, height;
832 static int initialized = FALSE;
834 if (!initialized)
836 static XtActionsRec actions[] =
838 { "key-dialog-chgall-accept", chgall_accept_action },
839 { "key-dialog-chgall-cancel", chgall_cancel_action }
842 initialized = TRUE;
844 XtAppAddActions (app_context, actions, XtNumber (actions));
847 if (chgall_state)
849 XRaiseWindow (display, XtWindow (chgall_state->w.shell));
850 return;
853 shell =
854 I_T(XtCreatePopupShell
856 "chgalldialog",
857 transientShellWidgetClass,
858 parent,
859 NULL, 0
862 state = chgall_state = fc_malloc (sizeof (struct chgall_data));
863 state->w.shell = shell;
865 XtAddCallback (state->w.shell, XtNdestroyCallback,
866 chgall_shell_destroy, state);
868 chgall_main =
869 XtVaCreateManagedWidget
871 "chgallform",
872 formWidgetClass,
873 state->w.shell,
874 NULL
877 fr_viewport =
878 XtVaCreateManagedWidget
880 "chgallfrviewport",
881 viewportWidgetClass,
882 chgall_main,
883 NULL
886 state->w.fr =
887 XtVaCreateManagedWidget
889 "chgallfrlist",
890 listWidgetClass,
891 fr_viewport,
892 NULL
895 to_viewport =
896 XtVaCreateManagedWidget
898 "chgalltoviewport",
899 viewportWidgetClass,
900 chgall_main,
901 NULL
904 state->w.to =
905 XtVaCreateManagedWidget
907 "chgalltolist",
908 listWidgetClass,
909 to_viewport,
910 NULL
913 state->w.change =
914 I_L(XtVaCreateManagedWidget
916 "chgallchangecommand",
917 commandWidgetClass,
918 chgall_main,
919 NULL
922 state->w.refresh =
923 I_L(XtVaCreateManagedWidget
925 "chgallrefreshcommand",
926 commandWidgetClass,
927 chgall_main,
928 NULL
931 state->w.cancel =
932 I_L(XtVaCreateManagedWidget
934 "chgallcancelcommand",
935 commandWidgetClass,
936 chgall_main,
937 NULL
940 XtAddCallback (state->w.fr, XtNcallback,
941 chgall_fr_list_callback, state);
942 XtAddCallback (state->w.to, XtNcallback,
943 chgall_to_list_callback, state);
944 XtAddCallback (state->w.change, XtNcallback,
945 chgall_change_command_callback, state);
946 XtAddCallback (state->w.refresh, XtNcallback,
947 chgall_refresh_command_callback, state);
948 XtAddCallback (state->w.cancel, XtNcallback,
949 chgall_cancel_command_callback, state);
951 chgall_refresh_command_callback (NULL, (XtPointer)state, NULL);
953 XtRealizeWidget (state->w.shell);
954 XtVaGetValues (parent, XtNwidth, &width, XtNheight, &height, NULL);
955 XtTranslateCoords (parent,
956 (Position)(width / 20), (Position)(height / 20),
957 &x, &y);
958 XtVaSetValues (state->w.shell, XtNx, x, XtNy, y, NULL);
960 XtPopup (state->w.shell, XtGrabNone);
962 /* force refresh of viewports so the scrollbar is added.
963 * Buggy sun athena requires this */
964 XtVaSetValues (fr_viewport, XtNforceBars, True, NULL);
965 XtVaSetValues (to_viewport, XtNforceBars, True, NULL);
968 /**************************************************************************
970 **************************************************************************/
972 static void chgall_accept_action (Widget w, XEvent *event,
973 String *params, Cardinal *num_params)
975 Widget target = XtNameToWidget (w, "chgallchangecommand");
977 if (target)
979 x_simulate_button_click (target);
983 /**************************************************************************
985 **************************************************************************/
987 static void chgall_cancel_action (Widget w, XEvent *event,
988 String *params, Cardinal *num_params)
990 Widget target = XtNameToWidget (w, "chgallcancelcommand");
992 if (target)
994 x_simulate_button_click (target);
998 /**************************************************************************
1000 **************************************************************************/
1002 static void chgall_shell_destroy(Widget w, XtPointer client_data,
1003 XtPointer call_data)
1005 int i;
1007 for (i = 0; i < chgall_state->fr_count; i++) {
1008 free(chgall_state->fr_list[i]);
1010 for (i = 0; i < chgall_state->to_count; i++) {
1011 free(chgall_state->to_list[i]);
1014 chgall_state = NULL;
1016 free(client_data);
1019 /**************************************************************************
1021 **************************************************************************/
1023 static void chgall_fr_list_callback (Widget w, XtPointer client_data,
1024 XtPointer call_data)
1026 chgall_update_widgets_state ((struct chgall_data *)client_data);
1029 /**************************************************************************
1031 **************************************************************************/
1033 static void chgall_to_list_callback (Widget w, XtPointer client_data,
1034 XtPointer call_data)
1036 chgall_update_widgets_state ((struct chgall_data *)client_data);
1039 /**************************************************************************
1041 **************************************************************************/
1042 static void chgall_change_command_callback (Widget w, XtPointer client_data,
1043 XtPointer call_data)
1045 struct chgall_data *state = (struct chgall_data *)client_data;
1046 struct universal fr;
1047 struct universal to;
1049 chgall_update_widgets_state (state);
1051 if (!(state->may_change)) {
1052 return;
1055 fr = cid_decode(state->fr_cids[state->fr_index]);
1056 to = cid_decode(state->to_cids[state->to_index]);
1058 client_change_all(&fr, &to);
1060 XtDestroyWidget(state->w.shell);
1063 /**************************************************************************
1065 **************************************************************************/
1067 static void chgall_refresh_command_callback(Widget w,
1068 XtPointer client_data,
1069 XtPointer call_data)
1071 struct chgall_data *state = (struct chgall_data *) client_data;
1072 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
1073 struct item items[MAX_NUM_PRODUCTION_TARGETS];
1074 int i;
1076 state->fr_count = collect_currently_building_targets(targets);
1077 name_and_sort_items(targets, state->fr_count, items, false, NULL);
1078 for (i = 0; i < state->fr_count; i++) {
1079 state->fr_list[i] = fc_strdup(items[i].descr);
1080 state->fr_cids[i] = cid_encode(items[i].item);
1082 XawListChange(state->w.fr, state->fr_list, state->fr_count, 0, FALSE);
1084 state->to_count = collect_buildable_targets(targets);
1085 name_and_sort_items(targets, state->to_count, items, TRUE, NULL);
1086 for (i = 0; i < state->to_count; i++) {
1087 state->to_list[i] = fc_strdup(items[i].descr);
1088 state->to_cids[i] = cid_encode(items[i].item);
1090 XawListChange(state->w.to, state->to_list, state->to_count, 0, FALSE);
1092 chgall_update_widgets_state(state);
1095 /**************************************************************************
1097 **************************************************************************/
1099 static void chgall_cancel_command_callback (Widget w, XtPointer client_data,
1100 XtPointer call_data)
1102 struct chgall_data *state = (struct chgall_data *)client_data;
1104 XtDestroyWidget (state->w.shell);
1107 /**************************************************************************
1109 **************************************************************************/
1111 static void chgall_update_widgets_state (struct chgall_data *state)
1113 state->fr_index = (XawListShowCurrent (state->w.fr))->list_index;
1114 state->to_index = (XawListShowCurrent (state->w.to))->list_index;
1116 state->may_change =
1117 ((state->fr_index != XAW_LIST_NONE)
1118 && (state->to_index != XAW_LIST_NONE)
1119 && (state->fr_cids[state->fr_index] !=
1120 state->to_cids[state->to_index]));
1122 XtSetSensitive (state->w.change, state->may_change);