[Marble-commits] KDE/kdeedu/marble/src

Dennis Nienhüser earthwings at gentoo.org
Thu Apr 22 18:59:59 CEST 2010


SVN commit 1117638 by nienhueser:

When no current location is available but a position provider was activated by the user, show the position provider status to the user: "Initializing current location service...", "Waiting for current location information...", "Error when determining current location: $error". The patch also fixes PositionProviderStatus (must not be flags, must match GeoCute::Status which static_casts the conversion, apparently unused yet). Interruptions of gpsd (e.g. plugging out the device) are detected now. Some improvements in the N900 GPS handling (state handling and data querying).
CCBUG: 233603

 M  +32 -1     lib/MarbleControlBox.cpp  
 M  +2 -0      lib/MarbleControlBox.h  
 M  +3 -0      lib/MarbleControlBox.ui  
 M  +18 -1     lib/PositionProviderPluginInterface.cpp  
 M  +12 -6     lib/PositionProviderPluginInterface.h  
 M  +8 -5      lib/gps/PositionTracking.cpp  
 M  +6 -3      lib/gps/PositionTracking.h  
 M  +55 -5     plugins/positionprovider/gpsd/GpsdConnection.cpp  
 M  +14 -6     plugins/positionprovider/gpsd/GpsdConnection.h  
 M  +10 -1     plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.cpp  
 M  +1 -0      plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.h  
 M  +21 -3     plugins/positionprovider/gpsd/GpsdThread.cpp  
 M  +16 -2     plugins/positionprovider/gpsd/GpsdThread.h  
 M  +14 -6     plugins/positionprovider/maemo/MaemoPositionProviderPlugin.cpp  


--- trunk/KDE/kdeedu/marble/src/lib/MarbleControlBox.cpp #1117637:1117638
@@ -336,6 +336,9 @@
              this, SLOT( changePositionProvider( QString ) ) );
     connect( d->uiWidget.locationLabel, SIGNAL( linkActivated( QString ) ),
              this, SLOT( centerOnCurrentLocation() ) );
+    connect( d->m_widget->model()->gpsLayer()->getPositionTracking(),
+             SIGNAL( statusChanged( PositionProviderStatus) ), this,
+             SLOT( adjustPositionTrackingStatus( PositionProviderStatus) ) );
 }
 
 void MarbleControlBox::setWidgetTabShown( QWidget * widget,
@@ -412,7 +415,35 @@
              this,                      SIGNAL( zoomChanged( int ) ) );
 }
 
+void MarbleControlBox::adjustPositionTrackingStatus( PositionProviderStatus status )
+{
+    if ( status == PositionProviderStatusAvailable ) {
+        return;
+    }
 
+    QString html = "<html><body><p>";
+
+    switch ( status ) {
+        case PositionProviderStatusUnavailable:
+            html += tr( "Waiting for current location information..." );
+            break;
+        case PositionProviderStatusAcquiring:
+            html += tr( "Initializing current location service..." );
+            break;
+        case PositionProviderStatusAvailable:
+            Q_ASSERT( false );
+            break;
+        case PositionProviderStatusError:
+            html += tr( "Error when determining current location: " );
+            html += d->m_widget->model()->gpsLayer()->getPositionTracking()->error();
+            break;
+    }
+
+    html += "</p></body></html>";
+    d->uiWidget.locationLabel->setEnabled( true );
+    d->uiWidget.locationLabel->setText( html );
+}
+
 void MarbleControlBox::receiveGpsCoordinates( const GeoDataCoordinates &position, qreal speed )
 {
     d->m_currentPosition = position;
@@ -430,7 +461,7 @@
     html += "<tr><td>Altitude</td><td>%3</td></tr>";
     html += "<tr><td>Speed</td><td>%4</td></tr>";
     html += "</table>";
-    html += "</html></body>";
+    html += "</body></html>";
 
     switch ( d->m_locale->measureSystem() ) {
         case Metric:
--- trunk/KDE/kdeedu/marble/src/lib/MarbleControlBox.h #1117637:1117638
@@ -15,6 +15,7 @@
 
 
 #include "marble_export.h"
+#include "PositionProviderPlugin.h"
 
 #include <QtGui/QWidget>
 
@@ -245,6 +246,7 @@
     void adjustForStill();
 
     void changePositionProvider( const QString &provider );
+    void adjustPositionTrackingStatus( PositionProviderStatus status );
     void centerOnCurrentLocation();
 
  private:
--- trunk/KDE/kdeedu/marble/src/lib/MarbleControlBox.ui #1117637:1117638
@@ -700,6 +700,9 @@
          <property name="textFormat">
           <enum>Qt::RichText</enum>
          </property>
+         <property name="wordWrap">
+          <bool>true</bool>
+         </property>
         </widget>
        </item>
        <item>
--- trunk/KDE/kdeedu/marble/src/lib/PositionProviderPluginInterface.cpp #1117637:1117638
@@ -10,8 +10,25 @@
 
 #include "PositionProviderPluginInterface.h"
 
+namespace Marble
+{
 
+PositionProviderPluginInterface::~PositionProviderPluginInterface()
+{
+    // nothing to do
+}
 
-Marble::PositionProviderPluginInterface::~PositionProviderPluginInterface()
+QString PositionProviderPluginInterface::error() const
 {
+    // Subclasses are expected to override this, but we provide
+    // a default implementation
+
+    if ( status() == PositionProviderStatusError )
+    {
+        return QObject::tr( "Unknown error" );
+    }
+
+    return QString();
 }
+
+} // namespace Marble
--- trunk/KDE/kdeedu/marble/src/lib/PositionProviderPluginInterface.h #1117637:1117638
@@ -22,14 +22,13 @@
 namespace Marble
 {
   
-enum PositionProviderStatusFlag {
-    PositionProviderStatusUnavailable = 0,
+enum PositionProviderStatus {
+    PositionProviderStatusError = 0,
+    PositionProviderStatusUnavailable,
     PositionProviderStatusAcquiring,
     PositionProviderStatusAvailable
 };
 
-Q_DECLARE_FLAGS(PositionProviderStatus, PositionProviderStatusFlag)
-
 /**
  * @short The interface for position provider plugins.
  *
@@ -42,12 +41,19 @@
     virtual PositionProviderStatus status() const = 0;
     virtual GeoDataCoordinates position() const = 0;
     virtual GeoDataAccuracy accuracy() const = 0;
+
+    /**
+      * Returns an error string to be presented to the user
+      * if the status is PositionProviderStatusError. For other
+      * states, the result value is undefined.
+      */
+    virtual QString error() const;
 };
 
 }
 
-Q_DECLARE_INTERFACE( Marble::PositionProviderPluginInterface, "org.kde.Marble.PositionProviderPluginInterface/1.00" )
+Q_DECLARE_INTERFACE( Marble::PositionProviderPluginInterface, "org.kde.Marble.PositionProviderPluginInterface/1.01" )
 
+Q_DECLARE_METATYPE( Marble::PositionProviderStatus );
 
-
 #endif
--- trunk/KDE/kdeedu/marble/src/lib/gps/PositionTracking.cpp #1117637:1117638
@@ -17,17 +17,13 @@
 #include "Track.h"
 #include "TrackPoint.h"
 #include "TrackSegment.h"
-#include "PositionProviderPlugin.h"
 #include "MarbleMath.h"
+#include "MarbleDebug.h"
 #include "ViewParams.h"
 
 #include <QtXml/QXmlInputSource>
 #include <QtXml/QXmlSimpleReader>
 
-#include "MarbleDebug.h"
-
-
-
 using namespace Marble;
 
 PositionTracking::PositionTracking( GpxFile *currentGpx,
@@ -203,8 +199,15 @@
     if ( m_positionProvider ) {
         m_positionProvider->setParent( this );
         mDebug() << "Initializing position provider:" << m_positionProvider->name();
+        connect( m_positionProvider, SIGNAL( statusChanged( PositionProviderStatus ) ),
+                this, SIGNAL( statusChanged(PositionProviderStatus ) ) );
         m_positionProvider->initialize();
     }
 }
 
+QString PositionTracking::error() const
+{
+    return m_positionProvider ? m_positionProvider->error() : QString();
+}
+
 #include "PositionTracking.moc"
--- trunk/KDE/kdeedu/marble/src/lib/gps/PositionTracking.h #1117637:1117638
@@ -12,14 +12,14 @@
 #ifndef MARBLE_POSITIONTRACKING_H
 #define MARBLE_POSITIONTRACKING_H
 
+#include "PositionProviderPlugin.h"
+
 #include <QtGui/QRegion>
 #include <QtGui/QPolygonF>
 #include <QtCore/QObject>
 #include <QtCore/QTemporaryFile>
 #include <QtNetwork/QHttp>
 
-
-
 namespace Marble
 {
 
@@ -32,7 +32,6 @@
 class Waypoint;
 class GeoDataCoordinates;
 class PluginManager;
-class PositionProviderPlugin;
 
 class PositionTracking : public QObject 
 {
@@ -89,12 +88,16 @@
       */
     void setPositionProviderPlugin( PositionProviderPlugin* plugin );
 
+    QString error() const;
+
  public slots:
     void  notifyPosition( GeoDataCoordinates );
 
 Q_SIGNALS:
     void  gpsLocation( GeoDataCoordinates, qreal );
 
+    void statusChanged( PositionProviderStatus status );
+
  private:
     void updateSpeed( TrackPoint* previous, TrackPoint* next );
 
--- trunk/KDE/kdeedu/marble/src/plugins/positionprovider/gpsd/GpsdConnection.cpp #1117637:1117638
@@ -12,21 +12,62 @@
 
 #include "MarbleDebug.h"
 
+#include <errno.h>
+
 using namespace Marble;
 
 GpsdConnection::GpsdConnection( QObject* parent )
     : QObject( parent ),
       m_timer( 0 )
 {
+    connect( &m_timer, SIGNAL( timeout() ), this, SLOT( update() ) );
+}
+
+void GpsdConnection::initialize()
+{
+    m_timer.stop();
     gps_data_t* data = m_gpsd.open();
     if ( data ) {
+        m_status = PositionProviderStatusAcquiring;
+        emit statusChanged( m_status );
+
 #if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 3 ) && defined( WATCH_ENABLE )
         m_gpsd.stream( WATCH_ENABLE );
 #endif
-        connect( &m_timer, SIGNAL( timeout() ), this, SLOT( update() ) );
         m_timer.start( 1000 );
-    } else
-        mDebug() << "Connection to gpsd failed, no position info available.";
+    }
+    else {
+        // There is also gps_errstr() for libgps version >= 2.90,
+        // but it doesn't return a sensible error description
+        switch ( errno ) {
+            case NL_NOSERVICE:
+                m_error = tr("Internal gpsd error (cannot get service entry)");
+                break;
+            case NL_NOHOST:
+                m_error = tr("Internal gpsd error (cannot get host entry)");
+                break;
+            case NL_NOPROTO:
+                m_error = tr("Internal gpsd error (cannot get protocol entry)");
+                break;
+            case NL_NOSOCK:
+                m_error = tr("Internal gpsd error (unable to create socket)");
+                break;
+            case NL_NOSOCKOPT:
+                m_error = tr("Internal gpsd error (unable to set socket option)");
+                break;
+            case NL_NOCONNECT:
+                m_error = tr("No GPS device found by gpsd.");
+                break;
+            default:
+                m_error = tr("Unknown error when opening gpsd connection");
+                break;
+        }
+
+        m_status = PositionProviderStatusError;
+        emit statusChanged( m_status );
+
+        mDebug() << "Connection to gpsd failed, no position info available: " << m_error;
+    }
 }
 
 void GpsdConnection::update()
@@ -39,10 +80,19 @@
 #else
     data = m_gpsd.query( "o" );
 #endif
-    if ( data )
+
+    if ( data ) {
         emit gpsdInfo( *data );
+    }
+    else if ( m_status != PositionProviderStatusAcquiring ) {
+        mDebug() << "Lost connection to gpsd, trying to re-open.";
+        initialize();
+    }
 }
 
+QString GpsdConnection::error() const
+{
+    return m_error;
+}
 
-
 #include "GpsdConnection.moc"
--- trunk/KDE/kdeedu/marble/src/plugins/positionprovider/gpsd/GpsdConnection.h #1117637:1117638
@@ -11,13 +11,13 @@
 #ifndef GPSDCONNECTION_H
 #define GPSDCONNECTION_H
 
+#include "PositionProviderPlugin.h"
+
 #include <QtCore/QObject>
 #include <QtCore/QTimer>
 
 #include <libgpsmm.h>
 
-
-
 namespace Marble
 {
 
@@ -28,12 +28,22 @@
  public:
     GpsdConnection( QObject* parent = 0 );
 
+    void initialize();
+
+    QString error() const;    
+
  signals:
     void gpsdInfo( gps_data_t data );
-    
- private:
+
+    void statusChanged( PositionProviderStatus status ) const;    
+
+private:
+    void open();
+
     gpsmm m_gpsd;
     QTimer m_timer;
+    PositionProviderStatus m_status;
+    QString m_error;
     
  private slots:
     void update();
@@ -41,6 +51,4 @@
 
 }
 
-
-
 #endif
--- trunk/KDE/kdeedu/marble/src/plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.cpp #1117637:1117638
@@ -13,7 +13,6 @@
 #include "GpsdThread.h"
 #include "MarbleDebug.h"
 
-
 using namespace Marble;
 
 QString GpsdPositionProviderPlugin::name() const
@@ -43,9 +42,14 @@
 
 void GpsdPositionProviderPlugin::initialize()
 {
+    m_status = PositionProviderStatusAcquiring;
+    emit statusChanged( m_status );
+
     m_thread = new GpsdThread;
     connect( m_thread, SIGNAL( gpsdInfo( gps_data_t ) ),
              this, SLOT( update( gps_data_t ) ) );
+    connect( m_thread, SIGNAL( statusChanged( PositionProviderStatus ) ),
+             this, SIGNAL( statusChanged( PositionProviderStatus ) ) );
     m_thread->start();
 }
 
@@ -116,6 +120,11 @@
     }
 }
 
+QString GpsdPositionProviderPlugin::error() const
+{
+    return m_thread->error();
+}
+
 Q_EXPORT_PLUGIN2( GpsdPositionProviderPlugin, Marble::GpsdPositionProviderPlugin )
 
 
--- trunk/KDE/kdeedu/marble/src/plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.h #1117637:1117638
@@ -43,6 +43,7 @@
     virtual PositionProviderStatus status() const;
     virtual GeoDataCoordinates position() const;
     virtual GeoDataAccuracy accuracy() const;
+    virtual QString error() const;
     
  private:
     GpsdThread* m_thread;
--- trunk/KDE/kdeedu/marble/src/plugins/positionprovider/gpsd/GpsdThread.cpp #1117637:1117638
@@ -14,19 +14,37 @@
 
 #include "GpsdConnection.h"
 
+namespace Marble
+{
 
+GpsdThread::GpsdThread() : m_connection( 0 )
+{
+    // nothing to do
+}
 
-using namespace Marble;
+GpsdThread::~GpsdThread()
+{
+    delete m_connection;
+}
 
 void GpsdThread::run()
 {
     qRegisterMetaType<gps_data_t>( "gps_data_t" );
-    GpsdConnection connection;
-    connect( &connection, SIGNAL( gpsdInfo( gps_data_t ) ),
+    qRegisterMetaType<PositionProviderStatus>("PositionProviderStatus");
+    m_connection = new GpsdConnection;
+    connect( m_connection, SIGNAL( statusChanged( PositionProviderStatus) ),
+             this, SIGNAL( statusChanged( PositionProviderStatus) ) );
+    connect( m_connection, SIGNAL( gpsdInfo( gps_data_t ) ),
              this, SIGNAL( gpsdInfo( gps_data_t ) ) );
+    m_connection->initialize();
     exec();
 }
 
+QString GpsdThread::error() const
+{
+    return m_connection->error();
+}
 
+} // namespace Marble
 
 #include "GpsdThread.moc"
--- trunk/KDE/kdeedu/marble/src/plugins/positionprovider/gpsd/GpsdThread.h #1117637:1117638
@@ -11,6 +11,8 @@
 #ifndef GPSDTHREAD_H
 #define GPSDTHREAD_H
 
+#include "PositionProviderPlugin.h"
+
 #include <QtCore/QThread>
 
 #include <libgpsmm.h>
@@ -20,12 +22,26 @@
 namespace Marble
 {
 
+class GpsdConnection;
+
 class GpsdThread: public QThread
 {
     Q_OBJECT
 
  public:
+    GpsdThread();
+
+    ~GpsdThread();
+
     virtual void run();
+
+    QString error() const;
+
+Q_SIGNALS:
+    void statusChanged( PositionProviderStatus status ) const;
+
+private:
+    GpsdConnection* m_connection;
     
  signals:
     void gpsdInfo( gps_data_t data );
@@ -33,6 +49,4 @@
 
 }
 
-
-
 #endif
--- trunk/KDE/kdeedu/marble/src/plugins/positionprovider/maemo/MaemoPositionProviderPlugin.cpp #1117637:1117638
@@ -31,7 +31,7 @@
 };
 
 MaemoPositionProviderPluginPrivate::MaemoPositionProviderPluginPrivate() :
-        m_control( 0 ), m_device( 0 ), m_status( PositionProviderStatusUnavailable )
+        m_control( 0 ), m_device( 0 ), m_status( PositionProviderStatusAcquiring )
 {
     m_timer.setInterval( 1000 );
 }
@@ -79,11 +79,16 @@
 
 GeoDataCoordinates MaemoPositionProviderPlugin::position() const
 {
-    if ( status() == PositionProviderStatusAvailable ) {
+    if ( status() == PositionProviderStatusAvailable &&
+         d->m_device->fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET ) {
+        qreal alt = 0.0;
+        if ( d->m_device->fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET ) {
+            alt = d->m_device->fix->altitude;
+        }
+
         return GeoDataCoordinates( d->m_device->fix->longitude,
                                    d->m_device->fix->latitude,
-                                   d->m_device->fix->altitude,
-                                   GeoDataCoordinates::Degree );
+                                   alt, GeoDataCoordinates::Degree );
     }
 
     return GeoDataCoordinates();
@@ -142,9 +147,12 @@
 
 void MaemoPositionProviderPlugin::update()
 {
-    PositionProviderStatus newStatus = PositionProviderStatusUnavailable;
+    PositionProviderStatus newStatus = PositionProviderStatusAcquiring;
     if ( d->m_device ) {
-        newStatus = d->m_device->fix ? PositionProviderStatusAvailable : PositionProviderStatusAcquiring;
+        if ( d->m_device->status == LOCATION_GPS_DEVICE_STATUS_FIX && d->m_device->fix )
+            newStatus = PositionProviderStatusAvailable;
+        else
+            newStatus = PositionProviderStatusUnavailable;
     }
 
     if ( newStatus != d->m_status ) {


More information about the Marble-commits mailing list