diff --git a/src/app/gps/qgsgpsinformationwidget.cpp b/src/app/gps/qgsgpsinformationwidget.cpp
index ab9bc1e..56465f9 100644
--- a/src/app/gps/qgsgpsinformationwidget.cpp
+++ b/src/app/gps/qgsgpsinformationwidget.cpp
@@ -18,6 +18,7 @@
 #include "qgsnmeaconnection.h"
 #include "qgsgpsconnectionregistry.h"
 #include "qgsgpsdetector.h"
+#include "info.h"
 #include "qgscoordinatetransform.h"
 #include <qgspoint.h>
 #include <qgsrubberband.h>
@@ -29,6 +30,7 @@
 #include "qgslogger.h"
 #include "qgsfeatureaction.h"
 #include "qgsgeometry.h"
+#include <qgisapp.h>
 
 //for avoid intersections static method
 #include "qgsmaptooladdfeature.h"
@@ -39,7 +41,6 @@
 #include <qwt_plot.h>
 #include <qwt_plot_grid.h>
 // QWT Polar plot add on
-#include <qpen.h>
 #include <qwt_data.h>
 #include <qwt_symbol.h>
 #include <qwt_polar_grid.h>
@@ -49,9 +50,10 @@
 #include <QMessageBox>
 #include <QSettings>
 #include <QFileInfo>
-#include <QPointF>
+//#include <QPointF>
 #include <QColorDialog>
-
+#include <QFileDialog>
+#include <QPixmap>
 
 QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWidget * parent, Qt::WindowFlags f ):
     QWidget( parent, f ),
@@ -59,6 +61,13 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
     mpCanvas( thepCanvas )
 {
   setupUi( this );
+
+  // to connect signals that layers have changed (which layer, edit state)
+  mpLegend = QgisApp::instance()->legend();
+  mpLastLayer = 0;
+
+  mLastGpsPosition = QgsPoint( 0.0, 0.0 );
+
   mpMapMarker = 0;
   mpRubberBand = 0;
   populateDevices();
@@ -67,13 +76,14 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
   // Set up the graph for signal strength
   //
   mpPlot = new QwtPlot( mpHistogramWidget );
+  mpPlot->setAutoReplot( false );   // plot on demand
   //mpPlot->setTitle(QObject::tr("Signal Status"));
   //mpPlot->insertLegend(new QwtLegend(), QwtPlot::BottomLegend);
   // Set axis titles
   //mpPlot->setAxisTitle(QwtPlot::xBottom, QObject::tr("Satellite"));
   //mpPlot->setAxisTitle(QwtPlot::yLeft, QObject::tr("Value"));
   mpPlot->setAxisScale( QwtPlot::xBottom, 0, 20 );
-  mpPlot->setAxisScale( QwtPlot::yLeft, 0, 100 );
+  mpPlot->setAxisScale( QwtPlot::yLeft, 0, 100 );  // max is 50dB SNR, I believe - SLM
   // add a grid
   //QwtPlotGrid * mypGrid = new QwtPlotGrid();
   //mypGrid->attach( mpPlot );
@@ -96,43 +106,47 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
   // Set up the polar graph for satellite pos
   //
   QWidget * mpPolarWidget = mStackedWidget->widget( 2 );
-  //mpSatellitesWidget = new QwtPolarPlot(QwtText(tr("Satellite Positions")), myTab );
-  mpSatellitesWidget = new QwtPolarPlot( mpPolarWidget );
-  mpSatellitesWidget->setAutoReplot( true );
+  mpSatellitesWidget = new QwtPolarPlot( /*QwtText( tr( "Satellite View" ), QwtText::PlainText ),*/ mpPolarWidget );  // possible title for graph removed for now as it is too large in small windows
+  mpSatellitesWidget->setAutoReplot( false  );  // plot on demand (after all data has been handled)
   mpSatellitesWidget->setPlotBackground( Qt::white );
   // scales
-  mpSatellitesWidget->setScale( QwtPolar::Azimuth,
-                                0, //min
-                                360, //max
-                                30 //interval
+  mpSatellitesWidget->setScale( QwtPolar::ScaleAzimuth,
+                                360, //min - reverse the min/max values to get compass orientation - increasing clockwise
+                                0, //max
+                                90 //interval - just show cardinal and intermediate (NE, N, NW, etc.) compass points (in degrees)
                               );
+  mpSatellitesWidget->setAzimuthOrigin( M_PI_2 );    // to get compass orientation - need to rotate 90 deg. ccw; this is in Radians (not indicated in QwtPolarPlot docs)
 
-  mpSatellitesWidget->setScaleMaxMinor( QwtPolar::Azimuth, 10 );
-  mpSatellitesWidget->setScale( QwtPolar::Radius,
-                                0, //min
-                                100 //max
+//  mpSatellitesWidget->setScaleMaxMinor( QwtPolar::ScaleRadius, 2 );  // seems unnecessary
+  mpSatellitesWidget->setScale( QwtPolar::ScaleRadius,
+                                90, //min - reverse the min/max to get 0 at edge, 90 at center
+                                0, //max
+                                45 //interval
                               );
 
   // grids, axes
 
   QwtPolarGrid * mypSatellitesGrid = new QwtPolarGrid();
+  mypSatellitesGrid->setGridAttribute( QwtPolarGrid::AutoScaling, false );   // This fixes the issue of autoscaling on the Radius grid. It is ON by default AND is separate from the scaleData.doAutoScale in QwtPolarPlot::setScale(), etc. THIS IS VERY TRICKY!
   mypSatellitesGrid->setPen( QPen( Qt::black ) );
+  QPen minorPen( Qt::gray );  // moved outside of for loop; NOTE setting the minor pen isn't necessary if the minor grids aren't shown
   for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
   {
-    mypSatellitesGrid->showGrid( scaleId );
+    //mypSatellitesGrid->showGrid( scaleId );
     //mypSatellitesGrid->showMinorGrid(scaleId);
-    QPen minorPen( Qt::gray );
     mypSatellitesGrid->setMinorGridPen( scaleId, minorPen );
   }
-  mypSatellitesGrid->setAxisPen( QwtPolar::AxisAzimuth, QPen( Qt::black ) );
+//  mypSatellitesGrid->setAxisPen( QwtPolar::AxisAzimuth, QPen( Qt::black ) );
 
   mypSatellitesGrid->showAxis( QwtPolar::AxisAzimuth, true );
   mypSatellitesGrid->showAxis( QwtPolar::AxisLeft, false ); //alt axis
   mypSatellitesGrid->showAxis( QwtPolar::AxisRight, false );//alt axis
   mypSatellitesGrid->showAxis( QwtPolar::AxisTop, false );//alt axis
   mypSatellitesGrid->showAxis( QwtPolar::AxisBottom, false );//alt axis
-  mypSatellitesGrid->showGrid( QwtPolar::Azimuth, true );
-  mypSatellitesGrid->showGrid( QwtPolar::Radius, true );
+  mypSatellitesGrid->showGrid( QwtPolar::ScaleAzimuth, false ); // hide the grid; just show ticks at edge
+  mypSatellitesGrid->showGrid( QwtPolar::ScaleRadius, true );
+//  mypSatellitesGrid->showMinorGrid( QwtPolar::ScaleAzimuth, true );
+  mypSatellitesGrid->showMinorGrid( QwtPolar::ScaleRadius, true );   // for 22.5, 67.5 degree circles
   mypSatellitesGrid->attach( mpSatellitesWidget );
 
   //QwtLegend *legend = new QwtLegend;
@@ -142,13 +156,21 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
   mpPolarLayout->addWidget( mpSatellitesWidget );
   mpPolarWidget->setLayout( mpPolarLayout );
 
+  // replot on command
+  mpSatellitesWidget->replot();
+  mpPlot->replot();
 
   // Restore state
   QSettings mySettings;
+  mGroupShowMarker->setChecked(  mySettings.value( "/gps/showMarker", "true" ).toBool() );
   mSliderMarkerSize->setValue( mySettings.value( "/gps/markerSize", "12" ).toInt() );
   mSpinTrackWidth->setValue( mySettings.value( "/gps/trackWidth", "2" ).toInt() );
+  mTrackColour = mySettings.value( "/gps/trackColour", QColor( Qt::red ) ).value<QColor>();
   QString myPortMode = mySettings.value( "/gps/portMode", "scanPorts" ).toString();
 
+  mSpinMapExtentMultiplier->setValue( mySettings.value( "/gps/mapExtentMultiplier", "50" ).toInt() );
+  mDateTimeFormat = mySettings.value( "/gps/dateTimeFormat", "" ).toString(); // zero-length string signifies default format
+
   mGpsdHost->setText( mySettings.value( "/gps/gpsdHost", "localhost" ).toString() );
   mGpsdPort->setText( mySettings.value( "/gps/gpsdPort", 2947 ).toString() );
   mGpsdDevice->setText( mySettings.value( "/gps/gpsdDevice" ).toString() );
@@ -166,9 +188,12 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
   {
     mRadGpsd->setChecked( true );
   }
+
   //auto digitising behaviour
-  bool myAutoAddVertexFlag = mySettings.value( "/gps/autoAddVertices", "false" ).toBool();
-  mCbxAutoAddVertices->setChecked( myAutoAddVertexFlag );
+  mCbxAutoAddVertices->setChecked( mySettings.value( "/gps/autoAddVertices", "false" ).toBool() );
+
+  mCbxAutoCommit->setChecked( mySettings.value( "/gps/autoCommit", "false" ).toBool() );
+
   //pan mode
   QString myPanMode = mySettings.value( "/gps/panMode", "recenterWhenNeeded" ).toString();
   if ( myPanMode == "none" )
@@ -184,25 +209,45 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi
     radRecenterWhenNeeded->setChecked( true );
   }
   // Set up the rubber band to show digitising
-  createRubberBand();
+
   mWgs84CRS.createFromOgcWmsCrs( "EPSG:4326" );
-  //for now I am hiding accuracy and date widgets
-  mDateTime->hide();
-  mVerticalAccuracy->hide();
-  mHorizontalAccuracy->hide();
-  mBtnDebug->hide();
+
+  mBtnDebug->setVisible(mySettings.value( "/gps/showDebug", "false" ).toBool());  // use a registry setting to control - power users/devs could set it
+
+  // status = unknown
+  setStatusIndicator( NoData );
+
+  //SLM - added functionality
+  mLogFile = 0;
+
+  connect( mpLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
+           this, SLOT( updateCloseFeatureButton( QgsMapLayer* ) ) );
+
+  mStackedWidget->setCurrentIndex( 3 ); // force to Options
+  mBtnPosition->setFocus( Qt::TabFocusReason );
 }
 
 QgsGPSInformationWidget::~QgsGPSInformationWidget()
 {
+  if ( mNmea )
+  {
+      disconnectGps();
+  }
+
   if ( mpMapMarker )
     delete mpMapMarker;
 
   QSettings mySettings;
   mySettings.setValue( "/gps/lastPort", mCboDevices->itemData( mCboDevices->currentIndex() ).toString() );
   mySettings.setValue( "/gps/trackWidth", mSpinTrackWidth->value() );
+  mySettings.setValue( "/gps/trackColour", mTrackColour );
   mySettings.setValue( "/gps/markerSize", mSliderMarkerSize->value() );
+  mySettings.setValue( "/gps/showMarker", mGroupShowMarker->isChecked() );
   mySettings.setValue( "/gps/autoAddVertices", mCbxAutoAddVertices->isChecked() );
+  mySettings.setValue( "/gps/autoCommit", mCbxAutoCommit->isChecked() );
+
+  mySettings.setValue( "/gps/mapExtentMultiplier", mSpinMapExtentMultiplier->value() );
+
   // scan, explicit port or gpsd
   if ( mRadAutodetect->isChecked() )
   {
@@ -243,8 +288,6 @@ QgsGPSInformationWidget::~QgsGPSInformationWidget()
 
 void QgsGPSInformationWidget::on_mSpinTrackWidth_valueChanged( int theValue )
 {
-  QSettings mySettings;
-  mySettings.setValue( "/gps/trackWidth", theValue );
   if ( mpRubberBand )
   {
     mpRubberBand->setWidth( theValue );
@@ -253,18 +296,18 @@ void QgsGPSInformationWidget::on_mSpinTrackWidth_valueChanged( int theValue )
 
 void QgsGPSInformationWidget::on_mBtnTrackColour_clicked( )
 {
-  QSettings mySettings;
-  QColor myColor( mySettings.value( "/qgis/gps/line_color_red", 255 ).toInt(),
-                  mySettings.value( "/qgis/gps/line_color_green", 0 ).toInt(),
-                  mySettings.value( "/qgis/gps/line_color_blue", 0 ).toInt() );
-  myColor = QColorDialog::getColor( myColor, this );
-  mySettings.setValue( "/qgis/gps/line_color_red", myColor.red() );
-  mySettings.setValue( "/qgis/gps/line_color_green", myColor.green() );
-  mySettings.setValue( "/qgis/gps/line_color_blue", myColor.blue() );
-  setTrackColour();
+  QColor myColor = QColorDialog::getColor( mTrackColour, this );
+  if ( myColor.isValid() )  // check that a color was picked
+  {
+    mTrackColour = myColor;
+    if ( mpRubberBand )
+    {
+      mpRubberBand->setColor( myColor );
+    }
+  }
 }
 
-
+#if 0 //no longer used
 void QgsGPSInformationWidget::setTrackColour( )
 {
   QSettings mySettings;
@@ -276,19 +319,24 @@ void QgsGPSInformationWidget::setTrackColour( )
     mpRubberBand->setColor( myColor );
   }
 }
+#endif
+
 void QgsGPSInformationWidget::on_mBtnPosition_clicked( )
 {
   mStackedWidget->setCurrentIndex( 0 );
+  if ( mNmea ) displayGPSInformation( mNmea->currentGPSInformation() );
 }
 
 void QgsGPSInformationWidget::on_mBtnSignal_clicked( )
 {
   mStackedWidget->setCurrentIndex( 1 );
+  if ( mNmea ) displayGPSInformation( mNmea->currentGPSInformation() );
 }
 
 void QgsGPSInformationWidget::on_mBtnSatellites_clicked( )
 {
   mStackedWidget->setCurrentIndex( 2 );
+  if ( mNmea ) displayGPSInformation( mNmea->currentGPSInformation() );
 }
 
 void QgsGPSInformationWidget::on_mBtnOptions_clicked( )
@@ -315,6 +363,24 @@ void QgsGPSInformationWidget::on_mConnectButton_toggled( bool theFlag )
 
 void QgsGPSInformationWidget::connectGps()
 {
+  // clear position page fields to give better indication that something happened (or didn't happen)
+  mTxtLatitude->clear();
+  mTxtLongitude->clear();
+  mTxtAltitude->clear();
+  mTxtDateTime->clear();
+  mTxtSpeed->clear();
+  mTxtDirection->clear();
+  mTxtHdop->clear();
+  mTxtVdop->clear();
+  mTxtPdop->clear();
+  mTxtFixMode->clear();
+  mTxtFixType->clear();
+  mTxtQuality->clear();
+  mTxtSatellitesUsed->clear();
+  mTxtStatus->clear();
+
+  mLastGpsPosition = QgsPoint( 0.0, 0.0 );
+
   QString port;
 
   if ( mRadUserPath->isChecked() )
@@ -335,18 +401,21 @@ void QgsGPSInformationWidget::connectGps()
     port = QString( "%1:%2:%3" ).arg( mGpsdHost->text() ).arg( mGpsdPort->text() ).arg( mGpsdDevice->text() );
   }
 
-  mGPSTextEdit->append( tr( "Connecting..." ) );
+  mGPSPlainTextEdit->appendPlainText( tr( "Connecting..." ) );
+  showStatusBarMessage( tr( "Connecting to GPS device..." ) );
 
   QgsGPSDetector *detector = new QgsGPSDetector( port );
   connect( detector, SIGNAL( detected( QgsGPSConnection * ) ), this, SLOT( connected( QgsGPSConnection * ) ) );
   connect( detector, SIGNAL( detectionFailed() ), this, SLOT( timedout() ) );
+  detector->advance();   // start the detection process
 }
 
 void QgsGPSInformationWidget::timedout()
 {
   mConnectButton->setChecked( false );
   mNmea = NULL;
-  mGPSTextEdit->append( tr( "Timed out!" ) );
+  mGPSPlainTextEdit->appendPlainText( tr( "Timed out!" ) );
+  showStatusBarMessage( tr( "Failed to connect to GPS device." ) );
 }
 
 void QgsGPSInformationWidget::connected( QgsGPSConnection *conn )
@@ -354,158 +423,328 @@ void QgsGPSInformationWidget::connected( QgsGPSConnection *conn )
   mNmea = conn;
   QObject::connect( mNmea, SIGNAL( stateChanged( const QgsGPSInformation& ) ),
                     this, SLOT( displayGPSInformation( const QgsGPSInformation& ) ) );
-  mGPSTextEdit->append( tr( "Connected!" ) );
-  mConnectButton->setText( tr( "Disconnect" ) );
+  mGPSPlainTextEdit->appendPlainText( tr( "Connected!" ) );
+  mConnectButton->setText( tr( "Dis&connect" ) );
   //insert connection into registry such that it can also be used by other dialogs or plugins
   QgsGPSConnectionRegistry::instance()->registerConnection( mNmea );
+  showStatusBarMessage( tr( "Connected to GPS device." ) );
+
+  if ( mLogFileGroupBox->isChecked() && ! mTxtLogFile->text().isEmpty() )
+  {
+    if ( ! mLogFile )
+    {
+      mLogFile = new QFile( mTxtLogFile->text() );
+    }
+
+    if ( mLogFile->open( QIODevice::Append ) )  // open in binary and explicitly output CR + LF per NMEA
+    {
+      mLogFileTextStream.setDevice( mLogFile );
+
+      // crude way to separate chunks - use when manually editing file - NMEA parsers should discard
+      mLogFileTextStream << "====" << "\r\n";
+
+      QObject::connect( mNmea, SIGNAL( nmeaSentenceReceived( const QString& ) ), this, SLOT( logNmeaSentence( const QString& ) ) ); // added to handle raw data
+    }
+    else  // error opening file
+    {
+      delete mLogFile;
+      mLogFile = 0;
+
+      // need to indicate why - this just reports that an error occurred
+      showStatusBarMessage( tr( "Error opening log file." ) );
+    }
+  }
 }
 
 void QgsGPSInformationWidget::disconnectGps()
 {
+  if ( mLogFile && mLogFile->isOpen() )
+  {
+    QObject::disconnect( mNmea, SIGNAL( nmeaSentenceReceived( const QString& ) ), this, SLOT( logNmeaSentence( const QString& ) ) );
+    mLogFile->close();
+    delete mLogFile;
+    mLogFile = 0;
+  }
+
   QgsGPSConnectionRegistry::instance()->unregisterConnection( mNmea );
   delete mNmea;
-  mGPSTextEdit->append( tr( "Disconnected..." ) );
+  mNmea = NULL;
+  if ( mpMapMarker )  // marker should not be shown on GPS disconnected - not current position
+  {
+    delete mpMapMarker;
+    mpMapMarker = NULL;
+  }
+  mGPSPlainTextEdit->appendPlainText( tr( "Disconnected..." ) );
   mConnectButton->setChecked( false );
-  mConnectButton->setText( tr( "Connect" ) );
-}
+  mConnectButton->setText( tr( "&Connect" ) );
+  showStatusBarMessage( tr( "Disconnected from GPS device." ) );
 
+  setStatusIndicator( NoData );
+
+}
 
 void QgsGPSInformationWidget::displayGPSInformation( const QgsGPSInformation& info )
 {
-  mGPSTextEdit->clear();
-
   QwtArray<double> myXData;//qwtarray is just a wrapped qvector
   QwtArray<double> mySignalData;//qwtarray is just a wrapped qvector
-  mpPlot->setAxisScale( QwtPlot::xBottom, 0, info.satellitesInView.size() );
-  while ( !mMarkerList.isEmpty() )
+
+  // set validity flag and status from GPS data
+  // based on GGA, GSA and RMC sentences - the logic does not require all
+  bool validFlag = false; // true if GPS indicates position fix
+  FixStatus fixStatus = NoData;
+
+  // no fix if any of the three report bad; default values are invalid values and won't be changed if the corresponding NMEA msg is not received
+  if ( info.status == 'V' || info.fixType == NMEA_FIX_BAD || info.quality == 0 ) // some sources say that 'V' indicates position fix, but is below acceptable quality
+  {
+    fixStatus = NoFix;
+  }
+  else if ( info.fixType == NMEA_FIX_2D ) // 2D indication (from GGA)
+  {
+    fixStatus = Fix2D;
+    validFlag = true;
+  }
+  else if ( info.status == 'A' || info.fixType == NMEA_FIX_3D || info.quality > 0 ) // good
+  {
+    fixStatus = Fix3D;
+    validFlag = true;
+  }
+  else  // unknown status (not likely)
   {
-    delete mMarkerList.takeFirst();
   }
 
-  for ( int i = 0; i < info.satellitesInView.size(); ++i )
+  // set visual status indicator -- do only on change of state
+  if ( fixStatus != mLastFixStatus )
   {
-    QgsSatelliteInfo currentInfo = info.satellitesInView.at( i );
+    setStatusIndicator( fixStatus );
+  }
 
-    myXData.append( i );
-    mySignalData.append( 0 );
-    myXData.append( i );
-    mySignalData.append( currentInfo.signal );
-    myXData.append( i + 1 );
-    mySignalData.append( currentInfo.signal );
-    myXData.append( i + 1 );
-    mySignalData.append( 0 );
-    mGPSTextEdit->append( "Satellite" );
-    if ( currentInfo.inUse )
+  if ( mStackedWidget->currentIndex() == 1 && info.satInfoComplete ) //signal
+  {
+    mpPlot->setAxisScale( QwtPlot::xBottom, 0, info.satellitesInView.size() );
+  } //signal
+
+  if ( mStackedWidget->currentIndex() == 2 && info.satInfoComplete ) //satellites
+  {
+    while ( !mMarkerList.isEmpty() )
     {
-      mGPSTextEdit->append( "In use" );
+      delete mMarkerList.takeFirst();
     }
-    else
+  } //satellites
+
+  if ( mStackedWidget->currentIndex() == 4 ) //debug
+  {
+    mGPSPlainTextEdit->clear();
+  } //debug
+
+  for ( int i = 0; i < info.satellitesInView.size(); ++i ) //satellite processing loop
+  {
+    QgsSatelliteInfo currentInfo = info.satellitesInView.at( i );
+
+    if ( mStackedWidget->currentIndex() == 1 && info.satInfoComplete ) //signal
     {
-      mGPSTextEdit->append( "Not in use" );
-    }
-    mGPSTextEdit->append( "id: " + QString::number( currentInfo.id ) );
-    mGPSTextEdit->append( "elevation: " + QString::number( currentInfo.elevation ) );
-    mGPSTextEdit->append( "azimuth: " + QString::number( currentInfo.azimuth ) );
-    mGPSTextEdit->append( "signal: " + QString::number( currentInfo.signal ) );
-    // Add a marker to the polar plot
-    QwtPolarMarker *mypMarker = new QwtPolarMarker();
-    mypMarker->setPosition( QwtPolarPoint( currentInfo.azimuth, currentInfo.elevation ) );
-    QColor myColour;
-    if ( currentInfo.signal < 30 ) //weak signal
+      myXData.append( i );
+      mySignalData.append( 0 );
+      myXData.append( i );
+      mySignalData.append( currentInfo.signal );
+      myXData.append( i + 1 );
+      mySignalData.append( currentInfo.signal );
+      myXData.append( i + 1 );
+      mySignalData.append( 0 );
+    } //signal
+
+#if 0
+    if ( mStackedWidget->currentIndex() == 4 ) //debug
     {
-      myColour = Qt::red;
-    }
-    else
+#if 0   // temporarily removed as the info isn't being set in GSA/GSV processing
+      //    mGPSPlainTextEdit->appendPlainText( "Satellite" );
+      if ( currentInfo.inUse )
+      {
+        mGPSPlainTextEdit->appendPlainText( "Satellite In use" );
+      }
+      else
+      {
+        mGPSPlainTextEdit->appendPlainText( "Satellite Not in use" );
+      }
+#endif
+#if 0
+      mGPSPlainTextEdit->appendPlainText( "id: " + QString::number( currentInfo.id ) );
+      mGPSPlainTextEdit->appendPlainText( "elevation: " + QString::number( currentInfo.elevation ) );
+      mGPSPlainTextEdit->appendPlainText( "azimuth: " + QString::number( currentInfo.azimuth ) );
+      mGPSPlainTextEdit->appendPlainText( "signal: " + QString::number( currentInfo.signal ) );
+#else // as a single line per satellite - easier to read
+      mGPSPlainTextEdit->appendPlainText( "sat: " + QString::number( currentInfo.id )
+      + ", elev: " + QString::number( currentInfo.elevation )
+      + ", azimuth: " + QString::number( currentInfo.azimuth )
+      + ", signal: " + QString::number( currentInfo.signal ) );
+#endif
+    } //debug
+#endif
+
+    if ( mStackedWidget->currentIndex() == 2 && info.satInfoComplete ) //satellites
     {
-      myColour = Qt::black; //strong signal
-    }
-    mypMarker->setSymbol( QwtSymbol( QwtSymbol::Ellipse,
-                                     QBrush( Qt::black ), QPen( myColour ), QSize( 9, 9 ) ) );
-    mypMarker->setLabelAlignment( Qt::AlignHCenter | Qt::AlignTop );
-    QwtText text( QString::number( currentInfo.id ) );
-    text.setColor( myColour );
-    QColor bg( Qt::white );
-    bg.setAlpha( 200 );
-    text.setBackgroundBrush( QBrush( bg ) );
-    mypMarker->setLabel( text );
-    mypMarker->attach( mpSatellitesWidget );
-    mMarkerList << mypMarker;
-  }
-  mpCurve->setData( myXData, mySignalData );
-  mpPlot->replot();
-  if ( mpMapMarker )
-    delete mpMapMarker;
+      QColor bg( Qt::white ); // moved several items outside of the following if block to minimize loop time
+      bg.setAlpha( 200 );
+      QColor myColour;
+      QBrush symbolBrush( Qt::black );
+      QBrush textBgBrush( bg );
+      QSize markerSize( 9, 9 );
+      // Add a marker to the polar plot
+      if ( currentInfo.id > 0 )       // don't show satellite if id=0 (no satellite indication)
+      {
+        QwtPolarMarker *mypMarker = new QwtPolarMarker();
+        mypMarker->setPosition( QwtPolarPoint( currentInfo.azimuth, currentInfo.elevation ) );
+        if ( currentInfo.signal < 30 ) //weak signal
+        {
+          myColour = Qt::red;
+        }
+        else
+        {
+          myColour = Qt::black; //strong signal
+        }
+        mypMarker->setSymbol( QwtSymbol( QwtSymbol::Ellipse,
+                                         symbolBrush , QPen( myColour ), markerSize ) );
+        mypMarker->setLabelAlignment( Qt::AlignHCenter | Qt::AlignTop );
+        QwtText text( QString::number( currentInfo.id ) );
+        text.setColor( myColour );
+        text.setBackgroundBrush( textBgBrush );
+        mypMarker->setLabel( text );
+        mypMarker->attach( mpSatellitesWidget );
+        mMarkerList << mypMarker;
+      } // currentInfo.id > 0
+    } //satellites
+  } //satellite processing loop
+
+  if ( mStackedWidget->currentIndex() == 1 && info.satInfoComplete ) //signal
+  {
+    mpCurve->setData( myXData, mySignalData );
+    mpPlot->replot();
+  } //signal
+
+  if ( mStackedWidget->currentIndex() == 2 && info.satInfoComplete ) //satellites
+  {
+    mpSatellitesWidget->replot();
+  } //satellites
 
-  //after loosing connection, the first gps info sometimes has uninitialized coords
   QgsPoint myNewCenter;
-  if ( doubleNear( info.longitude, 0.0 ) && doubleNear( info.latitude, 0.0 ) )
+  if ( validFlag )
   {
-    myNewCenter = mLastGpsPosition;
+    myNewCenter = QgsPoint( info.longitude, info.latitude );
   }
   else
   {
-    myNewCenter = QgsPoint( info.longitude, info.latitude );
+    myNewCenter = mLastGpsPosition;
   }
 
-  if ( mGroupShowMarker->isChecked() )
+  if ( mStackedWidget->currentIndex() == 0 ) //position
   {
-    mpMapMarker = new QgsGpsMarker( mpCanvas );
-    mpMapMarker->setSize( mSliderMarkerSize->value() );
-    mpMapMarker->setCenter( myNewCenter );
-    mpMapMarker->update();
-  }
-  else
+    mTxtLatitude->setText( QString::number( info.latitude, 'f', 8 ) );
+    mTxtLongitude->setText( QString::number( info.longitude, 'f', 8 ) );
+    mTxtAltitude->setText( tr( "%1 m" ).arg( info.elevation, 0, 'f', 1 ) ); // don't know of any GPS receivers that output better than 0.1 m precision
+    if ( mDateTimeFormat.isEmpty() )
+    {
+      mTxtDateTime->setText( info.utcDateTime.toString( Qt::TextDate ) );  // default format
+    }
+    else
+    {
+      mTxtDateTime->setText( info.utcDateTime.toString( mDateTimeFormat ) );  //user specified format string for testing the millisecond part of time
+    }
+    mTxtSpeed->setText( tr( "%1 km/h" ).arg( info.speed, 0, 'f', 1 ) );
+    mTxtDirection->setText( QString::number( info.direction, 'f', 1 ) );
+    mTxtHdop->setText( QString::number( info.hdop, 'f', 1 ) );
+    mTxtVdop->setText( QString::number( info.vdop, 'f', 1 ) );
+    mTxtPdop->setText( QString::number( info.pdop, 'f', 1 ) );
+    mTxtFixMode->setText( info.fixMode == 'A' ? tr( "Automatic" ) : info.fixMode == 'M' ? tr( "Manual" ) : "" ); // A=automatic 2d/3d, M=manual; allowing for anything else
+    mTxtFixType->setText( info.fixType == 3 ? tr( "3D" ) : info.fixType == 2 ? tr( "2D" ) : info.fixType == 1 ? tr( "No fix" ) : QString::number( info.fixType) ); // 1=no fix, 2=2D, 3=3D; allowing for anything else
+    mTxtQuality->setText( info.quality == 2 ? tr( "Differential" ) : info.quality == 1 ? tr( "Non-differential" ) : info.quality == 0 ? tr( "No position" ) : info.quality > 2 ? QString::number( info.quality) : "" ); // allowing for anything else
+    mTxtSatellitesUsed->setText( QString::number( info.satellitesUsed ) );
+    mTxtStatus->setText( info.status == 'A' ? tr( "Valid") : info.status == 'V' ? tr( "Invalid" ) : "" );
+  } //position
+
+#if 0
+  if ( mStackedWidget->currentIndex() == 4 )    //debug
   {
-    mpMapMarker = 0;
-  }
-  mSpinLatitude->setValue( info.latitude );
-  mSpinLongitude->setValue( info.longitude );
-  mSpinElevation->setValue( info.elevation );
-  mHorizontalAccuracy->setValue( 10 - info.hdop );
-  mVerticalAccuracy->setValue( 10 - info.vdop );
-  mGPSTextEdit->append( "longitude: " + QString::number( info.longitude ) );
-  mGPSTextEdit->append( "latitude: " + QString::number( info.latitude ) );
-  mGPSTextEdit->append( "elevation: " + QString::number( info.elevation ) );
-  mGPSTextEdit->append( "pdop: " + QString::number( info.pdop ) );
-  mGPSTextEdit->append( "hdop: " + QString::number( info.hdop ) );
-  mGPSTextEdit->append( "vdop: " + QString::number( info.vdop ) );
+    QString s;
+    for ( int i = 0; i < info.satPrn.size(); i++ )
+    {
+      if ( info.satPrn.at( i ) > 0 )  //don't show 0 (no satellite)
+      {
+        s.append( QString::number( info.satPrn.at( i ) ).append( " " ) );
+      }
+    }
+    mGPSPlainTextEdit->appendPlainText( "UTC date/time: " + info.utcDateTime.toString() );
+    mGPSPlainTextEdit->appendPlainText( "longitude: " + QString::number( info.longitude, 'f', 8 ) );
+    mGPSPlainTextEdit->appendPlainText( "latitude: " + QString::number( info.latitude, 'f', 8 ) );
+    mGPSPlainTextEdit->appendPlainText( "elevation: " + QString::number( info.elevation ) );
+    mGPSPlainTextEdit->appendPlainText( "speed (knots): " + QString::number( info.speed ) );
+    mGPSPlainTextEdit->appendPlainText( "direction: " + QString::number( info.direction ) );
+    mGPSPlainTextEdit->appendPlainText( "pdop: " + QString::number( info.pdop ) );
+    mGPSPlainTextEdit->appendPlainText( "hdop: " + QString::number( info.hdop ) );
+    mGPSPlainTextEdit->appendPlainText( "vdop: " + QString::number( info.vdop ) );
+    mGPSPlainTextEdit->appendPlainText( "satellites in use: " + s );
+    mGPSPlainTextEdit->appendPlainText( "fix mode: " + QString( info.fixMode ) );
+    mGPSPlainTextEdit->appendPlainText( "fix type: " + QString::number( info.fixType ) );
+  } //debug
+#endif
 
   // Avoid refreshing / panning if we havent moved
   if ( mLastGpsPosition != myNewCenter )
   {
     mLastGpsPosition = myNewCenter;
-    if ( mCbxAutoAddVertices->isChecked() )
-    {
-      addVertex();
-    }
-    // Pan based on user specified behaviour
 
+    // Pan based on user specified behaviour
     if ( radRecenterMap->isChecked() || radRecenterWhenNeeded->isChecked() )
     {
       QgsCoordinateReferenceSystem mypSRS = mpCanvas->mapRenderer()->destinationCrs();
-      QgsCoordinateReferenceSystem myLatLongRefSys = QgsCoordinateReferenceSystem( 4326 );
-      QgsCoordinateTransform myTransform( myLatLongRefSys, mypSRS );
+      QgsCoordinateTransform myTransform( mWgs84CRS, mypSRS ); // use existing WGS84 CRS
 
       QgsPoint myPoint = myTransform.transform( myNewCenter );
       //keep the extent the same just center the map canvas in the display so our feature is in the middle
-      QgsRectangle myRect(
-        myPoint.x( ) - ( mpCanvas->extent( ).width( ) / 2 ),
-        myPoint.y( ) - ( mpCanvas->extent( ).height( ) / 2 ),
-        myPoint.x( ) + ( mpCanvas->extent( ).width( ) / 2 ),
-        myPoint.y( ) + ( mpCanvas->extent( ).height( ) / 2 ) );
+      QgsRectangle myRect( myPoint, myPoint );  // empty rect can be used to set new extent that is centered on the point used to construct the rect
+
+      // testing if position is outside some proportion of the map extent
+      // this is a user setting - useful range: 5% to 100% (0.05 to 1.0)
+      QgsRectangle myExtentLimit( mpCanvas->extent() );
+      myExtentLimit.scale( mSpinMapExtentMultiplier->value() * 0.01 );
 
       // only change the extents if the point is beyond the current extents to minimise repaints
-      if (( !mpCanvas->extent().contains( myPoint ) &&
-            radRecenterWhenNeeded->isChecked() ) ||
-          radRecenterMap->isChecked() )
+      if ( radRecenterMap->isChecked() ||
+           ( radRecenterWhenNeeded->isChecked() && !myExtentLimit.contains( myPoint ) ) )
       {
         mpCanvas->setExtent( myRect );
         mpCanvas->refresh( );
       }
     } //otherwise never recenter automatically
+
+    if ( mCbxAutoAddVertices->isChecked() )
+    {
+      addVertex();
+    }
+  } // mLastGpsPosition != myNewCenter
+
+  // new marker position after recentering
+  if ( mGroupShowMarker->isChecked() ) // show marker
+  {
+    if ( validFlag ) // update cursor position if valid position
+    {                // initially, cursor isn't drawn until first valid fix; remains visible until GPS disconnect
+      if ( ! mpMapMarker )
+      {
+        mpMapMarker = new QgsGpsMarker( mpCanvas );
+      }
+      mpMapMarker->setSize( mSliderMarkerSize->value() );
+      mpMapMarker->setCenter( myNewCenter );
+    }
   }
+  else
+  {
+    if ( mpMapMarker )
+    {
+      delete mpMapMarker;
+      mpMapMarker = 0;
+    }
+  } // show marker
 }
 
+#if 0 // not needed - signals/slots set up in UI file; may be needed in the future if GPS valid is used to control whether button is available (should use enable/disable instead of show/hide)
 void QgsGPSInformationWidget::on_mCbxAutoAddVertices_toggled( bool theFlag )
 {
   if ( theFlag )
@@ -517,6 +756,7 @@ void QgsGPSInformationWidget::on_mCbxAutoAddVertices_toggled( bool theFlag )
     mBtnAddVertex->show();
   }
 }
+#endif
 
 void QgsGPSInformationWidget::on_mBtnAddVertex_clicked( )
 {
@@ -535,6 +775,8 @@ void QgsGPSInformationWidget::addVertex( )
   // calling close feature
   mCaptureList.push_back( mLastGpsPosition );
   // we store the rubber band points in map canvas CRS so transform to map crs
+  // potential problem with transform errors and wrong coordinates if map CRS is changed after points are stored - SLM
+  // should catch map CRS change and transform the points
   QgsPoint myPoint;
   if ( mpCanvas && mpCanvas->mapRenderer() )
   {
@@ -550,53 +792,50 @@ void QgsGPSInformationWidget::addVertex( )
 
 void QgsGPSInformationWidget::on_mBtnResetFeature_clicked( )
 {
-  mNmea->disconnect();
-  if ( mpRubberBand )
-  {
-    delete mpRubberBand;
-    mpRubberBand = 0;
-  }
-  createRubberBand( );
+  mNmea->disconnect( this, SLOT( displayGPSInformation( const QgsGPSInformation& ) ) );
+  createRubberBand( ); //deletes existing rubberband
   mCaptureList.clear();
   connectGpsSlot();
 }
 
 void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked( )
 {
-  mNmea->disconnect();
   QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mpCanvas->currentLayer() );
+  QGis::WkbType layerWKBType = vlayer->wkbType();
 
   // -------------- preconditions ------------------------
+  // most of these preconditions are already handled due to the button being enabled/disabled based on layer geom type and editing capabilities, but not on valid GPS data
+#if 0
   if ( !vlayer )
   {
     QMessageBox::information( 0, tr( "Not a vector layer" ),
                               tr( "The current layer is not a vector layer" ) );
-    connectGpsSlot();
     return;
   }
   QGis::WkbType layerWKBType = vlayer->wkbType();
 
   //no support for adding features to 2.5D types yet
-  if ( layerWKBType == QGis::WKBLineString25D || layerWKBType == QGis::WKBPolygon25D ||
-       layerWKBType == QGis::WKBMultiLineString25D || layerWKBType == QGis::WKBPoint25D || layerWKBType == QGis::WKBMultiPoint25D )
+  if ( layerWKBType == QGis::WKBPoint25D ||
+       layerWKBType == QGis::WKBLineString25D ||
+       layerWKBType == QGis::WKBPolygon25D ||
+       layerWKBType == QGis::WKBMultiPoint25D ||
+       layerWKBType == QGis::WKBMultiLineString25D ||
+       layerWKBType == QGis::WKBMultiPolygon25D )
   {
     QMessageBox::critical( 0, tr( "2.5D shape type not supported" ), tr(
                              "Adding features to 2.5D shapetypes is not supported yet. Please "
                              "select a different editable, non 2.5D layer and try again." ) );
-    connectGpsSlot();
     return;
   }
 
   // Multipart features not supported
-  if ( layerWKBType == QGis::WKBMultiLineString ||
-       layerWKBType == QGis::WKBMultiPoint ||
+  if ( layerWKBType == QGis::WKBMultiPoint ||
        layerWKBType == QGis::WKBMultiLineString ||
        layerWKBType == QGis::WKBMultiPolygon )
   {
     QMessageBox::critical( 0, tr( "Multipart shape type not supported" ), tr(
                              "Adding features to multipart shapetypes is not supported yet. Please "
                              "select a different editable, non 2.5D layer and try again." ) );
-    connectGpsSlot();
     return;
 
   }
@@ -607,7 +846,6 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked( )
   {
     QMessageBox::information( 0, tr( "Layer cannot be added to" ),
                               tr( "The data provider for this layer does not support the addition of features." ) );
-    connectGpsSlot();
     return;
   }
 
@@ -616,16 +854,15 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked( )
     QMessageBox::information( 0, tr( "Layer not editable" ),
                               tr( "Cannot edit the vector layer. Use 'Toggle Editing' to make it editable." )
                             );
-    connectGpsSlot();
     return;
   }
+#endif
 
   //lines: bail out if there are not at least two vertices
   if ( layerWKBType == QGis::WKBLineString  && mCaptureList.size() < 2 )
   {
     QMessageBox::information( 0, tr( "Not enough vertices" ),
                               tr( "Cannot close a line feature until it has at least two vertices." ) );
-    connectGpsSlot();
     return;
   }
 
@@ -634,7 +871,6 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked( )
   {
     QMessageBox::information( 0, tr( "Not enough vertices" ),
                               tr( "Cannot close a polygon feature until it has at least three vertices." ) );
-    connectGpsSlot();
     return;
   }
   // -------------- end of preconditions ------------------------
@@ -644,42 +880,53 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked( )
   //
   if ( layerWKBType == QGis::WKBPoint )
   {
-    //only do the rest for provider with feature addition support
-    //note that for the grass provider, this will return false since
-    //grass provider has its own mechanism of feature addition
-    if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures )
-    {
-      QgsFeature* f = new QgsFeature( 0, "WKBPoint" );
-
-      int size = 0;
-      char end = QgsApplication::endian();
-      unsigned char *wkb = NULL;
-      int wkbtype = 0;
+    QgsFeature* f = new QgsFeature( 0, "WKBPoint" );
 
-      QgsCoordinateTransform t( mWgs84CRS, vlayer->crs() );
-      QgsPoint myPoint = t.transform( mLastGpsPosition );
-      double x = myPoint.x();
-      double y = myPoint.y();
+    int size = 0;
+    char end = QgsApplication::endian();
+    unsigned char *wkb = NULL;
+    int wkbtype = 0;
 
-      size = 1 + sizeof( int ) + 2 * sizeof( double );
-      wkb = new unsigned char[size];
-      wkbtype = QGis::WKBPoint;
-      memcpy( &wkb[0], &end, 1 );
-      memcpy( &wkb[1], &wkbtype, sizeof( int ) );
-      memcpy( &wkb[5], &x, sizeof( double ) );
-      memcpy( &wkb[5] + sizeof( double ), &y, sizeof( double ) );
+    QgsCoordinateTransform t( mWgs84CRS, vlayer->crs() );
+    QgsPoint myPoint = t.transform( mLastGpsPosition );
+    double x = myPoint.x();
+    double y = myPoint.y();
 
-      f->setGeometryAndOwnership( &wkb[0], size );
+    size = 1 + sizeof( int ) + 2 * sizeof( double );
+    wkb = new unsigned char[size];
+    wkbtype = QGis::WKBPoint;
+    memcpy( &wkb[0], &end, 1 );
+    memcpy( &wkb[1], &wkbtype, sizeof( int ) );
+    memcpy( &wkb[5], &x, sizeof( double ) );
+    memcpy( &wkb[5] + sizeof( double ), &y, sizeof( double ) );
 
-      QgsFeatureAction action( tr( "Feature added" ), *f, vlayer, -1, this );
-      if ( action.addFeature() )
-        mpCanvas->refresh();
+    f->setGeometryAndOwnership( &wkb[0], size );
 
-      delete f;
+    QgsFeatureAction action( tr( "Feature added" ), *f, vlayer, -1, this );
+    if ( action.addFeature() )
+    {
+      if ( mCbxAutoCommit->isChecked() )
+      {
+        // should canvas->isDrawing() be checked?
+        if ( !vlayer->commitChanges() ) //assumed to be vector layer and is editable and is in editing mode (preconditions have been tested)
+        {
+          QMessageBox::information( this,
+                                    tr( "Error" ),
+                                    tr( "Could not commit changes to layer %1\n\nErrors: %2\n" )
+                                    .arg( vlayer->name() )
+                                    .arg( vlayer->commitErrors().join( "\n  " ) ) );
+        }
+
+        vlayer->startEditing();
+      }
     }
-  }
+
+    delete f;
+  } // layerWKBType == QGis::WKBPoint
   else // Line or poly
   {
+    mNmea->disconnect(this, SLOT( displayGPSInformation( const QgsGPSInformation& ) ) );
+
     //create QgsFeature with wkb representation
     QgsFeature* f = new QgsFeature( 0, "WKBLineString" );
     unsigned char* wkb;
@@ -775,28 +1022,46 @@ void QgsGPSInformationWidget::on_mBtnCloseFeature_clicked( )
         return;
       }
     }
-    else //unknown type
+    // Should never get here, as preconditions should have removed any that aren't handled
+    else // layerWKBType == QGis::WKBPolygon  -  unknown type
     {
       QMessageBox::critical( 0, tr( "Error" ), tr( "Cannot add feature. "
                              "Unknown WKB type. Choose a different layer and try again." ) );
       connectGpsSlot();
       return; //unknown wkbtype
-    }
+    } // layerWKBType == QGis::WKBPolygon
 
     QgsFeatureAction action( tr( "Feature added" ), *f, vlayer, -1, this );
     if ( action.addFeature() )
-      mpCanvas->refresh();
+    {
+      if ( mCbxAutoCommit->isChecked() )
+      {
+        if ( !vlayer->commitChanges() ) //swiped... er... appropriated from QgisApp saveEdits()
+        {
+          QMessageBox::information( this,
+                                    tr( "Error" ),
+                                    tr( "Could not commit changes to layer %1\n\nErrors: %2\n" )
+                                    .arg( vlayer->name() )
+                                    .arg( vlayer->commitErrors().join( "\n  " ) ) );
+        }
+
+        vlayer->startEditing();
+      }
+      delete mpRubberBand;
+      mpRubberBand = NULL;
 
-    delete f;
+      // delete the elements of mCaptureList
+      mCaptureList.clear();
+    } // action.addFeature()
 
-    delete mpRubberBand;
-    mpRubberBand = NULL;
+    delete f;
+    connectGpsSlot();
+  } // layerWKBType == QGis::WKBPoint
+  mpCanvas->refresh();  // NOTE: cancelling feature add refreshes canvas, OK does not; this may change, however, so do it anyway
 
-    // delete the elements of mCaptureList
-    mCaptureList.clear();
-    mpCanvas->refresh();
-  }
-  connectGpsSlot();
+  // force focus back to GPS window/ Add Feature button for ease of use by keyboard
+  activateWindow();
+  mBtnCloseFeature->setFocus( Qt::OtherFocusReason );
 }
 
 void QgsGPSInformationWidget::connectGpsSlot( )
@@ -836,13 +1101,13 @@ void QgsGPSInformationWidget::createRubberBand( )
   {
     delete mpRubberBand;
   }
-  QSettings settings;
   mpRubberBand = new QgsRubberBand( mpCanvas, false );
-  setTrackColour();
-  mpRubberBand->setWidth( settings.value( "/gps/trackWidth", 2 ).toInt() );
+  mpRubberBand->setColor( mTrackColour );
+  mpRubberBand->setWidth( mSpinTrackWidth->value() );
   mpRubberBand->show();
 }
 
+#if 0 // this function isn't used
 QPointF QgsGPSInformationWidget::gpsToPixelPosition( const QgsPoint& point )
 {
   //transform to map crs
@@ -861,3 +1126,141 @@ QPointF QgsGPSInformationWidget::gpsToPixelPosition( const QgsPoint& point )
   mpCanvas->getCoordinateTransform()->transformInPlace( x, y );
   return QPointF( x, y ) ;
 }
+#endif
+
+void QgsGPSInformationWidget::on_mBtnLogFile_clicked()
+{
+//=========================
+  // This does not allow for an extension other than ".nmea"
+  // Retrieve last used log file dir from persistent settings
+  QSettings settings;
+  QString settingPath( "/gps/lastLogFileDir" );
+  QString lastUsedDir = settings.value( settingPath, "." ).toString();
+  QString saveFilePath = QFileDialog::getSaveFileName( this, tr( "Save GPS log file as" ), lastUsedDir, tr( "NMEA files (*.nmea)" ) );
+  if ( saveFilePath.isNull() ) //canceled
+  {
+    return;
+  }
+  QFileInfo myFI( saveFilePath );
+  QString myPath = myFI.path();
+  settings.setValue( settingPath, myPath );
+
+  // make sure the .nmea extension is included in the path name. if not, add it...
+  if ( "nmea" != myFI.suffix() )
+  {
+    saveFilePath = myFI.filePath() + ".nmea";
+  }
+  mTxtLogFile->setText( saveFilePath );
+  mTxtLogFile->setToolTip( saveFilePath );
+}
+
+void QgsGPSInformationWidget::logNmeaSentence( const QString& nmeaString )
+{
+  if ( mLogFileGroupBox->isChecked() && mLogFile && mLogFile->isOpen() )
+  {
+    mLogFileTextStream << nmeaString << "\r\n"; // specifically output CR + LF (NMEA requirement)
+  }
+}
+
+void QgsGPSInformationWidget::updateCloseFeatureButton( QgsMapLayer * lyr )
+{
+  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( lyr );
+
+  // Add feature button tracks edit state of layer
+  if ( vlayer != mpLastLayer )
+  {
+    if ( mpLastLayer )  // disconnect previous layer
+    {
+      disconnect( mpLastLayer, SIGNAL( editingStarted() ), this, SLOT( layerEditStateChanged() ) );
+      disconnect( mpLastLayer, SIGNAL( editingStopped() ), this, SLOT( layerEditStateChanged() ) );
+    }
+    if ( vlayer ) // connect new layer
+    {
+      connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( layerEditStateChanged() ) );
+      connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( layerEditStateChanged() ) );
+    }
+    mpLastLayer = vlayer;
+  }
+
+  QString buttonLabel = tr( "&Add feature" );
+  if ( vlayer ) // must be vector layer
+  {
+    QgsVectorDataProvider* provider = vlayer->dataProvider();
+    QGis::WkbType layerWKBType = vlayer->wkbType();
+
+    bool enable =
+      ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) &&  // layer can add features
+      vlayer->isEditable() && // layer is editing
+      ( // layer has geometry type that can be handled
+        layerWKBType == QGis::WKBPoint ||
+        layerWKBType == QGis::WKBLineString ||
+        layerWKBType == QGis::WKBPolygon
+        // add more types here as they are handled
+      )
+    ;
+    switch ( layerWKBType )
+    {
+      case QGis::WKBPoint:
+        buttonLabel = tr( "&Add Point" );
+        break;
+      case QGis::WKBLineString:
+        buttonLabel = tr( "&Add Line" );
+        break;
+      case QGis::WKBPolygon:
+        buttonLabel = tr( "&Add Polygon" );
+        break;
+      // for the future (also prevent compiler warnings)
+      case QGis::WKBMultiPoint:
+      case QGis::WKBMultiLineString:
+      case QGis::WKBMultiPolygon:
+      case QGis::WKBPoint25D:
+      case QGis::WKBLineString25D:
+      case QGis::WKBPolygon25D:
+      case QGis::WKBMultiPoint25D:
+      case QGis::WKBMultiLineString25D:
+      case QGis::WKBMultiPolygon25D:
+      case QGis::WKBUnknown:
+      case QGis::WKBNoGeometry:
+        ;
+    }
+    mBtnCloseFeature->setEnabled( enable );
+  }
+  else
+  {
+    mBtnCloseFeature->setEnabled( false );
+  }
+  mBtnCloseFeature->setText( buttonLabel );
+}
+
+void QgsGPSInformationWidget::layerEditStateChanged()
+{
+  updateCloseFeatureButton( mpLastLayer );
+}
+
+void QgsGPSInformationWidget::setStatusIndicator( const FixStatus statusValue )
+{
+  mLastFixStatus = statusValue;
+  // the pixmap will be expanded to the size of the label
+  QPixmap status( 4, 4 );
+  switch ( statusValue )
+  {
+    case NoFix:
+      status.fill( Qt::red );
+      break;
+    case Fix2D:
+      status.fill( Qt::yellow );
+      break;
+    case Fix3D:
+      status.fill( Qt::green );
+      break;
+    case NoData:
+    default: // anything else - shouldn't happen
+      status.fill( Qt::darkGray );
+  }
+  mLblStatusIndicator->setPixmap( status );
+}
+
+void QgsGPSInformationWidget::showStatusBarMessage( const QString& msg )
+{
+  QgisApp::instance()->statusBar()->showMessage( msg );
+}
diff --git a/src/app/gps/qgsgpsinformationwidget.h b/src/app/gps/qgsgpsinformationwidget.h
index 8d33522..e1bc5d4 100644
--- a/src/app/gps/qgsgpsinformationwidget.h
+++ b/src/app/gps/qgsgpsinformationwidget.h
@@ -29,7 +29,11 @@ class QextSerialPort;
 class QgsGPSConnection;
 class QgsGPSTrackerThread;
 struct QgsGPSInformation;
-class QPointF;
+//class QPointF;
+
+class QgsLegend;
+class QFile;
+class QColor;
 
 /**A dock widget that displays information from a GPS device and
  * allows the user to capture features using gps readings to
@@ -44,7 +48,10 @@ class QgsGPSInformationWidget: public QWidget, private Ui::QgsGPSInformationWidg
   private slots:
     void on_mConnectButton_toggled( bool theFlag );
     void displayGPSInformation( const QgsGPSInformation& info );
-    void setTrackColour( );
+    void logNmeaSentence( const QString& nmeaString ); // added to handle 'raw' data
+    void updateCloseFeatureButton( QgsMapLayer * lyr );
+    void layerEditStateChanged();
+ //   void setTrackColour( ); // no longer used
     void on_mBtnTrackColour_clicked( );
     void on_mSpinTrackWidth_valueChanged( int theValue );
     void on_mBtnPosition_clicked( );
@@ -56,17 +63,24 @@ class QgsGPSInformationWidget: public QWidget, private Ui::QgsGPSInformationWidg
     void on_mBtnAddVertex_clicked( );
     void on_mBtnCloseFeature_clicked( );
     void on_mBtnResetFeature_clicked( );
-    void on_mCbxAutoAddVertices_toggled( bool theFlag );
+// not needed    void on_mCbxAutoAddVertices_toggled( bool theFlag );
+    void on_mBtnLogFile_clicked();
 
     void connected( QgsGPSConnection * );
     void timedout();
 
   private:
+    enum FixStatus  //GPS status
+    {
+      NoData, NoFix, Fix2D, Fix3D
+    };
     void addVertex( );
     void connectGps();
     void connectGpsSlot( );
     void disconnectGps();
     void populateDevices();
+    void setStatusIndicator( const FixStatus statusValue );
+    void showStatusBarMessage( const QString& msg );
     QgsGPSConnection* mNmea;
     QgsMapCanvas * mpCanvas;
     QgsGpsMarker * mpMapMarker;
@@ -76,10 +90,17 @@ class QgsGPSInformationWidget: public QWidget, private Ui::QgsGPSInformationWidg
     QList< QwtPolarMarker * > mMarkerList;
     void createRubberBand( );
     QgsCoordinateReferenceSystem mWgs84CRS;
-    QPointF gpsToPixelPosition( const QgsPoint& point );
+// not used    QPointF gpsToPixelPosition( const QgsPoint& point );
     QgsRubberBand * mpRubberBand;
     QgsPoint mLastGpsPosition;
     QList<QgsPoint> mCaptureList;
+    FixStatus mLastFixStatus;
+    QString mDateTimeFormat; // user specified format string in registry (no UI presented)
+    QgsLegend * mpLegend;
+    QgsVectorLayer * mpLastLayer;
+    QFile * mLogFile;
+    QTextStream mLogFileTextStream;
+    QColor mTrackColour;
 };
 
 #endif // QGSGPSINFORMATIONWIDGET_H
diff --git a/src/app/gps/qgsgpsmarker.cpp b/src/app/gps/qgsgpsmarker.cpp
index e3544b4..551fcd1 100644
--- a/src/app/gps/qgsgpsmarker.cpp
+++ b/src/app/gps/qgsgpsmarker.cpp
@@ -14,7 +14,6 @@
  ***************************************************************************/
 
 #include <QPainter>
-#include <QSvgRenderer>
 
 #include "qgsgpsmarker.h"
 #include "qgscoordinatetransform.h"
@@ -27,6 +26,11 @@ QgsGpsMarker::QgsGpsMarker( QgsMapCanvas* mapCanvas )
 {
   mSize = 16;
   mWgs84CRS.createFromOgcWmsCrs( "EPSG:4326" );
+  mSvg.load( QString( ":/images/north_arrows/gpsarrow2.svg" ) );
+  if ( ! mSvg.isValid() )
+  {
+    qDebug( "GPS marker not found!" );
+  }
 }
 
 void QgsGpsMarker::setSize( int theSize )
@@ -60,14 +64,18 @@ void QgsGpsMarker::setCenter( const QgsPoint& point )
 
 void QgsGpsMarker::paint( QPainter* p )
 {
-  QSvgRenderer mySVG;
-  if ( !mySVG.load( QString( ":/images/north_arrows/gpsarrow2.svg" ) ) )
+  if ( ! mSvg.isValid() )
   {
-    qDebug( "GPS marker not found!" );
     return;
   }
+
+  // this needs to be done when the canvas is repainted to make for smoother map rendering
+  // if not done the map could be panned, but the cursor position won't be updated until the next valid GPS fix is received
+  QPointF pt = toCanvasCoordinates( mCenter );
+  setPos( pt );
+
   float myHalfSize = mSize / 2.0;
-  mySVG.render( p, QRectF( 0 - myHalfSize , 0 - myHalfSize, mSize, mSize ) );
+  mSvg.render( p, QRectF( 0 - myHalfSize , 0 - myHalfSize, mSize, mSize ) );
 }
 
 
diff --git a/src/app/gps/qgsgpsmarker.h b/src/app/gps/qgsgpsmarker.h
index fbeca42..cfc0d4d 100644
--- a/src/app/gps/qgsgpsmarker.h
+++ b/src/app/gps/qgsgpsmarker.h
@@ -19,6 +19,7 @@
 #include "qgsmapcanvasitem.h"
 #include "qgscoordinatereferencesystem.h"
 #include "qgspoint.h"
+#include <QSvgRenderer>
 
 class QPainter;
 
@@ -50,6 +51,7 @@ class QgsGpsMarker : public QgsMapCanvasItem
 
   private:
     QgsCoordinateReferenceSystem mWgs84CRS;
+    QSvgRenderer mSvg;
 
 };
 
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index 0143f87..10334cd 100755
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -452,6 +452,18 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
   addDockWidget( Qt::LeftDockWidgetArea, mBrowserWidget );
   mBrowserWidget->hide();
 
+  // create the GPS tool on starting QGIS - this is like the Browser
+  mpGpsWidget = new QgsGPSInformationWidget( mMapCanvas );
+  //create the dock widget
+  mpGpsDock = new QDockWidget( tr( "GPS Information" ), this );
+  mpGpsDock->setObjectName( "GPSInformation" );
+  mpGpsDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
+  addDockWidget( Qt::LeftDockWidgetArea, mpGpsDock );
+  // add to the Panel submenu
+  // now add our widget to the dock - ownership of the widget is passed to the dock
+  mpGpsDock->setWidget( mpGpsWidget );
+  mpGpsDock->hide();
+
   mInternalClipboard = new QgsClipboard; // create clipboard
   mQgisInterface = new QgisAppInterface( this ); // create the interfce
 
@@ -630,6 +642,8 @@ QgisApp::~QgisApp()
 
   delete mPythonUtils;
 
+  delete mpGpsWidget;
+
   deletePrintComposers();
   removeAnnotationItems();
 
@@ -729,11 +743,6 @@ void QgisApp::readSettings()
   {
     showTileScale();
   }
-  // Restore state of GPS Tracker
-  if ( settings.value( "/gps/widgetEnabled", false ).toBool() )
-  {
-    showGpsTool();
-  }
 }
 
 
@@ -830,7 +839,6 @@ void QgisApp::createActions()
   connect( mActionSetLayerCRS, SIGNAL( triggered() ), this, SLOT( setLayerCRS() ) );
   connect( mActionSetProjectCRSFromLayer, SIGNAL( triggered() ), this, SLOT( setProjectCRSFromLayer() ) );
   connect( mActionTileScale, SIGNAL( triggered() ), this, SLOT( showTileScale() ) );
-  connect( mActionGpsTool, SIGNAL( triggered() ), this, SLOT( showGpsTool() ) );
   connect( mActionLayerProperties, SIGNAL( triggered() ), this, SLOT( layerProperties() ) );
   connect( mActionLayerSubsetString, SIGNAL( triggered() ), this, SLOT( layerSubsetString() ) );
   connect( mActionAddToOverview, SIGNAL( triggered() ), this, SLOT( isInOverview() ) );
@@ -1871,17 +1879,6 @@ void QgisApp::saveWindowState()
     settings.setValue( "/UI/tileScaleEnabled", false );
   }
 
-  // Persist state of GPS Tracker
-  if ( mpGpsWidget )
-  {
-    settings.setValue( "/gps/widgetEnabled", true );
-    delete mpGpsWidget;
-  }
-  else
-  {
-    settings.setValue( "/gps/widgetEnabled", false );
-  }
-
   QgsPluginRegistry::instance()->unloadAll();
 }
 
@@ -4518,28 +4515,6 @@ void QgisApp::setProjectCRSFromLayer()
   mMapCanvas->refresh();
 }
 
-void QgisApp::showGpsTool()
-{
-  if ( !mpGpsWidget )
-  {
-    mpGpsWidget = new QgsGPSInformationWidget( mMapCanvas );
-    //create the dock widget
-    mpGpsDock = new QDockWidget( tr( "GPS Information" ), this );
-    mpGpsDock->setObjectName( "GPSInformation" );
-    mpGpsDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
-    addDockWidget( Qt::LeftDockWidgetArea, mpGpsDock );
-    // add to the Panel submenu
-    mPanelMenu->addAction( mpGpsDock->toggleViewAction() );
-    // now add our widget to the dock - ownership of the widget is passed to the dock
-    mpGpsDock->setWidget( mpGpsWidget );
-    mpGpsWidget->show();
-  }
-  else
-  {
-    mpGpsDock->setVisible( mpGpsDock->isHidden() );
-  }
-}
-
 void QgisApp::showTileScale()
 {
   if ( !mpTileScaleWidget )
diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h
index c6bcbad..6abb280 100644
--- a/src/app/qgisapp.h
+++ b/src/app/qgisapp.h
@@ -265,7 +265,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
     QAction *actionSetLayerCRS() { return mActionSetLayerCRS; }
     QAction *actionSetProjectCRSFromLayer() { return mActionSetProjectCRSFromLayer; }
     QAction *actionTileScale() { return mActionTileScale; }
-    QAction *actionGpsTool() { return mActionGpsTool; }
     QAction *actionLayerProperties() { return mActionLayerProperties; }
     QAction *actionLayerSubsetString() { return mActionLayerSubsetString; }
     QAction *actionAddToOverview() { return mActionAddToOverview; }
@@ -483,8 +482,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
     void setLayerCRS();
     //! Assign layer CRS to project
     void setProjectCRSFromLayer();
-    //! Show GPS tool
-    void showGpsTool();
     //! Show tile scale slider
     void showTileScale();
     //! zoom to extent of layer
diff --git a/src/core/gps/nmeatime.h b/src/core/gps/nmeatime.h
index b762a76..493da99 100644
--- a/src/core/gps/nmeatime.h
+++ b/src/core/gps/nmeatime.h
@@ -32,7 +32,7 @@ extern "C"
     int     hour;       /**< Hours since midnight - [0,23] */
     int     min;        /**< Minutes after the hour - [0,59] */
     int     sec;        /**< Seconds after the minute - [0,59] */
-    int     hsec;       /**< Hundredth part of second - [0,99] */
+    int     msec;       /**< Thousandths part of second - [0,999] */
 
   } nmeaTIME;
 
diff --git a/src/core/gps/parse.c b/src/core/gps/parse.c
index 518d26a..799c2a6 100644
--- a/src/core/gps/parse.c
+++ b/src/core/gps/parse.c
@@ -75,11 +75,22 @@ int _nmea_parse_time( const char *buff, int buff_sz, nmeaTIME *res )
                                  ) );
       break;
     case sizeof( "hhmmss.s" ) - 1:
+      success = ( 4 == nmea_scanf( buff, buff_sz,
+                                   "%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->msec )
+                                 ) );
+      res->msec = res->msec * 100;   // tenths sec * 100 = thousandths
+      break;
     case sizeof( "hhmmss.ss" ) - 1:
+      success = ( 4 == nmea_scanf( buff, buff_sz,
+                                   "%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->msec )
+                                 ) );
+      res->msec = res->msec * 10;   // hundredths sec * 10 = thousandths
+      break;
     case sizeof( "hhmmss.sss" ) - 1:
       success = ( 4 == nmea_scanf( buff, buff_sz,
-                                   "%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->hsec )
+                                   "%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->msec )
                                  ) );
+      // already thousandths
       break;
     default:
       nmea_error( "Parse of time error (format error)!" );
@@ -380,7 +391,7 @@ void nmea_GPGGA2info( nmeaGPGGA *pack, nmeaINFO *info )
   info->utc.hour = pack->utc.hour;
   info->utc.min = pack->utc.min;
   info->utc.sec = pack->utc.sec;
-  info->utc.hsec = pack->utc.hsec;
+  info->utc.msec = pack->utc.msec;
   info->sig = pack->sig;
   info->HDOP = pack->HDOP;
   info->elv = pack->elv;
diff --git a/src/core/gps/qextserialport/qextserialenumerator.h b/src/core/gps/qextserialport/qextserialenumerator.h
index 9503926..39c72d7 100644
--- a/src/core/gps/qextserialport/qextserialenumerator.h
+++ b/src/core/gps/qextserialport/qextserialenumerator.h
@@ -13,9 +13,14 @@
 
 #ifdef Q_OS_WIN
     #ifdef __MINGW32__
+      #ifdef _WIN32_WINNT
+        #if _WIN32_WINNT < 0x0500
+          #undef _WIN32_WINNT
+          #define _WIN32_WINNT 0x0500
+        #endif
+      #else
         #define _WIN32_WINNT 0x0500
-        #define _WIN32_WINDOWS 0x0500
-        #define WINVER 0x0500 
+      #endif
     #endif
     #include <windows.h>
     #include <setupapi.h>
diff --git a/src/core/gps/qgsgpsconnection.cpp b/src/core/gps/qgsgpsconnection.cpp
index 8ba805b..b341163 100644
--- a/src/core/gps/qgsgpsconnection.cpp
+++ b/src/core/gps/qgsgpsconnection.cpp
@@ -94,6 +94,13 @@ void QgsGPSConnection::clearLastGPSInformation()
   mLastGPSInformation.satellitesInView.clear();
   mLastGPSInformation.speed = 0;
   mLastGPSInformation.vdop = 0;
+  mLastGPSInformation.quality = -1;  // valid values: 0,1,2, maybe others
+  mLastGPSInformation.satellitesUsed = 0;
+  mLastGPSInformation.fixMode = ' ';
+  mLastGPSInformation.fixType = 0; // valid values: 1,2,3
+  mLastGPSInformation.status = ' '; // valid values: A,V
   mLastGPSInformation.utcDateTime.setDate( QDate() );
+  mLastGPSInformation.satPrn.clear();
   mLastGPSInformation.utcDateTime.setTime( QTime() );
+  mLastGPSInformation.satInfoComplete = false;
 }
diff --git a/src/core/gps/qgsgpsconnection.h b/src/core/gps/qgsgpsconnection.h
index 04a04c8..fd88151 100644
--- a/src/core/gps/qgsgpsconnection.h
+++ b/src/core/gps/qgsgpsconnection.h
@@ -20,6 +20,7 @@
 
 #include <QDateTime>
 #include <QObject>
+#include <QString>
 
 class QIODevice;
 
@@ -44,6 +45,13 @@ struct CORE_EXPORT QgsGPSInformation
   double hdop;
   double vdop;
   QDateTime utcDateTime;
+  QChar fixMode;
+  int fixType;
+  int quality;      // from GPGGA
+  int satellitesUsed; // from GPGGA
+  QChar status;     // from GPRMC A,V
+  QList<int>satPrn; // list of SVs in use; needed for QgsSatelliteInfo.inUse and other uses
+  bool satInfoComplete;  // based on GPGSV sentences - to be used to determine when to graph signal and satellite position
 };
 
 /**Abstract base class for connection to a GPS device*/
@@ -81,6 +89,7 @@ class CORE_EXPORT QgsGPSConnection : public QObject
 
   signals:
     void stateChanged( const QgsGPSInformation& info );
+    void nmeaSentenceReceived( const QString& substring );  // added to capture 'raw' data
 
   protected:
     /**Data source (e.g. serial device, socket, file,...)*/
diff --git a/src/core/gps/qgsgpsdetector.cpp b/src/core/gps/qgsgpsdetector.cpp
index 4ce739e..7535da3 100644
--- a/src/core/gps/qgsgpsdetector.cpp
+++ b/src/core/gps/qgsgpsdetector.cpp
@@ -89,7 +89,7 @@ QList< QPair<QString, QString> > QgsGPSDetector::availablePorts()
 QgsGPSDetector::QgsGPSDetector( QString portName )
 {
   mConn = 0;
-  mBaudList << BAUD4800 << BAUD9600 << BAUD38400;
+  mBaudList << BAUD4800 << BAUD9600 << BAUD38400 << BAUD57600;  //add 57600 for SXBlueII GPS unit
 
   if ( portName.isEmpty() )
   {
@@ -102,8 +102,6 @@ QgsGPSDetector::QgsGPSDetector( QString portName )
 
   mPortIndex = 0;
   mBaudIndex = -1;
-
-  advance();
 }
 
 QgsGPSDetector::~QgsGPSDetector()
diff --git a/src/core/gps/qgsnmeaconnection.cpp b/src/core/gps/qgsnmeaconnection.cpp
index aee451b..9a73152 100644
--- a/src/core/gps/qgsnmeaconnection.cpp
+++ b/src/core/gps/qgsnmeaconnection.cpp
@@ -27,6 +27,7 @@
 //from libnmea
 #include "parse.h"
 #include "gmath.h"
+#include "info.h"
 
 #define KNOTS_TO_KMH 1.852
 
@@ -48,7 +49,7 @@ void QgsNMEAConnection::parseData()
 
   //print out the data as a test
   qint64 numBytes = 0;
-  if ( mSource->isSequential() ) //necessary because of a bug in QExtSerialPort
+   if ( ! mSource->isSequential() ) //necessary because of a bug in QExtSerialPort   //SLM - bytesAvailable() works on Windows, so I reversed the logic (added ! ); this is what QIODevice docs say to do; the orig impl of win_qextserialport had an (unsigned int)-1 return on error - it should be (qint64)-1, which was fixed by ?
   {
     numBytes = mSource->size();
   }
@@ -130,6 +131,7 @@ void QgsNMEAConnection::processStringBuffer()
           mStatus = GPSDataReceived;
           QgsDebugMsg( "*******************GPS data received****************" );
         }
+        emit nmeaSentenceReceived( substring );  // added to be able to save raw data
       }
     }
     mStringBuffer.remove( 0, endSentenceIndex + 2 );
@@ -156,6 +158,8 @@ void QgsNMEAConnection::processGGASentence( const char* data, int len )
     mLastGPSInformation.longitude = nmea_ndeg2degree( longitude );
     mLastGPSInformation.latitude = nmea_ndeg2degree( latitude );
     mLastGPSInformation.elevation = result.elv;
+    mLastGPSInformation.quality = result.sig;
+    mLastGPSInformation.satellitesUsed = result.satinuse;
   }
 }
 
@@ -178,10 +182,11 @@ void QgsNMEAConnection::processRMCSentence( const char* data, int len )
     mLastGPSInformation.latitude = nmea_ndeg2degree( latitude );
     mLastGPSInformation.speed = KNOTS_TO_KMH * result.speed;
     mLastGPSInformation.direction = result.direction;
+    mLastGPSInformation.status = result.status;  // A,V
 
     //date and time
     QDate date( result.utc.year + 1900, result.utc.mon + 1, result.utc.day );
-    QTime time( result.utc.hour, result.utc.min, result.utc.sec );
+    QTime time( result.utc.hour, result.utc.min, result.utc.sec, result.utc.msec ); // added msec part
     if ( date.isValid() && time.isValid() )
     {
       mLastGPSInformation.utcDateTime.setTimeSpec( Qt::UTC );
@@ -206,6 +211,9 @@ void QgsNMEAConnection::processGSVSentence( const char* data, int len )
       mLastGPSInformation.satellitesInView.clear();
     }
 
+    // for determining when to graph sat info
+    mLastGPSInformation.satInfoComplete = ( result.pack_index == result.pack_count );
+
     for ( int i = 0; i < NMEA_SATINPACK; ++i )
     {
       nmeaSATELLITE currentSatellite = result.sat_data[i];
@@ -213,7 +221,7 @@ void QgsNMEAConnection::processGSVSentence( const char* data, int len )
       satelliteInfo.azimuth = currentSatellite.azimuth;
       satelliteInfo.elevation = currentSatellite.elv;
       satelliteInfo.id = currentSatellite.id;
-      satelliteInfo.inUse = currentSatellite.in_use;
+      satelliteInfo.inUse = currentSatellite.in_use; // the GSA processing below does NOT set the sats in use
       satelliteInfo.signal = currentSatellite.sig;
       mLastGPSInformation.satellitesInView.append( satelliteInfo );
     }
@@ -235,8 +243,15 @@ void QgsNMEAConnection::processGSASentence( const char* data, int len )
   nmeaGPGSA result;
   if ( nmea_parse_GPGSA( data, len, &result ) )
   {
+    mLastGPSInformation.satPrn.clear();
     mLastGPSInformation.hdop = result.HDOP;
     mLastGPSInformation.pdop = result.PDOP;
     mLastGPSInformation.vdop = result.VDOP;
+    mLastGPSInformation.fixMode = result.fix_mode;
+    mLastGPSInformation.fixType = result.fix_type;
+    for ( int i = 0; i < NMEA_MAXSAT; i++ )
+    {
+      mLastGPSInformation.satPrn.append( result.sat_prn[ i ] );
+    }
   }
 }
diff --git a/src/core/gps/time.c b/src/core/gps/time.c
index 0c77014..2a7942b 100644
--- a/src/core/gps/time.c
+++ b/src/core/gps/time.c
@@ -38,7 +38,7 @@ void nmea_time_now( nmeaTIME *stm )
   stm->hour = st.wHour;
   stm->min = st.wMinute;
   stm->sec = st.wSecond;
-  stm->hsec = st.wMilliseconds / 10;
+  stm->msec = st.wMilliseconds;
 }
 
 #else /* NMEA_WIN */
@@ -57,7 +57,7 @@ void nmea_time_now( nmeaTIME *stm )
   stm->hour = tt->tm_hour;
   stm->min = tt->tm_min;
   stm->sec = tt->tm_sec;
-  stm->hsec = 0;
+  stm->msec = 0;
 }
 
 #endif
diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui
index 2eacbb3..68b76a5 100644
--- a/src/ui/qgisapp.ui
+++ b/src/ui/qgisapp.ui
@@ -118,7 +118,6 @@
     <addaction name="mActionShowBookmarks"/>
     <addaction name="mActionDraw"/>
     <addaction name="mActionTileScale"/>
-    <addaction name="mActionGpsTool"/>
    </widget>
    <widget class="QMenu" name="mLayerMenu">
     <property name="title">
@@ -1187,11 +1186,6 @@
     <string>Tile scale slider</string>
    </property>
   </action>
-  <action name="mActionGpsTool">
-   <property name="text">
-    <string>Live GPS tracking</string>
-   </property>
-  </action>
   <action name="mActionLayerProperties">
    <property name="text">
     <string>Properties...</string>
diff --git a/src/ui/qgsgpsinformationwidgetbase.ui b/src/ui/qgsgpsinformationwidgetbase.ui
index edcf642..689b95d 100644
--- a/src/ui/qgsgpsinformationwidgetbase.ui
+++ b/src/ui/qgsgpsinformationwidgetbase.ui
@@ -6,30 +6,148 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>279</width>
-    <height>723</height>
+    <width>215</width>
+    <height>591</height>
    </rect>
   </property>
   <property name="windowTitle">
-   <string>Form</string>
+   <string>GPS Connect</string>
   </property>
   <layout class="QGridLayout" name="gridLayout_4">
-   <property name="leftMargin">
-    <number>3</number>
+   <property name="verticalSpacing">
+    <number>2</number>
    </property>
-   <property name="topMargin">
-    <number>0</number>
+   <property name="margin">
+    <number>2</number>
    </property>
-   <property name="rightMargin">
-    <number>0</number>
-   </property>
-   <property name="bottomMargin">
-    <number>0</number>
-   </property>
-   <item row="0" column="0">
+   <item row="1" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_4" stretch="50,0">
+     <property name="spacing">
+      <number>2</number>
+     </property>
+     <property name="sizeConstraint">
+      <enum>QLayout::SetDefaultConstraint</enum>
+     </property>
+     <item>
+      <widget class="QPushButton" name="mBtnCloseFeature">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>&amp;Add feature</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="mLblStatusIndicator">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>42</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>42</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="toolTip">
+        <string>Quick status indicator:
+green = good or 3D fix
+yellow = good 2D fix
+red = no fix or bad fix
+gray = no data
+
+2D/3D depends on this information being available</string>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::Box</enum>
+       </property>
+       <property name="text">
+        <string/>
+       </property>
+       <property name="scaledContents">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <property name="spacing">
+      <number>2</number>
+     </property>
+     <property name="bottomMargin">
+      <number>4</number>
+     </property>
+     <item>
+      <widget class="QPushButton" name="mBtnAddVertex">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Add track point</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="mBtnResetFeature">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>32</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="toolTip">
+        <string>Reset track</string>
+       </property>
+       <property name="text">
+        <string>...</string>
+       </property>
+       <property name="icon">
+        <iconset resource="../../images/images.qrc">
+         <normaloff>:/images/themes/default/mActionRotatePointSymbols.png</normaloff>:/images/themes/default/mActionRotatePointSymbols.png</iconset>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="3" column="0">
     <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <property name="spacing">
+      <number>2</number>
+     </property>
      <item>
       <widget class="QToolButton" name="mBtnPosition">
+       <property name="toolTip">
+        <string>Position</string>
+       </property>
        <property name="text">
         <string>...</string>
        </property>
@@ -41,6 +159,9 @@
      </item>
      <item>
       <widget class="QToolButton" name="mBtnSignal">
+       <property name="toolTip">
+        <string>Signal</string>
+       </property>
        <property name="text">
         <string>...</string>
        </property>
@@ -52,6 +173,9 @@
      </item>
      <item>
       <widget class="QToolButton" name="mBtnSatellites">
+       <property name="toolTip">
+        <string>Satellite</string>
+       </property>
        <property name="text">
         <string>...</string>
        </property>
@@ -63,6 +187,9 @@
      </item>
      <item>
       <widget class="QToolButton" name="mBtnOptions">
+       <property name="toolTip">
+        <string>Options</string>
+       </property>
        <property name="text">
         <string>...</string>
        </property>
@@ -74,6 +201,9 @@
      </item>
      <item>
       <widget class="QToolButton" name="mBtnDebug">
+       <property name="toolTip">
+        <string>Debug</string>
+       </property>
        <property name="text">
         <string>...</string>
        </property>
@@ -105,7 +235,7 @@
         </sizepolicy>
        </property>
        <property name="text">
-        <string>Connect</string>
+        <string>&amp;Connect</string>
        </property>
        <property name="checkable">
         <bool>true</bool>
@@ -114,155 +244,374 @@
      </item>
     </layout>
    </item>
-   <item row="1" column="0">
+   <item row="4" column="0">
     <widget class="QStackedWidget" name="mStackedWidget">
      <property name="currentIndex">
-      <number>0</number>
+      <number>3</number>
      </property>
      <widget class="QWidget" name="stackedWidgetPage1">
-      <layout class="QGridLayout" name="gridLayout_2">
+      <layout class="QGridLayout" name="gridLayout_11">
        <property name="margin">
         <number>0</number>
        </property>
        <item row="0" column="0">
-        <widget class="QDateTimeEdit" name="mDateTime">
-         <property name="readOnly">
-          <bool>true</bool>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="0">
-        <widget class="QDoubleSpinBox" name="mSpinLatitude">
-         <property name="readOnly">
-          <bool>true</bool>
-         </property>
-         <property name="suffix">
-          <string> Latitude</string>
-         </property>
-         <property name="minimum">
-          <double>-90.000000000000000</double>
-         </property>
-         <property name="maximum">
-          <double>90.000000000000000</double>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="0">
-        <widget class="QDoubleSpinBox" name="mSpinLongitude">
-         <property name="readOnly">
-          <bool>true</bool>
-         </property>
-         <property name="suffix">
-          <string> Longitude</string>
-         </property>
-         <property name="minimum">
-          <double>-180.000000000000000</double>
-         </property>
-         <property name="maximum">
-          <double>180.000000000000000</double>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="0">
-        <widget class="QDoubleSpinBox" name="mSpinElevation">
-         <property name="readOnly">
+        <widget class="QScrollArea" name="scrollArea_2">
+         <property name="widgetResizable">
           <bool>true</bool>
          </property>
-         <property name="suffix">
-          <string> Elevation</string>
-         </property>
-         <property name="maximum">
-          <double>9999.989999999999782</double>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="0">
-        <widget class="QProgressBar" name="mVerticalAccuracy">
-         <property name="maximum">
-          <number>10</number>
-         </property>
-         <property name="value">
-          <number>5</number>
-         </property>
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="textDirection">
-          <enum>QProgressBar::BottomToTop</enum>
-         </property>
-         <property name="format">
-          <string>Vertical Accuracy</string>
-         </property>
-        </widget>
-       </item>
-       <item row="5" column="0">
-        <widget class="QProgressBar" name="mHorizontalAccuracy">
-         <property name="maximum">
-          <number>10</number>
-         </property>
-         <property name="value">
-          <number>5</number>
-         </property>
-         <property name="format">
-          <string>Horizontal Accuracy</string>
-         </property>
-        </widget>
-       </item>
-       <item row="6" column="0">
-        <widget class="QPushButton" name="mBtnAddVertex">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="text">
-          <string>Add vertex</string>
-         </property>
-        </widget>
-       </item>
-       <item row="7" column="0">
-        <layout class="QHBoxLayout" name="horizontalLayout_4">
-         <item>
-          <widget class="QPushButton" name="mBtnCloseFeature">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Add feature</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="mBtnResetFeature">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>32</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="toolTip">
-            <string>Reset current feature</string>
-           </property>
-           <property name="text">
-            <string>...</string>
+         <widget class="QWidget" name="scrollAreaWidgetContents_2">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>209</width>
+            <height>501</height>
+           </rect>
+          </property>
+          <layout class="QGridLayout" name="gridLayout_2">
+           <property name="verticalSpacing">
+            <number>2</number>
            </property>
-           <property name="icon">
-            <iconset resource="../../images/images.qrc">
-             <normaloff>:/images/themes/default/mActionRotatePointSymbols.png</normaloff>:/images/themes/default/mActionRotatePointSymbols.png</iconset>
+           <property name="margin">
+            <number>2</number>
            </property>
-          </widget>
-         </item>
-        </layout>
+           <item row="4" column="0">
+            <spacer name="verticalSpacer">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+           <item row="2" column="0">
+            <layout class="QGridLayout" name="gridLayout_10">
+             <property name="margin">
+              <number>2</number>
+             </property>
+             <property name="spacing">
+              <number>2</number>
+             </property>
+             <item row="0" column="1">
+              <widget class="QLineEdit" name="mTxtLatitude">
+               <property name="toolTip">
+                <string>latitude of position fix (degrees)</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="3" column="1">
+              <spacer name="verticalSpacer_2">
+               <property name="orientation">
+                <enum>Qt::Vertical</enum>
+               </property>
+               <property name="sizeType">
+                <enum>QSizePolicy::Fixed</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>20</width>
+                 <height>6</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item row="1" column="0">
+              <widget class="QLabel" name="mLblLongitude">
+               <property name="text">
+                <string>Longitude</string>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="1">
+              <widget class="QLineEdit" name="mTxtLongitude">
+               <property name="toolTip">
+                <string>longitude of position fix (degrees)</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="1">
+              <widget class="QLineEdit" name="mTxtAltitude">
+               <property name="toolTip">
+                <string>antenna altitude with respect to geoid (mean sea level)</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="2" column="0">
+              <widget class="QLabel" name="mLblAltitude">
+               <property name="text">
+                <string>Altitude</string>
+               </property>
+              </widget>
+             </item>
+             <item row="0" column="0">
+              <widget class="QLabel" name="mLblLatitude">
+               <property name="text">
+                <string>Latitude</string>
+               </property>
+              </widget>
+             </item>
+             <item row="4" column="0">
+              <widget class="QLabel" name="mLblUtcTime">
+               <property name="text">
+                <string>Time of fix</string>
+               </property>
+              </widget>
+             </item>
+             <item row="4" column="1">
+              <widget class="QLineEdit" name="mTxtDateTime">
+               <property name="toolTip">
+                <string>date/time of position fix (UTC)</string>
+               </property>
+               <property name="text">
+                <string/>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="8" column="1">
+              <spacer name="verticalSpacer_4">
+               <property name="orientation">
+                <enum>Qt::Vertical</enum>
+               </property>
+               <property name="sizeType">
+                <enum>QSizePolicy::Fixed</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>20</width>
+                 <height>6</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item row="6" column="1">
+              <widget class="QLineEdit" name="mTxtSpeed">
+               <property name="toolTip">
+                <string>speed over ground</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="6" column="0">
+              <widget class="QLabel" name="mLblSpeed">
+               <property name="toolTip">
+                <string/>
+               </property>
+               <property name="text">
+                <string>Speed</string>
+               </property>
+              </widget>
+             </item>
+             <item row="7" column="1">
+              <widget class="QLineEdit" name="mTxtDirection">
+               <property name="toolTip">
+                <string>track direction (degrees)</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="7" column="0">
+              <widget class="QLabel" name="mLblDirection">
+               <property name="toolTip">
+                <string/>
+               </property>
+               <property name="text">
+                <string>Direction</string>
+               </property>
+              </widget>
+             </item>
+             <item row="5" column="1">
+              <spacer name="verticalSpacer_5">
+               <property name="orientation">
+                <enum>Qt::Vertical</enum>
+               </property>
+               <property name="sizeType">
+                <enum>QSizePolicy::Fixed</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>20</width>
+                 <height>6</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item row="9" column="1">
+              <widget class="QLineEdit" name="mTxtHdop">
+               <property name="toolTip">
+                <string>Horizontal Dilution of Precision</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="9" column="0">
+              <widget class="QLabel" name="mLblHdop">
+               <property name="text">
+                <string>HDOP</string>
+               </property>
+              </widget>
+             </item>
+             <item row="10" column="1">
+              <widget class="QLineEdit" name="mTxtVdop">
+               <property name="toolTip">
+                <string>Vertical Dilution of Precision</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="10" column="0">
+              <widget class="QLabel" name="mLblVdop">
+               <property name="text">
+                <string>VDOP</string>
+               </property>
+              </widget>
+             </item>
+             <item row="11" column="1">
+              <widget class="QLineEdit" name="mTxtPdop">
+               <property name="toolTip">
+                <string>Position Dilution of Precision</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="11" column="0">
+              <widget class="QLabel" name="mLblPdop">
+               <property name="text">
+                <string>PDOP</string>
+               </property>
+              </widget>
+             </item>
+             <item row="12" column="1">
+              <spacer name="verticalSpacer_3">
+               <property name="orientation">
+                <enum>Qt::Vertical</enum>
+               </property>
+               <property name="sizeType">
+                <enum>QSizePolicy::Fixed</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>20</width>
+                 <height>6</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item row="13" column="1">
+              <widget class="QLineEdit" name="mTxtFixMode">
+               <property name="toolTip">
+                <string>GPS receiver configuration 2D/3D mode: Automatic or Manual</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="13" column="0">
+              <widget class="QLabel" name="mLblFixMode">
+               <property name="text">
+                <string>Mode</string>
+               </property>
+              </widget>
+             </item>
+             <item row="14" column="1">
+              <widget class="QLineEdit" name="mTxtFixType">
+               <property name="toolTip">
+                <string>position fix dimensions: 2D, 3D or No fix</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="14" column="0">
+              <widget class="QLabel" name="mLblFixType">
+               <property name="text">
+                <string>Dimensions</string>
+               </property>
+              </widget>
+             </item>
+             <item row="15" column="1">
+              <widget class="QLineEdit" name="mTxtQuality">
+               <property name="toolTip">
+                <string>quality of the position fix: Differential, Non-differential or No position</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="15" column="0">
+              <widget class="QLabel" name="mLblQuality">
+               <property name="text">
+                <string>Quality</string>
+               </property>
+              </widget>
+             </item>
+             <item row="16" column="1">
+              <widget class="QLineEdit" name="mTxtStatus">
+               <property name="toolTip">
+                <string>position fix status: Valid or Invalid</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="16" column="0">
+              <widget class="QLabel" name="mLblStatus">
+               <property name="text">
+                <string>Status</string>
+               </property>
+              </widget>
+             </item>
+             <item row="17" column="1">
+              <widget class="QLineEdit" name="mTxtSatellitesUsed">
+               <property name="toolTip">
+                <string>number of satellites used in the position fix</string>
+               </property>
+               <property name="readOnly">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item row="17" column="0">
+              <widget class="QLabel" name="mLblSatellitesUsed">
+               <property name="text">
+                <string>Satellites</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </widget>
+        </widget>
        </item>
       </layout>
      </widget>
@@ -273,6 +622,9 @@
        <property name="margin">
         <number>0</number>
        </property>
+       <property name="verticalSpacing">
+        <number>6</number>
+       </property>
        <item row="0" column="0">
         <widget class="QScrollArea" name="scrollArea">
          <property name="widgetResizable">
@@ -283,20 +635,32 @@
            <rect>
             <x>0</x>
             <y>0</y>
-            <width>272</width>
-            <height>684</height>
+            <width>209</width>
+            <height>501</height>
            </rect>
           </property>
           <layout class="QGridLayout" name="gridLayout_7">
+           <property name="verticalSpacing">
+            <number>4</number>
+           </property>
            <property name="margin">
-            <number>0</number>
+            <number>2</number>
            </property>
            <item row="0" column="0">
             <widget class="QGroupBox" name="mDeviceGroupBox">
              <property name="title">
-              <string>GPS connection</string>
+              <string>Connection</string>
              </property>
              <layout class="QGridLayout" name="gridLayout">
+              <property name="topMargin">
+               <number>2</number>
+              </property>
+              <property name="bottomMargin">
+               <number>4</number>
+              </property>
+              <property name="spacing">
+               <number>2</number>
+              </property>
               <item row="0" column="0">
                <widget class="QRadioButton" name="mRadAutodetect">
                 <property name="text">
@@ -310,26 +674,18 @@
               <item row="2" column="0">
                <widget class="QRadioButton" name="mRadUserPath">
                 <property name="text">
-                 <string>Use path / port below</string>
+                 <string>Serial device</string>
                 </property>
                </widget>
               </item>
               <item row="3" column="0">
-               <layout class="QHBoxLayout" name="horizontalLayout">
-                <item>
-                 <widget class="QLabel" name="mPathLabel">
-                  <property name="text">
-                   <string>Path to serial device</string>
-                  </property>
-                  <property name="buddy">
-                   <cstring>mCboDevices</cstring>
-                  </property>
-                 </widget>
-                </item>
-               </layout>
-              </item>
-              <item row="4" column="0">
                <layout class="QHBoxLayout" name="horizontalLayout_3">
+                <property name="spacing">
+                 <number>2</number>
+                </property>
+                <property name="leftMargin">
+                 <number>20</number>
+                </property>
                 <item>
                  <widget class="QComboBox" name="mCboDevices">
                   <property name="enabled">
@@ -342,6 +698,9 @@
                   <property name="enabled">
                    <bool>false</bool>
                   </property>
+                  <property name="toolTip">
+                   <string>Refresh serial device list</string>
+                  </property>
                   <property name="text">
                    <string>...</string>
                   </property>
@@ -353,8 +712,14 @@
                 </item>
                </layout>
               </item>
-              <item row="6" column="0">
+              <item row="5" column="0">
                <layout class="QGridLayout" name="gridLayout_12">
+                <property name="leftMargin">
+                 <number>20</number>
+                </property>
+                <property name="verticalSpacing">
+                 <number>2</number>
+                </property>
                 <item row="1" column="0">
                  <widget class="QLabel" name="label_4">
                   <property name="text">
@@ -390,6 +755,12 @@
                   <property name="enabled">
                    <bool>false</bool>
                   </property>
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
                  </widget>
                 </item>
                 <item row="0" column="1">
@@ -397,6 +768,12 @@
                   <property name="enabled">
                    <bool>false</bool>
                   </property>
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
                  </widget>
                 </item>
                 <item row="1" column="1">
@@ -404,8 +781,14 @@
                   <property name="enabled">
                    <bool>false</bool>
                   </property>
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
                   <property name="inputMask">
-                   <string>ddddd; </string>
+                   <string>00000; </string>
                   </property>
                   <property name="maxLength">
                    <number>5</number>
@@ -414,110 +797,225 @@
                 </item>
                </layout>
               </item>
-              <item row="5" column="0">
+              <item row="4" column="0">
                <widget class="QRadioButton" name="mRadGpsd">
                 <property name="text">
-                 <string>Connection to gpsd</string>
+                 <string>gpsd</string>
                 </property>
                </widget>
               </item>
              </layout>
             </widget>
            </item>
-           <item row="1" column="0">
-            <widget class="QGroupBox" name="mGroupShowMarker">
+           <item row="2" column="0">
+            <widget class="QGroupBox" name="groupBox_2">
              <property name="title">
-              <string>GPS cursor size</string>
-             </property>
-             <property name="checkable">
-              <bool>true</bool>
+              <string>Digitizing</string>
              </property>
-             <layout class="QGridLayout" name="gridLayout_3">
-              <item row="0" column="0" colspan="3">
-               <widget class="QSlider" name="mSliderMarkerSize">
-                <property name="minimum">
-                 <number>8</number>
-                </property>
-                <property name="maximum">
-                 <number>128</number>
-                </property>
-                <property name="singleStep">
-                 <number>4</number>
-                </property>
-                <property name="pageStep">
-                 <number>8</number>
-                </property>
-                <property name="sliderPosition">
-                 <number>10</number>
-                </property>
-                <property name="orientation">
-                 <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="tickPosition">
-                 <enum>QSlider::TicksBelow</enum>
-                </property>
-               </widget>
-              </item>
+             <layout class="QGridLayout" name="gridLayout_9">
+              <property name="topMargin">
+               <number>2</number>
+              </property>
+              <property name="bottomMargin">
+               <number>4</number>
+              </property>
+              <property name="verticalSpacing">
+               <number>2</number>
+              </property>
               <item row="1" column="0">
-               <widget class="QLabel" name="label">
-                <property name="text">
-                 <string>Small</string>
+               <widget class="QGroupBox" name="groupBox_3">
+                <property name="title">
+                 <string>Track</string>
                 </property>
+                <layout class="QVBoxLayout" name="verticalLayout">
+                 <property name="spacing">
+                  <number>2</number>
+                 </property>
+                 <property name="topMargin">
+                  <number>2</number>
+                 </property>
+                 <property name="bottomMargin">
+                  <number>4</number>
+                 </property>
+                 <item>
+                  <widget class="QCheckBox" name="mCbxAutoAddVertices">
+                   <property name="text">
+                    <string>Automatically add points</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <layout class="QHBoxLayout" name="horizontalLayout_7">
+                   <item>
+                    <widget class="QSpinBox" name="mSpinTrackWidth">
+                     <property name="toolTip">
+                      <string>Track width in pixels</string>
+                     </property>
+                     <property name="suffix">
+                      <string> width</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item>
+                    <widget class="QPushButton" name="mBtnTrackColour">
+                     <property name="styleSheet">
+                      <string/>
+                     </property>
+                     <property name="text">
+                      <string>Color</string>
+                     </property>
+                    </widget>
+                   </item>
+                  </layout>
+                 </item>
+                </layout>
                </widget>
               </item>
-              <item row="1" column="1">
-               <spacer name="horizontalSpacer_2">
-                <property name="orientation">
-                 <enum>Qt::Horizontal</enum>
-                </property>
-                <property name="sizeHint" stdset="0">
-                 <size>
-                  <width>207</width>
-                  <height>20</height>
-                 </size>
+              <item row="0" column="0">
+               <widget class="QCheckBox" name="mCbxAutoCommit">
+                <property name="toolTip">
+                 <string>save layer after every feature added</string>
                 </property>
-               </spacer>
-              </item>
-              <item row="1" column="2">
-               <widget class="QLabel" name="label_2">
                 <property name="text">
-                 <string>Large</string>
+                 <string>Automatically save added feature</string>
                 </property>
                </widget>
               </item>
              </layout>
             </widget>
            </item>
-           <item row="2" column="0">
-            <widget class="QGroupBox" name="groupBox_2">
+           <item row="5" column="0">
+            <widget class="QGroupBox" name="mLogFileGroupBox">
+             <property name="enabled">
+              <bool>true</bool>
+             </property>
+             <property name="minimumSize">
+              <size>
+               <width>0</width>
+               <height>0</height>
+              </size>
+             </property>
+             <property name="toolTip">
+              <string>save GPS data (NMEA sentences) to a file</string>
+             </property>
              <property name="title">
-              <string>GPS digitizing</string>
+              <string>Log File</string>
              </property>
-             <layout class="QGridLayout" name="gridLayout_9">
+             <property name="checkable">
+              <bool>true</bool>
+             </property>
+             <property name="checked">
+              <bool>false</bool>
+             </property>
+             <layout class="QGridLayout" name="gridLayout_13" columnstretch="100,0">
+              <property name="topMargin">
+               <number>2</number>
+              </property>
+              <property name="bottomMargin">
+               <number>4</number>
+              </property>
               <item row="0" column="0">
-               <widget class="QCheckBox" name="mCbxAutoAddVertices">
+               <widget class="QLineEdit" name="mTxtLogFile">
+                <property name="enabled">
+                 <bool>true</bool>
+                </property>
+                <property name="sizePolicy">
+                 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <property name="acceptDrops">
+                 <bool>false</bool>
+                </property>
+                <property name="readOnly">
+                 <bool>true</bool>
+                </property>
+               </widget>
+              </item>
+              <item row="0" column="1">
+               <widget class="QPushButton" name="mBtnLogFile">
+                <property name="sizePolicy">
+                 <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                  <horstretch>23</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <property name="minimumSize">
+                 <size>
+                  <width>23</width>
+                  <height>0</height>
+                 </size>
+                </property>
+                <property name="toolTip">
+                 <string>browse for log file</string>
+                </property>
                 <property name="text">
-                 <string>Auto-add vertices</string>
+                 <string>...</string>
                 </property>
                </widget>
               </item>
              </layout>
             </widget>
            </item>
-           <item row="3" column="0">
+           <item row="4" column="0">
             <widget class="QGroupBox" name="groupBox">
              <property name="title">
-              <string>GPS map recenter</string>
+              <string>Map centering</string>
              </property>
              <layout class="QGridLayout" name="gridLayout_8">
+              <property name="topMargin">
+               <number>2</number>
+              </property>
+              <property name="bottomMargin">
+               <number>4</number>
+              </property>
+              <property name="verticalSpacing">
+               <number>2</number>
+              </property>
               <item row="1" column="0">
                <widget class="QRadioButton" name="radRecenterWhenNeeded">
                 <property name="text">
-                 <string>when leaving extents</string>
+                 <string>when leaving</string>
                 </property>
                </widget>
               </item>
               <item row="2" column="0">
+               <layout class="QHBoxLayout" name="horizontalLayout">
+                <property name="leftMargin">
+                 <number>20</number>
+                </property>
+                <item>
+                 <widget class="QSpinBox" name="mSpinMapExtentMultiplier">
+                  <property name="enabled">
+                   <bool>false</bool>
+                  </property>
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="suffix">
+                   <string>% of map extent</string>
+                  </property>
+                  <property name="minimum">
+                   <number>5</number>
+                  </property>
+                  <property name="maximum">
+                   <number>100</number>
+                  </property>
+                  <property name="singleStep">
+                   <number>1</number>
+                  </property>
+                  <property name="value">
+                   <number>50</number>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </item>
+              <item row="3" column="0">
                <widget class="QRadioButton" name="radNeverRecenter">
                 <property name="text">
                  <string>never</string>
@@ -537,26 +1035,91 @@
              </layout>
             </widget>
            </item>
-           <item row="4" column="0">
-            <widget class="QGroupBox" name="groupBox_3">
+           <item row="3" column="0">
+            <widget class="QGroupBox" name="mGroupShowMarker">
              <property name="title">
-              <string>Track</string>
+              <string>Cursor</string>
              </property>
-             <layout class="QGridLayout" name="gridLayout_11">
-              <item row="0" column="0">
-               <widget class="QPushButton" name="mBtnTrackColour">
-                <property name="styleSheet">
-                 <string/>
+             <property name="checkable">
+              <bool>true</bool>
+             </property>
+             <layout class="QGridLayout" name="gridLayout_3">
+              <property name="topMargin">
+               <number>4</number>
+              </property>
+              <property name="bottomMargin">
+               <number>4</number>
+              </property>
+              <property name="verticalSpacing">
+               <number>2</number>
+              </property>
+              <item row="0" column="0" colspan="3">
+               <widget class="QSlider" name="mSliderMarkerSize">
+                <property name="sizePolicy">
+                 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
                 </property>
-                <property name="text">
-                 <string>Color</string>
+                <property name="minimum">
+                 <number>8</number>
+                </property>
+                <property name="maximum">
+                 <number>128</number>
+                </property>
+                <property name="singleStep">
+                 <number>4</number>
+                </property>
+                <property name="pageStep">
+                 <number>8</number>
+                </property>
+                <property name="sliderPosition">
+                 <number>10</number>
+                </property>
+                <property name="orientation">
+                 <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="tickPosition">
+                 <enum>QSlider::TicksBelow</enum>
                 </property>
                </widget>
               </item>
               <item row="1" column="0">
-               <widget class="QSpinBox" name="mSpinTrackWidth">
-                <property name="suffix">
-                 <string> width</string>
+               <widget class="QLabel" name="label">
+                <property name="sizePolicy">
+                 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <property name="text">
+                 <string>Small</string>
+                </property>
+               </widget>
+              </item>
+              <item row="1" column="1">
+               <spacer name="horizontalSpacer_2">
+                <property name="orientation">
+                 <enum>Qt::Horizontal</enum>
+                </property>
+                <property name="sizeHint" stdset="0">
+                 <size>
+                  <width>20</width>
+                  <height>10</height>
+                 </size>
+                </property>
+               </spacer>
+              </item>
+              <item row="1" column="2">
+               <widget class="QLabel" name="label_2">
+                <property name="sizePolicy">
+                 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                  <horstretch>0</horstretch>
+                  <verstretch>0</verstretch>
+                 </sizepolicy>
+                </property>
+                <property name="text">
+                 <string>Large</string>
                 </property>
                </widget>
               </item>
@@ -575,7 +1138,14 @@
         <number>0</number>
        </property>
        <item row="0" column="0">
-        <widget class="QTextEdit" name="mGPSTextEdit"/>
+        <widget class="QPlainTextEdit" name="mGPSPlainTextEdit">
+         <property name="acceptDrops">
+          <bool>false</bool>
+         </property>
+         <property name="undoRedoEnabled">
+          <bool>false</bool>
+         </property>
+        </widget>
        </item>
       </layout>
      </widget>
@@ -589,21 +1159,46 @@
   <tabstop>mBtnSatellites</tabstop>
   <tabstop>mBtnOptions</tabstop>
   <tabstop>mBtnDebug</tabstop>
-  <tabstop>mDateTime</tabstop>
-  <tabstop>mSpinLatitude</tabstop>
-  <tabstop>mSpinLongitude</tabstop>
-  <tabstop>mSpinElevation</tabstop>
-  <tabstop>mBtnAddVertex</tabstop>
+  <tabstop>mConnectButton</tabstop>
   <tabstop>mBtnCloseFeature</tabstop>
+  <tabstop>mBtnAddVertex</tabstop>
+  <tabstop>mBtnResetFeature</tabstop>
+  <tabstop>mTxtLatitude</tabstop>
+  <tabstop>mTxtLongitude</tabstop>
+  <tabstop>mTxtAltitude</tabstop>
+  <tabstop>mTxtDateTime</tabstop>
+  <tabstop>mTxtSpeed</tabstop>
+  <tabstop>mTxtDirection</tabstop>
+  <tabstop>mTxtHdop</tabstop>
+  <tabstop>mTxtVdop</tabstop>
+  <tabstop>mTxtPdop</tabstop>
+  <tabstop>mTxtFixMode</tabstop>
+  <tabstop>mTxtFixType</tabstop>
+  <tabstop>mTxtQuality</tabstop>
+  <tabstop>mTxtStatus</tabstop>
+  <tabstop>mTxtSatellitesUsed</tabstop>
   <tabstop>mRadAutodetect</tabstop>
   <tabstop>mRadUserPath</tabstop>
   <tabstop>mCboDevices</tabstop>
+  <tabstop>mBtnRefreshDevices</tabstop>
+  <tabstop>mRadGpsd</tabstop>
+  <tabstop>mGpsdHost</tabstop>
+  <tabstop>mGpsdPort</tabstop>
+  <tabstop>mGpsdDevice</tabstop>
+  <tabstop>mCbxAutoCommit</tabstop>
+  <tabstop>mCbxAutoAddVertices</tabstop>
+  <tabstop>mSpinTrackWidth</tabstop>
+  <tabstop>mBtnTrackColour</tabstop>
   <tabstop>mGroupShowMarker</tabstop>
   <tabstop>mSliderMarkerSize</tabstop>
   <tabstop>radRecenterMap</tabstop>
   <tabstop>radRecenterWhenNeeded</tabstop>
+  <tabstop>mSpinMapExtentMultiplier</tabstop>
   <tabstop>radNeverRecenter</tabstop>
-  <tabstop>mGPSTextEdit</tabstop>
+  <tabstop>mLogFileGroupBox</tabstop>
+  <tabstop>mTxtLogFile</tabstop>
+  <tabstop>mBtnLogFile</tabstop>
+  <tabstop>mGPSPlainTextEdit</tabstop>
  </tabstops>
  <resources>
   <include location="../../images/images.qrc"/>
@@ -612,22 +1207,6 @@
   <connection>
    <sender>mRadAutodetect</sender>
    <signal>toggled(bool)</signal>
-   <receiver>mPathLabel</receiver>
-   <slot>setDisabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>114</x>
-     <y>65</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>101</x>
-     <y>122</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>mRadAutodetect</sender>
-   <signal>toggled(bool)</signal>
    <receiver>mCboDevices</receiver>
    <slot>setDisabled(bool)</slot>
    <hints>
@@ -644,22 +1223,6 @@
   <connection>
    <sender>mRadUserPath</sender>
    <signal>toggled(bool)</signal>
-   <receiver>mPathLabel</receiver>
-   <slot>setEnabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>208</x>
-     <y>93</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>207</x>
-     <y>122</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>mRadUserPath</sender>
-   <signal>toggled(bool)</signal>
    <receiver>mCboDevices</receiver>
    <slot>setEnabled(bool)</slot>
    <hints>
@@ -897,5 +1460,101 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>radRecenterWhenNeeded</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>mSpinMapExtentMultiplier</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>132</x>
+     <y>339</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>141</x>
+     <y>360</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>radRecenterMap</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>mSpinMapExtentMultiplier</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>132</x>
+     <y>320</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>141</x>
+     <y>360</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>radNeverRecenter</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>mSpinMapExtentMultiplier</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>132</x>
+     <y>382</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>141</x>
+     <y>360</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>mCbxAutoAddVertices</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>mBtnAddVertex</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>94</x>
+     <y>348</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>122</x>
+     <y>41</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>mConnectButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>mDeviceGroupBox</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>191</x>
+     <y>71</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>107</x>
+     <y>173</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>mConnectButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>mLogFileGroupBox</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>191</x>
+     <y>71</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>107</x>
+     <y>563</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
