GPS4Palm

Source Code Documentation


TrackForm.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: TrackForm_8c-source.html,v $
00004  *
00005  * GPS4Palm Tracks 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:34 $
00016  *
00017  * $Revision: 1.5.2.1 $
00018  *
00019  * $Log: TrackForm_8c-source.html,v $
00019  * Revision 1.5.2.1  2007-10-08 20:40:34  mp
00019  * updated for gps4palm V0.9.5 beta
00019  *
00020  * Revision 1.13  2005-05-06 13:40:29  mp
00021  * added workaround for Bluetooth-Open Bug
00022  *
00023  * Revision 1.12  2005/01/30 21:22:13  mp
00024  * added PortsMenu event handling
00025  *
00026  * Revision 1.11  2005/01/23 10:01:32  mp
00027  * changed re-opening of GPS serial port after data transfer
00028  *
00029  * Revision 1.10  2004/12/18 16:11:58  mp
00030  * fixed serial port re-opening for PDAs with New Serial Manager
00031  *
00032  * Revision 1.9  2004/12/14 20:10:34  mp
00033  * fixed alert
00034  *
00035  * Revision 1.8  2004/12/10 19:54:45  mp
00036  * replaced DmGet1Resource by DmGetResource, implemented clipboard,
00037  * SysKeyboardDialog, and SysGraffitiReferenceDialog
00038  *
00039  * Revision 1.7  2004/12/09 17:29:25  mp
00040  * replaced default track comment and Start/Stop button labels by
00041  * string resources
00042  *
00043  * Revision 1.6  2004/12/08 20:47:45  mp
00044  * added track logging, fixed table display
00045  *
00046  * Revision 1.5  2004/12/07 17:20:50  mp
00047  * removed TrackSelectButton event handling,
00048  * modified TrackLogButton event handling (gTrackDB open/close,
00049  * Active Track selection)
00050  *
00051  * Revision 1.4  2004/12/06 21:12:57  mp
00052  * implemented display and editing of TrackIdentField
00053  *
00054  * Revision 1.3  2004/12/04 11:48:01  mp
00055  * modified TrackTable display and track deleting, added track transfer
00056  *
00057  * Revision 1.2  2004/12/02 23:22:48  mp
00058  * added track header adding/deletion and table handling
00059  *
00060  * Revision 1.1  2004/11/30 21:10:41  mp
00061  * initial version
00062  *
00063  *
00064  ****************************************************************************/
00065 
00066 #define DO_NOT_ALLOW_ACCESS_TO_INTERNALS_OF_STRUCTS
00067 #include <BuildDefines.h>
00068 #ifdef DEBUG_BUILD
00069 #define ERROR_CHECK_LEVEL ERROR_CHECK_FULL
00070 #endif
00071 #include <PalmOS.h>
00072 #include <SerialMgrOld.h>
00073 #include "ResourceDefines.h"
00074 #include "gpslib.h"
00075 #include "TrackForm.h"
00076 #include "Data.h"
00077 #include "DataExchange.h"
00078 #include "Utils.h"
00079 #include "Serial.h"
00080 #include "geo.h"
00081 #include "fp.h"
00082 #include "common.h"
00083 
00084 /* Global Variables */
00085 extern PrefsType        gPrefs;                 /* application preferences */
00086 extern UInt32           gSerialPort;            /* serial port name/no. */
00087 ActRouteType            gSelTrack;              /**< selected track */
00088 
00089 /* Local Variables */
00090 static UInt16           nr_waypoints;           /* number of waypoints */
00091 static UInt16           nr_routes;              /* number of routes */
00092 static UInt16           nr_tracks;              /* number of tracks */
00093 
00094 
00095 /* Static Functions */
00096 static void TrackFormInit(FormPtr frmP)                 TRACK_SECTION;
00097 static void TrackFormDeinit(FormPtr frmP)               TRACK_SECTION;
00098 static Err create_track(void)                           TRACK_SECTION;
00099 static void ChangePorts(void)                           TRACK_SECTION;
00100 
00101 
00102 /*****************************************************************************
00103  * FUNCTION:    TrackFormInit
00104  *
00105  * DESCRIPTION: Track Form Init Function
00106  *
00107  ****************************************************************************/
00108 static void TrackFormInit(FormPtr frmP)
00109 {
00110 #pragma unused(frmP)
00111   // warning-- don't do any drawing in this routine.
00112   // Also, don't call FrmSetFocus from here (it must be called *after*
00113   // FrmDrawForm)
00114   
00115 }
00116 
00117 
00118 /*****************************************************************************
00119  * FUNCTION:    TrackFormDeinit
00120  *
00121  * DESCRIPTION: Track Form De-Init Function
00122  *
00123  ****************************************************************************/
00124 static void TrackFormDeinit(FormPtr frmP)
00125 {
00126 #pragma unused(frmP)
00127 
00128 }
00129 
00130 
00131 /*****************************************************************************
00132  * FUNCTION:    TableDrawCommentCell
00133  *
00134  * DESCRIPTION: Custom table cell drawing function for Route Number
00135  *              (max. 3 digits) and Route Comment (string, max. 20
00136  *              characters). The DB record number is retrieved via
00137  *              TblGetRowData().
00138  *
00139  * GLOBALS:     gRouteDB        -- route DB reference
00140  *
00141  * PARAMETERS:  Note: The function's prototype is defined by PalmOS
00142  *                    (TableDrawItemFuncType).
00143  *
00144  * RETURNED:    -
00145  ****************************************************************************/
00146 static void TableDrawCell(void *tblP, Int16 row, Int16 column,
00147                    RectangleType *bounds)
00148 {
00149   Char                  str[51];                /* string buffer */
00150   MemHandle             trkhDBEntry;            /* record handle */
00151   UInt32                trackID;                /* track ID */ 
00152   UInt16                rec;                    /* record index */
00153   trk_header_t          *trkh;                  /* track header */
00154   Int16                 cell_width;             /* table cell width in pixels */
00155   Boolean               fits;                   /* string fits in table cell */
00156   Int16                 offset;                 /* offset within table cell */
00157   Int16                 length;                 /* string length */
00158   DmOpenRef             db_ref;                 /* data base reference */
00159   UInt16                nr_trackpoints;         /* number of track points */
00160   
00161   /* get record index from row data */
00162   rec = (UInt16)TblGetRowData(tblP, row);
00163   
00164   /* Display track identifier (truncated to fit) */
00165   if (column == 0) {
00166     WinEraseRectangle(bounds, 0);
00167     
00168     if (TblRowUsable(tblP, row)) {
00169       trkhDBEntry = DmQueryRecord(gTrackHdrDB, rec);
00170 
00171       /* get unique Track ID */
00172       DmRecordInfo(gTrackHdrDB, rec, NULL /* *attrP */,
00173         &trackID /* *uniqueIDP */, NULL /* *chunkIDP */);
00174 
00175       if (gPrefs.act_trk.valid && (trackID == gPrefs.act_trk.trackID)) {
00176         FntSetFont(boldFont);
00177       } else {
00178         FntSetFont(stdFont);
00179       }
00180 
00181       trkh = (trk_header_t *)MemHandleLock(trkhDBEntry);
00182       MemSet((Char *)str, sizeof(str), 0);
00183       StrCopy(str, (Char *)trkh->trk_ident);
00184       MemHandleUnlock(trkhDBEntry);
00185       
00186       /* truncate string to fit in table cell */
00187       length = StrLen(str);
00188       cell_width = bounds->extent.x;
00189       FntCharsInWidth(str, &cell_width, &length, &fits);
00190      
00191       /* display track identifier */
00192       WinDrawChars(str, length, bounds->topLeft.x + 1, bounds->topLeft.y);
00193       
00194     } /* (TblRowUsable(tblP, row)) */
00195   } /* if (column == 0) */
00196   
00197   /* Display number of track points (right aligned, bold) */
00198   if (column == 1) {
00199     WinEraseRectangle(bounds, 0);
00200     
00201     /*
00202      * Set font to bold, because route items column (which is numeric, too)
00203      * uses it due to ItemStyle numericTableItem.
00204      */
00205     FntSetFont(boldFont);
00206 
00207     if (TblRowUsable(tblP, row)) {
00208       trkhDBEntry = DmQueryRecord(gTrackHdrDB, rec);
00209 
00210       /* get unique Track ID */
00211       DmRecordInfo(gTrackHdrDB, rec, NULL /* *attrP */,
00212         &trackID /* *uniqueIDP */, NULL /* *chunkIDP */);      
00213 
00214       /* create track data base name */
00215       TrackDBName(str, trackID);
00216 
00217       /* open track point data base */
00218       db_ref = DmOpenDatabase(0 /* cardNo */,
00219         DmFindDatabase(0 /* cardNo */, str), dmModeReadOnly);
00220       
00221       if (db_ref) {
00222         /* open succeeded, get number of track points */
00223         nr_trackpoints = DmNumRecordsInCategory(db_ref, dmAllCategories);
00224         
00225         /* close DB */
00226         DmCloseDatabase(db_ref);
00227         
00228         /* print number of track points to string */
00229         StrPrintF(str, "%u", nr_trackpoints);
00230         
00231         /* calculate offset to right-align number */
00232         length = StrLen(str);
00233         cell_width = bounds->extent.x;
00234         offset = cell_width - FntCharsWidth(str, length);
00235         
00236         /* display no. of track points, aligned right */
00237         WinDrawChars(str, length,
00238           bounds->topLeft.x + offset, bounds->topLeft.y);
00239       } /* if (db_ref) */
00240       
00241     } /* if (TblRowUsable(tblP, row)) */
00242   } /* if (column == 1) */
00243 }
00244 
00245 
00246 /****************************************************************************/
00247 /**
00248  * \brief       Tracks table drawing function
00249  *              TBD: adapt template from RouteForm for tracks
00250  *
00251  * \param       top             top table row
00252  * \param       sel             pointer to selected table row
00253  *
00254  *****************************************************************************/
00255 void trackDrawTable(Int32 top, UInt16 *sel)
00256 {
00257   TablePtr              tblP;                   /* table ptr */
00258   FormPtr               frmP;                   /* form ptr */
00259   ScrollBarPtr          sclP;                   /* scrollbar ptr */
00260   UInt16                row;                    /* table row counter */
00261   UInt16                rec;                    /* record nr */
00262   UInt16                max_rows;               /* total nr. of routes */
00263   UInt16                numRows;                /* number of visible rows */
00264   MemHandle             trkhDBEntry;            /* record handle */
00265   trk_header_t          *trkh;                  /* track header */
00266   Err                   err;                    /* error code */
00267   
00268   frmP = FrmGetActiveForm();
00269   tblP = (TablePtr)GetObjectFromForm(frmP, TrackTable);
00270   sclP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, TrackScrl));
00271   
00272   /* total number of routes */
00273   max_rows = DmNumRecordsInCategory(gTrackHdrDB, dmAllCategories);
00274   
00275   /* number of visible rows */
00276   numRows = TblGetNumberOfRows(tblP);
00277 
00278   /* set columns usable */
00279   TblSetColumnUsable(tblP, 0, true);
00280   TblSetColumnUsable(tblP, 1, true);
00281       
00282   /* set row data to Track Header DB entries (record index) */
00283   for (row = 0; row < numRows; row++) {
00284 
00285     /* default: mark row as not usable (empty or no valid record) */
00286     TblSetRowUsable(tblP, row, true);
00287 
00288     if (row + top < max_rows) {
00289       /* seek from beginning of database */
00290       rec = 0;
00291       
00292       /* get next record */
00293       err = DmSeekRecordInCategory(gTrackHdrDB, &rec /* index */,
00294         top + row /* offset */, dmSeekForward, dmAllCategories);
00295       
00296       if (err == errNone) {
00297         /* query record */
00298         trkhDBEntry = DmQueryRecord(gTrackHdrDB, rec);
00299 
00300         if (trkhDBEntry) {
00301           /*
00302            * Record is valid, set row data to index and
00303            * mark table row as usable.
00304            */
00305           TblSetRowData(tblP, row, rec);
00306           TblSetRowUsable(tblP, row, true);
00307         }
00308       }
00309     } /*  if (row + top < max_rows) */
00310   } /* for (row = 0; row < numRows; row++) */  
00311   
00312   /* initialize table */
00313   for (row = 0; row < numRows; row++) {
00314     
00315     if (row + top < max_rows) {
00316       /* set all rows selectable */
00317       TblSetRowSelectable(tblP, row, true);
00318 
00319       /* get record index from row data */
00320       rec = TblGetRowData(tblP, row);
00321       
00322       /* track identifier */
00323       TblSetItemStyle(tblP, row, 0, customTableItem);    
00324       TblSetCustomDrawProcedure(tblP, 0, TableDrawCell);
00325 
00326       /* number of track points */
00327       /*
00328        * Note:  ItemStyle customTableItem is used instead of
00329        *        numericTableItem, because otherwise
00330        *        TblSelectItem() does not work properly.
00331        */      
00332       TblSetItemStyle(tblP, row, 1, customTableItem);    
00333       TblSetCustomDrawProcedure(tblP, 1, TableDrawCell);
00334       
00335       /* mark row as usable */
00336       TblSetRowUsable(tblP, row, true);
00337       
00338       /* mark all rows as invalid to trigger table update by FrmDrawForm() */
00339       TblMarkRowInvalid(tblP, row);
00340     } else {
00341       /* rows empty, mark as not usable */
00342       TblSetRowUsable(tblP, row, false);
00343     }
00344   }
00345   
00346   /* set scrollbar: value, min, max, pagesize */
00347   if (max_rows <= numRows) {
00348     SclSetScrollBar(sclP, 0, 0, 0, numRows);
00349   } else {
00350     SclSetScrollBar(sclP, top, 0, max_rows - numRows, numRows);
00351   }
00352 
00353   /*
00354    * Selected route scolled below visible table rows,
00355    *   selection is switched to last visible entry.
00356    */
00357   if ( *sel > (top + numRows - 1) ) {
00358     *sel = top + numRows - 1;
00359   }
00360 
00361   /*
00362    * Selected route scolled above visible table rows,
00363    *   selection is switched to first visible entry.
00364    */  
00365   if (*sel < top) {
00366     *sel = top;
00367   }
00368 
00369   for (row = 0; row < numRows; row++, top++) {
00370     if ((top < max_rows) && (top == *sel)) {
00371       TblSelectItem(tblP, row, 0);
00372       break;
00373     }
00374   }
00375 
00376   /* get record handle of selected track */
00377   trkhDBEntry = DmQueryRecord(gTrackHdrDB, *sel);
00378 
00379   if (trkhDBEntry) {
00380     /* show track identifier */
00381     trkh = (trk_header_t *)MemHandleLock(trkhDBEntry);
00382     SetFieldText(TrackIdentField, trkh->trk_ident, false, true);
00383     MemHandleUnlock(trkhDBEntry);
00384   }  
00385 
00386   FrmDrawForm(frmP);
00387 }
00388 
00389 
00390 /****************************************************************************/
00391 /**
00392  * \brief       Add new track to database
00393  *
00394  * GLOBALS:     gTrackHdrDB     -- Route Database Reference
00395  *
00396  *
00397  * \returned    false if Track Database full/max. number of entries reached
00398  ****************************************************************************/
00399 static
00400 Err create_track(void)
00401 {
00402   UInt16        index;                  /* record index */
00403   MemHandle     trkhDBEntry;            /* track header record handle */
00404   trk_header_t  trkhdr;                 /* track header record ptr */
00405   UInt32        trackID;                /* track ID */
00406   UInt32        seconds;                /* current time */
00407   DateTimeType  dt;                     /* date/time structure */
00408   Char          dbname[dmDBNameLength]; /* data base name */
00409   Err           err;                    /* error code */
00410   MemHandle     strH;                   /* string handle */ 
00411   MemPtr        strP;                   /* string ptr */
00412   
00413   /* Limit number of Tracks */
00414   if ( DmNumRecordsInCategory(gTrackHdrDB, dmAllCategories) == 0x100 )
00415     return 1;
00416   
00417   /* No particular order - add at the end of the database */
00418   index = dmMaxRecordIndex;
00419   
00420   trkhDBEntry = DmNewRecord(gTrackHdrDB, &index, sizeof(trk_header_t));
00421   
00422   if (!trkhDBEntry) {
00423     err = DmGetLastErr();
00424     
00425     if (err == memErrNotEnoughSpace) {
00426       /* Data Base is full */
00427       return err;
00428     } else {
00429       /* Some other error occurred - fatal! */
00430       Die("Cannot create track header record!");
00431       return err;
00432     }
00433   }
00434   
00435   /* release new record */
00436   DmReleaseRecord(gTrackHdrDB, index, false /* dirty */);
00437   
00438   /* set default display flag */
00439   trkhdr.dspl = true;
00440   
00441   /* set default color */
00442   trkhdr.color = Default_Color;
00443   
00444   /*
00445    * create comment: <Track yy-mm-dd hh:mm>
00446    */
00447   MemSet((Char *)trkhdr.trk_ident, sizeof(trkhdr.trk_ident), 0);
00448 
00449   /* get string from resource */
00450   strH = DmGetResource(strRsc, TrackStr);
00451   if (strH != NULL) {
00452     /* string handle valid, lock it */
00453     strP = MemHandleLock(strH);
00454   
00455     /* copy string */
00456     StrCopy(trkhdr.trk_ident, strP);
00457 
00458     /* unlock string handle */
00459     MemHandleUnlock(strH);
00460 
00461     /* release string resource */
00462     DmReleaseResource(strH);
00463   }
00464 
00465   
00466   /* get current time and date */
00467   seconds = TimGetSeconds();
00468   TimSecondsToDateTime(seconds, &dt);
00469   
00470   /* write date to string */
00471   DateToAscii(dt.month, dt.day, dt.year,
00472     dfYMDWithDashes,
00473     &trkhdr.trk_ident[StrLen(trkhdr.trk_ident)]);
00474 
00475   /* append space */
00476   StrCat(trkhdr.trk_ident, " ");
00477   
00478   /* write time to string */
00479   TimeToAscii(dt.hour, dt.minute,
00480     tfColon24h,
00481     &trkhdr.trk_ident[StrLen(trkhdr.trk_ident)]);
00482   
00483   /* append bracket */
00484   StrCat(trkhdr.trk_ident, ">");
00485   
00486   /* Store Route Header in Database */
00487   StoreTrkHdr(&trkhdr, index);    
00488 
00489   DmRecordInfo(gTrackHdrDB, index, NULL /* *attrP */,
00490     &trackID /* *uniqueIDP */, NULL /* *chunkIDP */);
00491 
00492   TrackDBName(dbname, trackID);
00493   
00494   err = DmCreateDatabase(0 /* cardNo */, dbname,
00495     kCreatorId /* creator */, kTrkDBType /* type */, false /* resDB */);
00496   
00497   if (err != errNone) {
00498     DmRemoveRecord(gTrackHdrDB, index);
00499     return err;
00500   }
00501   
00502   /* success */
00503   return 0;
00504 }
00505 
00506 
00507 /****************************************************************************/
00508 /**
00509  * \brief       Terminate Garmin mode, close host port and open GPS port.
00510  *
00511  * \note        This function could actually be called
00512  *              from TrackFormHandleEvent() upon reception of a
00513  *              frmCloseEvent. Unfortunately, when a Bluetooth GPS device
00514  *              is used and SrmOpen/SrmExtOpen opens the connection progress
00515  *              window, the frmOpenEvent queued by calling FrmGotoForm()
00516  *              previously seems to have been lost.
00517  *              As a (rather awkward) workaround, we have to call
00518  *              ChangePorts() _before_ FrmGotoForm() (scattered throughout
00519  *              TrackFormHandleEvent()).
00520  *
00521  ****************************************************************************/
00522 static void ChangePorts(void)
00523 {
00524   Err           err;            /* error code */
00525 
00526   /* Terminate Garmin mode and close serial port */
00527   GPSEndOfOperation();
00528 
00529   /*
00530    * open GPS port
00531    *
00532    * Note:      At this stage we have to cut corners. Even if the
00533    *            NewSerialManager is installed, we do not open the
00534    *            PortForm again to let the user select the connection
00535    *            profile. The error checking is also slightly simplified
00536    *          (because we have already checked that the serial port
00537    *          is available).
00538    */
00539   if (gNewSerialManager) {
00540 
00541     if (gSerialPort == sysFileCVirtRfComm) {
00542       /*
00543        * Bluetooth Virtual Serial Port --
00544        * Connect to known device (address)
00545        */
00546       err = BluetoothOpen(gSerialPort, gPrefs.serprefs.gps_baud,
00547         gPrefs.serprefs.gps_btaddr, &gPortID);
00548 
00549     } else {
00550       /* open non-BT serial port */
00551       err = SrmOpen(gSerialPort, gPrefs.serprefs.gps_baud, &gPortID);
00552     }
00553   } else {
00554     err = SerOpen(gPortID, 0, kBaudRate);
00555   }
00556 
00557   if (err) {
00558     EventType           event;                  /* event to queue */
00559 
00560     FrmAlert(CantOpenSerialAlert);
00561     event.eType = appStopEvent;
00562     EvtAddEventToQueue(&event);
00563   }
00564 }
00565 
00566 
00567 /****************************************************************************/
00568 /**
00569  * \brief       Track Form event handler
00570  *
00571  * \param       eventP          pointer to event structure
00572  *
00573  * \return      Status flag: event handled
00574  ****************************************************************************/
00575 Boolean TrackFormHandleEvent(EventPtr eventP)
00576 {
00577   Boolean               handled = false;        /* event handled flag */
00578   Err                   err;                    /* error */
00579   FormPtr               frmP;                   /* form ptr */
00580   FieldPtr              fldP;                   /* field ptr */
00581   TablePtr              tblP;                   /* table ptr */
00582   ScrollBarPtr          sclP;                   /* scrollbar ptr */
00583   Char                  *strP;                  /* string ptr */
00584   MemHandle             strH;                   /* string handle */ 
00585   FieldAttrType         fld_attr;               /* field attributes */
00586   MemHandle             trkhDBEntry;            /* record handle */
00587   trk_header_t          *trkh;                  /* track header ptr */
00588   trk_header_t          trkheader;              /* track header */
00589   Char                  dbname[dmDBNameLength]; /* data base name */
00590   UInt32                trackID;                /* track header record ID */
00591   UInt16                rec;                    /* record index */
00592   UInt16                len;                    /* string length */
00593   static Int32          track_top = 0;          /* track table top */
00594   static UInt16         track_sel = 0;          /* track selected row */
00595 
00596   frmP = FrmGetActiveForm();
00597   tblP = (TablePtr)GetObjectFromForm(frmP, TrackTable);
00598   fldP = (FieldPtr)GetObjectFromActiveForm(TrackIdentField);
00599 
00600   /* copy Track Identifier to Track Header record if modified */
00601   if ( FldDirty(fldP) ) {
00602     strP = FldGetTextPtr(fldP);
00603     len = StrLen(strP);
00604     
00605     /* get record handle of selected track */
00606     trkhDBEntry = DmQueryRecord(gTrackHdrDB, track_sel);
00607 
00608     if (trkhDBEntry) {
00609       /* copy other struct members */
00610       trkh = (trk_header_t *)MemHandleLock(trkhDBEntry);
00611       trkheader.dspl  = trkh->dspl;
00612       trkheader.color = trkh->color;
00613       MemSet((Char *)trkheader.trk_ident, 50, 0);
00614       MemHandleUnlock(trkhDBEntry);
00615     
00616       /* copy modified string */
00617       StrNCopy(trkheader.trk_ident, strP, (len > 49) ? 49 : len);
00618 
00619       /* update track header record in data base */
00620       StoreTrkHdr(&trkheader, track_sel);
00621 
00622       /* update table row */
00623       TblMarkRowInvalid(tblP, track_sel - track_top);
00624       FrmDrawForm(frmP);
00625 
00626       /* clear dirty flag */
00627       FldSetDirty(fldP, false);   
00628     } /* if (trkhDBEntry) */
00629   } /* if ( FldDirty(fldP) ) */
00630 
00631 
00632   /* Number of Waypoints/Routes/Tracks (could have been modified by download) */
00633   nr_waypoints = DmNumRecordsInCategory(gWaypointDB, dmAllCategories);
00634   nr_routes    = DmNumRecordsInCategory(gRouteDB, dmAllCategories);
00635   nr_tracks    = DmNumRecordsInCategory(gTrackHdrDB, dmAllCategories);
00636   
00637   switch (eventP->eType) {
00638   case frmOpenEvent:
00639     fldP = (FieldPtr)GetObjectFromActiveForm(TrackGpslibField);
00640     
00641     /* close serial port - Garmin uses 9600 baud */
00642     DoClose(gPortID);
00643     
00644     /* configure GPS4Palm to emulate Garmin III */
00645     GarminSetHostMode(fldP, GIII /* EmulatedGPS */);
00646     
00647     /* receive waypoints from host */
00648     GarminGetWpts(store_wpt, fldP);
00649     
00650     /* receive routes from host */
00651     GarminGetRtes(store_rte, fldP);
00652 
00653     /* receive tracks from host */
00654     GarminGetTrks(store_trk, fldP);
00655     
00656     frmP = FrmGetActiveForm();
00657     TrackFormInit(frmP);
00658     
00659     /* get string from resource */
00660     strH = DmGetResource(strRsc,
00661       (gPrefs.act_trk.log_state) ? StopStr : StartStr);
00662     
00663     if (strH != NULL) {
00664       /* string handle valid, lock it */
00665       strP = (Char *)MemHandleLock(strH);
00666 
00667       /* Set Start/Stop button label from preferences */
00668       CtlSetLabel((ControlPtr)GetObjectFromActiveForm(TrackLogButton), strP);
00669 
00670       /* unlock string handle */
00671       MemHandleUnlock(strH);
00672 
00673       /* release string resource */
00674       DmReleaseResource(strH);
00675     }
00676 
00677     FrmDrawForm(frmP);
00678         
00679     /* draw the table */
00680     trackDrawTable(track_top, &track_sel);
00681         
00682     handled = true;
00683     break;
00684 
00685   case nilEvent:
00686     GpslibTicks();
00687     handled = true;
00688     break;
00689 
00690   case TransferWptReqEvent:
00691     /* gpslib - request to transfer waypoints to host*/
00692     fldP = (FieldPtr)GetObjectFromActiveForm(TrackGpslibField);
00693     GarminPutWpts(get_next_wpt, fldP, nr_waypoints);
00694     handled = true;
00695     break;
00696   
00697   case TransferRteReqEvent:
00698     /* gpslib - request to transfer routes to host */
00699     fldP = (FieldPtr)GetObjectFromActiveForm(TrackGpslibField);
00700     GarminPutRtes(get_next_rte, fldP, NumRtePackets());
00701     handled = true;
00702     break;
00703 
00704   case TransferTrkReqEvent:
00705     /* gpslib - request to transfer tracks */
00706     fldP = (FieldPtr)GetObjectFromActiveForm(TrackGpslibField);
00707     GarminPutTrks(get_next_trk, fldP, NumTrkPackets());
00708     handled = true;
00709     break;
00710     
00711   case menuEvent:
00712     /* check if TrackIdentField has focus */
00713     fldP = (FieldPtr)GetObjectFromActiveForm(TrackIdentField);
00714     FldGetAttributes(fldP, &fld_attr);
00715     
00716     switch (eventP->data.menu.itemID) {
00717 
00718       case PositionMenu:
00719         ChangePorts();
00720         FrmGotoForm(GPSMainForm);
00721         handled = true;
00722         break;
00723 
00724       case SkyviewMenu:
00725         ChangePorts();
00726         FrmGotoForm(SkyviewForm);
00727         handled = true;
00728         break;
00729 
00730       case NavigationMenu:
00731         ChangePorts();
00732         FrmGotoForm(NavigationForm);
00733         handled = true;
00734         break;
00735 
00736       case MapMenu:
00737         ChangePorts();
00738         FrmGotoForm(MapForm);
00739         handled = true;
00740         break;
00741 
00742       case MiscOptsMenu:
00743         ChangePorts();
00744         FrmGotoForm(MiscOptsForm);
00745         handled = true;
00746         break;
00747 
00748       case MapOptsMenu:
00749         ChangePorts();
00750         FrmGotoForm(MapOptsForm);
00751         handled = true;
00752         break;
00753 
00754       case PortsMenu:
00755         if (gNewSerialManager) {
00756           ChangePorts();
00757           FrmGotoForm(GPSPortForm);
00758         }
00759         handled = true;
00760         break;
00761 
00762       case WaypointMenu:
00763         ChangePorts();
00764         FrmGotoForm(WaypointForm);
00765         handled = true;
00766         break;
00767 
00768       case RouteMenu:
00769         ChangePorts();
00770         FrmGotoForm(RouteForm);
00771         handled = true;
00772         break;
00773 
00774       case AboutMenu:
00775         ChangePorts();
00776         FrmGotoForm(AboutForm);
00777         handled = true;
00778         break;
00779         
00780       case UndoMenu:
00781         if (fld_attr.hasFocus == 1)
00782           FldUndo(fldP);
00783         handled = true;
00784         break;
00785 
00786       case CutMenu:
00787         if (fld_attr.hasFocus == 1)
00788           FldCut(fldP);
00789         handled = true;
00790         break;
00791 
00792       case CopyMenu:
00793         if (fld_attr.hasFocus == 1)
00794           FldCopy(fldP);
00795         handled = true;
00796         break;
00797 
00798       case PasteMenu:
00799         if (fld_attr.hasFocus == 1)
00800           FldPaste(fldP);
00801         handled = true;
00802         break;
00803 
00804       case KeyboardMenu:
00805         if (fld_attr.hasFocus == 1)
00806           SysKeyboardDialog(kbdAlpha);
00807         handled = true;
00808         break;
00809 
00810       case GraffitiMenu:
00811         SysGraffitiReferenceDialog(referenceDefault);
00812         handled = true;
00813         break;
00814     }
00815     break;  
00816 
00817   case tblSelectEvent:
00818     /* update table selection */
00819     track_sel = eventP->data.tblSelect.row + track_top;
00820     
00821     /* always select column 0 */
00822     if (eventP->data.tblSelect.column != 0) {
00823       TblSelectItem(tblP, eventP->data.tblSelect.row, 0);
00824     }
00825     
00826     /* get record index from row data */
00827     rec = (UInt16)TblGetRowData(tblP, track_sel - track_top);
00828     
00829     /* get record handle */
00830     trkhDBEntry = DmQueryRecord(gTrackHdrDB, rec);
00831     
00832     /* show track identifier */
00833     trkh = (trk_header_t *)MemHandleLock(trkhDBEntry);
00834     SetFieldText(TrackIdentField, trkh->trk_ident, false, true);
00835     MemHandleUnlock(trkhDBEntry);
00836 
00837     handled = true;
00838     break;
00839   
00840   case sclRepeatEvent:
00841     /* handle scrollbar */
00842     Doscroll(TrackTable, TrackScrl, nr_tracks, &track_top);
00843     trackDrawTable(track_top, &track_sel);
00844     /* Note: scrollbar needs to handle the event, too */
00845     handled = false;
00846     break;
00847   
00848   case keyDownEvent:
00849     switch (eventP->data.keyDown.chr) {
00850     
00851     case pageUpChr:
00852     case pageDownChr:
00853       Dopage(TrackTable, (eventP->data.keyDown.chr == pageDownChr), nr_tracks,
00854         &track_top);
00855       trackDrawTable(track_top, &track_sel);
00856       /* Note: scrollbar needs to handle the event, too */
00857       handled = false;
00858       break;
00859     }
00860     break;
00861   
00862   case ctlSelectEvent:
00863     switch (eventP->data.ctlSelect.controlID) {
00864       case TrackLogButton:
00865         if (nr_tracks == 0)
00866           break;
00867        
00868         /* start/stop track log (toggle) */
00869         if (gPrefs.act_trk.log_state) {
00870           /* old state: running, new state: stopped */
00871 
00872           /* get string from resource */
00873           strH = DmGetResource(strRsc, StartStr);
00874 
00875           if (strH != NULL) {
00876             /* string handle valid, lock it */
00877             strP = (Char *)MemHandleLock(strH);
00878 
00879             /* Set Start/Stop button label from preferences */
00880             CtlSetLabel((ControlPtr)GetObjectFromActiveForm(TrackLogButton),
00881               strP);
00882 
00883             /* unlock string handle */
00884             MemHandleUnlock(strH);
00885 
00886             /* release string resource */
00887             DmReleaseResource(strH);
00888           }
00889           
00890           gPrefs.act_trk.log_state = false;
00891           
00892           /* mark active track as invalid */
00893           gPrefs.act_trk.valid = false;
00894 
00895           /* close track point DB */
00896           DmCloseDatabase(gTrackDB);
00897           gTrackDB = 0;
00898           
00899           /* mark row as invalid to trigger table update by FrmDrawForm() */
00900           TblMarkRowInvalid(tblP, track_sel - track_top );
00901           FrmDrawForm(frmP);
00902 
00903         } else {
00904           /* old state: stopped, new state: running */
00905 
00906           /* get string from resource */
00907           strH = DmGetResource(strRsc, StopStr);
00908 
00909           if (strH != NULL) {
00910             /* string handle valid, lock it */
00911             strP = (Char *)MemHandleLock(strH);
00912 
00913             /* Set Start/Stop button label from preferences */
00914             CtlSetLabel((ControlPtr)GetObjectFromActiveForm(TrackLogButton),
00915               strP);
00916 
00917             /* unlock string handle */
00918             MemHandleUnlock(strH);
00919 
00920             /* release string resource */
00921             DmReleaseResource(strH);
00922           }
00923           
00924           gPrefs.act_trk.log_state = true;
00925           
00926           /* get record index from row data */
00927           rec = (UInt16)TblGetRowData(tblP, track_sel - track_top);
00928 
00929           /* get unique Track ID */
00930           err = DmRecordInfo(gTrackHdrDB, rec, NULL /* *attrP */,
00931             &gPrefs.act_trk.trackID /* *uniqueIDP */, NULL /* *chunkIDP */);
00932 
00933           /* mark active track as valid/invalid */
00934           gPrefs.act_trk.valid = (err == errNone) ? true : false;
00935 
00936           if (!err) {
00937             Boolean new_trk = true;
00938             
00939             /* generate data base name */
00940             TrackDBName(dbname, gPrefs.act_trk.trackID);
00941             
00942             /* open track DB */
00943             gTrackDB = DmOpenDatabase(0 /* cardNo */,
00944               DmFindDatabase(0 /* cardNo */, dbname), dmModeReadWrite);
00945           
00946             /* init track logging */
00947             TrackIntervalCheck(true /* init */, &new_trk);
00948           }
00949 
00950           /* mark row as invalid to trigger table update by FrmDrawForm() */
00951           TblMarkRowInvalid(tblP, track_sel - track_top );
00952           FrmDrawForm(frmP);
00953           
00954         }
00955         handled = true;
00956         break;
00957         
00958 
00959       case TrackDeleteButton:
00960         if (nr_tracks == 0)
00961           break;
00962         
00963         /* get record index from row data */
00964         rec = (UInt16)TblGetRowData(tblP, track_sel - track_top);
00965 
00966         /* get unique recored ID */
00967         DmRecordInfo(gTrackHdrDB, rec, NULL /* *attrP */,
00968           &trackID /* *uniqueIDP */, NULL /* *chunkIDP */);
00969 
00970         if (gPrefs.act_trk.valid && gPrefs.act_trk.trackID == trackID) {
00971           /* selected track is active track, mark as invalid */
00972           gPrefs.act_trk.valid = false;
00973           
00974           if (gPrefs.act_trk.log_state) {
00975             /* selected track in use */
00976             FrmAlert(TrackDelErrorAlert);
00977             break;
00978           }
00979         }
00980         
00981         if ( FrmAlert(TrackDelConfirmAlert) == 0 ) {          
00982           /*
00983            * Only data base backup, no synchronizing available.
00984            * This means a record can simply be deleted.
00985            */
00986           DmRemoveRecord(gTrackHdrDB, rec);
00987 
00988           /* update number of records */
00989           nr_tracks = DmNumRecordsInCategory(gTrackHdrDB, dmAllCategories);
00990           
00991           /* 
00992            * Redraw route table, select previous Waypoint
00993            * of the route and make sure it is visible.
00994            */
00995           if (track_sel > 0) {
00996             track_sel--;
00997           }
00998           
00999           /* update scroll bar */
01000           Doscroll(TrackTable, TrackScrl, nr_tracks, &track_top);         
01001 
01002           /* redraw table */
01003           trackDrawTable(track_top, &track_sel);
01004           
01005           /* generate data base name */
01006           TrackDBName(dbname, trackID);
01007           
01008           /* delete track point data base */
01009           DmDeleteDatabase(0 /* cardNo */,
01010             DmFindDatabase(0 /* cardNo */, dbname));
01011         }
01012         handled = true;
01013         break;
01014     
01015       case TrackNewButton:
01016         /* create new track */
01017         if ( create_track() ) {
01018           /* Track Header DB full */ 
01019           FrmAlert(TrackCreateAlert);
01020           handled = true;
01021           break;
01022         }
01023 
01024         /* update number of records */
01025         nr_tracks = DmNumRecordsInCategory(gTrackHdrDB, dmAllCategories);
01026         
01027         /* select last (e.g. new) track */
01028         track_sel = nr_tracks-1;
01029 
01030         /* set top table row to ensure selected item is visible */
01031         if (track_sel-track_top > TblGetNumberOfRows(tblP)-1) {
01032           track_top = track_sel-TblGetNumberOfRows(tblP)+1;         
01033         }         
01034 
01035         /* update scroll bar */
01036         sclP = (ScrollBarPtr)GetObjectFromActiveForm(TrackScrl);
01037         SclSetScrollBar(sclP, track_sel /* value */,
01038           0 /* min */, nr_tracks /* max */,
01039           TblGetNumberOfRows(tblP) /* page size */);  
01040                 
01041         /* redraw table */
01042         trackDrawTable(track_top, &track_sel);
01043         
01044         handled = true;
01045         break;
01046 
01047     }
01048     break;
01049 
01050   case frmCloseEvent:
01051     /* Deallocate Fields' Text Memory */
01052     SetFieldText(TrackIdentField, NULL, false, true);
01053     SetFieldText(TrackGpslibField, NULL, false, true);
01054 
01055     TrackFormDeinit(FrmGetActiveForm());
01056     handled = false;
01057     break;
01058 
01059   default:
01060     break;
01061   }
01062   
01063   return handled;
01064 }

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