]> git.mxchange.org Git - flightgear.git/blob - src/ATC/ATCDialog.cxx
1e4617d569ffe046ac7bbe4c51d18767a41f19f4
[flightgear.git] / src / ATC / ATCDialog.cxx
1 // ATCDialog.cxx - Functions and classes to handle the pop-up ATC dialog
2 //
3 // Written by Alexander Kappes and David Luff, started February 2003.
4 //
5 // Copyright (C) 2003  Alexander Kappes and David Luff
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 as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // 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., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 #include <simgear/structure/commands.hxx>
22
23 #include <Main/globals.hxx>
24 #include <GUI/gui.h>
25
26 #include "ATCDialog.hxx"
27 #include "ATC.hxx"
28 #include "ATCmgr.hxx"
29 #include "commlist.hxx"
30 #include "ATCutils.hxx"
31 #include <Airports/simple.hxx>
32
33 FGATCDialog *current_atcdialog;
34
35 // For the command manager - maybe eventually this should go in the built in command list
36 static bool do_ATC_dialog(const SGPropertyNode* arg) {
37         globals->get_ATC_mgr()->doPopupDialog();
38         return(true);
39 }
40
41 static bool do_ATC_freq_search(const SGPropertyNode* arg) {
42         current_atcdialog->FreqDialog();
43         return(true);
44 }
45
46 ATCMenuEntry::ATCMenuEntry() {
47   stationid    = "";
48   stationfr    = 0;
49   transmission = "";
50   menuentry    = "";
51 }
52
53 ATCMenuEntry::~ATCMenuEntry() {
54 }
55
56 static char* t0 = "No communication currently available";
57 //static char* t1 = "Request departure clearance";
58 //static char* t2 = "Report Runway vacated";
59 static char** towerOptions = new char*[2];
60
61 // ----------------------- DCL ------------------------------------------
62 // For the ATC dialog - copied from the Autopilot new heading dialog code!
63 static puDialogBox*             atcDialog;
64 static puFrame*                 atcDialogFrame;
65 static puText*                  atcDialogMessage;
66 //static puInput*                       atcDialogInput;
67 static puOneShot*               atcDialogOkButton;
68 static puOneShot*               atcDialogCancelButton;
69 static puButtonBox*             atcDialogCommunicationOptions;
70 // ----------------------------------------------------------------------
71
72 // ------------------------ AK ------------------------------------------
73 static puDialogBox  *ATCMenuBox = 0;
74 static puFrame      *ATCMenuFrame = 0;
75 static puText       *ATCMenuBoxMessage = 0;
76 static puButtonBox      *ATCOptionsList = 0;
77 // ----------------------------------------------------------------------
78
79 // AK
80 static void AKATCDialogOK(puObject *)
81 {
82         switch(ATCOptionsList->getValue()) {
83         case 0:
84                 //cout << "Option 0 chosen\n";
85                 fgSetBool("/sim/atc/opt0",true);
86                 break;
87         case 1:
88                 //cout << "Option 1 chosen\n";
89                 fgSetBool("/sim/atc/opt1",true);
90                 break;
91         case 2:
92                 //cout << "Option 2 chosen\n";
93                 fgSetBool("/sim/atc/opt2",true);
94                 break;
95         case 3:
96                 //cout << "Option 2 chosen\n";
97                 fgSetBool("/sim/atc/opt3",true);
98                 break;
99         default:
100                 break;
101         }
102         FG_POP_PUI_DIALOG( ATCMenuBox );
103 }
104
105 // AK
106 static void AKATCDialogCancel(puObject *)
107 {
108     FG_POP_PUI_DIALOG( ATCMenuBox );
109 }
110
111 // DCL
112 static void ATCDialogCancel(puObject *)
113 {
114     //ATCDialogInput->rejectInput();
115     FG_POP_PUI_DIALOG( atcDialog );
116 }
117
118 // DCL
119 static void ATCDialogOK (puObject *me)
120 {
121         // Note that currently the dialog is hardwired to comm1 only here.
122         switch(globals->get_ATC_mgr()->GetComm1ATCType()) {
123         case INVALID:
124                 break;
125         case ATIS:
126                 break;
127         case TOWER: {
128                 /*
129                 FGTower* twr = (FGTower*)globals->get_ATC_mgr()->GetComm1ATCPointer();
130                 switch(atcDialogCommunicationOptions->getValue()) {
131                 case 0:
132                         //cout << "Option 0 chosen\n";
133                         twr->RequestLandingClearance("charlie foxtrot sierra");
134                         break;
135                 case 1:
136                         //cout << "Option 1 chosen\n";
137                         twr->RequestDepartureClearance("charlie foxtrot sierra");
138                         break;
139                 case 2:
140                         //cout << "Option 2 chosen\n";
141                         twr->ReportRunwayVacated("charlie foxtrot sierra");
142                         break;
143                 default:
144                         break;
145                 }
146                 */
147                 break;
148         }
149         case GROUND:
150                 break;
151         case APPROACH:
152                 break;
153         default:
154                 break;
155         }
156
157     ATCDialogCancel(me);
158     //if(error) mkDialog(s.c_str());
159 }
160
161 // DCL
162 static void ATCDialog(puObject *cb)
163 {
164     //ApHeadingDialogInput   ->    setValue ( heading );
165     //ApHeadingDialogInput    -> acceptInput();
166     FG_PUSH_PUI_DIALOG(atcDialog);
167 }
168
169 // DCL
170 void ATCDialogInit()
171 {
172         char defaultATCLabel[] = "Enter desired option to communicate with ATC:";
173         char *s;
174
175         // Option lists hardwired per ATC type  
176         towerOptions[0] = new char[strlen(t0)+1];
177         strcpy(towerOptions[0], t0);
178         //towerOptions[1] = new char[strlen(t1)+1];
179         //strcpy(towerOptions[1], t1);
180         //towerOptions[2] = new char[strlen(t2)+1];
181         //strcpy(towerOptions[2], t2);
182         towerOptions[1] = NULL;
183         
184         atcDialog = new puDialogBox (150, 50);
185         {
186                 atcDialogFrame   = new puFrame (0, 0, 500, 250);
187                 
188                 atcDialogMessage = new puText          (250, 220);
189                 atcDialogMessage    -> setDefaultValue (defaultATCLabel);
190                 atcDialogMessage    -> getDefaultValue (&s);
191                 atcDialogMessage    -> setLabel        (s);
192                 atcDialogMessage    -> setLabelPlace   (PUPLACE_TOP_CENTERED);
193
194                 atcDialogCommunicationOptions = new puButtonBox (50, 50, 450, 210, NULL, true);
195                 
196                 atcDialogOkButton     =  new puOneShot         (50, 10, 110, 50);
197                 atcDialogOkButton     ->     setLegend         (gui_msg_OK);
198                 atcDialogOkButton     ->     makeReturnDefault (TRUE);
199                 atcDialogOkButton     ->     setCallback       (ATCDialogOK);
200                 
201                 atcDialogCancelButton =  new puOneShot         (140, 10, 210, 50);
202                 atcDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
203                 atcDialogCancelButton ->     setCallback       (ATCDialogCancel);
204                 
205         }
206         FG_FINALIZE_PUI_DIALOG(atcDialog);
207         
208         // Add ATC-dialog to the command list
209         globals->get_commands()->addCommand("ATC-dialog", do_ATC_dialog);
210 }
211
212 ///////////////////////////////////////////////////////////////////////
213 //
214 // ATCDoDialog is in a state of flux at the moment
215 // Stations other than approach are handled by DCL's simple code
216 // Approach is handled by AK's fancy dynamic-list code
217 // Hopefully all interactive stations should go to AK's code eventually
218 //
219 ///////////////////////////////////////////////////////////////////////
220 void ATCDoDialog(atc_type type) {
221         switch(type) {
222         case INVALID:
223                 atcDialogCommunicationOptions->newList(NULL);
224                 atcDialogMessage->setLabel("Not tuned in to any ATC service.");
225                 break;
226         case ATIS:
227                 atcDialogCommunicationOptions->newList(NULL);
228                 atcDialogMessage->setLabel("Tuned in to ATIS: no communication possible.");
229                 break;
230         case TOWER: 
231                 atcDialogCommunicationOptions->newList(towerOptions);
232                 atcDialogMessage->setLabel("Tuned in to Tower - select communication to transmit:");
233                 break;
234         case GROUND:
235                 atcDialogCommunicationOptions->newList(NULL);
236                 atcDialogMessage->setLabel("Tuned in to Ground - select communication to transmit:");
237                 break;
238         case APPROACH:
239                 current_atcdialog->DoDialog();
240                 break;
241         default:
242                 atcDialogCommunicationOptions->newList(NULL);
243                 atcDialogMessage->setLabel("Tuned in to unknown ATC service - enter transmission:");
244                 break;
245         }
246
247         // Third - display the dialog without pausing sim.
248         if(type != APPROACH) {  
249                 ATCDialog(NULL);
250         }
251 }
252
253 void FGATCDialog::Init() {
254         // Add ATC-freq-search to the command list
255         globals->get_commands()->addCommand("ATC-freq-search", do_ATC_freq_search);
256 }
257
258 // AK
259 // Add an entry
260 void FGATCDialog::add_entry(string station, string transmission, string menutext ) {
261   
262   ATCMenuEntry a;
263
264   a.stationid = station;
265   a.transmission = transmission;
266   a.menuentry = menutext;
267
268   atcmentrylist_station[station.c_str()].push_back(a);
269
270 }
271
272 // AK
273 // query the database whether the transmission is already registered; 
274 bool FGATCDialog::trans_reg( const string &station, const string &trans ) {
275
276   atcmentry_list_type     atcmlist = atcmentrylist_station[station];
277   atcmentry_list_iterator current  = atcmlist.begin();
278   atcmentry_list_iterator last     = atcmlist.end();
279   
280   for ( ; current != last ; ++current ) {
281     if ( current->transmission == trans ) return true;
282   }
283   return false;
284 }
285
286 // AK
287 // ===================================================
288 // ===  Update ATC menue and look for keys pressed ===
289 // ===================================================
290 void FGATCDialog::DoDialog() {
291         
292         static string mentry[10];
293         static string mtrans[10];
294         char   buf[10];
295         TransPar TPar;
296         FGATC* atcptr = globals->get_ATC_mgr()->GetComm1ATCPointer();   // Hardwired to comm1 at the moment
297         
298         if(atcptr != NULL) {
299                 
300                 atcmentry_list_type     atcmlist = atcmentrylist_station[atcptr->get_ident()];
301                 //atcmentry_list_type     atcmlist = atcmentrylist_station["EGNX"];
302                 atcmentry_list_iterator current  = atcmlist.begin();
303                 atcmentry_list_iterator last     = atcmlist.end();
304                 
305                 // Set all opt flags to false before displaying box
306                 fgSetBool("/sim/atc/opt0",false);
307                 fgSetBool("/sim/atc/opt1",false);
308                 fgSetBool("/sim/atc/opt2",false);
309                 fgSetBool("/sim/atc/opt3",false);
310                 fgSetBool("/sim/atc/opt4",false);
311                 fgSetBool("/sim/atc/opt5",false);
312                 fgSetBool("/sim/atc/opt6",false);
313                 fgSetBool("/sim/atc/opt7",false);
314                 fgSetBool("/sim/atc/opt8",false);
315                 fgSetBool("/sim/atc/opt9",false);
316                 
317                 //int yc = 10;
318                 int yc = 70;
319                 int xsize = 600;
320                 
321                 if ( atcmlist.size() != 0 ){ 
322                         int k=atcmlist.size();
323                         //int k = 3;
324                         //cout << "k = " << k << endl;
325                         int y = (fgGetInt("/sim/startup/ysize") - 200 - 20 - k*20);
326                         ATCMenuBox = new puDialogBox (100, y);
327                         ATCMenuFrame      =  new puFrame (0,0,xsize,yc+40);
328                         // loop over all entries in atcmentrylist
329                         ATCOptionsList = new puButtonBox (50, 50, 450, 50+(k*25), NULL, true);
330                         char** optList = new char*[k+1];
331                         int kk = 0;
332                         for ( ; current != last ; ++current ) {
333                                 string dum;
334                                 sprintf( buf, "%i", kk+1 );
335                                 buf[1] = '\0';
336                                 dum = (string)(buf);
337                                 mentry[kk] = dum + ". " + current->menuentry;
338                                 optList[kk] = new char[strlen(mentry[kk].c_str()) + 1];
339                                 strcpy(optList[kk], mentry[kk].c_str());
340                                 //cout << "optList[" << kk << "] = " << optList[kk] << endl; 
341                                 mtrans[kk] =              current->transmission;
342                                 //ATCMenuBoxMessage =  new puText (10, yc);
343                                 //ATCMenuBoxMessage ->     setLabel( mentry[kk].c_str() );
344                                 yc += 20;
345                                 ++kk;
346                         } 
347                         yc += 2*20;
348                         optList[k] = NULL;
349                         ATCOptionsList->newList(optList);
350                 } else {
351                         int y = (fgGetInt("/sim/startup/ysize") - 100 - 20 );
352                         ATCMenuBox = new puDialogBox (10, y);
353                         ATCMenuFrame      =  new puFrame (0,0,xsize,yc+40);
354                         ATCMenuBoxMessage =  new puText (10, yc-10);
355                         ATCMenuBoxMessage ->     setLabel( "No transmission available" );
356                 }
357                 
358                 ATCMenuBoxMessage =  new puText (10, yc+10);
359                 ATCMenuBoxMessage ->     setLabel( "ATC Menu" );
360                 atcDialogOkButton     =  new puOneShot         ((xsize/2)-85, 10, (xsize/2)-25, 50);
361                 atcDialogOkButton     ->     setLegend         (gui_msg_OK);
362                 atcDialogOkButton     ->     makeReturnDefault (TRUE);
363                 atcDialogOkButton     ->     setCallback       (AKATCDialogOK);
364                 
365                 atcDialogCancelButton =  new puOneShot         ((xsize/2)+25, 10, (xsize/2)+85, 50);
366                 atcDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
367                 atcDialogCancelButton ->     setCallback       (AKATCDialogCancel);
368                 FG_FINALIZE_PUI_DIALOG( ATCMenuBox );
369                 FG_PUSH_PUI_DIALOG( ATCMenuBox );
370                 
371                 
372                 /*      
373                 if ( atckey != -1 && TransDisplayed && mtrans[atckey-1].c_str() != "" ) {
374                         cout << mtrans[atckey-1].c_str() << endl;
375                         TPar = current_transmissionlist->extract_transpar( mtrans[atckey-1].c_str() );
376                         current_atcmentrylist->reset = true;
377                         current_transparlist->add_entry( TPar );
378                         
379                         //    transpar_list_type test = current_transparlist;
380                         // transpar_list_iterator current = test.begin();
381                         //for ( ; current != test.end(); ++current ) {
382                                 // current->tpar.intention;
383                         //}
384                 }
385                 
386                 if ( current_atcmentrylist->freq != (int)(comm1_freq*100.0 + 0.5) ) {
387                         current_atcmentrylist->reset = true;
388                 }
389                 
390                 // reset (delete) ATCmenue list if reset is true
391                 if ( current_atcmentrylist->reset == true ) {
392                         delete ( current_atcmentrylist );
393                         current_atcmentrylist = new FGatcmentryList;
394                         current_atcmentrylist->init( (int)(comm1_freq*100.0 + 0.5) );
395                         if ( TransDisplayed ) {
396                                 FG_POP_PUI_DIALOG( ATCMenuBox ); 
397                                 TransDisplayed = false;
398                         }
399                 }
400                 */      
401         }
402 }
403
404 //////////////////////////////////////////////////////
405 //
406 //  STUFF FOR THE FREQUENCY SEARCH DIALOG
407 //
408 //////////////////////////////////////////////////////
409
410 static puDialogBox*             atcFreqDialog;
411 static puFrame*                 atcFreqDialogFrame;
412 static puText*                  atcFreqDialogMessage;
413 static puInput*                 atcFreqDialogInput;
414 static puOneShot*               atcFreqDialogOkButton;
415 static puOneShot*               atcFreqDialogCancelButton;
416 //static puButtonBox*           atcFreqDialogCommunicationOptions;
417
418 static puText* atcFreqDisplayText[20];
419         
420 static void FreqDialogCancel(puObject*) {
421         FG_POP_PUI_DIALOG(atcFreqDialog);
422         delete atcFreqDialog;
423 }
424
425 static void FreqDialogOK(puObject*) {
426         string tmp = atcFreqDialogInput->getStringValue();
427         FG_POP_PUI_DIALOG(atcFreqDialog);
428         delete atcFreqDialog;
429         current_atcdialog->FreqDisplay(tmp);
430 }
431
432 static void FreqDisplayOK(puObject*) {
433         FG_POP_PUI_DIALOG(atcFreqDialog);
434         delete atcFreqDialog;
435 }
436
437 void FGATCDialog::FreqDialog() {
438
439         // Find the ATC stations within a reasonable range (about 40 miles?)
440         //comm_list_type atc_stations;
441         //comm_list_iterator atc_stat_itr;
442         
443         //double lon = fgGetDouble("/position/longitude-deg");
444         //double lat = fgGetDouble("/position/latitude-deg");
445         //double elev = fgGetDouble("/position/altitude-ft");
446         
447         /*
448         // search stations in range
449         int num_stat = current_commlist->FindByPos(lon, lat, elev, 40.0, &atc_stations);
450         if (num_stat != 0) {
451         } else {
452                 // Make up a message saying no things in range
453         }
454         */
455         
456         //char defaultATCLabel[] = "Enter desired option to communicate with ATC:";
457         char *s;
458         
459         int hsize = 150;
460         atcFreqDialog = new puDialogBox (150, 50);
461         {
462                 atcFreqDialogFrame   = new puFrame (0, 0, 300, hsize);
463                 
464                 atcFreqDialogMessage = new puText          (40, (hsize - 30));
465                 atcFreqDialogMessage    -> setDefaultValue ("Enter airport identifier:");
466                 atcFreqDialogMessage    -> getDefaultValue (&s);
467                 atcFreqDialogMessage    -> setLabel        (s);
468                 //atcFreqDialogMessage    -> setLabelPlace   (PUPLACE_TOP_CENTERED);
469                 //atcFreqDialogMessage    -> setLabelPlace   (0);
470
471                 atcFreqDialogInput = new puInput (50, (hsize - 75), 150, (hsize - 45));
472                 atcFreqDialogInput->acceptInput();
473                 
474                 atcFreqDialogOkButton     =  new puOneShot         (50, 10, 110, 50);
475                 atcFreqDialogOkButton     ->     setLegend         (gui_msg_OK);
476                 atcFreqDialogOkButton     ->     makeReturnDefault (TRUE);
477                 atcFreqDialogOkButton     ->     setCallback       (FreqDialogOK);
478                 
479                 atcFreqDialogCancelButton =  new puOneShot         (140, 10, 210, 50);
480                 atcFreqDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
481                 atcFreqDialogCancelButton ->     setCallback       (FreqDialogCancel);
482                 
483         }
484         FG_FINALIZE_PUI_DIALOG(atcFreqDialog);
485         
486         FG_PUSH_PUI_DIALOG(atcFreqDialog);
487         
488 }
489
490 static void atcUppercase(string &s)
491 {
492         for(unsigned int i=0; i<s.size(); ++i) {
493                 s[i] = toupper(s[i]);
494         }
495 }
496
497 void FGATCDialog::FreqDisplay(string ident) {
498
499         // Find the ATC stations within a reasonable range (about 40 miles?)
500         //comm_list_type atc_stations;
501         //comm_list_iterator atc_stat_itr;
502         
503         //double lon = fgGetDouble("/position/longitude-deg");
504         //double lat = fgGetDouble("/position/latitude-deg");
505         //double elev = fgGetDouble("/position/altitude-ft");
506         
507         /*
508         // search stations in range
509         int num_stat = current_commlist->FindByPos(lon, lat, elev, 40.0, &atc_stations);
510         if (num_stat != 0) {
511         } else {
512                 // Make up a message saying no things in range
513         }
514         */
515         
516         atcUppercase(ident);
517         
518         //char defaultATCLabel[] = "Enter desired option to communicate with ATC:";
519         string label = "Frequencies for airport ";
520         label += ident;
521         label += ":";
522         char *s;
523         
524         int n = 0;      // Number of ATC frequencies at this airport
525         string freqs[20];
526         char buf[8];
527
528     FGAirport a;
529     if ( dclFindAirportID( ident, &a ) ) {
530                 comm_list_type stations;
531                 int found = current_commlist->FindByPos(a.longitude, a.latitude, a.elevation, 20.0, &stations);
532                 if(found) {
533                         comm_list_iterator itr = stations.begin();
534                         while(itr != stations.end()) {
535                                 if((*itr).ident == ident) {
536                                         switch((*itr).type) {
537                                         case ATIS:
538                                                 freqs[n] = "ATIS     -     ";
539                                                 sprintf(buf, "%.2f", ((*itr).freq / 100.0));    // Convert from KHz to MHz
540                                                 // Hack alert!
541                                                 if(buf[5] == '3') buf[5] = '2';
542                                                 if(buf[5] == '8') buf[5] = '7';
543                                                 freqs[n] += buf;
544                                                 n++;
545                                                 //cout << "ATIS\n";
546                                                 break;
547                                         case TOWER:
548                                                 freqs[n] = "TOWER    -     ";
549                                                 sprintf(buf, "%.2f", ((*itr).freq / 100.0));    // Convert from KHz to MHz
550                                                 // Hack alert!
551                                                 if(buf[5] == '3') buf[5] = '2';
552                                                 if(buf[5] == '8') buf[5] = '7';
553                                                 freqs[n] += buf;
554                                                 n++;
555                                                 //cout << "TOWER\n";
556                                                 break;
557                                         case GROUND:
558                                                 freqs[n] = "GROUND   -     ";
559                                                 sprintf(buf, "%.2f", ((*itr).freq / 100.0));    // Convert from KHz to MHz
560                                                 // Hack alert!
561                                                 if(buf[5] == '3') buf[5] = '2';
562                                                 if(buf[5] == '8') buf[5] = '7';
563                                                 freqs[n] += buf;
564                                                 n++;
565                                                 //cout << "GROUND\n";
566                                                 break;
567                                         case APPROACH:
568                                                 freqs[n] = "APPROACH  -     ";
569                                                 sprintf(buf, "%.2f", ((*itr).freq / 100.0));    // Convert from KHz to MHz
570                                                 // Hack alert!
571                                                 if(buf[5] == '3') buf[5] = '2';
572                                                 if(buf[5] == '8') buf[5] = '7';
573                                                 freqs[n] += buf;
574                                                 n++;
575                                                 //cout << "APPROACH\n";
576                                                 break;
577                                         case DEPARTURE:
578                                                 freqs[n] = "DEPARTURE  -     ";
579                                                 sprintf(buf, "%.2f", ((*itr).freq / 100.0));    // Convert from KHz to MHz
580                                                 // Hack alert!
581                                                 if(buf[5] == '3') buf[5] = '2';
582                                                 if(buf[5] == '8') buf[5] = '7';
583                                                 freqs[n] += buf;
584                                                 n++;
585                                                 //cout << "DEPARTURE\n";
586                                                 break;
587                                         case ENROUTE:   // not really associated with an airport possibly.
588                                                 freqs[n] = "ENROUTE  -     ";
589                                                 sprintf(buf, "%.2f", ((*itr).freq / 100.0));    // Convert from KHz to MHz
590                                                 // Hack alert!
591                                                 if(buf[5] == '3') buf[5] = '2';
592                                                 if(buf[5] == '8') buf[5] = '7';
593                                                 freqs[n] += buf;
594                                                 n++;
595                                                 //cout << "ENROUTE\n";
596                                                 break;
597                                         case INVALID:   // need to include this to stop the compiler complaining.
598                                                 break;
599                                         }
600                                 }
601                                 ++itr;
602                         }
603                 }
604     } else {
605                 label = "Airport ";
606                 label += ident;
607                 label += " not found in database.";
608                 n = -1;
609         }
610         
611         if(n == 0) {
612                 label = "No frequencies found for airport ";
613                 label += ident;
614         }
615
616         int hsize = (n < 0 ? 100 : 105 + (n * 30));
617         atcFreqDialog = new puDialogBox (250, 50);
618         {
619                 atcFreqDialogFrame   = new puFrame (0, 0, 400, hsize);
620                 
621                 atcFreqDialogMessage = new puText          (40, (hsize - 30));
622                 atcFreqDialogMessage    -> setDefaultValue (label.c_str());
623                 atcFreqDialogMessage    -> getDefaultValue (&s);
624                 atcFreqDialogMessage    -> setLabel        (s);
625                 
626                 for(int i=0; i<n; ++i) {
627                         atcFreqDisplayText[i] = new puText(40, hsize - 65 - (30 * i));
628                         atcFreqDisplayText[i]->setDefaultValue(freqs[i].c_str());
629                         atcFreqDisplayText[i]-> getDefaultValue (&s);
630                         atcFreqDisplayText[i]-> setLabel        (s);
631                 }
632                 
633                 atcFreqDialogOkButton     =  new puOneShot         (50, 10, 110, 50);
634                 atcFreqDialogOkButton     ->     setLegend         (gui_msg_OK);
635                 atcFreqDialogOkButton     ->     makeReturnDefault (TRUE);
636                 atcFreqDialogOkButton     ->     setCallback       (FreqDisplayOK);
637                 
638                 atcFreqDialogCancelButton =  new puOneShot         (140, 10, 210, 50);
639                 atcFreqDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
640                 atcFreqDialogCancelButton ->     setCallback       (FreqDialogCancel);
641                 
642         }
643         FG_FINALIZE_PUI_DIALOG(atcFreqDialog);
644         
645         FG_PUSH_PUI_DIALOG(atcFreqDialog);
646         
647 }
648