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 }