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 }