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/StringDefs.h>
24 #include <X11/Xaw/Form.h>
25 #include <X11/Xaw/Label.h>
26 #include <X11/Xaw/SimpleMenu.h>
27 #include <X11/Xaw/Command.h>
28 #include <X11/Xaw/List.h>
29 #include <X11/Xaw/Viewport.h>
30 
31 /* utility */
32 #include "log.h"
33 #include "mem.h"
34 
35 /* common */
36 #include "game.h"
37 #include "player.h"
38 
39 /* gui-xaw */
40 #include "mapview.h"
41 #include "gui_main.h"
42 #include "gui_stuff.h"
43 
44 #include "finddlg.h"
45 
46 static Widget find_dialog_shell;
47 static Widget find_form;
48 static Widget find_label;
49 static Widget find_viewport;
50 static Widget find_list;
51 static Widget find_center_command;
52 static Widget find_cancel_command;
53 
54 void update_find_dialog(Widget find_list);
55 
56 void find_center_command_callback(Widget w, XtPointer client_data,
57 				  XtPointer call_data);
58 void find_cancel_command_callback(Widget w, XtPointer client_data,
59 				  XtPointer call_data);
60 void find_list_callback(Widget w, XtPointer client_data, XtPointer call_data);
61 
62 static char *dummy_city_list[]={
63   "                                ",
64   "                                ",
65   "                                ",
66   "                                ",
67   "                                ",
68   "                                ",
69   "                                ",
70   "                                ",
71   "                                ",
72   0
73 };
74 
75 static int ncities_total;
76 static char **city_name_ptrs;
77 static struct tile *original_tile;
78 
79 /****************************************************************
80 popup the dialog 10% inside the main-window
81 *****************************************************************/
popup_find_dialog(void)82 void popup_find_dialog(void)
83 {
84   Position x, y;
85   Dimension width, height;
86 
87   original_tile = get_center_tile_mapcanvas();
88 
89   XtSetSensitive(main_form, FALSE);
90 
91   find_dialog_shell =
92     I_T(XtCreatePopupShell("finddialog", transientShellWidgetClass,
93 			   toplevel, NULL, 0));
94 
95   find_form = XtVaCreateManagedWidget("findform",
96 				      formWidgetClass,
97 				      find_dialog_shell, NULL);
98 
99 
100   find_label = I_L(XtVaCreateManagedWidget("findlabel", labelWidgetClass,
101 					   find_form, NULL));
102 
103   find_viewport = XtVaCreateManagedWidget("findviewport",
104 				      viewportWidgetClass,
105 				      find_form,
106 				      NULL);
107 
108 
109   find_list = XtVaCreateManagedWidget("findlist",
110 				      listWidgetClass,
111 				      find_viewport,
112 				      XtNlist,
113 				      (XtArgVal)dummy_city_list,
114 				      NULL);
115 
116   find_center_command =
117     I_L(XtVaCreateManagedWidget("findcentercommand", commandWidgetClass,
118 				find_form, NULL));
119 
120   find_cancel_command =
121     I_L(XtVaCreateManagedWidget("findcancelcommand", commandWidgetClass,
122 				find_form, NULL));
123 
124   XtAddCallback(find_list, XtNcallback, find_list_callback, NULL);
125   XtAddCallback(find_center_command, XtNcallback,
126 		find_center_command_callback, NULL);
127   XtAddCallback(find_cancel_command, XtNcallback,
128 		find_cancel_command_callback, NULL);
129 
130 
131   XtRealizeWidget(find_dialog_shell);
132 
133   update_find_dialog(find_list);
134 
135   XtVaGetValues(toplevel, XtNwidth, &width, XtNheight, &height, NULL);
136 
137   XtTranslateCoords(toplevel, (Position) width/10, (Position) height/10,
138 		    &x, &y);
139   XtVaSetValues(find_dialog_shell, XtNx, x, XtNy, y, NULL);
140 
141   XtPopup(find_dialog_shell, XtGrabNone);
142 
143   /* force refresh of viewport so the scrollbar is added.
144    * Buggy sun athena requires this */
145   XtVaSetValues(find_viewport, XtNforceBars, True, NULL);
146 }
147 
148 
149 
150 /**************************************************************************
151 ...
152 **************************************************************************/
update_find_dialog(Widget search_list)153 void update_find_dialog(Widget search_list)
154 {
155   int j = 0;
156 
157   ncities_total = 0;
158   players_iterate(pplayer) {
159     ncities_total += city_list_size(pplayer->cities);
160   } players_iterate_end;
161 
162   city_name_ptrs=fc_malloc(ncities_total*sizeof(char*));
163 
164   players_iterate(pplayer) {
165     city_list_iterate(pplayer->cities, pcity) {
166       *(city_name_ptrs+j++)=fc_strdup(city_name_get(pcity));
167     } city_list_iterate_end;
168   } players_iterate_end;
169 
170   if (ncities_total) {
171     qsort(city_name_ptrs, ncities_total, sizeof(char *), compare_strings_ptrs);
172     XawListChange(search_list, (CONST_FOR_XAW_LIST_CHANGE char **) city_name_ptrs,
173                   ncities_total, 0, True);
174   }
175 }
176 
177 /**************************************************************************
178 ...
179 **************************************************************************/
popdown_find_dialog(void)180 static void popdown_find_dialog(void)
181 {
182   int i;
183 
184   for(i=0; i<ncities_total; i++)
185     free(*(city_name_ptrs+i));
186 
187   XtDestroyWidget(find_dialog_shell);
188   free(city_name_ptrs);
189   XtSetSensitive(main_form, TRUE);
190 }
191 
192 /**************************************************************************
193 ...
194 **************************************************************************/
find_center_command_callback(Widget w,XtPointer client_data,XtPointer call_data)195 void find_center_command_callback(Widget w, XtPointer client_data,
196 				  XtPointer call_data)
197 {
198   struct city *pcity;
199   XawListReturnStruct *ret;
200 
201   ret = XawListShowCurrent(find_list);
202 
203   if (ret->list_index != XAW_LIST_NONE) {
204     if ((pcity = game_city_by_name(ret->string))) {
205       center_tile_mapcanvas(pcity->tile);
206     }
207   }
208 
209   popdown_find_dialog();
210 }
211 
212 /**************************************************************************
213 ...
214 **************************************************************************/
find_cancel_command_callback(Widget w,XtPointer client_data,XtPointer call_data)215 void find_cancel_command_callback(Widget w, XtPointer client_data,
216 				  XtPointer call_data)
217 {
218   center_tile_mapcanvas(original_tile);
219   popdown_find_dialog();
220 }
221 
222 /**************************************************************************
223 ...
224 **************************************************************************/
find_list_callback(Widget w,XtPointer client_data,XtPointer call_data)225 void find_list_callback(Widget w, XtPointer client_data, XtPointer call_data)
226 {
227   struct city *pcity;
228   XawListReturnStruct *ret;
229 
230   ret=XawListShowCurrent(find_list);
231 
232   if (ret->list_index != XAW_LIST_NONE) {
233     if ((pcity = game_city_by_name(ret->string))) {
234       center_tile_mapcanvas(pcity->tile);
235     }
236   }
237 }
238