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)
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 ***********************************************************************/
15 #include <fc_config.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>
46 #include "client_main.h"
52 #include "cityrepdata.h"
54 #include "gui_stuff.h"
56 #include "optiondlg.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
,
76 /******************************************************************/
77 void create_city_report_dialog(bool make_modal
);
78 void city_close_callback(Widget w
, XtPointer client_data
,
80 void city_center_callback(Widget w
, XtPointer client_data
,
82 void city_popup_callback(Widget w
, XtPointer client_data
,
84 void city_buy_callback(Widget w
, XtPointer client_data
,
86 void city_chgall_callback(Widget w
, XtPointer client_data
,
88 void city_refresh_callback(Widget w
, XtPointer client_data
,
90 void city_change_callback(Widget w
, XtPointer client_data
,
92 void city_list_callback(Widget w
, XtPointer client_data
,
94 void city_config_callback(Widget w
, XtPointer client_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 " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
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
;
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;
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
;
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;
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");
162 /****************************************************************
166 ****************************************************************/
168 /****************************************************************
170 ****************************************************************/
171 void city_report_dialog_popup(bool make_modal
)
173 if(!city_dialog_shell
) {
175 Dimension width
, height
;
177 city_dialog_shell_is_modal
=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,
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
;
221 I_T(XtVaCreatePopupShell("reportcitypopup",
222 (make_modal
? transientShellWidgetClass
:
223 topLevelShellWidgetClass
),
226 city_form
= XtVaCreateManagedWidget("reportcityform",
231 report_title
=get_centered_report_title(_("Cities"));
232 city_label
= XtVaCreateManagedWidget("reportcitylabel",
238 free((void *) report_title
);
239 city_list_label
= XtVaCreateManagedWidget("reportcitylistlabel",
243 get_city_table_header(),
245 city_viewport
= XtVaCreateManagedWidget("reportcityviewport",
250 city_list
= XtVaCreateManagedWidget("reportcitylist",
254 (XtArgVal
)dummy_city_list
,
258 I_L(XtVaCreateManagedWidget("reportcityclosecommand", commandWidgetClass
,
261 city_center_command
=
262 I_L(XtVaCreateManagedWidget("reportcitycentercommand", commandWidgetClass
,
266 I_L(XtVaCreateManagedWidget("reportcitypopupcommand", commandWidgetClass
,
272 I_L(XtVaCreateManagedWidget("reportcitybuycommand", commandWidgetClass
,
275 city_change_command
=
276 I_L(XtVaCreateManagedWidget("reportcitychangemenubutton",
277 menuButtonWidgetClass
,
280 city_chgall_command
=
281 I_L(XtVaCreateManagedWidget("reportcitychgallcommand",
285 city_refresh_command
=
286 I_L(XtVaCreateManagedWidget("reportcityrefreshcommand",
290 city_config_command
=
291 I_L(XtVaCreateManagedWidget("reportcityconfigcommand",
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
,
322 XawListReturnStruct
*ret
=XawListShowCurrent(city_list
);
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;
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
));
337 XtDestroyWidget(city_popupmenu
);
339 city_popupmenu
=XtVaCreatePopupShell("menu",
340 simpleMenuWidgetClass
,
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
;
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
;
358 } unit_type_iterate_end
;
360 name_and_sort_items(targets
, targets_used
, items
, TRUE
, NULL
);
362 for (i
= 0; i
< targets_used
; i
++) {
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
);
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
,
386 XawListReturnStruct
*ret
= XawListShowCurrent(city_list
);
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
];
415 /****************************************************************
417 *****************************************************************/
418 void city_chgall_callback(Widget w
, XtPointer client_data
,
421 popup_chgall_dialog (XtParent (w
));
424 /****************************************************************
426 *****************************************************************/
427 void city_refresh_callback(Widget w
, XtPointer client_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
];
437 dsend_packet_city_refresh(&client
.conn
, pcity
->id
);
440 dsend_packet_city_refresh(&client
.conn
, 0);
444 /****************************************************************
446 *****************************************************************/
447 void city_close_callback(Widget w
, XtPointer client_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
,
467 XawListReturnStruct
*ret
=XawListShowCurrent(city_list
);
469 if(ret
->list_index
!=XAW_LIST_NONE
) {
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
,
482 XawListReturnStruct
*ret
=XawListShowCurrent(city_list
);
484 if (ret
->list_index
!=XAW_LIST_NONE
) {
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
,
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()) {
515 if(city_dialog_shell
) {
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
;
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
);
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.
554 city_list_iterate(client
.conn
.playing
->cities
, pcity
) {
555 cities_in_list
[i
++] = pcity
;
556 } city_list_iterate_end
;
558 qsort(cities_in_list
, n
, sizeof(struct city
*), city_name_compare
);
560 get_city_text(cities_in_list
[i
], city_list_text
[i
], MAX_LEN_CITY_TEXT
);
564 fc_strlcpy(city_list_text
[0],
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
);
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
)
597 if (!city_dialog_shell
) {
601 for(i
=0; cities_in_list
[i
]; i
++) {
602 if(cities_in_list
[i
]==pcity
) {
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
])) {
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
);
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
);
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
641 *****************************************************************/
642 void hilite_cities_from_canvas(void)
647 /****************************************************************
648 Toggle a city's hilited status.
649 *****************************************************************/
650 void toggle_city_hilite(struct city
*pcity
, bool on_off
)
655 /****************************************************************
657 CITY REPORT CONFIGURE DIALOG
659 ****************************************************************/
661 /****************************************************************
663 *****************************************************************/
664 void popup_city_report_config_dialog(void)
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
;
695 config_shell
= I_T(XtCreatePopupShell("cityconfig",
696 transientShellWidgetClass
,
699 config_form
= XtVaCreateManagedWidget("cityconfigform",
703 config_label
= I_L(XtVaCreateManagedWidget("cityconfiglabel",
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",
720 config_toggle
[i
] = XtVaCreateManagedWidget("cityconfigtoggle",
724 XtNfromHoriz
, config_optlabel
,
729 I_L(XtVaCreateManagedWidget("cityconfigokcommand",
732 XtNfromVert
, config_optlabel
,
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
,
752 struct city_report_spec
*spec
;
755 XtDestroyWidget(config_shell
);
757 for(i
=0, spec
=city_report_specs
+i
; i
<NUM_CREPORT_COLS
; i
++, spec
++) {
760 XtVaGetValues(config_toggle
[i
], XtNstate
, &b
, NULL
);
761 spec
->show
= (bool) b
;
764 real_city_report_dialog_update();
767 /**************************************************************************
771 **************************************************************************/
786 char *fr_list
[U_LAST
+ B_LAST
];
787 cid fr_cids
[U_LAST
+ B_LAST
];
790 char *to_list
[U_LAST
+ B_LAST
];
791 cid to_cids
[U_LAST
+ B_LAST
];
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
;
831 Dimension width
, height
;
832 static int initialized
= FALSE
;
836 static XtActionsRec actions
[] =
838 { "key-dialog-chgall-accept", chgall_accept_action
},
839 { "key-dialog-chgall-cancel", chgall_cancel_action
}
844 XtAppAddActions (app_context
, actions
, XtNumber (actions
));
849 XRaiseWindow (display
, XtWindow (chgall_state
->w
.shell
));
854 I_T(XtCreatePopupShell
857 transientShellWidgetClass
,
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
);
869 XtVaCreateManagedWidget
878 XtVaCreateManagedWidget
887 XtVaCreateManagedWidget
896 XtVaCreateManagedWidget
905 XtVaCreateManagedWidget
914 I_L(XtVaCreateManagedWidget
916 "chgallchangecommand",
923 I_L(XtVaCreateManagedWidget
925 "chgallrefreshcommand",
932 I_L(XtVaCreateManagedWidget
934 "chgallcancelcommand",
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),
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");
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");
994 x_simulate_button_click (target
);
998 /**************************************************************************
1000 **************************************************************************/
1002 static void chgall_shell_destroy(Widget w
, XtPointer client_data
,
1003 XtPointer call_data
)
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
;
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
)) {
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
];
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
;
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
);