GPS4Palm

Source Code Documentation


WaypointForm.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: WaypointForm_8c-source.html,v $
00004  *
00005  * GPS4Palm Waypoint Form
00006  *
00007  *
00008  * This program is Copyright (C) 12/2002 Matthias Prinke
00009  * <matthias.prinke@surfeu.de> and covered by GNU's GPL.
00010  * In particular, this program is free software and comes WITHOUT
00011  * ANY WARRANTY.
00012  *
00013  * $Author: mp $
00014  *
00015  * $Date: 2007-10-08 20:40:35 $
00016  *
00017  * $Revision: 1.7.2.1 $
00018  *
00019  * $Log: WaypointForm_8c-source.html,v $
00019  * Revision 1.7.2.1  2007-10-08 20:40:35  mp
00019  * updated for gps4palm V0.9.5 beta
00019  *
00020  * Revision 1.32  2005-05-06 13:39:42  mp
00021  * added workaround for Bluetooth-Open Bug
00022  *
00023  * Revision 1.31  2005/01/30 21:22:13  mp
00024  * added PortsMenu event handling
00025  *
00026  * Revision 1.30  2005/01/23 10:01:32  mp
00027  * changed re-opening of GPS serial port after data transfer
00028  *
00029  * Revision 1.29  2004/12/18 16:12:04  mp
00030  * fixed serial port re-opening for PDAs with New Serial Manager
00031  *
00032  * Revision 1.28  2004/12/09 17:27:24  mp
00033  * replaced waypoint display mode strings by WaypointDispList object
00034  *
00035  * Revision 1.27  2004/12/02 19:02:47  mp
00036  * improved string alignment for compatibility
00037  *
00038  * Revision 1.26  2004/11/30 20:41:33  mp
00039  * added TransferTrkReqEvent and TrackMenu event handling, added GarminGetTrks()
00040  *
00041  * Revision 1.25  2004/11/26 20:11:03  mp
00042  * modified TableDrawPosnCell()
00043  *
00044  * Revision 1.24  2004/11/24 21:30:07  mp
00045  * moved static function declarations from header to implementation file,
00046  * added AboutForm menu event handling
00047  *
00048  * Revision 1.23  2004/11/23 17:46:55  mp
00049  * removed unused variables
00050  *
00051  * Revision 1.22  2004/11/20 16:54:01  mp
00052  * added disabling of active route when selecting active waypoint
00053  *
00054  * Revision 1.21  2004/11/18 17:35:07  mp
00055  * added QueryRouteWaypoint() and modified WaypointDeleteButton event handling:
00056  * if a waypoint is part of any route, deletion is denied
00057  *
00058  * Revision 1.20  2004/11/14 22:44:14  mp
00059  * code cleanup
00060  *
00061  * Revision 1.19  2004/11/13 18:52:20  mp
00062  * added freeing of WaypointGpslibField memory, fixed rec index data type
00063  *
00064  * Revision 1.18  2004/11/11 18:52:04  mp
00065  * fixed table update after waypoint download (PC -> PDA)
00066  *
00067  * Revision 1.17  2004/06/23 18:06:31  mp
00068  * Modified comments, modified table scroll/page functions, updated DataExchange functions.
00069  *
00070  * Revision 1.16  2004/04/23 16:05:05  mp
00071  * Added error handling for serial port.
00072  *
00073  * Revision 1.15  2004/04/22 19:48:00  mp
00074  * Changed handling of waypoint reception if a record with same waypoint ID
00075  * already exists: existing waypoint is updated, no new record is created.
00076  *
00077  * Revision 1.14  2004/04/21 18:37:23  mp
00078  * fixed handling of empty waypoint DB, fixed transmission of comments
00079  *
00080  * Revision 1.13  2004/04/18 18:19:14  mp
00081  * added waypoint upload/download
00082  *
00083  * Revision 1.12  2004/03/28 18:56:36  mp
00084  * modified waypoint displaying
00085  *
00086  * Revision 1.11  2004/03/28 17:45:51  mp
00087  * added waypoint symbol bitmap display
00088  *
00089  * Revision 1.10  2004/03/20 13:34:44  mp
00090  * fixed waypoint table selection, changed waypoint data type to double
00091  *
00092  * Revision 1.9  2004/03/15 17:19:23  mp
00093  * added Waypoint Copy function
00094  *
00095  * Revision 1.8  2004/03/13 12:39:47  mp
00096  * moved call of Set_UTM_Parameters() to AppStart()
00097  *
00098  * Revision 1.7  2004/03/10 22:00:50  mp
00099  * added active waypoint check, modified comments
00100  *
00101  * Revision 1.6  2004/03/10 17:26:59  mp
00102  * Modified due to changes in Data.h. Added handling of WaypointGotoButton.
00103  *
00104  * Revision 1.5  2004/03/09 19:17:58  mp
00105  * added WaypointDispField handling
00106  *
00107  * Revision 1.4  2004/03/07 10:39:03  mp
00108  * Moved database open/close to AppStart()/AppStop() (GPS.c)
00109  *
00110  * Revision 1.3  2004/03/03 19:02:59  mp
00111  * added WaypointNewButton handling
00112  *
00113  * Revision 1.2  2004/03/01 19:58:46  mp
00114  * Fixed waypoint deletion.
00115  *
00116  * Revision 1.1  2004/03/01 19:00:36  mp
00117  * initial version, deleting not working properly
00118  *
00119  *
00120  ****************************************************************************/
00121 
00122 #define DO_NOT_ALLOW_ACCESS_TO_INTERNALS_OF_STRUCTS
00123 #include <BuildDefines.h>
00124 #ifdef DEBUG_BUILD
00125 #define ERROR_CHECK_LEVEL ERROR_CHECK_FULL
00126 #endif
00127 #include <PalmOS.h>
00128 #include <SerialMgrOld.h>
00129 #include "ResourceDefines.h"
00130 #include "gpslib.h"
00131 #include "WaypointForm.h"
00132 #include "Data.h"
00133 #include "DataExchange.h"
00134 #include "Utils.h"
00135 #include "Serial.h"
00136 #include "utm.h"
00137 #include "geo.h"
00138 #include "fp.h"
00139 #include "common.h"
00140 
00141 /* Waypoint Symbol Coordinates */
00142 #define WPT_X   146
00143 #define WPT_Y   94
00144 
00145 /* Global Variables */
00146 extern PrefsType        gPrefs;                 /* application preferences */
00147 ActWayptType            gSelWaypoint;           /**< selected waypoint */
00148 extern UInt32           gSerialPort;            /* serial port name/no. */
00149 
00150 
00151 /* Local Variables */
00152 static Int32            gWayptTopRow;           /* top table row */
00153 static UInt16           gWayptSel;              /* selected waypoint (table) */
00154 
00155 
00156 /* Static Functions */
00157 static void WaypointFormInit(FormPtr frmP)              WAYPOINT_SECTION;
00158 static void WaypointFormDeinit(FormPtr frmP)            WAYPOINT_SECTION;
00159 static Boolean QueryRouteWaypoint(UInt16 wpt_index,
00160   G_byte *nmbr)                                         WAYPOINT_SECTION;
00161 static void TableDrawIdentCell(void *tblP, Int16 row,
00162   Int16 column, RectangleType *bounds)                  WAYPOINT_SECTION;
00163 static void TableDrawPosnCell(void *tblP, Int16 row,
00164   Int16 column, RectangleType *bounds)                  WAYPOINT_SECTION;
00165 static void ChangePorts(void)                           WAYPOINT_SECTION;
00166                    
00167 /*****************************************************************************
00168  * FUNCTION:    WayptEditFormInit
00169  *
00170  * DESCRIPTION: Waypoint Form Init Function (not used)
00171  *
00172  ****************************************************************************/
00173 static void WaypointFormInit(FormPtr frmP)
00174 {
00175 #pragma unused(frmP)
00176   // warning-- don't do any drawing in this routine.
00177   // Also, don't call FrmSetFocus from here (it must be called *after*
00178   // FrmDrawForm)
00179 }
00180 
00181 
00182 /*****************************************************************************
00183  * FUNCTION:    WayptEditFormInit
00184  *
00185  * DESCRIPTION: Waypoint Form De-Init Function (not used)
00186  *
00187  ****************************************************************************/
00188 static void WaypointFormDeinit(FormPtr frmP)
00189 {
00190 #pragma unused(frmP)
00191 }
00192 
00193 
00194 /****************************************************************************/
00195 /**
00196  * \brief       Check if waypoint is part of any route
00197  *
00198  * 
00199  * \param       wpt_index       waypoint record index
00200  * \param       nmbr            route number returned by reference,
00201  *                                undefined if waypoint not found
00202  *
00203  * \return
00204  *              - true if waypoint found in route
00205  *              - false if waypoint not found in route
00206  *****************************************************************************/
00207 static
00208 Boolean QueryRouteWaypoint(UInt16 wpt_index, G_byte *nmbr)
00209 {
00210   MemHandle     routeDBEntry;   /* route record handle */
00211   route_t       *route;         /* route record ptr */
00212   UInt16        rte_index;      /* route record index */
00213   UInt16        rte;            /* route loop index */
00214   UInt16        wpt;            /* waypoint loop index */
00215   UInt32        wpt_rec_id;     /* waypoint record ID */
00216   UInt16        nr_routes;      /* number of routes */
00217   Boolean       found = false;  /* flag: waypoint found */
00218   
00219   /* get waypoint record ID */
00220   DmRecordInfo(gWaypointDB, wpt_index, NULL /* *attrP */,
00221           &wpt_rec_id /* *uniqueIDP */, NULL /* *chunkIDP */);
00222   
00223    /* get number of routes */
00224   nr_routes = DmNumRecordsInCategory(gRouteDB, dmAllCategories);
00225  
00226   for (rte=0; rte < nr_routes; rte++) {
00227     /* start seeking from begin */
00228     rte_index = 0;
00229     
00230     /* get next route record */
00231     DmSeekRecordInCategory(gRouteDB, &rte_index /* index */,
00232       rte /* offset */, dmSeekForward, dmAllCategories);
00233 
00234     /* get record handle */
00235     routeDBEntry = DmQueryRecord(gRouteDB, rte_index);
00236 
00237     /* lock record */
00238     route = MemHandleLock(routeDBEntry);
00239 
00240     for (wpt=0; wpt < route->items; wpt++) {
00241       if (route->wpt_rec_id[wpt] == wpt_rec_id) {
00242         /* found the waypoint! */
00243         found = true;
00244         
00245         /* return route number */
00246         *nmbr = route->nmbr;
00247         break;
00248       }
00249     }
00250     
00251     /* unlock record */
00252     MemHandleUnlock(routeDBEntry);
00253   
00254     if (found == true)
00255       break;
00256   }
00257     
00258   return found;
00259 }
00260 
00261 
00262 /* Table Drawing Callback Functions */
00263 TableDrawItemFuncType TableDrawIdentCell;
00264 TableDrawItemFuncType TableDrawPosnCell;
00265 
00266 
00267 /*****************************************************************************
00268  * FUNCTION:    TableDrawIdentCell
00269  *
00270  * DESCRIPTION: Custom table cell drawing function for Waypoint Identifier
00271  *              (string, max. 6 characters). The DB record number is
00272  *              retrieved via TblGetRowData().
00273  *
00274  * GLOBALS:     gWaypointDB     -- waypoint DB reference
00275  *
00276  * PARAMETERS:  Note: The function's prototype is defined by PalmOS
00277  *                    (TableDrawItemFuncType).
00278  *
00279  * RETURNED:    -
00280  ****************************************************************************/
00281 static void TableDrawIdentCell(void *tblP, Int16 row, Int16 column,
00282                    RectangleType *bounds)
00283 {
00284   Char                  tmp[8];                 /* string buffer */
00285   MemHandle             waypointDBEntry;        /* record handle */
00286   UInt16                rec;                    /* record index */
00287   waypoint_t            waypoint;               /* unpacked waypoint */
00288   packed_waypoint_t     *packed_waypoint;       /* packed waypoint (ptr) */
00289 
00290   /* get record index from row data */
00291   rec = (UInt16)TblGetRowData(tblP, row);
00292 
00293   if (column == 0) {
00294     WinEraseRectangle(bounds, 0);
00295     
00296     if (TblRowUsable(tblP, row)) {
00297       waypointDBEntry = DmQueryRecord(gWaypointDB, rec);
00298       packed_waypoint = (packed_waypoint_t *)MemHandleLock(waypointDBEntry);
00299       UnpackWaypoint(&waypoint, packed_waypoint);
00300       MemSet((Char *)tmp, 7, 0);
00301       StrNCopy(tmp, (Char *)&waypoint.ident, 6);
00302       MemHandleUnlock(waypointDBEntry);
00303 
00304       WinDrawChars(tmp, StrLen(tmp), bounds->topLeft.x + 1, bounds->topLeft.y);
00305     }
00306   }
00307 }
00308 
00309 
00310 /*****************************************************************************
00311  * FUNCTION:    TableDrawPosnCell
00312  *
00313  * DESCRIPTION: Custom table cell drawing function for Waypoint Position
00314  *              Column 1 - Latitude or UTM Zone and Easting
00315  *              Column 2 - Longitude or UTM Northing
00316  *              The DB record number is retrieved via TblGetRowData().
00317  *              The display format is determined by gPrefs.units.pos_unit
00318  *              (Application Preferences). The table width is not sufficient
00319  *              for the DMS format.
00320  *
00321  * GLOBALS:     gWaypointDB     -- waypoint DB reference
00322  *
00323  * PARAMETERS:  Note: The function's prototype is defined by PalmOS
00324  *                    (TableDrawItemFuncType).
00325  *
00326  * RETURNED:    -
00327  ****************************************************************************/
00328 static void TableDrawPosnCell(void *tblP, Int16 row, Int16 column,
00329                    RectangleType *bounds)
00330 {
00331   Char                  lat_str[20];            /* latitude string buffer */
00332   Char                  lon_str[20];            /* longitude string buffer */
00333   MemHandle             waypointDBEntry;        /* record handle */
00334   UInt16                rec;                    /* record index */
00335   waypoint_t            waypoint;               /* unpacked waypoint */
00336   packed_waypoint_t     *packed_waypoint;       /* packed waypoint (ptr) */
00337   double                lat;                    /* latitude */
00338   double                lon;                    /* longitude */
00339   Int32                 err;                    /* error code */
00340   Int32                 zone;                   /* UTM Zone */
00341   char                  hemisphere;             /* 'N' / 'S' */
00342   double                easting;                /* Easting in m */
00343   double                northing;               /* Northing in m */
00344   Int16                 cell_width;             /* table cell width in pixels */
00345   Int16                 length;                 /* string length */
00346   Int16                 offset = 0;             /* string alignment offset */
00347   Boolean               fits;                   /* flag: string fits in cell */
00348 
00349   /* get record index from row data */
00350   rec = (UInt16)TblGetRowData(tblP, row);
00351   
00352   if (column == 1) {
00353     /* erase table cell */
00354     WinEraseRectangle(bounds, 0);
00355     
00356     /* get record */
00357     waypointDBEntry = DmQueryRecord(gWaypointDB, rec);
00358     
00359     /* unpack record */
00360     packed_waypoint = (packed_waypoint_t *)MemHandleLock(waypointDBEntry);
00361     UnpackWaypoint(&waypoint, packed_waypoint);
00362     
00363     /* convert semicircles to floating point */
00364     lat = semi2deg(waypoint.posn.lat);
00365     lon = semi2deg(waypoint.posn.lon);
00366 
00367     /* unlock record */
00368     MemHandleUnlock(waypointDBEntry);
00369 
00370     /*
00371      * Convert latitude from floating pont to string
00372      * (depending on selected position unit from preferences)
00373      */
00374     switch (gPrefs.units.pos_unit) {
00375       case POS_D:
00376         /* align numbers */
00377         offset = (lat < 0) ? 0 : FntCharWidth('-');
00378 
00379         deg_to_d_str(lat, lon, lat_str, lon_str);
00380         break;
00381         
00382       case POS_DM:
00383         /* align numbers */
00384         offset = (lat < 0) ? 0 : FntCharWidth('-');
00385         
00386         deg_to_dm_str(lat, lon, lat_str, lon_str);
00387         break;
00388         
00389       case POS_DMS:
00390         /* align numbers */
00391         offset = (lat < 0) ? 0 : FntCharWidth('-');
00392         
00393         deg_to_dms_str(lat, lon, lat_str, lon_str);
00394         break;
00395       
00396       case POS_UTM:
00397         err = Convert_Geodetic_To_UTM (
00398                         (double)(lat/180.0 * M_PI) /* Latitude (rad) */,
00399                         (double)(lon/180.0 * M_PI) /* Longitude (rad) */,
00400                         &zone /* long  *Zone */,
00401                         &hemisphere /* Hemisphere */,
00402                         &easting /* *Easting */,
00403                         &northing /* *Northing */);
00404 
00405         if (!err) {
00406           /* print zone and belt to string */
00407           StrPrintF(lat_str, "%ld%c ", zone, Lat_To_UTM_Belt(lat));
00408         
00409           /* print easting to string */
00410           format_number(easting, 1, &lat_str[StrLen(lat_str)]);
00411         }
00412         break;
00413     }
00414 
00415     /* table cell width in pixels */
00416     cell_width = bounds->extent.x - offset;
00417 
00418     /* truncate string to fit in cell */
00419     length = StrLen(lat_str);
00420     FntCharsInWidth(lat_str, &cell_width, &length, &fits);
00421     
00422     /* print to table cell */
00423     WinDrawChars(lat_str, length,
00424       bounds->topLeft.x + offset + 1, bounds->topLeft.y);
00425   }
00426   
00427   if (column == 2) {
00428     /* erase table cell */
00429     WinEraseRectangle(bounds, 0);
00430     
00431     /* get record */
00432     waypointDBEntry = DmQueryRecord(gWaypointDB, rec);
00433     
00434     /* unpack record */
00435     packed_waypoint = (packed_waypoint_t *)MemHandleLock(waypointDBEntry);
00436     UnpackWaypoint(&waypoint, packed_waypoint);
00437     
00438     /* convert semicircles to floating point */
00439     lat = semi2deg(waypoint.posn.lat);
00440     lon = semi2deg(waypoint.posn.lon);
00441 
00442     /* unlock record */
00443     MemHandleUnlock(waypointDBEntry);
00444 
00445     /*
00446      * Convert longitude from floating pont to string
00447      * (depending on selected position unit from preferences)
00448      */
00449     switch (gPrefs.units.pos_unit) {
00450       case POS_D:
00451         /* align numbers */
00452         offset = (lon < 0) ? 0 : FntCharWidth('-');
00453 
00454         deg_to_d_str(lat, lon, lat_str, lon_str);
00455         break;
00456         
00457       case POS_DM:
00458         /* align numbers */
00459         offset = (lon < 0) ? 0 : FntCharWidth('-');
00460         
00461         deg_to_dm_str(lat, lon, lat_str, lon_str);
00462         break;
00463         
00464       case POS_DMS:
00465         /* align numbers */
00466         offset = (lon < 0) ? 0 : FntCharWidth('-');
00467         
00468         deg_to_dms_str(lat, lon, lat_str, lon_str);
00469         break;
00470       
00471       case POS_UTM:
00472         err = Convert_Geodetic_To_UTM (
00473                         deg2rad(lat) /* Latitude (rad) */,
00474                         deg2rad(lon) /* Longitude (rad) */,
00475                         &zone /* long  *Zone */,
00476                         &hemisphere /* Hemisphere */,
00477                         &easting /* *Easting */,
00478                         &northing /* *Northing */);
00479         
00480         /* print northing to string */
00481         if (!err) {
00482           StrCopy(lon_str, "  ");
00483           format_number(northing, 1, &lon_str[2]);
00484         }
00485         break;
00486     }
00487     
00488     /* table cell width in pixels */
00489     cell_width = bounds->extent.x - offset;
00490 
00491     /* truncate string to fit in cell */
00492     length = StrLen(lon_str);
00493     FntCharsInWidth(lon_str, &cell_width, &length, &fits);
00494     
00495     /* print to table cell */
00496     WinDrawChars(lon_str, length,
00497       bounds->topLeft.x + offset + 1, bounds->topLeft.y);
00498   }
00499 }
00500 
00501 
00502 /****************************************************************************/
00503 /**
00504  * \brief       Waypoint table drawing function
00505  *
00506  *****************************************************************************/
00507 void wayptDrawTable(void)
00508 {
00509   TablePtr              tblP;                   /* table ptr */
00510   FormPtr               frmP;                   /* form ptr */
00511   ScrollBarPtr          sclP;                   /* scrollbar ptr */
00512   ListPtr               lstP;                   /* list ptr */
00513   UInt16                top;                    /* table row counter */
00514   UInt16                row;                    /* table row counter */
00515   UInt16                rec;                    /* record nr */
00516   UInt16                max_rows;               /* total nr. of waypoints */
00517   UInt16                numRows;                /* number of visible rows */
00518   MemHandle             waypointDBEntry;        /* record handle */
00519   waypoint_t            waypoint;               /* unpacked waypoint */
00520   packed_waypoint_t     *packed_waypoint;       /* packed waypoint (ptr) */
00521   Char                  tmp[20];                /* string buffer */
00522   UInt16                smbl;                   /* waypoint symbol ID */
00523   MemHandle             resH;                   /* resource handle */
00524   BitmapType            *bmpP;                  /* bitmap ptr */
00525   RectangleType         rect;                   /* rectangle */
00526   
00527   frmP = FrmGetActiveForm();
00528   tblP = GetObjectFromForm(frmP, WaypointTable);
00529   lstP = GetObjectFromForm(frmP, WaypointDispList);
00530   top = gWayptTopRow;
00531   
00532   max_rows = DmNumRecordsInCategory(gWaypointDB, dmAllCategories);
00533 
00534   /* number of visible rows */
00535   numRows = TblGetNumberOfRows(tblP);
00536 
00537   /* set columns usable */
00538   TblSetColumnUsable(tblP, 0, true);
00539   TblSetColumnUsable(tblP, 1, true);
00540   TblSetColumnUsable(tblP, 2, true);
00541   
00542   rec = 0;
00543   
00544   /* seek to record at top of the table */
00545   DmSeekRecordInCategory(gWaypointDB, &rec /* index */, top /* offset */,
00546     dmSeekForward, dmAllCategories);
00547   
00548   /* set row data to Waypoint DB entries (unique waypoint IDs) */
00549   for (row = 0; row < numRows; row++) {
00550     if (row + top < max_rows) {
00551       /* get next record */
00552       waypointDBEntry = DmQueryNextInCategory(gWaypointDB, &rec, 
00553         dmAllCategories);
00554       
00555       /* set row data to record number */
00556       TblSetRowData(tblP, row, (UInt32)(rec++));
00557     }
00558   }
00559 
00560   top = gWayptTopRow;
00561   
00562   for (row = 0; row < numRows; row++, top++) {
00563     
00564     if (top < max_rows) {
00565       /* set all rows selectable */
00566       TblSetRowSelectable(tblP, row, true);
00567       
00568       /* set columns to custom style, set custom cell drawing functions */
00569       TblSetItemStyle(tblP, row, 0, customTableItem);  
00570       TblSetCustomDrawProcedure(tblP, 0, TableDrawIdentCell);
00571       TblSetItemStyle(tblP, row, 1, customTableItem);    
00572       TblSetCustomDrawProcedure(tblP, 1, TableDrawPosnCell);
00573       TblSetItemStyle(tblP, row, 2, customTableItem);    
00574       TblSetCustomDrawProcedure(tblP, 2, TableDrawPosnCell);
00575       
00576       /* mark row as usable */
00577       TblSetRowUsable(tblP, row, true);
00578       
00579       /* mark all rows as invalid to trigger table update by FrmDrawForm() */
00580       TblMarkRowInvalid(tblP, row);
00581     } else {
00582       /* rows empty, mark as not usable */
00583       TblSetRowUsable(tblP, row, false);
00584     }
00585   }
00586 
00587   sclP = GetObjectFromForm(frmP, WaypointScrl);
00588 
00589   /* set scrollbar: value, min, max, pagesize */
00590   if (max_rows <= numRows) {
00591     SclSetScrollBar(sclP, 0, 0, 0, numRows);
00592   } else {
00593     SclSetScrollBar(sclP, gWayptTopRow, 0, max_rows - numRows, numRows);
00594   }
00595   
00596   top = gWayptTopRow;
00597   
00598   /*
00599    * Selected waypoint scolled below visible table rows,
00600    *   selection is switched to last visible entry.
00601    */
00602   if ( gWayptSel > (gWayptTopRow + numRows - 1) ) {
00603     gWayptSel = gWayptTopRow + numRows - 1;
00604   }
00605 
00606   /*
00607    * Selected waypoint scolled above visible table rows,
00608    *   selection is switched to first visible entry.
00609    */  
00610   if (gWayptSel < gWayptTopRow) {
00611     gWayptSel = gWayptTopRow;
00612   }
00613   
00614   if (max_rows == 0) {
00615     /* no data - clear fields */
00616     SetFieldText(WaypointCmntField, NULL, false, true);
00617     SetFieldText(WaypointProxField, NULL, false, true);    
00618     SetFieldText(WaypointDispField, NULL, false, true);
00619 
00620     /* clear waypoint */
00621     RctSetRectangle(&rect, WPT_X-1, WPT_Y-1, 16 /* w */, 14 /* h */);
00622     WinEraseRectangle(&rect, 0 /* cornerDiam */ );
00623   }
00624   
00625   for (row = 0; row < numRows; row++, top++) {
00626     if ((top < max_rows) && (top == gWayptSel)) {
00627       TblSelectItem(tblP, row, 0);
00628 
00629       /* Update additinal info for selected waypoint */
00630       /* get record, record# = row# */
00631       waypointDBEntry = DmQueryRecord(gWaypointDB, top);
00632 
00633       /* unpack waypoint */
00634       packed_waypoint = (packed_waypoint_t *)MemHandleLock(waypointDBEntry);
00635       UnpackWaypoint(&waypoint, packed_waypoint);
00636 
00637       /* set comment field */
00638       SetFieldTextFromStr((FieldPtr) GetObjectFromActiveForm(WaypointCmntField),
00639         (Char *)waypoint.cmnt, true);
00640 
00641       /* set proximity distance field */
00642       format_number(waypoint.dst, 0, tmp);
00643       SetFieldTextFromStr((FieldPtr) GetObjectFromActiveForm(WaypointProxField),
00644         tmp, true);
00645 
00646       /* set display mode field */
00647       SetFieldTextFromStr((FieldPtr) GetObjectFromActiveForm(WaypointDispField),
00648         LstGetSelectionText(lstP, waypoint.dspl), true);
00649 
00650       /* show waypoint symbol */
00651       /* correction for limited Resource ID range */
00652       smbl = (waypoint.smbl >= 16383) ? waypoint.smbl-16000 : waypoint.smbl;
00653       resH = DmGetResource('Tbmp', smbl);
00654 
00655       /* use default if symbol unavailable */
00656       if (!resH) {
00657         resH = DmGetResource('Tbmp', WayptDefBmp);
00658       }
00659 
00660       /* draw bitmap */
00661       if (resH) { 
00662         RctSetRectangle(&rect, WPT_X-1, WPT_Y-1, 16 /* w */, 14 /* h */);
00663         WinEraseRectangle(&rect, 0 /* cornerDiam */ );
00664         bmpP = MemHandleLock(resH);
00665         WinDrawBitmap(bmpP, WPT_X, WPT_Y);
00666         MemHandleUnlock(resH);
00667         DmReleaseResource(resH);
00668       }
00669 
00670       /* unlock record */
00671       MemHandleUnlock(waypointDBEntry);
00672       
00673       break;
00674     }
00675   }
00676 
00677   FrmDrawForm(frmP);
00678 }
00679 
00680 
00681 /****************************************************************************/
00682 /**
00683  * \brief       Terminate Garmin mode, close host port and open GPS port.
00684  *
00685  * \note        This function could actually be called
00686  *              from WaypointFormHandleEvent() upon reception of a
00687  *              frmCloseEvent. Unfortunately, when a Bluetooth GPS device
00688  *              is used and SrmOpen/SrmExtOpen opens the connection progress
00689  *              window, the frmOpenEvent queued by calling FrmGotoForm()
00690  *              previously seems to have been lost.
00691  *              As a (rather awkward) workaround, we have to call
00692  *              ChangePorts() _before_ FrmGotoForm() (scattered throughout
00693  *              WaypointFormHandleEvent()).
00694  *
00695  ****************************************************************************/
00696 static void ChangePorts(void)
00697 {
00698   Err           err;            /* error code */
00699 
00700   /* Terminate Garmin mode and close serial port */
00701   GPSEndOfOperation();
00702 
00703   /*
00704    * open GPS port
00705    *
00706    * Note:      At this stage we have to cut corners. Even if the
00707    *            NewSerialManager is installed, we do not open the
00708    *            PortForm again to let the user select the connection
00709    *            profile. The error checking is also slightly simplified
00710    *          (because we have already checked that the serial port
00711    *          is available).
00712    */
00713   if (gNewSerialManager) {
00714 
00715     if (gSerialPort == sysFileCVirtRfComm) {
00716       /*
00717        * Bluetooth Virtual Serial Port --
00718        * Connect to known device (address)
00719        */
00720       err = BluetoothOpen(gSerialPort, gPrefs.serprefs.gps_baud,
00721         gPrefs.serprefs.gps_btaddr, &gPortID);
00722 
00723     } else {
00724       /* open non-BT serial port */
00725       err = SrmOpen(gSerialPort, gPrefs.serprefs.gps_baud, &gPortID);
00726     }
00727   } else {
00728     err = SerOpen(gPortID, 0, kBaudRate);
00729   }
00730 
00731   if (err) {
00732     EventType           event;                  /* event to queue */
00733 
00734     FrmAlert(CantOpenSerialAlert);
00735     event.eType = appStopEvent;
00736     EvtAddEventToQueue(&event);
00737   }
00738 }
00739 
00740 
00741 /****************************************************************************/
00742 /**
00743  * \brief       Waypoint Form event handler
00744  *
00745  * \param       eventP          pointer to event structure
00746  *
00747  * \return      Status flag: event handled
00748  ****************************************************************************/
00749 Boolean WaypointFormHandleEvent(EventPtr eventP)
00750 {
00751   Boolean               handled = false;        /* event handled flag */
00752   Err                   err;                    /* error */
00753   Char                  tmp[20];                /* string buffer */
00754   FormPtr               frmP;                   /* form ptr */
00755   FieldPtr              fldP;                   /* field ptr */
00756   TablePtr              tblP;                   /* table ptr */
00757   ListPtr               lstP;                   /* list ptr */
00758   UInt16                rec;                    /* record index */
00759   MemHandle             waypointDBEntry;        /* waypoint record handle */
00760   waypoint_t            waypoint;               /* unpacked waypoint */
00761   packed_waypoint_t     *packed_waypoint;       /* packed waypoint (ptr) */
00762   UInt16                smbl;                   /* waypoint symbol ID */
00763   MemHandle             resH;                   /* resource handle */
00764   BitmapType            *bmpP;                  /* bitmap ptr */
00765   RectangleType         rect;                   /* rectangle */
00766   UInt16                nr_waypoints;           /* number of waypoints */
00767   G_byte                rte_nmbr;               /* 1st route where wpt found */
00768 
00769   frmP = FrmGetActiveForm();
00770   tblP = GetObjectFromForm(frmP, WaypointTable);
00771 
00772   /* Number of Waypoints/Routes (could have been modified by download) */
00773   nr_waypoints = DmNumRecordsInCategory(gWaypointDB, dmAllCategories);
00774   
00775   switch (eventP->eType) {
00776   case frmOpenEvent:
00777     fldP = (FieldPtr)GetObjectFromActiveForm(WaypointGpslibField);
00778     
00779     /* close serial port - Garmin uses 9600 baud */
00780     DoClose(gPortID);
00781     
00782     /* configure GPS4Palm to emulate Garmin III */
00783     GarminSetHostMode(fldP, GIII /* EmulatedGPS */);
00784     
00785     /* receive waypoints from host */
00786     GarminGetWpts(store_wpt, fldP);
00787     
00788     /* receive routes from host */
00789     GarminGetRtes(store_rte, fldP);
00790     
00791     /* receive tracks from host */
00792     GarminGetTrks(store_trk, fldP);
00793     
00794     frmP = FrmGetActiveForm();
00795     WaypointFormInit(frmP);
00796     FrmDrawForm(frmP);
00797         
00798     /* draw the table */
00799     wayptDrawTable();
00800 
00801     handled = true;
00802     break;
00803 
00804   case nilEvent:
00805     GpslibTicks();
00806     handled = true;
00807     break;
00808 
00809   case TransferWptReqEvent:
00810     /* gpslib - request to transfer waypoints */
00811     fldP = (FieldPtr)GetObjectFromActiveForm(WaypointGpslibField);
00812     GarminPutWpts(get_next_wpt, fldP, nr_waypoints);
00813     handled = true;
00814     break;
00815   
00816   case TransferRteReqEvent:
00817     /* gpslib - request to transfer routes */
00818     fldP = (FieldPtr)GetObjectFromActiveForm(WaypointGpslibField);
00819     GarminPutRtes(get_next_rte, fldP, NumRtePackets());
00820     handled = true;
00821     break;
00822   
00823   case TransferTrkReqEvent:
00824     /* gpslib - request to transfer tracks */
00825     fldP = (FieldPtr)GetObjectFromActiveForm(WaypointGpslibField);
00826     GarminPutTrks(get_next_trk, fldP, NumTrkPackets());
00827     handled = true;
00828     break;
00829         
00830   case menuEvent:
00831     switch (eventP->data.menu.itemID) {
00832 
00833       case PositionMenu:
00834         ChangePorts();
00835         FrmGotoForm(GPSMainForm);
00836         handled = true;
00837         break;
00838 
00839       case SkyviewMenu:
00840         ChangePorts();
00841         FrmGotoForm(SkyviewForm);
00842         handled = true;
00843         break;
00844 
00845       case NavigationMenu:
00846         ChangePorts();
00847         FrmGotoForm(NavigationForm);
00848         handled = true;
00849         break;
00850 
00851       case MapMenu:
00852         ChangePorts();
00853         FrmGotoForm(MapForm);
00854         handled = true;
00855         break;
00856 
00857       case MiscOptsMenu:
00858         ChangePorts();
00859         FrmGotoForm(MapOptsForm);
00860         handled = true;
00861         FrmGotoForm(MiscOptsForm);
00862         handled = true;
00863         break;
00864 
00865       case MapOptsMenu:
00866         ChangePorts();
00867         FrmGotoForm(MapOptsForm);
00868         handled = true;
00869         break;
00870 
00871       case PortsMenu:
00872         if (gNewSerialManager) {
00873           ChangePorts();
00874           FrmGotoForm(GPSPortForm);
00875         }
00876         handled = true;
00877         break;
00878 
00879       case RouteMenu:
00880         ChangePorts();
00881         FrmGotoForm(RouteForm);
00882         handled = true;
00883         break;
00884 
00885       case TrackMenu:
00886         ChangePorts();
00887         FrmGotoForm(TrackForm);
00888         handled = true;
00889         break;
00890 
00891       case AboutMenu:
00892         ChangePorts();
00893         FrmGotoForm(AboutForm);
00894         handled = true;
00895         break;
00896 
00897     }
00898     break;  
00899 
00900   case tblSelectEvent:
00901     gWayptSel = eventP->data.tblSelect.row + gWayptTopRow;
00902     
00903     /* always select column 0 */
00904     if (eventP->data.tblSelect.column != 0) {
00905       TblSelectItem(tblP, eventP->data.tblSelect.row, 0);
00906     }
00907 
00908     /* get record index from row data */
00909     rec = (UInt16)TblGetRowData(tblP, gWayptSel - gWayptTopRow);
00910 
00911     /* get record */
00912     waypointDBEntry = DmQueryRecord(gWaypointDB, rec);
00913 
00914     /* unpack waypoint */
00915     packed_waypoint = (packed_waypoint_t *)MemHandleLock(waypointDBEntry);
00916     UnpackWaypoint(&waypoint, packed_waypoint);
00917 
00918     /* set comment field */
00919     SetFieldTextFromStr((FieldPtr) GetObjectFromActiveForm(WaypointCmntField), 
00920       (Char *)waypoint.cmnt, true);
00921 
00922     /* set proximity distance field */
00923     format_number(waypoint.dst, 0, tmp);
00924     SetFieldTextFromStr((FieldPtr) GetObjectFromActiveForm(WaypointProxField), 
00925       tmp, true);
00926 
00927     /* set display mode field */
00928     lstP = GetObjectFromActiveForm(WaypointDispList);
00929     SetFieldTextFromStr((FieldPtr) GetObjectFromActiveForm(WaypointDispField), 
00930       LstGetSelectionText(lstP, waypoint.dspl), true);
00931     
00932     /* show waypoint symbol */
00933     /* correction for limited Resource ID range */
00934     smbl = (waypoint.smbl >= 16383) ? waypoint.smbl-16000 : waypoint.smbl;
00935     resH = DmGetResource('Tbmp', smbl);
00936     
00937     /* use default if symbol unavailable */
00938     if (!resH) {
00939       resH = DmGetResource('Tbmp', WayptDefBmp);
00940     }
00941     
00942     /* draw bitmap */
00943     if (resH) { 
00944       RctSetRectangle(&rect, WPT_X-1, WPT_Y-1, 16 /* w */, 14 /* h */);
00945       WinEraseRectangle(&rect, 0 /* cornerDiam */ );
00946       bmpP = MemHandleLock(resH);
00947       WinDrawBitmap(bmpP, WPT_X, WPT_Y);
00948       MemHandleUnlock(resH);
00949       DmReleaseResource(resH);
00950     }
00951     
00952     /* unlock record */
00953     MemHandleUnlock(waypointDBEntry);
00954     
00955     handled = true;
00956     break;
00957   
00958   case sclRepeatEvent:
00959     /* handle scrollbar */
00960     Doscroll(WaypointTable, WaypointScrl, nr_waypoints, &gWayptTopRow);
00961     wayptDrawTable();
00962     /* Note: scrollbar needs to handle the event, too */
00963     handled = false;
00964     break;
00965   
00966   case keyDownEvent:
00967     switch (eventP->data.keyDown.chr) {
00968     
00969     case pageUpChr:
00970     case pageDownChr:
00971       Dopage(WaypointTable, (eventP->data.keyDown.chr == pageDownChr),
00972         nr_waypoints, &gWayptTopRow);
00973       wayptDrawTable();
00974       /* Note: scrollbar needs to handle the event, too */
00975       handled = false;
00976       break;
00977     }
00978     break;
00979   
00980   case ctlSelectEvent:
00981     switch (eventP->data.ctlSelect.controlID) {
00982 
00983       case WaypointDeleteButton:
00984         if (nr_waypoints == 0)
00985           break;
00986 
00987         /* get record index from row data */
00988         rec = (UInt16)TblGetRowData(tblP, gWayptSel - gWayptTopRow);
00989 
00990         if ( QueryRouteWaypoint(rec, &rte_nmbr) ) {
00991           StrIToA(tmp, rte_nmbr);
00992           FrmCustomAlert(WaypointDelErrorAlert, tmp, "", ""); 
00993           break;
00994         }
00995 
00996         if ( FrmAlert(WaypointDelConfirmAlert) == 0 ) {
00997           
00998           /*
00999            * Only data base backup, no synchronizing available.
01000            * This means a record can simply be deleted.
01001            */
01002           DmRemoveRecord(gWaypointDB, rec);
01003 
01004           /* update number of records */
01005           nr_waypoints = DmNumRecordsInCategory(gWaypointDB, dmAllCategories);
01006           
01007           /* redraw the table */
01008           gWayptTopRow = 0;
01009           gWayptSel = 0;
01010           wayptDrawTable();
01011         }
01012         handled = true;
01013         break;
01014     
01015       case WaypointNewButton:
01016         /* create new waypoint */
01017         ChangePorts();
01018         FrmGotoForm(WayptEditForm);
01019         gSelWaypoint.valid = false;
01020         handled = true;
01021         break;
01022 
01023       case WaypointCopyButton:
01024         /* create new waypoint starting from existing one */
01025         if (nr_waypoints == 0)
01026           break;
01027 
01028         /* get record index from row data */
01029         rec = (UInt16)TblGetRowData(tblP, gWayptSel - gWayptTopRow);
01030         
01031         /* get unique waypoint ID */
01032         err = DmRecordInfo(gWaypointDB, rec, NULL /* *attrP */,
01033           &gSelWaypoint.waypointID /* *uniqueIDP */, NULL /* *chunkIDP */);
01034         
01035         /* mark selected waypoint as valid/invalid */
01036         gSelWaypoint.valid = (err == errNone) ? true : false;
01037 
01038         ChangePorts();
01039         FrmGotoForm(WayptEditForm);
01040         handled = true;
01041         break;
01042       
01043       case WaypointGotoButton:
01044         if (nr_waypoints == 0)
01045           break;
01046 
01047         /* get record index from row data */
01048         rec = (UInt16)TblGetRowData(tblP, gWayptSel - gWayptTopRow);
01049         
01050         /* get unique waypoint ID */
01051         err = DmRecordInfo(gWaypointDB, rec, NULL /* *attrP */,
01052           &gPrefs.act_wpt.waypointID /* *uniqueIDP */, NULL /* *chunkIDP */);
01053         
01054         /* mark active waypoint as valid/invalid */
01055         gPrefs.act_wpt.valid = (err == errNone) ? true : false;
01056         
01057         /* mark active route as invalid */
01058         gPrefs.act_rte.valid = false;
01059         
01060         ChangePorts();
01061         FrmGotoForm(NavigationForm);
01062         handled = true;
01063         break;
01064     }
01065     break;
01066 
01067   case frmCloseEvent:    
01068     if (gPrefs.act_wpt.valid) {
01069       /* check if active waypoint still exists, mark as invalid if not */
01070       err = DmFindRecordByID(gWaypointDB, gPrefs.act_wpt.waypointID, &rec);
01071       gPrefs.act_wpt.valid = (err) ? false : true;
01072     }
01073     
01074     /* Deallocate Fields' Text Memory */
01075     SetFieldText(WaypointCmntField, NULL, false, true);
01076     SetFieldText(WaypointDispField, NULL, false, true);
01077     SetFieldText(WaypointProxField, NULL, false, true);
01078     SetFieldText(WaypointGpslibField, NULL, false, true);
01079 
01080     WaypointFormDeinit(FrmGetActiveForm());
01081     handled = false;
01082     break;
01083 
01084   default:
01085     break;
01086   }
01087   
01088   return handled;
01089 }

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