1 /*
2  *
3  * XASTIR, Amateur Station Tracking and Information Reporting
4  * Copyright (C) 1999,2000  Frank Giannandrea
5  * Copyright (C) 2000-2019 The Xastir Group
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * Look at the README for more information on the program.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25   #include "config.h"
26 #endif  // HAVE_CONFIG_H
27 
28 #include "snprintf.h"
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 
33 #include <Xm/XmAll.h>
34 #ifdef HAVE_XBAE_MATRIX_H
35   #include <Xbae/Matrix.h>
36 #endif  // HAVE_XBAE_MATRIX_H
37 
38 
39 #include "xastir.h"
40 #include "main.h"
41 #include "lang.h"
42 //#include "maps.h"
43 #include "io.h"
44 #include "geo.h"
45 
46 // Must be last include file
47 #include "leak_detection.h"
48 
49 extern XmFontList fontlist1;    // Menu/System fontlist
50 
51 Widget geocoder_place_dialog = (Widget)NULL;
52 Widget geocoder_zip_data = (Widget)NULL;
53 Widget geocoder_state_data = (Widget)NULL;
54 Widget geocoder_locality_data = (Widget)NULL;
55 Widget geocoder_address_data = (Widget)NULL;
56 Widget geocoder_map_file_data = (Widget)NULL;
57 char geocoder_zip_name[50];
58 char geocoder_state_name[50];
59 char geocoder_locality_name[255];
60 char geocoder_address_name[255];
61 char geocoder_map_filename[400];
62 static xastir_mutex geocoder_place_dialog_lock;
63 
64 long destination_coord_lat = 0;
65 long destination_coord_lon = 0;
66 int mark_destination = 0;
67 int show_destination_mark = 0;
68 
69 
70 
71 
72 
geocoder_gui_init(void)73 void geocoder_gui_init(void)
74 {
75   init_critical_section( &geocoder_place_dialog_lock );
76   geocoder_zip_name[0] = '\0';
77   geocoder_state_name[0] = '\0';
78   geocoder_locality_name[0] = '\0';
79   geocoder_address_name[0] = '\0';
80 }
81 
82 
83 
84 
85 
86 /**** GEOCODER FIND PLACE ******/
87 
Geocoder_place_destroy_shell(Widget UNUSED (widget),XtPointer clientData,XtPointer UNUSED (callData))88 void Geocoder_place_destroy_shell(Widget UNUSED(widget), XtPointer clientData, XtPointer UNUSED(callData) )
89 {
90   Widget shell = (Widget) clientData;
91   XtPopdown(shell);
92 
93   begin_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place_destroy_shell" );
94 
95   XtDestroyWidget(shell);
96   geocoder_place_dialog = (Widget)NULL;
97 
98   end_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place_destroy_shell" );
99 
100 }
101 
102 
103 
104 
105 
106 /*
107  *  Geocoder a place by centering the map at its position
108  */
Geocoder_place_now(Widget w,XtPointer clientData,XtPointer callData)109 void Geocoder_place_now(Widget w, XtPointer clientData, XtPointer callData)
110 {
111   struct io_file *index;
112   struct geo_location loc;
113   char input[1024];
114   char *temp_ptr;
115 
116 
117   /* find place and go there */
118   temp_ptr = XmTextFieldGetString(geocoder_zip_data);
119   xastir_snprintf(geocoder_zip_name,
120                   sizeof(geocoder_zip_name),
121                   "%s",
122                   temp_ptr);
123   XtFree(temp_ptr);
124 
125   temp_ptr = XmTextFieldGetString(geocoder_state_data);
126   xastir_snprintf(geocoder_state_name,
127                   sizeof(geocoder_state_name),
128                   "%s",
129                   temp_ptr);
130   XtFree(temp_ptr);
131 
132   temp_ptr = XmTextFieldGetString(geocoder_locality_data);
133   xastir_snprintf(geocoder_locality_name,
134                   sizeof(geocoder_locality_name),
135                   "%s",
136                   temp_ptr);
137   XtFree(temp_ptr);
138 
139   temp_ptr = XmTextFieldGetString(geocoder_address_data);
140   xastir_snprintf(geocoder_address_name,
141                   sizeof(geocoder_address_name),
142                   "%s",
143                   temp_ptr);
144   XtFree(temp_ptr);
145 
146   temp_ptr = XmTextFieldGetString(geocoder_map_file_data);
147   xastir_snprintf(geocoder_map_filename,
148                   sizeof(geocoder_map_filename),
149                   "%s",
150                   temp_ptr);
151   XtFree(temp_ptr);
152 
153   (void)remove_trailing_spaces(geocoder_zip_name);
154   (void)remove_trailing_spaces(geocoder_state_name);
155   (void)remove_trailing_spaces(geocoder_locality_name);
156   (void)remove_trailing_spaces(geocoder_address_name);
157 
158   /*
159   fprintf(stderr,"%s\n%s\n%s\n%s\n%s\n",
160       geocoder_zip_name,
161       geocoder_state_name,
162       geocoder_locality_name,
163       geocoder_address_name,
164       geocoder_map_filename);
165   */
166 
167   index = io_open(geocoder_map_filename);
168 
169   xastir_snprintf(input,
170                   sizeof(input),
171                   "%s %s%s%s %s",
172                   geocoder_address_name,
173                   geocoder_locality_name,
174                   (strlen(geocoder_state_name) != 0)?",":"",
175                   geocoder_state_name,
176                   geocoder_zip_name);
177 
178   if (debug_level & 1)
179   {
180     fprintf(stderr,"Searching for: %s\n", input);
181   }
182 
183   if (geo_find(index,input,strlen(input),&loc))
184   {
185     long coord_lon, coord_lat;
186     char lat_str[20];
187     char long_str[20];
188     int lon, lat, lons, lats, tmp1;
189     char lond = 'E';
190     char latd = 'N';
191     double res, tmp;
192 
193 
194     if (loc.at.longitude < 0)
195     {
196       loc.at.longitude = -loc.at.longitude;
197       lond = 'W';
198     }
199     if (loc.at.latitude < 0)
200     {
201       loc.at.latitude = -loc.at.latitude;
202       latd = 'S';
203     }
204 
205     lon = loc.at.longitude;
206     lat = loc.at.latitude;
207 
208     res = loc.at.longitude - lon;
209     tmp = (res * 100);
210     tmp = tmp * 60 / 100;
211     tmp1 = tmp;
212     lon = (lon * 100) + tmp1;
213     lons = (tmp - tmp1) * 100;
214 
215     res = loc.at.latitude - lat;
216     tmp = (res * 100);
217     tmp = tmp * 60 / 100;
218     tmp1 = tmp;
219     lat = (lat * 100) + tmp1;
220     lats = (tmp - tmp1) * 100;
221 
222     xastir_snprintf(lat_str,
223                     sizeof(lat_str),
224                     "%d.%02d%c",
225                     lat,
226                     lats,
227                     latd);
228 
229     coord_lat = convert_lat_s2l(lat_str);
230 
231     xastir_snprintf(long_str,
232                     sizeof(long_str),
233                     "%s%d.%02d%c",
234                     (lon < 10000)?"0":"",
235                     lon,
236                     lons,
237                     lond);
238 
239     coord_lon = convert_lon_s2l(long_str);
240 
241     destination_coord_lat = coord_lat;
242     destination_coord_lon = coord_lon;
243     mark_destination = 1;
244 
245     popup_message_always( langcode("POPEM00029"), geocoder_address_name );
246     set_map_position(w, coord_lat, coord_lon);
247   }
248   else
249   {
250     popup_message_always(langcode("POPEM00025"),geocoder_address_name);
251   }
252   Geocoder_place_destroy_shell(w, clientData, callData);
253 }
254 
255 
256 
257 
258 
Show_dest_toggle(Widget UNUSED (widget),XtPointer clientData,XtPointer callData)259 void  Show_dest_toggle( Widget UNUSED(widget), XtPointer clientData, XtPointer callData)
260 {
261   char *which = (char *)clientData;
262   XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *)callData;
263 
264   if(state->set)
265   {
266     show_destination_mark = atoi(which);
267   }
268   else
269   {
270     show_destination_mark = 0;
271   }
272 }
273 
274 
275 
276 
277 
Geocoder_place(Widget UNUSED (w),XtPointer UNUSED (clientData),XtPointer UNUSED (callData))278 void Geocoder_place(Widget UNUSED(w), XtPointer UNUSED(clientData), XtPointer UNUSED(callData) )
279 {
280   static Widget pane, scrollwindow, form, button_ok, button_cancel, sep,
281          zip, state, locality, address, map_file, show_dest_toggle;
282   Atom delw;
283 
284   if (!geocoder_place_dialog)
285   {
286 
287     begin_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place" );
288 
289     // Find Address
290     geocoder_place_dialog = XtVaCreatePopupShell(langcode("PULDNMP029"),
291                             xmDialogShellWidgetClass, appshell,
292                             XmNdeleteResponse,XmDESTROY,
293                             XmNdefaultPosition, FALSE,
294                             XmNfontList, fontlist1,
295                             NULL);
296 
297     pane = XtVaCreateWidget("Geocoder_place pane",xmPanedWindowWidgetClass, geocoder_place_dialog,
298                             XmNbackground, colors[0xff],
299                             NULL);
300 
301     scrollwindow = XtVaCreateManagedWidget("Geocoder_place scrollwindow",
302                                            xmScrolledWindowWidgetClass,
303                                            pane,
304                                            XmNscrollingPolicy, XmAUTOMATIC,
305                                            NULL);
306 
307     form =  XtVaCreateWidget("Geocoder_place form",
308                              xmFormWidgetClass,
309                              scrollwindow,
310                              XmNfractionBase, 2,
311                              XmNbackground, colors[0xff],
312                              XmNautoUnmanage, FALSE,
313                              XmNshadowThickness, 1,
314                              NULL);
315 
316     // Address:
317     address = XtVaCreateManagedWidget(langcode("FEATURE007"),xmLabelWidgetClass, form,
318                                       XmNtopAttachment, XmATTACH_FORM,
319                                       XmNtopOffset, 10,
320                                       XmNbottomAttachment, XmATTACH_NONE,
321                                       XmNleftAttachment, XmATTACH_FORM,
322                                       XmNleftOffset, 10,
323                                       XmNrightAttachment, XmATTACH_NONE,
324                                       XmNbackground, colors[0xff],
325                                       XmNfontList, fontlist1,
326                                       NULL);
327 
328     geocoder_address_data = XtVaCreateManagedWidget("Geocoder_address_data", xmTextFieldWidgetClass, form,
329                             XmNeditable,   TRUE,
330                             XmNcursorPositionVisible, TRUE,
331                             XmNsensitive, TRUE,
332                             XmNshadowThickness,    1,
333                             XmNcolumns, 32,
334                             XmNwidth, ((32*7)+2),
335                             XmNmaxLength, 254,
336                             XmNbackground, colors[0x0f],
337                             XmNtopAttachment, XmATTACH_FORM,
338                             XmNtopOffset, 5,
339                             XmNbottomAttachment,XmATTACH_NONE,
340                             XmNleftAttachment, XmATTACH_WIDGET,
341                             XmNleftWidget, address,
342                             XmNleftOffset, 10,
343                             XmNrightAttachment,XmATTACH_FORM,
344                             XmNrightOffset, 10,
345                             XmNnavigationType, XmTAB_GROUP,
346                             XmNtraversalOn, TRUE,
347                             XmNfontList, fontlist1,
348                             NULL);
349 
350     // City:
351     locality = XtVaCreateManagedWidget(langcode("FEATURE008"),xmLabelWidgetClass, form,
352                                        XmNtopAttachment, XmATTACH_WIDGET,
353                                        XmNtopWidget, address,
354                                        XmNtopOffset, 10,
355                                        XmNbottomAttachment, XmATTACH_NONE,
356                                        XmNleftAttachment, XmATTACH_FORM,
357                                        XmNleftOffset, 10,
358                                        XmNrightAttachment, XmATTACH_NONE,
359                                        XmNbackground, colors[0xff],
360                                        XmNfontList, fontlist1,
361                                        NULL);
362 
363     geocoder_locality_data = XtVaCreateManagedWidget("Geocoder_address_data", xmTextFieldWidgetClass, form,
364                              XmNeditable,   TRUE,
365                              XmNcursorPositionVisible, TRUE,
366                              XmNsensitive, TRUE,
367                              XmNshadowThickness,    1,
368                              XmNcolumns, 32,
369                              XmNwidth, ((32*7)+2),
370                              XmNmaxLength, 254,
371                              XmNbackground, colors[0x0f],
372                              XmNtopAttachment,XmATTACH_WIDGET,
373                              XmNtopWidget, address,
374                              XmNtopOffset, 5,
375                              XmNbottomAttachment,XmATTACH_NONE,
376                              XmNleftAttachment, XmATTACH_WIDGET,
377                              XmNleftWidget, locality,
378                              XmNleftOffset, 10,
379                              XmNrightAttachment,XmATTACH_FORM,
380                              XmNrightOffset, 10,
381                              XmNnavigationType, XmTAB_GROUP,
382                              XmNtraversalOn, TRUE,
383                              XmNfontList, fontlist1,
384                              NULL);
385 
386     // State/Province:
387     state = XtVaCreateManagedWidget(langcode("FEATURE002"),xmLabelWidgetClass, form,
388                                     XmNtopAttachment, XmATTACH_WIDGET,
389                                     XmNtopWidget, locality,
390                                     XmNtopOffset, 10,
391                                     XmNbottomAttachment, XmATTACH_NONE,
392                                     XmNleftAttachment, XmATTACH_FORM,
393                                     XmNleftOffset, 10,
394                                     XmNrightAttachment, XmATTACH_NONE,
395                                     XmNbackground, colors[0xff],
396                                     XmNfontList, fontlist1,
397                                     NULL);
398 
399     geocoder_state_data = XtVaCreateManagedWidget("Geocoder_state_data", xmTextFieldWidgetClass, form,
400                           XmNeditable,   TRUE,
401                           XmNcursorPositionVisible, TRUE,
402                           XmNsensitive, TRUE,
403                           XmNshadowThickness,    1,
404                           XmNcolumns, 4,
405                           XmNwidth, ((4*7)+2),
406                           XmNmaxLength, 2,
407                           XmNbackground, colors[0x0f],
408                           XmNtopAttachment,XmATTACH_WIDGET,
409                           XmNtopWidget, locality,
410                           XmNtopOffset, 5,
411                           XmNbottomAttachment,XmATTACH_NONE,
412                           XmNleftAttachment, XmATTACH_WIDGET,
413                           XmNleftWidget, state,
414                           XmNleftOffset, 10,
415                           XmNrightAttachment,XmATTACH_NONE,
416                           XmNrightOffset, 10,
417                           XmNnavigationType, XmTAB_GROUP,
418                           XmNtraversalOn, TRUE,
419                           XmNfontList, fontlist1,
420                           NULL);
421 
422     // Mark Destination
423     show_dest_toggle = XtVaCreateManagedWidget(langcode("FEATURE009"),xmToggleButtonGadgetClass, form,
424                        XmNvisibleWhenOff, TRUE,
425                        XmNindicatorSize, 12,
426                        XmNtopAttachment, XmATTACH_WIDGET,
427                        XmNtopWidget, locality,
428                        XmNtopOffset, 10,
429                        XmNbottomAttachment, XmATTACH_NONE,
430                        XmNleftAttachment, XmATTACH_WIDGET,
431                        XmNleftWidget, geocoder_state_data,
432                        XmNleftOffset, 20,
433                        XmNrightAttachment, XmATTACH_NONE,
434                        XmNbackground, colors[0xff],
435                        MY_FOREGROUND_COLOR,
436                        MY_BACKGROUND_COLOR,
437                        XmNfontList, fontlist1,
438                        NULL);
439 
440     XtAddCallback(show_dest_toggle,XmNvalueChangedCallback,Show_dest_toggle,"1");
441     if (show_destination_mark)
442     {
443       XmToggleButtonSetState(show_dest_toggle,TRUE,FALSE);
444     }
445 
446 
447     // Zip Code:
448     zip = XtVaCreateManagedWidget(langcode("FEATURE010"),xmLabelWidgetClass, form,
449                                   XmNtopAttachment, XmATTACH_WIDGET,
450                                   XmNtopWidget, state,
451                                   XmNtopOffset, 10,
452                                   XmNbottomAttachment, XmATTACH_NONE,
453                                   XmNleftAttachment, XmATTACH_FORM,
454                                   XmNleftOffset, 10,
455                                   XmNrightAttachment, XmATTACH_NONE,
456                                   XmNbackground, colors[0xff],
457                                   XmNfontList, fontlist1,
458                                   NULL);
459 
460     geocoder_zip_data = XtVaCreateManagedWidget("Geocoder_zip_data", xmTextFieldWidgetClass, form,
461                         XmNeditable,   TRUE,
462                         XmNcursorPositionVisible, TRUE,
463                         XmNsensitive, TRUE,
464                         XmNshadowThickness,    1,
465                         XmNcolumns, 12,
466                         XmNwidth, ((12*7)+2),
467                         XmNmaxLength, 10,
468                         XmNbackground, colors[0x0f],
469                         XmNtopAttachment, XmATTACH_WIDGET,
470                         XmNtopWidget, state,
471                         XmNtopOffset, 5,
472                         XmNbottomAttachment,XmATTACH_NONE,
473                         XmNleftAttachment, XmATTACH_WIDGET,
474                         XmNleftWidget, zip,
475                         XmNleftOffset, 10,
476                         XmNrightAttachment,XmATTACH_NONE,
477                         XmNnavigationType, XmTAB_GROUP,
478                         XmNtraversalOn, TRUE,
479                         XmNfontList, fontlist1,
480                         NULL);
481 
482     // Geocoding File:
483     map_file = XtVaCreateManagedWidget(langcode("FEATURE011"),xmLabelWidgetClass, form,
484                                        XmNtopAttachment, XmATTACH_WIDGET,
485                                        XmNtopWidget, zip,
486                                        XmNtopOffset, 10,
487                                        XmNbottomAttachment, XmATTACH_NONE,
488                                        XmNleftAttachment, XmATTACH_FORM,
489                                        XmNleftOffset, 10,
490                                        XmNrightAttachment, XmATTACH_NONE,
491                                        XmNbackground, colors[0xff],
492                                        XmNfontList, fontlist1,
493                                        NULL);
494 
495     geocoder_map_file_data = XtVaCreateManagedWidget("geocoder_map_file_data", xmTextFieldWidgetClass, form,
496                              XmNeditable,   TRUE,
497                              XmNcursorPositionVisible, TRUE,
498                              XmNsensitive, TRUE,
499                              XmNshadowThickness,    1,
500                              XmNcolumns, 40,
501                              XmNwidth, ((40*7)+2),
502                              XmNmaxLength, 254,
503                              XmNbackground, colors[0x0f],
504                              XmNtopAttachment,XmATTACH_WIDGET,
505                              XmNtopWidget, zip,
506                              XmNtopOffset, 5,
507                              XmNbottomAttachment,XmATTACH_NONE,
508                              XmNleftAttachment, XmATTACH_WIDGET,
509                              XmNleftWidget, map_file,
510                              XmNleftOffset, 10,
511                              XmNrightAttachment,XmATTACH_FORM,
512                              XmNrightOffset, 10,
513                              XmNnavigationType, XmTAB_GROUP,
514                              XmNtraversalOn, TRUE,
515                              XmNfontList, fontlist1,
516                              NULL);
517 
518 
519     sep = XtVaCreateManagedWidget("Geocoder_place sep", xmSeparatorGadgetClass,form,
520                                   XmNorientation, XmHORIZONTAL,
521                                   XmNtopAttachment,XmATTACH_WIDGET,
522                                   XmNtopWidget,geocoder_map_file_data,
523                                   XmNtopOffset, 10,
524                                   XmNbottomAttachment,XmATTACH_NONE,
525                                   XmNleftAttachment, XmATTACH_FORM,
526                                   XmNrightAttachment,XmATTACH_FORM,
527                                   XmNbackground, colors[0xff],
528                                   XmNfontList, fontlist1,
529                                   NULL);
530 
531     button_ok = XtVaCreateManagedWidget(langcode("WPUPLSP005"),xmPushButtonGadgetClass, form,
532                                         XmNtopAttachment, XmATTACH_WIDGET,
533                                         XmNtopWidget, sep,
534                                         XmNtopOffset, 5,
535                                         XmNbottomAttachment, XmATTACH_FORM,
536                                         XmNbottomOffset, 5,
537                                         XmNleftAttachment, XmATTACH_POSITION,
538                                         XmNleftPosition, 0,
539                                         XmNleftOffset, 5,
540                                         XmNrightAttachment, XmATTACH_POSITION,
541                                         XmNrightPosition, 1,
542                                         XmNbackground, colors[0xff],
543                                         XmNnavigationType, XmTAB_GROUP,
544                                         XmNtraversalOn, TRUE,
545                                         XmNfontList, fontlist1,
546                                         NULL);
547 
548     button_cancel = XtVaCreateManagedWidget(langcode("UNIOP00002"),xmPushButtonGadgetClass, form,
549                                             XmNtopAttachment, XmATTACH_WIDGET,
550                                             XmNtopWidget, sep,
551                                             XmNtopOffset, 5,
552                                             XmNbottomAttachment, XmATTACH_FORM,
553                                             XmNbottomOffset, 5,
554                                             XmNleftAttachment, XmATTACH_POSITION,
555                                             XmNleftPosition, 1,
556                                             XmNrightAttachment, XmATTACH_POSITION,
557                                             XmNrightPosition, 2,
558                                             XmNrightOffset, 5,
559                                             XmNbackground, colors[0xff],
560                                             XmNnavigationType, XmTAB_GROUP,
561                                             XmNtraversalOn, TRUE,
562                                             XmNfontList, fontlist1,
563                                             NULL);
564 
565     XtAddCallback(button_ok, XmNactivateCallback, Geocoder_place_now, geocoder_place_dialog);
566     XtAddCallback(button_cancel, XmNactivateCallback, Geocoder_place_destroy_shell, geocoder_place_dialog);
567 
568     XmTextFieldSetString(geocoder_zip_data,geocoder_zip_name);
569     XmTextFieldSetString(geocoder_state_data,geocoder_state_name);
570     XmTextFieldSetString(geocoder_locality_data,geocoder_locality_name);
571     XmTextFieldSetString(geocoder_address_data,geocoder_address_name);
572     XmTextFieldSetString(geocoder_map_file_data,geocoder_map_filename);
573 
574     pos_dialog(geocoder_place_dialog);
575 
576     delw = XmInternAtom(XtDisplay(geocoder_place_dialog),"WM_DELETE_WINDOW", FALSE);
577     XmAddWMProtocolCallback(geocoder_place_dialog, delw, Geocoder_place_destroy_shell, (XtPointer)geocoder_place_dialog);
578 
579     XtManageChild(form);
580     XtManageChild(pane);
581 
582     resize_dialog(form, geocoder_place_dialog);
583 
584     end_critical_section(&geocoder_place_dialog_lock, "geocoder_gui.c:Geocoder_place" );
585 
586     XtPopup(geocoder_place_dialog,XtGrabNone);
587 
588     XmProcessTraversal(button_ok, XmTRAVERSE_CURRENT);
589 
590   }
591   else
592   {
593     (void)XRaiseWindow(XtDisplay(geocoder_place_dialog), XtWindow(geocoder_place_dialog));
594   }
595 }
596 
597 
598