GPS4Palm

Source Code Documentation


WayptEditForm.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: WayptEditForm_8c-source.html,v $
00004  *
00005  * GPS4Palm Waypoint Edit Form
00006  *
00007  * This program is Copyright (C) 03/2003 Matthias Prinke
00008  * <matthias.prinke@surfeu.de> and covered by GNU's GPL.
00009  * In particular, this program is free software and comes WITHOUT
00010  * ANY WARRANTY.
00011  *
00012  * $Author: mp $
00013  *
00014  * $Date: 2007-10-08 20:40:35 $
00015  *
00016  * $Revision: 1.7.2.1 $
00017  *
00018  * $Log: WayptEditForm_8c-source.html,v $
00018  * Revision 1.7.2.1  2007-10-08 20:40:35  mp
00018  * updated for gps4palm V0.9.5 beta
00018  *
00019  * Revision 1.19  2005-03-25 13:33:55  mp
00020  * increased field_str buffer length
00021  *
00022  * Revision 1.18  2005/01/30 21:00:44  mp
00023  * corrected comment field truncation
00024  *
00025  * Revision 1.17  2005/01/29 10:22:26  mp
00026  * fixed comment
00027  *
00028  * Revision 1.16  2005/01/29 10:12:09  mp
00029  * added waypoint import from GeoDB
00030  *
00031  * Revision 1.15  2004/12/10 19:57:33  mp
00032  * replaced DmGet1Resource by DmGetResource and WayptEditSymScrl by
00033  * WayptEditPrevSymButton and WayptEditNextSymButton,
00034  * implemented clipboard, SysKeyboardDialog, and SysGraffitiReferenceDialog
00035  *
00036  * Revision 1.14  2004/12/09 17:26:19  mp
00037  * replaced default waypoint identifier/comment strings by string resources
00038  *
00039  * Revision 1.13  2004/11/27 10:16:57  mp
00040  * replaced ErrFatalDisplay() by Die() for memory allocation failure
00041  *
00042  * Revision 1.12  2004/11/24 21:28:14  mp
00043  * moved static function declarations from header to implementation file
00044  *
00045  * Revision 1.11  2004/11/23 17:46:31  mp
00046  * removed unused variable
00047  *
00048  * Revision 1.10  2004/11/16 20:44:18  mp
00049  * added check after creating new record, modified PackWaypoint() call
00050  *
00051  * Revision 1.9  2004/04/17 12:47:13  mp
00052  * modified waypoint display mode encoding according to Garmin I/O Spec
00053  *
00054  * Revision 1.8  2004/03/31 15:47:59  mp
00055  * added default waypoint display on frmOpenEvent
00056  *
00057  * Revision 1.7  2004/03/30 19:32:40  mp
00058  * added Waypoint Symbol selection and display
00059  *
00060  * Revision 1.6  2004/03/15 17:20:21  mp
00061  * added Waypoint Copy function
00062  *
00063  * Revision 1.5  2004/03/11 18:54:31  mp
00064  * fixed handling of sign (for DM/DMS and special cases)
00065  *
00066  * Revision 1.4  2004/03/10 17:35:57  mp
00067  * Modifications due to changes in Data.h, fixed UTM input.
00068  *
00069  * Revision 1.3  2004/03/09 19:12:35  mp
00070  * improved input field handling
00071  *
00072  * Revision 1.2  2004/03/08 20:26:44  mp
00073  * Added Proxmity Distance field, fixed Waypoint Identifier input, fixed
00074  * added handling of active field when WayptEditOkButton is pressed.
00075  *
00076  * Revision 1.1  2004/03/07 14:25:22  mp
00077  * initial version
00078  *
00079  *
00080  ****************************************************************************/
00081 #include <PalmOS.h>
00082 #include "ResourceDefines.h"
00083 #include <Unix/sys_types.h>
00084 #include "stringil.h"
00085 #include "WayptEditForm.h"
00086 #include "GPS.h"                /*  ReadFromGPS() */
00087 #include "Serial.h"
00088 #include "Utils.h"
00089 #include "Data.h"
00090 #include "utm.h"
00091 #include "geo.h"
00092 #include "geodb.h"
00093 #include "fp.h"
00094 #include "common.h"
00095 
00096 #define WPT_X   90
00097 #define WPT_Y   30
00098 
00099 /* Global Variables */
00100 
00101 /** store the location data with importGeoDBLocation() */
00102 Location  location;
00103 
00104 extern PrefsType        gPrefs;         /* Preferences data structure */
00105 extern DmOpenRef        gWaypointDB;    /* Waypoint Data Base reference */
00106 extern GPSType          gGPSData;       /* GPS Data */
00107 extern ActWayptType     gSelWaypoint;   /* Selected waypoint */
00108 
00109 
00110 /* Static Functions */
00111 static void WayptEditFormInit(void)                     WAYPTEDIT_SECTION;
00112 static Boolean scan_position(UInt16 fieldID,
00113   double *lat, double *lon)                             WAYPTEDIT_SECTION;
00114 static Boolean scan_zone(UInt16 *utm_zone,
00115   Char *utm_belt)                                       WAYPTEDIT_SECTION;
00116 static void add_waypoint(double lat, double lon,
00117   UInt16 smbl)                                          WAYPTEDIT_SECTION;
00118 static Boolean insert_position(double lat, double lon,
00119   double *eastP, double *northP)                        WAYPTEDIT_SECTION;
00120 static Boolean field_active(UInt16 fieldID)             WAYPTEDIT_SECTION;
00121 static void select_symbol(UInt16 *sym, Int16 dir)       WAYPTEDIT_SECTION;
00122 static Boolean geodb_str_to_deg(Location *loc, 
00123   double *lat, double *lon)                             WAYPTEDIT_SECTION;
00124 
00125 /*****************************************************************************
00126  * FUNCTION:    WayptEditFormInit
00127  *
00128  * DESCRIPTION: Waypoint Edit Form Init Function (not used)
00129  *
00130  ****************************************************************************/
00131 static 
00132 void WayptEditFormInit(void)
00133 {  
00134 
00135 }
00136 
00137 
00138 /*****************************************************************************
00139  * FUNCTION:    field_active
00140  *
00141  * DESCRIPTION: Determines if the specified field is active, i.e. has the
00142  *              input focus.
00143  *
00144  * PARAMETERS:  fieldID         -- Field ID
00145  *
00146  * RETURNED:    Status flag: specified field has focus
00147  ****************************************************************************/
00148 static
00149 Boolean field_active(UInt16 fieldID)
00150 {
00151   FormPtr               frmP = FrmGetActiveForm();
00152   FieldAttrType         fld_attr;
00153   
00154   FldGetAttributes(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, fieldID)),
00155     &fld_attr);
00156   
00157   return (fld_attr.hasFocus == 1);
00158 }
00159 
00160 
00161 /*****************************************************************************
00162  * FUNCTION:    scan_position
00163  *
00164  * DESCRIPTION: Scan position fields to latitude/longitude
00165  *              depending on selevted position units.
00166  *
00167  *              Note: The code assumes to run on a device with
00168  *                    latin character set.
00169  *              Note: The degree sign '°' is named chrDegreeSign in
00170  *                    System/CharLatin.h (but we are sloppy...)
00171  *
00172  * GLOBALS:     gPrefs          -- Application Preferences
00173  *
00174  * PARAMETERS:  fieldID         -- ID of selected field
00175  *              lat             -- pointer to latitude
00176  *              lon             -- pointer to longitude
00177  *
00178  * RETURNED:    Status flag: valid entry
00179  ****************************************************************************/
00180 static
00181 Boolean scan_position(UInt16 fieldID, double *lat, double *lon)
00182 {
00183   FormPtr       frmP;           /* form ptr */
00184   Char          *strP;          /* string ptr */
00185   Char          *trailP;        /* trailing string ptr */
00186   double        tmp;            /* temp. double */
00187   short         frac;           /* number of fractional digits */
00188   Int16         sign;           /* sign */
00189   
00190   frmP = FrmGetActiveForm();
00191   strP = FldGetTextPtr(FrmGetObjectPtr(frmP,
00192             FrmGetObjectIndex(frmP, fieldID)));
00193   
00194   if (strP[0] == '-') {
00195     sign = -1;
00196     strP++;
00197   } else {
00198     sign = 1;
00199   }
00200   
00201   /* first value is either angle in degrees or cartesian coordinate in meters */
00202   tmp = cvt_atof(strP, &trailP, &frac);
00203 
00204   /* handle degrees part or esting/northing */
00205   switch (gPrefs.units.pos_unit) {
00206     case POS_D:
00207       /*
00208        * Field's contents considered as a single floating point number, 
00209        * which may or may not end with a degree sign (but nothing else).
00210        */
00211       if (*trailP == '\0' || *trailP == '°') {
00212         /* valid entry */
00213         if (fieldID == LatitudeField) {
00214           /* Latitude */
00215           if ((tmp > 90.0) || (tmp < -90.0)) {
00216             /* range error */
00217             return false;
00218           }
00219           /* o.k., update position */
00220           *lat = tmp * sign;
00221 
00222         } else {
00223           /* Longitude */
00224           if ((tmp > 180.0) || (tmp < -180.0)) {
00225             /* range error */
00226             return false;
00227           }
00228           /* o.k., update position */
00229           *lon = tmp * sign;
00230         
00231         }
00232         return true;
00233         
00234       } else {
00235         /* invalid entry */
00236         return false;
00237       }
00238       break;
00239       
00240     case POS_DM:
00241     case POS_DMS:
00242       /*
00243        * Field's contents must start with an integer number, 
00244        * which must end with a degree sign.
00245        */
00246       if (*trailP != '°' || frac > 0) {
00247         /* invalid entry */
00248         return false;
00249       } else {
00250         /* valid entry */
00251         if (fieldID == LatitudeField) {
00252           /* Latitude */
00253           if ((tmp > 90.0) || (tmp < -90.0)) {
00254             /* range error */
00255             return false;
00256           }
00257           /* o.k., update position */
00258           *lat = tmp;
00259 
00260         } else {
00261           /* Longitude */
00262           if ((tmp > 180.0) || (tmp < -180.0)) {
00263             /* range error */
00264             return false;
00265           }
00266           /* o.k., update position */
00267           *lon = tmp;
00268         }
00269       }
00270       break;
00271       
00272     case POS_UTM:
00273       /*
00274        * Field's contents must consist of a single floating point number only 
00275        */
00276       if (*trailP != '\0') {
00277         /* invalid entry */
00278         return false;
00279       }
00280       if (fieldID == LatitudeField) {
00281         if ((tmp >= 100000.0) && (tmp <= 900000.0)) {
00282           *lat = tmp;
00283           return true;
00284         } else {
00285           return false;
00286         }
00287       } else {
00288         if ((tmp >= 0.0) && (tmp <= 10000000.0)) {
00289           *lon = tmp;
00290           return true;
00291         } else {
00292           return false;
00293         }
00294       }
00295       break;
00296   } /* switch (gPrefs.units.pos_unit) */
00297 
00298   /* skip degree sign */
00299   strP = trailP + 1;
00300   
00301   /* convert string to float */
00302   tmp = cvt_atof(strP, &trailP, &frac);  
00303 
00304   /*
00305    * Handle minutes part
00306    *   The following input is valid:
00307    *   POS_DM:  <mm.m>'
00308    *   POS_DMS: <mm>'
00309    */
00310   if (*trailP != '\'') {
00311     /* invalid entry */
00312     return false;
00313   }
00314 
00315   if (gPrefs.units.pos_unit == POS_DMS && frac > 0) {
00316     /* invalid entry */
00317     return false;
00318   }
00319   if ((tmp >= 60.0) || (tmp < 0.0)) {
00320     /* range error */
00321     return false;
00322   }
00323 
00324   if (fieldID == LatitudeField) {
00325     /* o.k., update Latitude  */
00326     *lat += tmp/60.0;
00327   } else {
00328     /* o.k., update Longitude  */
00329     *lon += tmp/60.0;
00330   }
00331     
00332   if (gPrefs.units.pos_unit == POS_DMS) {
00333 
00334     /* skip minutes sign */
00335     strP = trailP + 1;
00336 
00337     /* convert string to float */
00338     tmp = cvt_atof(strP, &trailP, NULL);  
00339 
00340     /*
00341      * Handle seconds part
00342      *   The following input is valid:
00343      *   <ss.s>" or <ss>"
00344      */
00345     if (*trailP != '\"') {
00346       /* invalid entry */
00347       return false;
00348     }
00349     if ((tmp >= 60.0) || (tmp < 0.0)) {
00350       /* range error */
00351       return false;
00352     }
00353     if (fieldID == LatitudeField) {
00354       /* o.k., update Latitude  */
00355       *lat += tmp/3600.0;
00356     } else {
00357       /* o.k., update Longitude  */
00358       *lon += tmp/3600.0;
00359     }
00360   } /* if (gPrefs.units.pos_unit == POS_DMS) */
00361 
00362   if (fieldID == LatitudeField) {
00363     /* update sign of Latitude  */
00364     *lat = *lat * sign;
00365   } else {
00366     /* update sign of Longitude  */
00367     *lon = *lon * sign;
00368   }
00369 
00370   return true;     
00371 }
00372 
00373 
00374 /*****************************************************************************
00375  * FUNCTION:    scan_zone
00376  *
00377  * DESCRIPTION: Scan zone field to UTM zone and belt,
00378  *              update latitude and longitude
00379  *
00380  * PARAMETERS:  eventP          -- pointer to event structure
00381  *
00382  * RETURNED:    Status flag: valid entry
00383  ****************************************************************************/
00384 static
00385 Boolean scan_zone(UInt16 *utm_zone, Char *utm_belt)
00386 {
00387   FormPtr       frmP;
00388   Char          *strP;
00389   UInt16        zone;
00390   Char          belt;
00391   
00392   frmP = FrmGetActiveForm();
00393   strP = FldGetTextPtr(FrmGetObjectPtr(frmP,
00394             FrmGetObjectIndex(frmP, ZoneField)));
00395 
00396   if ((*strP >= '0') && (*strP <= '9')) {
00397     zone = *strP - '0';
00398     strP++;
00399   } else {
00400     return false;
00401   }
00402   
00403   if ((*strP >= '0') && (*strP <= '9')) {
00404     zone = zone * 10 + (*strP - '0');
00405     strP++;
00406   }
00407   
00408   if ((zone < 1) || (zone > 60)) {
00409     return false;
00410   }
00411   
00412   belt = toupper(*strP);
00413   
00414   if ((belt >= 'C') && (belt <= 'X') &&
00415       (belt != 'I') && (belt != 'O')) {
00416     *utm_zone = zone;
00417     *utm_belt = belt;
00418     return true;
00419   } else {
00420     return false;
00421   }
00422 }
00423 
00424 
00425 /*****************************************************************************
00426  * FUNCTION:    add_waypoint
00427  *
00428  * DESCRIPTION: Add new waypoint to database
00429  *
00430  * GLOBALS:     gWaypointDB     -- Waypoint Database Reference
00431  *
00432  * PARAMETERS:  lat             -- Latitude
00433  *              lon             -- Longitude
00434  *
00435  * RETURNED:    %
00436  ****************************************************************************/
00437 static
00438 void add_waypoint(double lat, double lon, UInt16 smbl)
00439 {
00440   FormPtr       frmP;
00441   ListPtr       lstP;
00442   waypoint_t    waypoint;
00443   UInt16        len;
00444   Char          *strP;
00445   UInt16        index;
00446   MemHandle     h;
00447   float         proxmity;
00448   
00449   frmP = FrmGetActiveForm();
00450   
00451   /* Copy Identifier */
00452   strP = FldGetTextPtr(FrmGetObjectPtr(frmP,
00453     FrmGetObjectIndex(frmP, IdentField)));
00454   len = StrLen(strP);
00455   MemSet((Char *)waypoint.ident, 6, 0);
00456   StrNCopy(waypoint.ident, strP, (len > 6) ? 6 : len);
00457   
00458   /* Copy Latitude */
00459   waypoint.posn.lat = deg2semi(lat);
00460   
00461   /* Copy Longitude */
00462   waypoint.posn.lon = deg2semi(lon);
00463    
00464   /* Copy Proxmity Distance (no sanity check done!) */
00465   strP = FldGetTextPtr(FrmGetObjectPtr(frmP,
00466     FrmGetObjectIndex(frmP, ProxField)));
00467   proxmity = cvt_atof(strP, NULL, NULL);
00468   proxmity = (proxmity < 0) ? 0 : proxmity;
00469   waypoint.dst = proxmity;
00470   
00471   /* Copy Symbol */
00472   waypoint.smbl = smbl;
00473   
00474   /* Copy Display Mode */
00475   lstP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, DisplayList));
00476   switch ( LstGetSelection(lstP) ) {
00477     case 0:
00478       /* none */
00479       waypoint.dspl = dspl_smbl_none;
00480       break;
00481 
00482     case 1:
00483       /* symbol only */
00484       waypoint.dspl = dspl_smbl_only;
00485       break;
00486       
00487     case 2:
00488       /* with name */
00489       waypoint.dspl = dspl_smbl_name;
00490       break;
00491     
00492     case 3:
00493       /* with comment */
00494       waypoint.dspl = dspl_smbl_cmnt;
00495       break;
00496   }  
00497   
00498   /* Copy Comment */
00499   strP = FldGetTextPtr(FrmGetObjectPtr(frmP,
00500     FrmGetObjectIndex(frmP, CommentField)));
00501   StrCopy(waypoint.cmnt, strP);
00502   
00503   /* Find sort position of new record in waypoint DB */  
00504   index = DmFindSortPosition(gWaypointDB, &waypoint, 0 /* newRecordInfo */,
00505     (DmComparF *)CompareWayptIdent /* DmComparF *compar */, 0 /* other */);
00506     
00507   h = DmNewRecord(gWaypointDB, &index, 
00508     1 /* size, will be set by PackWaypoint() */);
00509 
00510   if (h) {
00511     DmReleaseRecord(gWaypointDB, index, false /* dirty */);
00512   } else {
00513     Die("Cannot create waypoint record!");
00514   }
00515   
00516   /* Pack Waypoint and store it in Database */
00517   PackWaypoint(&waypoint, index);
00518   
00519 }
00520 
00521 
00522 /*****************************************************************************
00523  * FUNCTION:    insert_position
00524  *
00525  * DESCRIPTION: Insert position to fields
00526  *
00527  * GLOBALS:     gPrefs          -- Application Preferences
00528  *
00529  * PARAMETERS:  lat             -- Latitude
00530  *              lon             -- Longitude
00531  *              eastP           -- UTM Easting (ptr)
00532  *              northP          -- UTM Northing (ptr)
00533  *
00534  * RETURNED:    flag    -- Conversion to UTM successful. Always true, if any
00535  *              position format other than UTM is set in the preferences.
00536  *              If UTM position format is selected and the conversion is
00537  *              successful, easting and northing are updated by eastP/northP.
00538  ****************************************************************************/
00539 static
00540 Boolean insert_position(double lat, double lon, double *eastP, double *northP)
00541 {
00542   Char          lat_str[20];    /* string buffer */
00543   Char          lon_str[20];    /* string buffer */
00544   Char          field_str[5];   /* string buffer */
00545   Int32         err;            /* error code */
00546   Int32         zone;           /* UTM Zone */
00547   char          hemisphere;     /* 'N' / 'S' */
00548   double        easting;        /* Easting in m */
00549   double        northing;       /* Northing in m */
00550   
00551   switch (gPrefs.units.pos_unit) {
00552     case POS_D:
00553       /* Degrees */
00554       format_number(lat, 7, lat_str);
00555       StrCat(lat_str, "°");
00556       SetFieldText(LatitudeField, lat_str, false, true);
00557       
00558       format_number(lon, 7, lon_str);
00559       StrCat(lon_str, "°");
00560       SetFieldText(LongitudeField, lon_str, false, true);
00561       break;
00562     
00563     case POS_DM:
00564       deg_to_dm_str(lat, lon, lat_str, lon_str);
00565       SetFieldText(LatitudeField, lat_str, false, true);
00566       SetFieldText(LongitudeField, lon_str, false, true);
00567       break;
00568 
00569     case POS_DMS:
00570       deg_to_dms_str(lat, lon, lat_str, lon_str);
00571       SetFieldText(LatitudeField, lat_str, false, true);
00572       SetFieldText(LongitudeField, lon_str, false, true);
00573       break;
00574       
00575    case POS_UTM:   
00576       /* Universal Transverse Mercator - convert from lat/lon double values */ 
00577       err = Convert_Geodetic_To_UTM (
00578                                 deg2rad(lat) /* Latitude (rad) */,
00579                                 deg2rad(lon) /* Longitude (rad) */,
00580                                 &zone /* long  *Zone */,
00581                                 &hemisphere /* Hemisphere */,
00582                                 &easting /* *Easting */,
00583                                 &northing /* *Northing */);
00584       
00585       if (err == UTM_NO_ERROR) {
00586         /* print zone and belt to string */
00587         StrPrintF(field_str, "%ld%c ", zone, Lat_To_UTM_Belt(lat));
00588         SetFieldText(ZoneField, field_str, false, true);
00589         
00590         /* print easting to string */
00591         format_number(easting, 1, lat_str);
00592         SetFieldText(LatitudeField, lat_str, false, true);
00593                 
00594         /* print northing to string */
00595         format_number(northing, 1, lon_str);
00596         SetFieldText(LongitudeField, lon_str, false, true);
00597         
00598         /* return easting and northing */
00599         *eastP = easting;
00600         *northP = northing;
00601       } else {
00602         return false;
00603       }
00604       break;   
00605   } /* switch (gPrefs.units.pos_unit) */           
00606   
00607   return true;
00608 }
00609 
00610 
00611 /*****************************************************************************
00612  * FUNCTION:    select_symbol
00613  *
00614  * DESCRIPTION: Select waypoint symbol, show bitmap and string.
00615  *
00616  * PARAMETERS:  sym             -- Garmin symbol ID (ptr) 
00617  *              dir             -- change direction (-1/0/+1)
00618  *
00619  * RETURNED:    %
00620  ****************************************************************************/
00621 static
00622 void select_symbol(UInt16 *sym, Int16 dir)
00623 {
00624   FormPtr               frmP;                   /* form ptr */
00625   MemHandle             resH;                   /* resource handle */
00626   BitmapType            *bmpP;                  /* bitmap ptr */
00627   RectangleType         rect;                   /* rectangle */
00628   UInt16                wpt_smbl;               /* waypt. symbol ID (Garmin)*/
00629   UInt16                smbl;                   /* waypt. symbol ID (OS) */
00630         
00631   frmP = FrmGetActiveForm();
00632   wpt_smbl = *sym;
00633   wpt_smbl += dir;
00634         
00635   /* skip 'holes' */
00636   switch (wpt_smbl) {
00637     case sym_mob+1:
00638       wpt_smbl = sym_boat_ramp;
00639       break;
00640 
00641     case sym_boat_ramp-1:
00642       wpt_smbl = sym_mob;
00643       break;
00644 
00645     case sym_circle_x+1:
00646       wpt_smbl = sym_is_hwy;
00647       break;
00648 
00649     case sym_is_hwy-1:
00650       wpt_smbl = sym_circle_x;
00651       break;
00652 
00653     case sym_border+1:
00654       wpt_smbl = sym_airport;
00655       break;
00656 
00657     case sym_airport-1:
00658       wpt_smbl = sym_border;
00659       break;
00660   }
00661   
00662   /* update symbol ID */
00663   *sym = wpt_smbl;
00664   
00665   /* adjust PalmOS ID to Garmin ID */
00666   smbl = (wpt_smbl >= 16383) ? wpt_smbl-16000 : wpt_smbl;
00667   
00668   /* get bitmap resource */
00669   resH = DmGetResource('Tbmp', smbl);
00670 
00671   /* use default if symbol unavailable */
00672   if (!resH) {
00673     resH = DmGetResource('Tbmp', WayptDefBmp);
00674   }
00675 
00676   /* draw bitmap */
00677   if (resH) { 
00678     RctSetRectangle(&rect, WPT_X-1, WPT_Y-1, 16 /* w */, 14 /* h */);
00679     WinEraseRectangle(&rect, 0 /* cornerDiam */ );
00680     bmpP = MemHandleLock(resH);
00681     WinDrawBitmap(bmpP, WPT_X, WPT_Y);
00682     MemHandleUnlock(resH);
00683     DmReleaseResource(resH);
00684   }     
00685 
00686   /* get string resource */
00687   resH = DmGetResource('tSTR', smbl);
00688 
00689   /* use default if symbol string unavailable */
00690   if (!resH) {
00691     resH = DmGetResource('tSTR', WayptDefStr);
00692   }
00693 
00694   /* update field */
00695   if (resH) { 
00696     FldSetTextHandle(FrmGetObjectPtr(frmP,
00697       FrmGetObjectIndex(frmP, WayptEditSymField)), resH);
00698     FldDrawField(FrmGetObjectPtr(frmP,
00699       FrmGetObjectIndex(frmP, WayptEditSymField)));
00700     /* Note: resH still in use by field! */
00701     /* DmReleaseResource(resH); */
00702   }
00703 }
00704 
00705 
00706 /****************************************************************************/
00707 /**
00708  * \brief       Convert GeoDB location strings to Latitude/Longitude
00709  *
00710  * \note        This function has been adapted from scan_position()
00711  *
00712  * \param       loc             GeoDB location structure
00713  * \param       lat             latitude returned by reference
00714  * \param       lon             longitude returned by reference
00715  *
00716  ****************************************************************************/
00717 static
00718 Boolean geodb_str_to_deg(Location *loc, double *lat, double *lon)
00719 {
00720   Char          *trailP;        /* trailing string ptr */
00721   Char          *strP;          /* string ptr */
00722   double        tmp;            /* temp. double */
00723   short         frac;           /* number of fractional digits */
00724   
00725   /* Convert Latitude */
00726   
00727   /* first value is angle in degrees */
00728   tmp = cvt_atof(loc->latStr, &trailP, &frac);
00729   
00730   /*
00731    * Field's contents must start with an integer number, 
00732    * which must end with a colon.
00733    */
00734   if (*trailP != ':' || frac > 0) {
00735     /* invalid entry */
00736     return false;
00737   } else {
00738 
00739     if ((tmp > 90.0) || (tmp < 0.0)) {
00740       /* range error */
00741       return false;
00742     }
00743     /* o.k., update position */
00744     *lat = tmp;
00745 
00746   }
00747 
00748   /* Handle minutes part */
00749   /* skip degree sign/colon */
00750   strP = trailP + 1;
00751   
00752   /* convert string to float */
00753   tmp = cvt_atof(strP, &trailP, &frac);
00754 
00755   if ((tmp >= 60.0) || (tmp < 0.0)) {
00756     /* range error */
00757     return false;
00758   }
00759 
00760   *lat += tmp/60.0;
00761   
00762     
00763   /* Convert Longitude */
00764   
00765   /* first value is angle in degrees */
00766   tmp = cvt_atof(loc->longStr, &trailP, &frac);
00767   
00768   
00769   /*
00770    * Field's contents must start with an integer number, 
00771    * which must end with a colon.
00772    */
00773   if (*trailP != ':' || frac > 0) {
00774     /* invalid entry */
00775     return false;
00776   } else {  
00777     
00778     if ((tmp > 180.0) || (tmp < 0.0)) {
00779       /* range error */
00780       return false;
00781     } 
00782     /* o.k., update position */
00783     *lon = tmp;
00784   } 
00785 
00786   /* Handle minutes part */
00787   /* skip degree sign/colon */
00788   strP = trailP + 1;
00789   
00790   /* convert string to float */
00791   tmp = cvt_atof(strP, &trailP, &frac);
00792 
00793   if ((tmp >= 60.0) || (tmp < 0.0)) {
00794     /* range error */
00795     return false;
00796   }
00797 
00798   *lon += tmp/60.0;
00799 
00800   /* adjust signs */
00801   *lat = (loc->latNS) ? *lat : *lat * -1.0;
00802   *lon = (loc->longEW) ? *lon : *lon * -1.0;
00803   
00804   /* success */
00805   return true;
00806 }
00807 
00808 
00809 /****************************************************************************/
00810 /**
00811  * \brief       Waypoint Edit Form Event Handler
00812  *
00813  * GLOBALS:     gPrefs          Application Preferences
00814  *
00815  * \param       eventP          pointer to event structure
00816  *
00817  * \return      Status flag: event handled
00818  ****************************************************************************/
00819 Boolean WayptEditFormHandleEvent(EventPtr eventP)
00820 {
00821   Boolean               handled;                /* flag: event handled */
00822   FormPtr               frmP;                   /* form ptr */
00823   ListPtr               lstP;                   /* list ptr */
00824   FieldPtr              fldP;                   /* field ptr */
00825   UInt16                sel;                    /* list selection */
00826   UInt16                rec;                    /* record index */
00827   packed_waypoint_t     *packed_waypoint;       /* packed waypoint ptr */
00828   waypoint_t            waypoint;               /* unpacked waypoint */
00829   MemHandle             waypointDBEntry;        /* waypoint record handle */
00830   static double         lat;                    /* latitude */
00831   static double         lon;                    /* longitude */
00832   static UInt16         utm_zone = 32;          /* UTM zone */
00833   static char           utm_belt = 'U';         /* UTM belt */
00834   static Char           tmp[20];                /* temp. string buffer */
00835   static Boolean        lat_valid;              /* latitude valid */
00836   static Boolean        lon_valid;              /* longitude valid */
00837   Boolean               valid;                  /* input valid */
00838   UInt16                fld_focus;              /* ID of active field */
00839   static UInt16         fld_focus_old;          /* ID of previously act field */
00840   static UInt16         wpt_smbl;               /* waypoint symbol ID (Gar.) */
00841   Int16                 dir;                    /* waypoint change direction */
00842   Err                   err;                    /* UTM error */
00843 
00844   frmP = FrmGetActiveForm();
00845   handled = false;
00846   
00847   /*
00848    * The fields' contents have to be checked whenever a field looses focus. 
00849    * Unfortunately, there is no appropriate event (ctlExitEvent is not triggered
00850    * by fields). So we have to track the active field manually.
00851    */
00852   if ( field_active(LatitudeField) ) {
00853     fld_focus = LatitudeField;
00854   } else if ( field_active(LongitudeField) ) {
00855     fld_focus = LongitudeField;
00856   } else if ( field_active(ZoneField) ) {
00857     fld_focus = ZoneField;
00858   } else {
00859     /* none */
00860     fld_focus = 0;
00861   }
00862   
00863   if ((fld_focus_old != 0) && (fld_focus != fld_focus_old)) {
00864     /* Pseudo-fldExitEvent */
00865     switch (fld_focus_old) {
00866       case LatitudeField:
00867         valid = scan_position(LatitudeField, &lat, &lon);
00868 
00869         if (valid) {
00870           lat_valid = true; 
00871         } else {
00872           /* restore old text */
00873           SetFieldText(LatitudeField, tmp, false /* append */,
00874             true /* redraw */);   
00875         }
00876         break;
00877 
00878       case LongitudeField:
00879         valid = scan_position(LongitudeField, &lat, &lon);
00880 
00881         if (valid) {
00882           lon_valid = true;
00883         } else {
00884           /* restore old text */
00885           SetFieldText(LongitudeField, tmp, false /* append */,
00886             true /* redraw */);
00887         }
00888         break;
00889         
00890       case ZoneField:
00891         valid = scan_zone(&utm_zone, &utm_belt);
00892 
00893         if (!valid) {
00894           /* restore old text */
00895           SetFieldText(ZoneField, tmp, false /* append */,
00896             true /* redraw */);
00897         }
00898         break;
00899        
00900     }
00901   }
00902   
00903   switch (eventP->eType) {
00904     case frmOpenEvent:
00905       WayptEditFormInit();
00906       FrmDrawForm(frmP);
00907 
00908       lat_valid = lon_valid = false;
00909 
00910       /* show objects depending on selected position units */
00911       if (gPrefs.units.pos_unit == POS_UTM) {
00912         FrmShowObject(frmP, FrmGetObjectIndex(frmP, ZoneLabel));
00913         FrmShowObject(frmP, FrmGetObjectIndex(frmP, ZoneField));
00914         FrmShowObject(frmP, FrmGetObjectIndex(frmP, EastLabel));
00915         FrmShowObject(frmP, FrmGetObjectIndex(frmP, NorthLabel));
00916       } else {
00917         FrmShowObject(frmP, FrmGetObjectIndex(frmP, LatLabel));
00918         FrmShowObject(frmP, FrmGetObjectIndex(frmP, LonLabel));       
00919       }
00920 
00921       if (gSelWaypoint.valid) {
00922         /* write selected waypoint data to fields */
00923         /* Note: Waypoint Symbol will be lost */
00924         err = DmFindRecordByID(gWaypointDB, gSelWaypoint.waypointID,
00925           &rec);
00926         
00927         if (!err) {
00928           /* active waypoint found */
00929           waypointDBEntry = DmQueryRecord(gWaypointDB, rec);
00930           packed_waypoint =
00931             (packed_waypoint_t *)MemHandleLock(waypointDBEntry);
00932           UnpackWaypoint(&waypoint, packed_waypoint);
00933           
00934           /* copy waypoint ID */
00935           MemSet((Char *)tmp, 7, 0);
00936           StrNCopy(tmp, (Char *)&waypoint.ident, 6);
00937           SetFieldText(IdentField, tmp, false, true);
00938           
00939           /* copy comment */
00940           SetFieldText(CommentField, waypoint.cmnt, false, true);
00941           format_number(waypoint.dst, 0, tmp);
00942           
00943           /* copy proximity distance */
00944           SetFieldText(ProxField, tmp, false, true);
00945           
00946           /* set display mode pop-up selection */
00947           switch (waypoint.dspl) {
00948             case dspl_smbl_none:
00949               /* none */
00950               sel = 0;
00951               break;
00952 
00953             case dspl_smbl_only:
00954               /* symbol only */
00955               sel = 1;
00956               break;
00957 
00958             case dspl_smbl_name:
00959               /* with name */
00960               sel = 2;
00961               break;
00962 
00963             case dspl_smbl_cmnt:
00964               /* with comment */
00965               sel = 3;
00966               break;
00967             
00968             default:
00969               /* symbol only */
00970               sel = 1;
00971               break;
00972           }
00973           lstP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, DisplayList));
00974           LstSetSelection (lstP, sel);
00975           CtlSetLabel(FrmGetObjectPtr(frmP,
00976             FrmGetObjectIndex(frmP, DisplayPopup)),
00977             LstGetSelectionText(lstP, sel));
00978 
00979           /* draw waypoint symbol */
00980           wpt_smbl = waypoint.smbl;
00981           select_symbol(&wpt_smbl, 0 /* dir */);
00982           
00983           /* Insert current position to fields */
00984           if (insert_position(semi2deg(waypoint.posn.lat),
00985                               semi2deg(waypoint.posn.lon), &lat, &lon)) {
00986             if (gPrefs.units.pos_unit == POS_UTM) {
00987               /* easting/northing returned in lat/lon ! */
00988               /* get UTM field */
00989               scan_zone(&utm_zone, &utm_belt);
00990             } else {
00991               lat = semi2deg(waypoint.posn.lat);
00992               lon = semi2deg(waypoint.posn.lon);            
00993             }  
00994             lat_valid = true;
00995             lon_valid = true;
00996           }
00997           MemHandleUnlock(waypointDBEntry);
00998         }
00999         
01000       } else { 
01001         /* write templates to fields */
01002         MemHandle       strH;           /* string handle */
01003         MemPtr          strP;           /* string ptr */
01004         
01005         /* get string from resource */
01006         strH = DmGetResource(strRsc, WptIdentStr);
01007 
01008         if (strH != NULL) {
01009           /* string handle valid, lock it */
01010           strP = MemHandleLock(strH);
01011 
01012           SetFieldText(IdentField, strP, false, true);
01013           
01014           /* unlock string handle */
01015           MemHandleUnlock(strH);
01016 
01017           /* release string resource */
01018           DmReleaseResource(strH);
01019         }
01020 
01021         strH = DmGetResource(strRsc, WptCmntStr);
01022 
01023         if (strH != NULL) {
01024           /* string handle valid, lock it */
01025           strP = MemHandleLock(strH);
01026 
01027           SetFieldText(CommentField, strP, false, true);
01028           
01029           /* unlock string handle */
01030           MemHandleUnlock(strH);
01031 
01032           /* release string resource */
01033           DmReleaseResource(strH);
01034         }
01035 
01036         SetFieldText(ProxField, "1000.0", false, true);
01037 
01038         switch (gPrefs.units.pos_unit) {
01039           case POS_D:
01040             SetFieldText(LatitudeField, "DD.DDDDDDD°", false, true);
01041             SetFieldText(LongitudeField, "DDD.DDDDDDD°", false, true);
01042             break;
01043 
01044           case POS_DM:
01045             SetFieldText(LatitudeField, "DD°MM.MMMM\'", false, true);
01046             SetFieldText(LongitudeField, "DDD°MM.MMMM\'", false, true);
01047             break;
01048 
01049           case POS_DMS:
01050             SetFieldText(LatitudeField, "DD°MM\'SS.SSS\"", false, true);
01051             SetFieldText(LongitudeField, "DDD°MM\'SS.SSS\"", false, true);
01052             break;
01053 
01054           case POS_UTM:
01055             SetFieldText(ZoneField, "32U", false, true);
01056             SetFieldText(LatitudeField, "EEEEEE.E", false, true);
01057             SetFieldText(LongitudeField, "NNNNNNN.N", false, true);
01058             break;
01059         }
01060 
01061         /* set default pop-up selection */
01062         lstP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, DisplayList));
01063         LstSetSelection (lstP, 1 /* sel */);
01064         CtlSetLabel(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, DisplayPopup)),
01065           LstGetSelectionText(lstP, 1 /* sel */));
01066         
01067         /* draw waypoint symbol */
01068         wpt_smbl = WayptDefBmp;
01069         select_symbol(&wpt_smbl, 0 /* dir */);
01070         
01071       }                  
01072       handled = true;
01073       break;
01074     
01075     case menuEvent:
01076       /* check if any field has focus */      
01077       if ( field_active(IdentField)     ||
01078            field_active(CommentField)   ||
01079            field_active(LatitudeField)  ||
01080            field_active(LongitudeField) ||
01081            field_active(ProxField)) {   
01082         fldP = (FieldPtr)FrmGetObjectPtr(frmP, FrmGetFocus(frmP));
01083         handled = true;
01084       } else {
01085         fldP = NULL;
01086       }
01087       
01088       switch (eventP->data.menu.itemID) {
01089         case UndoMenu:
01090           if (fldP)
01091             FldUndo(fldP);
01092           break;
01093         
01094         case CutMenu:
01095           if (fldP)
01096             FldCut(fldP);
01097           break;
01098         
01099         case CopyMenu:
01100           if (fldP)
01101             FldCopy(fldP);
01102           break;
01103         
01104         case PasteMenu:
01105           if (fldP)
01106             FldPaste(fldP);
01107           break;          
01108           
01109         case KeyboardMenu:
01110           if ( field_active(IdentField) || field_active(CommentField) ) {
01111             SysKeyboardDialog(kbdAlpha);
01112           } else if ( field_active(LatitudeField)   ||
01113                       field_active(LongitudeField) ||
01114                       field_active(ProxField) ) {
01115             SysKeyboardDialog(kbdNumbersAndPunc);
01116           }
01117           handled = true;
01118           break;
01119           
01120         case GraffitiMenu:
01121           SysGraffitiReferenceDialog(referenceDefault);
01122           handled = true;
01123           break;
01124        
01125       } /* switch (eventP->data.menu.itemID) */
01126       break;
01127       
01128     case fldEnterEvent:
01129       switch (eventP->data.ctlSelect.controlID) {
01130         case LatitudeField:
01131           /*
01132            * save contents, we might have to restore it
01133            * if the new input is invalid
01134            */
01135           if (fld_focus_old != LatitudeField) {
01136             StrCopy(tmp, FldGetTextPtr(FrmGetObjectPtr(frmP,
01137               FrmGetObjectIndex(frmP, LatitudeField))));
01138           }
01139           break;
01140 
01141         case LongitudeField:
01142           /*
01143            * save contents, we might have to restore it
01144            * if the new input is invalid
01145            */
01146           if (fld_focus_old != LongitudeField) {
01147             StrCopy(tmp, FldGetTextPtr(FrmGetObjectPtr(frmP,
01148               FrmGetObjectIndex(frmP, LongitudeField))));
01149           }
01150           break;
01151 
01152         case ZoneField:
01153           /*
01154            * save contents, we might have to restore it
01155            * if the new input is invalid
01156            */
01157           if (fld_focus_old != ZoneField) {
01158             StrCopy(tmp, FldGetTextPtr(FrmGetObjectPtr(frmP,
01159               FrmGetObjectIndex(frmP, ZoneField))));
01160           }
01161           break;
01162           
01163       }
01164       break;
01165 
01166     case keyDownEvent:
01167       switch (eventP->data.keyDown.chr) {
01168 
01169       case pageUpChr:
01170         dir = 0;
01171         /* increment */
01172         if (wpt_smbl == sym_seaplane) {
01173           wpt_smbl = sym_anchor;
01174         } else {
01175           dir = 1;
01176         }
01177         select_symbol(&wpt_smbl, dir);
01178         handled = true;
01179         break;
01180         
01181       case pageDownChr:
01182         dir = 0;
01183         /* decrement */
01184         if (wpt_smbl == 0) {
01185           wpt_smbl = sym_seaplane;      /* wrap around */
01186         } else {
01187           dir = -1;
01188         }
01189         select_symbol(&wpt_smbl, dir);
01190         handled = true;
01191         break;
01192       }
01193       break;
01194     
01195     case ctlSelectEvent:
01196       switch (eventP->data.ctlSelect.controlID) {
01197 
01198         case WayptEditOkButton:
01199           switch (fld_focus) {
01200             case LatitudeField:
01201               /* Latitude field is still active, get contents */
01202               valid = scan_position(LatitudeField, &lat, &lon);
01203 
01204               if (valid) {
01205                 lat_valid = true;
01206               } else {
01207                 /* restore old text */
01208                 SetFieldText(LatitudeField, tmp, false /* append */,
01209                   true /* redraw */);
01210               }
01211               break;
01212             
01213             case LongitudeField:
01214               valid = scan_position(LongitudeField, &lat, &lon);
01215 
01216               if (valid) {
01217                 lon_valid = true;
01218               } else {
01219                 /* restore old text */
01220                 SetFieldText(LongitudeField, tmp, false /* append */,
01221                   true /* redraw */);
01222               }
01223               break;
01224 
01225             case ZoneField:
01226               valid = scan_zone(&utm_zone, &utm_belt);
01227 
01228               if (!valid) {
01229                 /* restore old text */
01230                 SetFieldText(ZoneField, tmp, false /* append */,
01231                   true /* redraw */);
01232               }
01233               break;
01234 
01235             default:
01236               valid = true;
01237               break;
01238           } /* switch (fld_focus) */
01239           
01240           if (gPrefs.units.pos_unit == POS_UTM) {
01241             /* lat and lon actually contain easting and northing! */
01242             double      easting  = lat;
01243             double      northing = lon;
01244 
01245             err = Convert_UTM_To_Geodetic(utm_zone,
01246                                  (utm_belt >= 'N') ? 'N' : 'S' /* Hemisphere */,
01247                                  easting,
01248                                  northing,
01249                                  &lat,
01250                                  &lon);     
01251                     
01252             if (err != UTM_NO_ERROR) {
01253               break;
01254             }
01255             
01256             lat = rad2deg(lat);
01257             lon = rad2deg(lon);
01258           }
01259           
01260           if (lat_valid & lon_valid) {
01261             /* add waypoint and close form only if fields are valid */
01262             add_waypoint(lat, lon, wpt_smbl);
01263             FrmGotoForm(WaypointForm);
01264           }
01265           handled = true;
01266           break;
01267           
01268         case WayptEditCancelButton:
01269           /* close form without changing database */
01270           FrmGotoForm(WaypointForm);
01271           handled = true;
01272           break;
01273       
01274         case WayptEditHereButton:
01275           /* insert current position */
01276 
01277           /* throw away anything in the buffer-- we want fresh data */
01278           DoReceiveFlush(gPortID, 1);
01279           
01280           /* get new data */
01281           ReadFromGPS();
01282           
01283           if (!gGPSData.valid)
01284             break;
01285           
01286           if (fld_focus != 0) {
01287             /* release focus from active field */
01288             FldReleaseFocus(FrmGetObjectPtr(frmP,
01289               FrmGetObjectIndex(frmP, fld_focus)));
01290             fld_focus = 0;
01291           }
01292           
01293           /* Insert current position to fields */
01294           if (insert_position(gGPSData.lat, gGPSData.lon, &lat, &lon)) {
01295             if (gPrefs.units.pos_unit == POS_UTM) {
01296               /* easting/northing returned in lat/lon ! */
01297               /* get UTM field */
01298               scan_zone(&utm_zone, &utm_belt);
01299             } else {
01300               lat = gGPSData.lat;
01301               lon = gGPSData.lon;           
01302             }  
01303             lat_valid = true;
01304             lon_valid = true;
01305           }
01306           
01307           handled = true;
01308           break;
01309         
01310         case WayptEditImportButton:
01311           /* get GeoDB data */
01312           if ( importGeoDBLocation() ) {
01313               Char      tempStr[80];    /* string buffer */
01314               Int       dls;            /* daylight saving time array index */
01315               CharPtr   dlsList[] = {
01316                                       "No", "Yes", "Australia", "Europe",
01317                                       "N.America", "S.America", "User Defined"
01318                                     };
01319             
01320             /* Convert GeoDB strings to double Latitude and Longitude */
01321             if ( geodb_str_to_deg(&location, &lat, &lon) ) {
01322               
01323               /* Insert current position to fields */
01324               if (insert_position(lat, lon, &lat, &lon)) {
01325               
01326                 if (gPrefs.units.pos_unit == POS_UTM) {
01327                   /* easting/northing returned in lat/lon ! */
01328                   /* get UTM field */
01329                   scan_zone(&utm_zone, &utm_belt);
01330                 }  
01331                 lat_valid = true;
01332                 lon_valid = true;
01333               }       
01334             }
01335             
01336             /* add Name */
01337             if (StrLen(location.name)) {
01338               StrPrintF(tempStr, "%s;",location.name);
01339             }
01340             
01341             /* add Altitude */
01342             if (StrLen(location.altStr)) {
01343               StrPrintF(&tempStr[StrLen(tempStr)],
01344                 "Alt: %s;", location.altStr);
01345             }
01346             
01347             /* add GMT Offset */
01348             if (StrLen(location.gmtStr)) {
01349               StrPrintF(&tempStr[StrLen(tempStr)], "GMT Offset: %s %s;",
01350                 location.gmtStr, (CharPtr)(location.gmtEW?"E":"W")); 
01351             } 
01352             
01353             /* add Daylight Saving Time */
01354             
01355             /* high bit set when daylight time */
01356             StrPrintF(&tempStr[StrLen(tempStr)], "DST: %s ",
01357               location.dayLight & 0x80?"ST":"DT");
01358 
01359             dls = location.dayLight & 0x7f;                                     // display DayLight rule
01360 
01361             if (dls <8) {
01362               StrCopy(&tempStr[StrLen(tempStr)], dlsList[dls]);
01363             } else {
01364               StrCopy(&tempStr[StrLen(tempStr)], "DLS Error");
01365             }
01366             
01367             /* truncate to Garmin Comment Field width */ 
01368             tempStr[39] = '\0';
01369             
01370             /* set Comment Field*/
01371             SetFieldText(CommentField, tempStr, false, true);
01372           
01373           } else {
01374             FrmAlert(GeodbImportAlert);
01375           }
01376           handled = true;
01377           break;
01378 
01379         case WayptEditPrevSymButton:
01380           dir = 0;
01381           /* increment */
01382           if (wpt_smbl == sym_seaplane) {
01383             wpt_smbl = sym_anchor;
01384           } else {
01385             dir = 1;
01386           }
01387           select_symbol(&wpt_smbl, dir);
01388           handled = true;
01389           break;
01390         
01391         case WayptEditNextSymButton:
01392           dir = 0;
01393           /* decrement */
01394           if (wpt_smbl == 0) {
01395             wpt_smbl = sym_seaplane;    /* wrap around */
01396           } else {
01397             dir = -1;
01398           }
01399           select_symbol(&wpt_smbl, dir);
01400           handled = true;
01401           break;
01402       }
01403       break;
01404 
01405     case frmCloseEvent:
01406       /* no active field */
01407       fld_focus = fld_focus_old = 0;
01408       
01409       /* Deallocate Fields' Text Memory */
01410       SetFieldText(IdentField, NULL, false, true);
01411       FldSetTextHandle(FrmGetObjectPtr(frmP,
01412         FrmGetObjectIndex(frmP, WayptEditSymField)), NULL);
01413       if (gPrefs.units.pos_unit == POS_UTM) {
01414         SetFieldText(ZoneField, NULL, false, true);
01415       }
01416       SetFieldText(LatitudeField, NULL, false, true);
01417       SetFieldText(LongitudeField, NULL, false, true);
01418       SetFieldText(ProxField, NULL, false, true);
01419       SetFieldText(CommentField, NULL, false, true);
01420       break;
01421   }
01422 
01423   /* save current focus */  
01424   fld_focus_old = fld_focus;
01425   
01426   return(handled);
01427 } /* WayptEditFormHandleEvent() */

Created: Mon, 08 Oct 2007 22:33:16 +0200
Copyright ©2004 M. Prinke