Garmin Fleet Management Controller  2.19.0
CMapViewerDlg.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 *
3 * MODULE NAME:
4 * CMapViewerDlg.cpp
5 *
6 * Copyright 2013 by Garmin Ltd. or its subsidiaries.
7 *---------------------------------------------------------------------
8 * $NoKeywords$
9 *********************************************************************/
10 #include "stdafx.h"
11 #include "CMapViewerDlg.h"
12 #include "CFileTransferDlg.h"
14 #include "util.h"
15 #include "comdef.h"
16 #include "StopListItem.h"
17 
18 #import <msxml6.dll> named_guids
19 
20 using namespace MSXML2;
21 
22 #if( FMI_SUPPORT_A613 )
23 
24 #if( FMI_SUPPORT_A614 )
25 #define SEND_ROUTE_TEMP_FILE _T( "send_route_temp.bin" )
26 #endif
27 
28 // CMapViewerDlg dialog
29 
30 IMPLEMENT_DYNAMIC(CMapViewerDlg, CDialog)
31 
32 BEGIN_MESSAGE_MAP(CMapViewerDlg, CDialog)
33  ON_WM_SIZE()
34 END_MESSAGE_MAP()
35 
36 //----------------------------------------------------------------------
38 //----------------------------------------------------------------------
39 CMapViewerDlg::CMapViewerDlg(CWnd* pParent, FmiApplicationLayer & aCom)
40  : CDialog( CMapViewerDlg::IDD, pParent ),
41  mCom( aCom )
42  {
43  }
44 
45 //----------------------------------------------------------------------
47 //----------------------------------------------------------------------
49 {
50  CoUninitialize();
51 }
52 
53 //----------------------------------------------------------------------
56 //----------------------------------------------------------------------
57 void CMapViewerDlg::DoDataExchange(CDataExchange* pDX)
58  {
59  CDialog::DoDataExchange(pDX);
60  DDX_Control( pDX, IDC_EMBEDDED_BROWSER, m_browser );
61  }
62 
63 //----------------------------------------------------------------------
66 //----------------------------------------------------------------------
68  {
69  CoInitialize(NULL);
70 
71  CDialog::OnInitDialog();
72 
73  refreshCatalog();
74 
75  return TRUE;
76  }
77 
78 //----------------------------------------------------------------------
92 //----------------------------------------------------------------------
94  (
95  UINT aType,
96  int aClientWidth,
97  int aClientHeight
98  )
99 {
100  CDialog::OnSize( aType, aClientWidth, aClientHeight );
101 
102  if ( NULL == m_browser.GetSafeHwnd() )
103  {
104  return;
105  }
106 
107  UpdateData();
108 
109  CRect rect;
110  GetClientRect( &rect );
111 
112  m_browser.MoveWindow( rect.left, rect.top, rect.Width(), rect.Height() );
113 }
114 
115 
116 
117 //----------------------------------------------------------------------
119 //----------------------------------------------------------------------
121  {
122  _variant_t flags( 0L, VT_I4 );
123  _variant_t target_frame_name( "" );
124  _variant_t post_data( "" );
125  _variant_t headers( "" );
126 
127  CFile catalog;
128  CFileException pEx;
129  if ( !catalog.Open( _T( "map-viewer\\catalog.xml" ), CFile::modeRead, &pEx ) )
130  {
131  if ( !catalog.Open( _T( "map-viewer\\catalog.xml" ), CFile::modeCreate | CFile::modeWrite, &pEx ) )
132  {
133  m_browser.Navigate( _T( "about:blank" ), &flags, &target_frame_name, &post_data, &headers );
134  TCHAR msg[256];
135  pEx.GetErrorMessage( msg, 256 );
136  m_browser.WriteContent( CString( msg ) );
137  return;
138  }
139 
140  //build empty catalog with XSL directive
141  write( &catalog, "<?xml version=\"1.0\" encoding=\"utf-8\"?><?xml-stylesheet type=\"text/xsl\" href=\"catalog.xsl\"?><catalog></catalog>\r\n" );
142  }
143  CString url( "file:///" );
144  url += catalog.GetFilePath();
145 
146  catalog.Close();
147 
148  m_browser.Navigate( url, &flags, &target_frame_name, &post_data, &headers );
149  }
150 
151 // CMapViewerDlg message handlers
152 BEGIN_EVENTSINK_MAP(CMapViewerDlg, CDialog)
153  ON_EVENT(CMapViewerDlg, IDC_EMBEDDED_BROWSER, 250, CMapViewerDlg::OnBeforeNavigate2, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
154 END_EVENTSINK_MAP()
155 
156 //----------------------------------------------------------------------
158 //----------------------------------------------------------------------
159 void CMapViewerDlg::OnBeforeNavigate2(LPDISPATCH, VARIANT* URL, VARIANT*, VARIANT*, VARIANT*, VARIANT*, BOOL* Cancel)
160  {
161  if ( URL->vt != VT_BSTR )
162  {
163  return;
164  }
165 
166  CString urlStr = URL->bstrVal;
167  if ( urlStr.Find( _T( "app:") ) == 0 )
168  {
169  // take over
170  *Cancel = TRUE;
171 
172  CString command = urlStr.Right( urlStr.GetLength() - (int) strlen( "app:" ) );
173  CString procedure = command.Left( command.Find( '(' ) );
174  CString args = command.Mid( procedure.GetLength() + 1, command.ReverseFind( ')') - ( procedure.GetLength() + 1 ) );
175  CStringArray arguments;
176  //split arguments separated by comma
177  int curPos = 0;
178  CString token = args.Tokenize( _T( "," ), curPos );
179  while ( token != _T( "" ) )
180  {
181  if ( 0 == token.Find( '"' ) )
182  {
183  if ( token.GetLength()-1 == token.ReverseFind( '"' ) )
184  {
185  token = token.Mid( 1, token.GetLength() - 2 );
186  token = CWebBrowser2::URLDecode( token );
187  }
188  else {
189  token += _T( "," );
190  token += args.Tokenize( _T( "," ), curPos );
191  continue;
192  }
193  }
194  arguments.Add( token );
195  token = args.Tokenize( _T( "," ), curPos );
196  }
197 
198  TRACE2( "app command '%s' executed with args '%s'\r\n", procedure, args );
199 
200  if ( procedure == _T( "addAvoidanceToCatalog" ) )
201  {
202  if ( arguments.GetCount() < 7 )
203  {
204  MessageBox( _T( "Insufficient arguments"), _T( "Add Region" ), MB_ICONERROR );
205  return;
206  }
207  addAvoidanceToCatalog(
208  _ttoi( arguments[0] ),
209  arguments[1],
210  arguments[2],
211  _ttol( arguments[3] ),
212  _ttol( arguments[4] ),
213  _ttol( arguments[5] ),
214  _ttol( arguments[6] )
215  );
216  }
217  else if ( procedure == _T( "removeAvoidanceFromCatalog" ) )
218  {
219  BOOL removed = removeAvoidanceFromCatalog( _ttoi( arguments[0] ) );
220  if ( arguments.GetCount() > 1 )
221  {
222  CStringArray callbackArgs;
223  callbackArgs.Add( removed ? _T( "true" ) : _T( "false" ) );
224  callbackArgs.Add( arguments[0] );
225  m_browser.InvokeScript( arguments[1], &callbackArgs );
226  }
227  }
228  else if ( procedure == _T( "sendAvoidanceToDevice" ) )
229  {
230  if ( arguments.GetCount() < 6 )
231  {
232  MessageBox( _T( "Insufficient arguments"), _T( "Send to Device" ), MB_ICONERROR );
233  return;
234  }
235  BOOL sent = sendAvoidanceToDevice(
236  _ttoi( arguments[0] ),
237  arguments[1],
238  _ttol( arguments[2] ),
239  _ttol( arguments[3] ),
240  _ttol( arguments[4] ),
241  _ttol( arguments[5] )
242  );
243  if ( arguments.GetCount() > 6 )
244  {
245  CStringArray callbackArgs;
246  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
247  m_browser.InvokeScript( arguments[6], &callbackArgs);
248  }
249  }
250  else if ( procedure == _T( "deleteAvoidanceFromDevice" ) )
251  {
252  BOOL sent = deleteAvoidanceFromDevice( _ttoi( arguments[0] ) );
253  if ( arguments.GetCount() > 1 )
254  {
255  CStringArray callbackArgs;
256  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
257  m_browser.InvokeScript( arguments[1], &callbackArgs);
258  }
259  }
260  else if ( procedure == _T( "enableAvoidanceOnDevice" ) )
261  {
262  BOOL sent = setAvoidanceEnabled( _ttoi( arguments[0] ), TRUE );
263  if ( arguments.GetCount() > 1 )
264  {
265  CStringArray callbackArgs;
266  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
267  m_browser.InvokeScript( arguments[1], &callbackArgs);
268  }
269  }
270  else if ( procedure == _T( "disableAvoidanceOnDevice" ) )
271  {
272  BOOL sent = setAvoidanceEnabled( _ttoi( arguments[0] ), FALSE );
273  if ( arguments.GetCount() > 1 )
274  {
275  CStringArray callbackArgs;
276  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
277  m_browser.InvokeScript( arguments[1], &callbackArgs);
278  }
279  }
280  else if ( procedure == _T( "addStopToCatalog" ) )
281  {
282  addStopToCatalog( arguments );
283  }
284 #if( FMI_SUPPORT_A614 )
285  else if ( procedure == _T( "beginAddRouteToCatalog" ) )
286  {
287  m_addRouteArguments.RemoveAll();
288  m_addRouteArguments.Append( arguments );
289  }
290  else if ( procedure == _T( "continueAddRouteToCatalog" ) )
291  {
292  m_addRouteArguments.Append( arguments );
293  }
294  else if ( procedure == _T( "endAddRouteToCatalog" ) )
295  {
296  if ( removeRouteFromCatalog( _ttoi( m_addRouteArguments[0] ) ) )
297  {
298  addRouteToCatalog( m_addRouteArguments );
299  }
300  m_addRouteArguments.RemoveAll();
301  }
302  else if ( procedure == _T( "removeRouteFromCatalog" ) )
303  {
304  BOOL removed = removeRouteFromCatalog( _ttoi( arguments[0] ) );
305  if ( arguments.GetCount() > 1 )
306  {
307  CStringArray callbackArgs;
308  callbackArgs.Add( removed ? _T( "true" ) : _T( "false" ) );
309  callbackArgs.Add( arguments[0] );
310  m_browser.InvokeScript( arguments[1], &callbackArgs );
311  }
312  }
313  else if ( procedure == _T( "sendRouteToDevice" ) )
314  {
315  if ( arguments.GetCount() == 1 )
316  {
317  BOOL sent = sendRouteToDevice( _ttoi( arguments[0] ) );
318  }
319  }
320  else if ( procedure == _T( "deleteRouteFromDevice" ) )
321  {
322  if ( arguments.GetCount() == 1 )
323  {
324  BOOL sent = deleteRouteFromDevice( _ttoi( arguments[0] ) );
325  if ( arguments.GetCount() > 1 )
326  {
327  CStringArray callbackArgs;
328  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
329  m_browser.InvokeScript( arguments[1], &callbackArgs);
330  }
331  }
332  }
333  else if ( procedure == _T( "activateStopOnDevice" ) )
334  {
335  if ( arguments.GetCount() == 1 )
336  {
337  BOOL sent = activateStopOnDevice( _ttoi( arguments[0] ) );
338  if ( arguments.GetCount() > 1 )
339  {
340  CStringArray callbackArgs;
341  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
342  m_browser.InvokeScript( arguments[1], &callbackArgs);
343  }
344  }
345  }
346  else if ( procedure == _T( "completeStopOnDevice" ) )
347  {
348  if ( arguments.GetCount() == 1 )
349  {
350  BOOL sent = completeStopOnDevice( _ttoi( arguments[0] ) );
351  if ( arguments.GetCount() > 1 )
352  {
353  CStringArray callbackArgs;
354  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
355  m_browser.InvokeScript( arguments[1], &callbackArgs);
356  }
357  }
358  }
359  else if ( procedure == _T( "moveStopOnDevice" ) )
360  {
361  if ( arguments.GetCount() == 2 )
362  {
363  BOOL sent = moveStopOnDevice( _ttoi( arguments[0] ), _ttoi( arguments[1] ) );
364  if ( arguments.GetCount() > 2 )
365  {
366  CStringArray callbackArgs;
367  callbackArgs.Add( sent ? _T( "true" ) : _T( "false" ) );
368  m_browser.InvokeScript( arguments[2], &callbackArgs);
369  }
370  }
371  }
372 #endif
373  }
374  }
375 
376 //----------------------------------------------------------------------
381 //----------------------------------------------------------------------
382 BOOL CMapViewerDlg::addAvoidanceToCatalog( int itemId, LPCTSTR name, LPCTSTR description, long north, long east, long south, long west )
383  {
384  // load the catalog
385  CString documentPath( _T( "map-viewer\\catalog.xml" ) );
386  MSXML2::IXMLDOMDocument2Ptr doc( MSXML2::CLSID_DOMDocument60 );
387  doc->async = VARIANT_FALSE;
388  doc->validateOnParse = VARIANT_FALSE;
389  doc->resolveExternals = VARIANT_TRUE;
390 
391  if ( VARIANT_TRUE == doc->load( _variant_t( documentPath ) ) )
392  {
393  // create new element and add to document root (catalog)
394  MSXML2::IXMLDOMElementPtr newRegion = doc->createElement( _bstr_t( "region" ) );
395  if ( 0 != _tcslen( description ) )
396  {
397  MSXML2::IXMLDOMNodePtr descr = doc->createElement( _bstr_t( "description" ) );
398  descr->put_text( _bstr_t( description ) );
399  newRegion->appendChild( descr );
400  }
401  newRegion->setAttribute( _bstr_t( "id" ), _variant_t( itemId ) );
402  newRegion->setAttribute( _bstr_t( "name" ), _variant_t( name ) );
403  newRegion->setAttribute( _bstr_t( "north" ), _variant_t( north ) );
404  newRegion->setAttribute( _bstr_t( "east" ), _variant_t( east ) );
405  newRegion->setAttribute( _bstr_t( "south" ), _variant_t( south ) );
406  newRegion->setAttribute( _bstr_t( "west" ), _variant_t( west ) );
407  doc->GetdocumentElement()->appendChild( newRegion );
408 
409  // store updated catalog
410  HRESULT hr = doc->save( _variant_t( documentPath ) );
411  if ( SUCCEEDED( hr ) )
412  {
413  return TRUE;
414  }
415  }
416 
417  return FALSE;
418  }
419 
420 //----------------------------------------------------------------------
425 //----------------------------------------------------------------------
427  {
428  CString path;
429  path.Format( _T( "region[@id=%d]" ), id );
430  return removeItemsFromCatalog( path );
431  }
432 
433 //----------------------------------------------------------------------
438 //----------------------------------------------------------------------
439 BOOL CMapViewerDlg::sendAvoidanceToDevice( int itemId, LPCTSTR name, long north, long east, long south, long west )
440  {
441  custom_avoid_type message;
442  memset( &message, 0, sizeof( message ) );
443 
444  message.unique_id = (uint16) itemId;
445 
446  message.point1.lat = north;
447  message.point1.lon = east;
448  message.point2.lat = south;
449  message.point2.lon = west;
450 
451  message.enable = true;
452 
453  WideCharToMultiByte( mCom.mClientCodepage, 0, name, -1, message.name, sizeof( message.name ) - 1, NULL, NULL );
454  message.name[sizeof( message.name ) - 1] = '\0';
455 
456  mCom.sendFmiPacket( FMI_CUSTOM_AVOID_ADD_REQUEST, (uint8*)&message, sizeof( message ) );
457 
458  return TRUE;
459  }
460 
461 //----------------------------------------------------------------------
464 //----------------------------------------------------------------------
466  {
467  custom_avoid_delete_type message;
468  memset( &message, 0, sizeof( message ) );
469 
470  message.unique_id = (uint16) id;
471 
472  mCom.sendFmiPacket( FMI_CUSTOM_AVOID_DEL_REQUEST, (uint8*)&message, sizeof( message ) );
473 
474  return TRUE;
475  }
476 
477 //----------------------------------------------------------------------
480 //----------------------------------------------------------------------
481 BOOL CMapViewerDlg::setAvoidanceEnabled(int id, BOOL enabled)
482  {
483  custom_avoid_enable_type message;
484  memset( &message, 0, sizeof( message ) );
485 
486  message.unique_id = (uint16) id;
487  message.enable = enabled == TRUE;
488 
489  mCom.sendFmiPacket( FMI_CUSTOM_AVOID_TOGGLE_REQUEST, (uint8*)&message, sizeof( message ) );
490 
491  return TRUE;
492  }
493 
494 //----------------------------------------------------------------------
499 //----------------------------------------------------------------------
500 BOOL CMapViewerDlg::addStopToCatalog( CStringArray & args )
501  {
502  // load the catalog
503  CString documentPath( _T( "map-viewer\\catalog.xml" ) );
504  MSXML2::IXMLDOMDocument2Ptr doc( MSXML2::CLSID_DOMDocument60 );
505  doc->async = VARIANT_FALSE;
506  doc->validateOnParse = VARIANT_FALSE;
507  doc->resolveExternals = VARIANT_TRUE;
508 
509  if ( VARIANT_TRUE == doc->load( _variant_t( documentPath ) ) )
510  {
511  // create new element and add to document root (catalog)
512  MSXML2::IXMLDOMElementPtr newItem = doc->createElement( _bstr_t( "route" ) );
513  newItem->setAttribute( _bstr_t( "id" ), _variant_t( _ttoi( args[0] ) ) );
514  newItem->setAttribute( _bstr_t( "name" ), _variant_t( args[1] ) );
515  if ( 0 != _tcslen( args[2] ) )
516  {
517  MSXML2::IXMLDOMElementPtr descr = doc->createElement( _bstr_t( "description" ) );
518  descr->put_text( _bstr_t( args[2] ) );
519  newItem->appendChild( descr );
520  }
521  newItem->setAttribute( _bstr_t( "end-lat" ), _variant_t( _ttol( args[3] ) ) );
522  newItem->setAttribute( _bstr_t( "end-lon" ), _variant_t( _ttol( args[4] ) ) );
523 
524  doc->GetdocumentElement()->appendChild( newItem );
525 
526  StopListItem& stopListItem = mCom.mA603Stops.get( newItem->getAttribute( "id" ) );
527  //stopListItem.setId( newItem->getAttribute( "id" ) );
528  stopListItem.setCurrentName( newItem->getAttribute( "name" ) );
529  stopListItem.setStopStatus( STOP_STATUS_UNREAD );
530  stopListItem.setValid();
531  mCom.mA603Stops.put( stopListItem );
532 
533  // store updated catalog
534  HRESULT hr = doc->save( _variant_t( documentPath ) );
535  if ( SUCCEEDED( hr ) )
536  {
537  return TRUE;
538  }
539  }
540 
541  return FALSE;
542  }
543 //----------------------------------------------------------------------
548 //----------------------------------------------------------------------
550  {
551 
552  //read route info from catalog
553  CString documentPath( _T( "map-viewer\\catalog.xml" ) );
554  MSXML2::IXMLDOMDocument2Ptr doc( MSXML2::CLSID_DOMDocument60 );
555  doc->async = VARIANT_FALSE;
556  doc->validateOnParse = VARIANT_FALSE;
557  doc->resolveExternals = VARIANT_TRUE;
558 
559  if ( VARIANT_TRUE != doc->load( _variant_t( documentPath ) ) )
560  {
561  return FALSE;
562  }
563 
564  CString selector;
565  selector.Format( _T( "route[@id=%d]" ), itemId );
566  MSXML2::IXMLDOMNodeListPtr nodes = doc->GetdocumentElement()->selectNodes( _bstr_t( selector ) );
567  if ( 0 == nodes->Getlength() )
568  {
569  return FALSE;
570  }
571 
572  MSXML2::IXMLDOMElementPtr stopNode = nodes->Getitem( 0 );
573 
574  CString nameString = stopNode->getAttribute( "name" );
575  int nameLen = WideCharToMultiByte( CP_UTF8, 0, nameString.GetBuffer(), -1, NULL, NULL, NULL, NULL );
576  char * name = new char[nameLen];
577  WideCharToMultiByte( CP_UTF8, 0, nameString.GetBuffer(), -1, name, nameLen, NULL, NULL );
578  uint32 unique_id = itemId;
579 
580  double lat = stopNode->getAttribute( _T( "end-lat" ) );
581  double lon = stopNode->getAttribute( _T( "end-lon" ) );
582 
583  mCom.sendA603Stop( lat, lon, name, unique_id );
584 
585  return TRUE;
586  }
587 
588 #if( FMI_SUPPORT_A614 )
589 //----------------------------------------------------------------------
594 //----------------------------------------------------------------------
595 BOOL CMapViewerDlg::addRouteToCatalog( CStringArray & args )
596  {
597  // load the catalog
598  CString documentPath( _T( "map-viewer\\catalog.xml" ) );
599  MSXML2::IXMLDOMDocument2Ptr doc( MSXML2::CLSID_DOMDocument60 );
600  doc->async = VARIANT_FALSE;
601  doc->validateOnParse = VARIANT_FALSE;
602  doc->resolveExternals = VARIANT_TRUE;
603 
604  if ( VARIANT_TRUE == doc->load( _variant_t( documentPath ) ) )
605  {
606  // create new element and add to document root (catalog)
607  MSXML2::IXMLDOMElementPtr newItem = doc->createElement( _bstr_t( "route" ) );
608  newItem->setAttribute( _bstr_t( "id" ), _variant_t( _ttoi( args[0] ) ) );
609  newItem->setAttribute( _bstr_t( "name" ), _variant_t( args[1] ) );
610  if ( 0 != _tcslen( args[2] ) )
611  {
612  MSXML2::IXMLDOMElementPtr descr = doc->createElement( _bstr_t( "description" ) );
613  descr->put_text( _bstr_t( args[2] ) );
614  newItem->appendChild( descr );
615  }
616  newItem->setAttribute( _bstr_t( "end-lat" ), _variant_t( _ttol( args[3] ) ) );
617  newItem->setAttribute( _bstr_t( "end-lon" ), _variant_t( _ttol( args[4] ) ) );
618  for ( int i=5; i+4<=args.GetCount(); i+=4 )
619  {
620  MSXML2::IXMLDOMElementPtr intermediate = doc->createElement( 0 == _ttoi( args[i] ) ? _bstr_t( "intermediate" ) : _bstr_t( "shaping" ) );
621  intermediate->setAttribute( _bstr_t( "name" ), _variant_t( args[i+1] ) );
622  intermediate->setAttribute( _bstr_t( "lat" ), _variant_t( _ttol( args[i+2] ) ) );
623  intermediate->setAttribute( _bstr_t( "lon" ), _variant_t( _ttol( args[i+3] ) ) );
624  newItem->appendChild( intermediate );
625  }
626  doc->GetdocumentElement()->appendChild( newItem );
627 
628  // store updated catalog
629  HRESULT hr = doc->save( _variant_t( documentPath ) );
630  if ( SUCCEEDED( hr ) )
631  {
632  return TRUE;
633  }
634  }
635 
636  return FALSE;
637  }
638 
639 //----------------------------------------------------------------------
644 //----------------------------------------------------------------------
646  {
647  CString path;
648  path.Format( _T( "route[@id=%d]" ), id );
649  return removeItemsFromCatalog( path );
650  }
651 
652 //----------------------------------------------------------------------
657 //----------------------------------------------------------------------
659  {
660  char file[MAX_PATH+1];
661  char versionString[35];
662  uint8 version[16];
663  uint8 versionLength;
664 
665  memset( version, 0, sizeof( version ) );
666  WideCharToMultiByte( mCom.mClientCodepage, 0, _T( "1" ), -1, versionString, 34, NULL, NULL );
667  versionString[34] = '\0';
668  versionLength = (uint8)minval( 16, strlen( versionString ) );
669  memmove( version, versionString, versionLength );
670 
671  WideCharToMultiByte( CP_ACP, 0, SEND_ROUTE_TEMP_FILE, -1, file, MAX_PATH+1, NULL, NULL );
672  file[MAX_PATH] = '\0';
673 
674  //read route info from catalog
675  CString documentPath( _T( "map-viewer\\catalog.xml" ) );
676  MSXML2::IXMLDOMDocument2Ptr doc( MSXML2::CLSID_DOMDocument60 );
677  doc->async = VARIANT_FALSE;
678  doc->validateOnParse = VARIANT_FALSE;
679  doc->resolveExternals = VARIANT_TRUE;
680 
681  if ( VARIANT_TRUE != doc->load( _variant_t( documentPath ) ) )
682  {
683  return FALSE;
684  }
685 
686  CString selector;
687  selector.Format( _T( "route[@id=%d]" ), itemId );
688  MSXML2::IXMLDOMNodeListPtr nodes = doc->GetdocumentElement()->selectNodes( _bstr_t( selector ) );
689  if ( 0 == nodes->Getlength() )
690  {
691  return FALSE;
692  }
693  MSXML2::IXMLDOMElementPtr routeNode = nodes->Getitem( 0 );
694  //serialize it to a temporary file
695  CFile tmpFile;
696  if ( !tmpFile.Open( SEND_ROUTE_TEMP_FILE, CFile::modeCreate | CFile::modeWrite ) )
697  {
698  return FALSE;
699  }
700 
701  CString nameString = routeNode->getAttribute( "name" );
702  CString stopText = nameString;
703  MSXML2::IXMLDOMNodeListPtr childNodes = routeNode->GetchildNodes();
704 
705  if( 1 == childNodes->Getlength() )
706  {
707  if( childNodes->Getitem( 0 )->GetnodeName() == _bstr_t( "description" ) )
708  {
709  return sendStopToDevice( itemId );
710  }
711  }
712  else if ( 0 == childNodes->Getlength() )
713  {
714  return sendStopToDevice( itemId );
715  }
716 
717  BYTE isShaping = 1;
718  short ver = 0;
719  time_type origination_time = UTIL_get_current_garmin_time();
720  uint32 unique_id = itemId;
721 
722  write( &tmpFile, "PSR+" );
723  tmpFile.Write( ( const void* ) &ver, sizeof( ver ) );
724 
725  //use the route description as the Stop Text, if available
726  //otherwise fall back to the route name
727  for ( int i=0, count = childNodes->Getlength(); i<count; i++ )
728  {
729  MSXML2::IXMLDOMElementPtr childNode = childNodes->Getitem( i );
730  if ( childNode->GetnodeName() == _bstr_t( "description" ) )
731  {
732  nameString = stopText = (LPCTSTR) childNode->Gettext();
733  break;
734  }
735  }
736  tmpFile.Write( ( const void* ) &origination_time, sizeof( origination_time ) );
737  tmpFile.Write( ( const void* ) &unique_id, sizeof( unique_id ) );
738  write( &tmpFile, nameString, 200 );
739 
740  sc_position_type pos;
741 
742  //send them to the device in reverse order since the catalog stores them last to first
743  for ( int i=childNodes->Getlength() - 1; i>=0; i-- )
744  {
745  MSXML2::IXMLDOMElementPtr childNode = childNodes->Getitem( i );
746  if ( childNode->GetnodeName() == _bstr_t( "intermediate" ) )
747  {
748  pos.lat = childNode->getAttribute( _T( "lat" ) );
749  pos.lon = childNode->getAttribute( _T( "lon" ) );
750  tmpFile.Write( ( const void *) &pos.lat, sizeof( pos.lat ) );
751  tmpFile.Write( ( const void *) &pos.lon, sizeof( pos.lon ) );
752  tmpFile.Write( "\0", 1 );
753  nameString = childNode->getAttribute( _T( "name" ) );
754  write( &tmpFile, nameString, 40 );
755  }
756  else if ( childNode->GetnodeName() == _bstr_t( "shaping" ) )
757  {
758  pos.lat = childNode->getAttribute( _T( "lat" ) );
759  pos.lon = childNode->getAttribute( _T( "lon" ) );
760  tmpFile.Write( ( const void *) &pos.lat, sizeof( pos.lat ) );
761  tmpFile.Write( ( const void *) &pos.lon, sizeof( pos.lon ) );
762  tmpFile.Write( ( const void* ) &isShaping, 1 );
763  }
764  }
765 
766  //now write the final destination (the stop) information contained on the top-level route element
767  pos.lat = routeNode->getAttribute( _T( "end-lat" ) );
768  pos.lon = routeNode->getAttribute( _T( "end-lon" ) );
769  tmpFile.Write( ( const void *) &pos.lat, sizeof( pos.lat ) );
770  tmpFile.Write( ( const void *) &pos.lon, sizeof( pos.lon ) );
771  tmpFile.Write( "\0", 1 );
772  nameString = routeNode->getAttribute( _T( "name" ) );
773  write( &tmpFile, nameString, 40 );
774 
775  tmpFile.Flush();
776  tmpFile.Close();
777 
778  mCom.sendFile( file, versionLength, version, (uint8) FMI_FILE_TYPE_PATH_SPECIFIC_ROUTE );
779 
780  //add this to the Stops list now so that the UI can receive status updates, as opposed
781  //to adding it after the transfer progress dialog returns from modal, which may happen
782  //after the device reports a status update of the new stop it receives to the Stops dialog
783  StopListItem& stopListItem = mCom.mA603Stops.get( itemId );
784  stopListItem.setCurrentName( stopText );
785  stopListItem.setStopStatus( STOP_STATUS_UNREAD );
786  stopListItem.setValid();
787  mCom.mA603Stops.put( stopListItem );
788 
789  CFileTransferProgressDlg sending_dlg( this, mCom );
790  UINT sendResult = sending_dlg.DoModal();
791  //remove the record from the Stops list if the file transfer failed
792  if ( IDOK != sendResult )
793  {
794  mCom.mA603Stops.remove( itemId );
795  }
796 
797  return TRUE;
798  }
799 
800 //----------------------------------------------------------------------
803 //----------------------------------------------------------------------
805  {
806  mCom.sendStopStatusRequest( id, REQUEST_DELETE_STOP );
807  return TRUE;
808  }
809 
810 //----------------------------------------------------------------------
813 //----------------------------------------------------------------------
815  {
816  mCom.sendStopStatusRequest( id, REQUEST_ACTIVATE_STOP );
817  return TRUE;
818  }
819 
820 //----------------------------------------------------------------------
823 //----------------------------------------------------------------------
825  {
826  mCom.sendStopStatusRequest( id, REQUEST_MARK_STOP_DONE );
827  return TRUE;
828  }
829 
830 //----------------------------------------------------------------------
833 //----------------------------------------------------------------------
834 BOOL CMapViewerDlg::moveStopOnDevice(int id, short newPosition)
835  {
836  mCom.sendStopStatusRequest( id, REQUEST_MOVE_STOP, newPosition );
837  return TRUE;
838  }
839 
840 #endif
841 
842 //----------------------------------------------------------------------
847 //----------------------------------------------------------------------
849  {
850  // load the catalog
851  CString documentPath( _T( "map-viewer\\catalog.xml" ) );
852  MSXML2::IXMLDOMDocument2Ptr doc( MSXML2::CLSID_DOMDocument60 );
853  doc->async = VARIANT_FALSE;
854  doc->validateOnParse = VARIANT_FALSE;
855  doc->resolveExternals = VARIANT_TRUE;
856 
857  if ( VARIANT_TRUE == doc->load( _variant_t( documentPath ) ) )
858  {
859  // find node(s) by specified selector and then remove from the root element (catalog)
860  MSXML2::IXMLDOMNodeListPtr nodes = doc->GetdocumentElement()->selectNodes( _bstr_t( selector ) );
861  for ( int i=nodes->Getlength()-1; i>=0; i-- )
862  {
863  doc->GetdocumentElement()->removeChild( nodes->Getitem( i ) );
864  }
865 
866  // store updated catalog
867  HRESULT hr = doc->save( _variant_t( documentPath ) );
868  if ( SUCCEEDED( hr ) )
869  {
870  return TRUE;
871  }
872  }
873 
874  return FALSE;
875  }
876 #endif
Modal dialog displaying the status of the file transfer.
BOOL addStopToCatalog(CStringArray &args)
This function adds an item to the catalog.
Data type for Custom Avoidance Enable/Disable (0X1234) from server to client.
Definition: fmi.h:1995
Browser-based container for listing the Custom Avoidances library.
Definition: CMapViewerDlg.h:24
char name[49]
Definition: fmi.h:1975
#define SEND_ROUTE_TEMP_FILE
BOOL OnInitDialog()
This function is called when the window is created.
BOOL completeStopOnDevice(int itemId)
This function marks the specified route as done on the device.
#define FALSE
Definition: garmin_types.h:46
void setValid(BOOL aValid=TRUE)
Set this item as valid.
Data structure to hold details of an A603 stop that the server needs to keep.
Definition: StopListItem.h:21
boolean enable
Definition: fmi.h:1973
afx_msg void OnSize(UINT aType, int aClientWidth, int aClientHeight)
Called after the dialog is resized; repositions the contents of the display.
Data type for Custom Avoidance Delete (0X1232) from server to client.
Definition: fmi.h:1988
#define TRUE
Definition: garmin_types.h:45
virtual ~CMapViewerDlg()
Destructor.
uint16 unique_id
Definition: fmi.h:1972
BOOL sendAvoidanceToDevice(int itemId, LPCTSTR name, long north, long east, long south, long west)
This function sends the specified region to the device.
BOOL addAvoidanceToCatalog(int itemId, LPCTSTR name, LPCTSTR description, long north, long east, long south, long west)
This function adds an item to the catalog.
sint32 lat
latitude in semicircles
Definition: garmin_types.h:126
void setCurrentName(CString aName)
Set the current name of the stop.
BOOL addRouteToCatalog(CStringArray &args)
This function adds an item to the catalog.
#define minval(_x, _y)
The smaller of _x and _y.
Definition: util_macros.h:95
#define IDC_EMBEDDED_BROWSER
Definition: resource.h:432
static void write(CFile *file, char *text)
This function is a helper for writing text to a file.
Serial communication controller for Garmin and FMI packets.
BOOL removeRouteFromCatalog(int itemId)
This function removes specific routes from the catalog.
Data type for Custom Avoidance Packet ID (0X1230) from server to client.
Definition: fmi.h:1968
sc_position_type point2
Definition: fmi.h:1971
BOOL deleteAvoidanceFromDevice(int itemId)
This function deletes the specified region from the device.
virtual void DoDataExchange(CDataExchange *pDX)
Perform dialog data exchange and validation.
unsigned short int uint16
16-bit unsigned integer
Definition: garmin_types.h:64
BOOL moveStopOnDevice(int itemId, short newPosition)
This function repositions the specified stop on the device.
void OnBeforeNavigate2(LPDISPATCH pDisp, VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers, BOOL *Cancel)
This catches navigation attempts for the purpose of handling application-specific navigation...
BOOL removeAvoidanceFromCatalog(int itemId)
This function removes specific regions from the catalog.
BOOL deleteRouteFromDevice(int itemId)
This function deletes the specified route from the device.
Indicates a latitude and longitude in semicircles.
Definition: garmin_types.h:124
void setStopStatus(stop_status_status_type aStatus)
Set the stop status.
static CString URLDecode(CString sIn)
translate escape sequences into their original characters
unsigned char uint8
8-bit unsigned integer
Definition: garmin_types.h:62
time_type UTIL_get_current_garmin_time()
Get the current server time in Garmin format.
Definition: util.cpp:603
BOOL removeItemsFromCatalog(LPCTSTR selector)
This function removes specific routes from the catalog.
BOOL sendRouteToDevice(int itemId)
This function sends the specified route to the device.
sc_position_type point1
Definition: fmi.h:1970
unsigned long int uint32
32-bit unsigned integer
Definition: garmin_types.h:66
void refreshCatalog()
This function is called to reload the catalog document.
sint32 lon
longitude in semicircles
Definition: garmin_types.h:127
uint32 time_type
Absolute time (number of seconds since 12/31/1989 12:00 am UTC)
Definition: garmin_types.h:97
BOOL setAvoidanceEnabled(int itemId, BOOL enabled=TRUE)
This function toggles enabled for the region on the device.
BOOL activateStopOnDevice(int itemId)
This function activates the specified route on the device.
BOOL sendStopToDevice(int itemId)
This function sends the specified stop to the device.