diff --git a/CMakeLists.txt b/CMakeLists.txt index b7835616fa82..ae7a34cfa895 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,17 @@ IF (WITH_BINDINGS) SET (BINDINGS_GLOBAL_INSTALL FALSE CACHE BOOL "Install bindings to global python directory? (might need root)") ENDIF (WITH_BINDINGS) +#BUILD WITH QtMobility by default on android only. Other platform can force it +IF (ANDROID) + SET (DEFAULT_WITH_QTMOBILITY TRUE) +ELSE (ANDROID) + SET (DEFAULT_WITH_QTMOBILITY FALSE) +ENDIF (ANDROID) +SET (WITH_QTMOBILITY ${DEFAULT_WITH_QTMOBILITY} CACHE BOOL "Determines QtMobility related code should be build (for example internal GPS)") +IF (WITH_QTMOBILITY) + FIND_PACKAGE(QtMobility 1.1.0) +ENDIF (WITH_QTMOBILITY) + SET (WITH_GLOBE FALSE CACHE BOOL "Determines whether Globe plugin should be built") IF (WITH_GLOBE) SET(QT_USE_QTOPENGL 1) diff --git a/cmake/FindQtMobility.cmake b/cmake/FindQtMobility.cmake new file mode 100644 index 000000000000..cf7bbd636e09 --- /dev/null +++ b/cmake/FindQtMobility.cmake @@ -0,0 +1,163 @@ +INCLUDE(FindQt4) + +set(MOBILITY_CONFIG_MKSPECS_FILE "") +IF(EXISTS "${QT_MKSPECS_DIR}/features/mobilityconfig.prf") + set(MOBILITY_CONFIG_MKSPECS_FILE "${QT_MKSPECS_DIR}/features/mobilityconfig.prf") +ELSEIF(EXISTS "${QT_MKSPECS_DIR}/features/mobility.prf") + set(MOBILITY_CONFIG_MKSPECS_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmakes/mobilityconfig.prf") +ENDIF() + +macro(export_component component) + IF(NOT ${MOBILITY_CONFIG_MKSPECS_FILE} STREQUAL "") + FILE(READ ${MOBILITY_CONFIG_MKSPECS_FILE} MOBILITY_FILE_CONTENTS) + STRING(TOLOWER ${component} _COMPONENT) + IF(${MOBILITY_FILE_CONTENTS} MATCHES "MOBILITY_CONFIG=.*${_COMPONENT}.*") + STRING(TOUPPER ${component} _COMPONENT) + SET(QT_MOBILITY_${_COMPONENT}_FOUND 1) + SET(QT_MOBILITY_${_COMPONENT}_INCLUDE_DIR ${QT_MOBILITY_PARENT_INCLUDE_DIR}/Qt${component}) + SET(QT_MOBILITY_${_COMPONENT}_LIBRARY Qt${component}) + ADD_DEFINITIONS(-DHAVE_QT_MOBILITY_${_COMPONENT}) + ENDIF() + ENDIF() +endmacro() + +set(VERSION_INFO "") +set(FEATURE_FILE_PREFIX "${QT_MKSPECS_DIR}/features/mobility") + +if(DEFINED MOBILITY_VERSION) + if(MOBILITY_VERSION STREQUAL "1.1" AND EXISTS "${FEATURE_FILE_PREFIX}11.prf") + set(MOBILITY_PRF_FILE "${FEATURE_FILE_PREFIX}11.prf") + set(VERSION_INFO "1.1") + elseif(MOBILITY_VERSION STREQUAL "1.2" AND EXISTS "${FEATURE_FILE_PREFIX}12.prf") + set(MOBILITY_PRF_FILE "${FEATURE_FILE_PREFIX}12.prf") + set(VERSION_INFO "1.2") + elseif(MOBILITY_VERSION STREQUAL "default" AND EXISTS "${FEATURE_FILE_PREFIX}.prf") + set(MOBILITY_PRF_FILE "${FEATURE_FILE_PREFIX}.prf") + set(VERSION_INFO "system's default") + else() + message(STATUS "Couldn't find QtMobility version: ${MOBILITY_VERSION}") + endif() +endif() + +if(NOT DEFINED MOBILITY_PRF_FILE) + if(EXISTS "${FEATURE_FILE_PREFIX}.prf") + set(MOBILITY_PRF_FILE "${FEATURE_FILE_PREFIX}.prf") + set(VERSION_INFO "system's default") + elseif(EXISTS "${FEATURE_FILE_PREFIX}12.prf") + set(MOBILITY_PRF_FILE "${FEATURE_FILE_PREFIX}12.prf") + set(VERSION_INFO "1.2") + elseif(EXISTS "${FEATURE_FILE_PREFIX}11.prf") + set(MOBILITY_PRF_FILE "${FEATURE_FILE_PREFIX}11.prf") + set(VERSION_INFO "1.1") + else() + message(FATAL_ERROR "Couldn't find any version of QtMobility.") + endif() +endif() + +message(STATUS "Using QtMobility version: ${VERSION_INFO}") + +IF(DEFINED MOBILITY_PRF_FILE) + FILE(READ ${MOBILITY_PRF_FILE} MOBILITY_FILE_CONTENTS) + + STRING(REGEX MATCH "MOBILITY_PREFIX=([^\n]+)" QT_MOBILITY_PREFIX "${MOBILITY_FILE_CONTENTS}") + SET(QT_MOBILITY_PREFIX ${CMAKE_MATCH_1}) + + STRING(REGEX MATCH "MOBILITY_INCLUDE=([^\n]+)" QT_MOBILITY_INCLUDE_DIR "${MOBILITY_FILE_CONTENTS}") + SET(QT_MOBILITY_INCLUDE_DIR ${CMAKE_MATCH_1}) + + STRING(REGEX MATCH "MOBILITY_LIB=([^\n]+)" "\\1" QT_MOBILITY_LIBRARY "${MOBILITY_FILE_CONTENTS}") + SET(QT_MOBILITY_LIBRARY_DIR ${CMAKE_MATCH_1}) + + #VERSION + IF(NOT ${MOBILITY_CONFIG_MKSPECS_FILE} STREQUAL "") + FILE(READ ${MOBILITY_CONFIG_MKSPECS_FILE} MOBILITY_CONFIG_FILE_CONTENTS) + STRING(REGEX MATCH "MOBILITY_VERSION = ([^\n]+)" QT_MOBILITY_VERSION "${MOBILITY_CONFIG_FILE_CONTENTS}") + SET(QT_MOBILITY_VERSION ${CMAKE_MATCH_1}) + + STRING(REGEX MATCH "MOBILITY_MAJOR_VERSION = ([^\n]+)" QT_MOBILITY_MAJOR_VERSION "${MOBILITY_CONFIG_FILE_CONTENTS}") + SET(QT_MOBILITY_MAJOR_VERSION ${CMAKE_MATCH_1}) + + STRING(REGEX MATCH "MOBILITY_MINOR_VERSION = ([^\n]+)" QT_MOBILITY_MINOR_VERSION "${MOBILITY_CONFIG_FILE_CONTENTS}") + SET(QT_MOBILITY_MINOR_VERSION ${CMAKE_MATCH_1}) + + STRING(REGEX MATCH "MOBILITY_PATCH_VERSION = ([^\n]+)" QT_MOBILITY_PATCH_VERSION "${MOBILITY_CONFIG_FILE_CONTENTS}") + SET(QT_MOBILITY_PATCH_VERSION ${CMAKE_MATCH_1}) + + message(STATUS "QtMobility version: ${QT_MOBILITY_VERSION}") + ELSE() + SET(QT_MOBILITY_VERSION 1.0.0) + SET(QT_MOBILITY_MAJOR_VERSION 1) + SET(QT_MOBILITY_MINOR_VERSION 0) + SET(QT_MOBILITY_PATCH_VERSION 0) + ENDIF() + + SET(QT_MOBILITY_PARENT_INCLUDE_DIR ${QT_MOBILITY_INCLUDE_DIR}) + SET(QT_MOBILITY_INCLUDE_DIR ${QT_MOBILITY_INCLUDE_DIR}/QtMobility) + + IF(QtMobility_FIND_VERSION_EXACT) + IF(QT_MOBILITY_VERSION VERSION_EQUAL QtMobility_FIND_VERSION) + SET(QT_MOBILITY_FOUND TRUE) + ELSE() + SET(QT_MOBILITY_FOUND FALSE) + IF(QT_MOBILITY_VERSION VERSION_LESS QtMobility_FIND_VERSION) + SET(QT_MOBILITY_TOO_OLD TRUE) + ELSE() + SET(QT_MOBILITY_TOO_NEW TRUE) + ENDIF() + ENDIF() + ELSE() + IF(QT_MOBILITY_VERSION VERSION_LESS QtMobility_FIND_VERSION) + SET(QT_MOBILITY_FOUND FALSE) + SET(QT_MOBILITY_TOO_OLD TRUE) + ELSE() + SET(QT_MOBILITY_FOUND TRUE) + ENDIF() + ENDIF() +ELSE() + SET(QT_MOBILITY_FOUND NOTFOUND) + SET(QT_MOBILITY_PREFIX NOTFOUND) + SET(QT_MOBILITY_INCLUDE NOTFOUND) + SET(QT_MOBILITY_LIB NOTFOUND) +ENDIF() + +IF(NOT QT_MOBILITY_FOUND) + if(QT_MOBILITY_TOO_OLD) + MESSAGE(FATAL_ERROR "The installed QtMobility version ${QT_MOBILITY_VERSION} it too old, version ${QtMobility_FIND_VERSION} is required.") + ELSEIF(QT_MOBILITY_TOO_NEW) + MESSAGE(FATAL_ERROR "The installed QtMobility version ${QT_MOBILITY_VERSION} it too new, version ${QtMobility_FIND_VERSION} is required.") + ELSE() + MESSAGE(FATAL_ERROR "QtMobility not found.") + ENDIF() +ELSE() + INCLUDE_DIRECTORIES(${QT_MOBILITY_INCLUDE_DIR}) + export_component(Bearer) + export_component(Feedback) + export_component(Gallery) + export_component(PublishSubscribe) + export_component(Location) + export_component(Organizer) + export_component(ServiceFramework) + export_component(SystemInfo) + export_component(Contacts) + export_component(Connectivity) + export_component(Messaging) + export_component(Versit) + export_component(Sensors) + # VersitOrganizer + if(QT_MOBILITY_VERSIT_FOUND AND QT_MOBILITY_ORGANIZER_FOUND) + SET(QT_MOBILITY_VERSITORGANIZER_FOUND 1) + SET(QT_MOBILITY_VERSITORGANIZER_INCLUDE_DIR ${QT_MOBILITY_PARENT_INCLUDE_DIR}/QtVersitOrganizer) + SET(QT_MOBILITY_VERSITORGANIZER_LIBRARY QtVersitOrganizer) + endif() + + # MultimediaKit - it's just 'multimedia' in the .prf file. + IF(NOT ${MOBILITY_CONFIG_MKSPECS_FILE} STREQUAL "") + FILE(READ ${MOBILITY_CONFIG_MKSPECS_FILE} MOBILITY_FILE_CONTENTS) + IF(${MOBILITY_FILE_CONTENTS} MATCHES "MOBILITY_CONFIG=.*multimedia.*") + SET(QT_MOBILITY_MULTIMEDIAKIT_FOUND 1) + SET(QT_MOBILITY_MULTIMEDIAKIT_INCLUDE_DIR ${QT_MOBILITY_PARENT_INCLUDE_DIR}/QtMultimediaKit) + SET(QT_MOBILITY_MULTIMEDIAKIT_LIBRARY QtMultimediaKit) + ENDIF() + ENDIF() + +ENDIF() diff --git a/src/app/gps/qgsgpsinformationwidget.cpp b/src/app/gps/qgsgpsinformationwidget.cpp index d8fbfe65302e..63389b9b93a0 100644 --- a/src/app/gps/qgsgpsinformationwidget.cpp +++ b/src/app/gps/qgsgpsinformationwidget.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - qgsgpsinformationwidget.h - description + qgsgpsinformationwidget.cpp - description ------------------- begin : Sat Jan 01 2010 copyright : (C) 2010 by Tim Sutton and Marco Hugentobler @@ -184,6 +184,10 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi { mRadAutodetect->setChecked( true ); } + else if ( myPortMode == "internalGPS" ) + { + mRadInternal->setChecked( true ); + } else if ( myPortMode == "explicitPort" ) { mRadUserPath->setChecked( true ); @@ -192,6 +196,11 @@ QgsGPSInformationWidget::QgsGPSInformationWidget( QgsMapCanvas * thepCanvas, QWi { mRadGpsd->setChecked( true ); } + //disable the internal port method if build is without QtLocation +#ifndef HAVE_QT_MOBILITY_LOCATION + mRadInternal->setDisabled( true ); + mRadAutodetect->setChecked( true ); +#endif //auto digitising behaviour mCbxAutoAddVertices->setChecked( mySettings.value( "/gps/autoAddVertices", "false" ).toBool() ); @@ -256,6 +265,10 @@ QgsGPSInformationWidget::~QgsGPSInformationWidget() { mySettings.setValue( "/gps/portMode", "scanPorts" ); } + else if ( mRadInternal->isChecked() ) + { + mySettings.setValue( "/gps/portMode", "internalGPS" ); + } else if ( mRadUserPath->isChecked() ) { mySettings.setValue( "/gps/portMode", "explicitPort" ); @@ -406,6 +419,10 @@ void QgsGPSInformationWidget::connectGps() { port = QString( "%1:%2:%3" ).arg( mGpsdHost->text() ).arg( mGpsdPort->text() ).arg( mGpsdDevice->text() ); } + else if ( mRadInternal->isChecked() ) + { + port = QString( "internalGPS" ); + } mGPSPlainTextEdit->appendPlainText( tr( "Connecting..." ) ); showStatusBarMessage( tr( "Connecting to GPS device..." ) ); @@ -678,10 +695,12 @@ void QgsGPSInformationWidget::displayGPSInformation( const QgsGPSInformation& in 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 ) ); + mTxtDirection->setText( QString::number( info.direction, 'f', 1 ) + QString::fromUtf8("°") ); mTxtHdop->setText( QString::number( info.hdop, 'f', 1 ) ); mTxtVdop->setText( QString::number( info.vdop, 'f', 1 ) ); mTxtPdop->setText( QString::number( info.pdop, 'f', 1 ) ); + mTxtHacc->setText( QString::number( info.hacc, 'f', 1 ) + "m" ); + mTxtVacc->setText( QString::number( info.vacc, 'f', 1 ) + "m" ); 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 @@ -794,7 +813,7 @@ void QgsGPSInformationWidget::on_mBtnAddVertex_clicked( ) void QgsGPSInformationWidget::addVertex( ) { - + QgsDebugMsg("Adding Vertex"); if ( !mpRubberBand ) { createRubberBand( ); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8ad2b22fe526..76f4920b5bc4 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -191,6 +191,13 @@ ELSE(WIN32) ADD_DEFINITIONS(-D_TTY_POSIX_) ENDIF(WIN32) +IF (QT_MOBILITY_LOCATION_FOUND) + SET(QGIS_CORE_SRCS + ${QGIS_CORE_SRCS} + gps/qgsqtlocationconnection.cpp + ) +ENDIF (QT_MOBILITY_LOCATION_FOUND) + IF (WITH_INTERNAL_SPATIALITE) IF (WIN32 OR APPLE OR ANDROID) INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR}) @@ -274,6 +281,13 @@ SET(QGIS_CORE_MOC_HDRS gps/qextserialport/qextserialenumerator.h ) +IF (QT_MOBILITY_LOCATION_FOUND) + SET(QGIS_CORE_MOC_HDRS + ${QGIS_CORE_MOC_HDRS} + gps/qgsqtlocationconnection.h + ) +ENDIF (QT_MOBILITY_LOCATION_FOUND) + QT4_WRAP_CPP(QGIS_CORE_MOC_SRCS ${QGIS_CORE_MOC_HDRS}) # install headers @@ -394,6 +408,13 @@ SET(QGIS_CORE_HDRS qgsspatialindex.h ) +IF (QT_MOBILITY_LOCATION_FOUND) + SET(QGIS_CORE_HDRS + ${QGIS_CORE_HDRS} + gps/qgsqtlocationconnection.h + ) +ENDIF (QT_MOBILITY_LOCATION_FOUND) + INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} composer @@ -494,6 +515,10 @@ IF(APPLE) TARGET_LINK_LIBRARIES(qgis_core "-framework CoreFoundation -framework IOKit") ENDIF(APPLE) +IF (QT_MOBILITY_LOCATION_FOUND) + TARGET_LINK_LIBRARIES(qgis_core ${QT_MOBILITY_LOCATION_LIBRARY}) +ENDIF (QT_MOBILITY_LOCATION_FOUND) + TARGET_LINK_LIBRARIES(qgis_core ${QT_QTMAIN_LIBRARY} ${QT_QTXML_LIBRARY} diff --git a/src/core/gps/qgsgpsconnection.cpp b/src/core/gps/qgsgpsconnection.cpp index b3411631cbcf..affe193fb0cd 100644 --- a/src/core/gps/qgsgpsconnection.cpp +++ b/src/core/gps/qgsgpsconnection.cpp @@ -94,6 +94,8 @@ void QgsGPSConnection::clearLastGPSInformation() mLastGPSInformation.satellitesInView.clear(); mLastGPSInformation.speed = 0; mLastGPSInformation.vdop = 0; + mLastGPSInformation.hacc = -1; + mLastGPSInformation.vacc = -1; mLastGPSInformation.quality = -1; // valid values: 0,1,2, maybe others mLastGPSInformation.satellitesUsed = 0; mLastGPSInformation.fixMode = ' '; diff --git a/src/core/gps/qgsgpsconnection.h b/src/core/gps/qgsgpsconnection.h index fd881517dee1..bfa18461033e 100644 --- a/src/core/gps/qgsgpsconnection.h +++ b/src/core/gps/qgsgpsconnection.h @@ -44,6 +44,8 @@ struct CORE_EXPORT QgsGPSInformation double pdop; double hdop; double vdop; + double hacc; //horizontal accurancy in meters + double vacc; //vertical accurancy in meters QDateTime utcDateTime; QChar fixMode; int fixType; diff --git a/src/core/gps/qgsgpsdetector.cpp b/src/core/gps/qgsgpsdetector.cpp index dbcd24f273c5..eab77cafbab2 100644 --- a/src/core/gps/qgsgpsdetector.cpp +++ b/src/core/gps/qgsgpsdetector.cpp @@ -22,6 +22,10 @@ #include "qgsnmeaconnection.h" #include "qgsgpsdconnection.h" +#ifdef HAVE_QT_MOBILITY_LOCATION +#include "qgsqtlocationconnection.h" +#endif + #include #include #include @@ -30,6 +34,10 @@ QList< QPair > QgsGPSDetector::availablePorts() { QList< QPair > devs; + // try local QtLocation first +#ifdef HAVE_QT_MOBILITY_LOCATION + devs << QPair( "internalGPS", tr( "internal GPS" ) ); +#endif // try local gpsd first devs << QPair( "localhost:2947:", tr( "local gpsd" ) ); @@ -145,6 +153,15 @@ void QgsGPSDetector::advance() mConn = new QgsGpsdConnection( gpsParams[0], gpsParams[1].toShort(), gpsParams[2] ); } + else if( mPortList[ mPortIndex ].first.contains( "internalGPS" ) ) + { +#ifdef HAVE_QT_MOBILITY_LOCATION + mConn = new QgsQtLocationConnection(); +#else + qWarning("QT_MOBILITY_LOCATION not found and mPortList matches internalGPS, this should never happen"); +#endif + } + else { QextSerialPort *serial = new QextSerialPort( mPortList[ mPortIndex ].first, QextSerialPort::EventDriven ); diff --git a/src/core/gps/qgsqtlocationconnection.cpp b/src/core/gps/qgsqtlocationconnection.cpp new file mode 100644 index 000000000000..5a1e6791b41c --- /dev/null +++ b/src/core/gps/qgsqtlocationconnection.cpp @@ -0,0 +1,223 @@ +/*************************************************************************** + QgsQtLocationConnection.cpp - description + --------------------- + begin : December 7th, 2011 + copyright : (C) 2011 by Marco Bernasocchi, Bernawebdesign.ch + email : marco at bernawebdesign dot ch + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsqtlocationconnection.h" +#include "qgslogger.h" + +#include +#include +#include + +QgsQtLocationConnection::QgsQtLocationConnection( ): QgsGPSConnection( new QLocalSocket() ) +{ + //needed to fix https://sourceforge.net/p/necessitas/tickets/146/ + qRegisterMetaType< QList >("QList"); + + startGPS(); + startSatelliteMonitor(); + + //HACK to signal the gpsinformationwidget that we have a QtLocationConnection + QTimer::singleShot( 500, this, SLOT( broadcastConnectionAvailable() ) ); +} + +QgsQtLocationConnection::~QgsQtLocationConnection() +{ + //connection will be closed by base class + QgsDebugMsg( "entered." ); +} + +//Needed to make connection detectable (half HACK) +//this signals that the device has started the GPS sucessfully, +//not that it has a fix yet. +void QgsQtLocationConnection::broadcastConnectionAvailable() +{ + if (locationDataSource){ + mStatus = GPSDataReceived; + emit stateChanged( mLastGPSInformation ); + } +} + +//TODO: Temporarely needed to workaround https://sourceforge.net/p/necessitas/tickets/147/ +void QgsQtLocationConnection::positionUpdated(const QGeoPositionInfo &info) +{ + mInfo = info; + parseData(); +} + +void QgsQtLocationConnection::parseData() +{ + if (locationDataSource){ + mStatus = GPSDataReceived; + //const QGeoPositionInfo &info = locationDataSource->lastKnownPosition(); + qDebug() << mInfo; + if (mInfo.isValid()) + { + // mInfo.HorizontalAccuracy; + mLastGPSInformation.latitude = mInfo.coordinate().latitude(); + mLastGPSInformation.longitude = mInfo.coordinate().longitude() ; + mLastGPSInformation.elevation = mInfo.coordinate().altitude(); + mLastGPSInformation.speed = mInfo.attribute(QGeoPositionInfo::GroundSpeed) * 3.6; // m/s to km/h + mLastGPSInformation.direction = mInfo.attribute(QGeoPositionInfo::Direction); + mLastGPSInformation.utcDateTime = mInfo.timestamp(); + mLastGPSInformation.fixType = mInfo.coordinate().type() + 1; + //< fixType, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) + //< coordinate().type(), returns 0 = Fix not available; 1 = 2D; 2 = 3D) + mLastGPSInformation.hacc = mInfo.attribute(QGeoPositionInfo::HorizontalAccuracy); //< Horizontal dilution of precision + mLastGPSInformation.vacc = mInfo.attribute(QGeoPositionInfo::VerticalAccuracy); //< Vertical dilution of precision + + //TODO implement dop maybe by getting a + //http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html + //into QtLocation and subclass QgsNMEAConnection directly? + mLastGPSInformation.pdop; //< Dilution of precision + mLastGPSInformation.hdop; //< Horizontal dilution of precision + mLastGPSInformation.vdop; //< Vertical dilution of precision + + mLastGPSInformation.fixMode; //< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D) + mLastGPSInformation.quality; //< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) + mLastGPSInformation.status; //< Status (A = active or V = void) + + emit stateChanged( mLastGPSInformation ); + QgsDebugMsg("Valid QGeoPositionInfo, positionUpdated"); + } + } +} + +void QgsQtLocationConnection::satellitesInViewUpdated( + const QList& satellites) +{ + // The number of satellites in view is updated + mLastGPSInformation.satellitesInView.clear(); + for (int i = 0; i < satellites.size(); ++i) + { + QGeoSatelliteInfo currentSatellite = satellites.at(i); + QgsSatelliteInfo satelliteInfo; + satelliteInfo.azimuth = currentSatellite.attribute( QGeoSatelliteInfo::Azimuth ); + satelliteInfo.elevation = currentSatellite.attribute( QGeoSatelliteInfo::Elevation ); + satelliteInfo.id = currentSatellite.prnNumber(); + satelliteInfo.signal = currentSatellite.signalStrength(); + mLastGPSInformation.satellitesInView.append( satelliteInfo ); + } + mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position + emit stateChanged( mLastGPSInformation ); + QgsDebugMsg("satellitesInViewUpdated"); +} + +void QgsQtLocationConnection::satellitesInUseUpdated( + const QList& satellites) { + // The number of satellites in use is updated + mLastGPSInformation.satellitesUsed = QString::number(satellites.count()).toInt(); + + mLastGPSInformation.satPrn.clear(); + for (int i = 0; i < satellites.size(); ++i) + { + QGeoSatelliteInfo currentSatellite = satellites.at(i); + //add pnr to mLastGPSInformation.satPrn + mLastGPSInformation.satPrn.append(currentSatellite.prnNumber()); + + //set QgsSatelliteInfo.inuse to true for the satellites in use + for (int i = 0; i < mLastGPSInformation.satellitesInView.size(); ++i) + { + QgsSatelliteInfo satInView = mLastGPSInformation.satellitesInView.at(i); + if ( satInView.id == currentSatellite.prnNumber() ) + { + satInView.inUse = true; + break; + } + } + } + mLastGPSInformation.satInfoComplete = true; //to be used to determine when to graph signal and satellite position + emit stateChanged( mLastGPSInformation ); + QgsDebugMsg("satellitesInUseUpdated"); +} + +void QgsQtLocationConnection::startGPS() +{ + QgsDebugMsg("Starting GPS QtLocation connection"); + // Obtain the location data source if it is not obtained already + if (!locationDataSource) + { + locationDataSource = QGeoPositionInfoSource::createDefaultSource(this); + if (locationDataSource) + { + locationDataSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods); //QGeoPositionInfoSource::AllPositioningMethods + // locationDataSource->setUpdateInterval(2000); + // Whenever the location data source signals that the current + // position is updated, the positionUpdated function is called. + QObject::connect(locationDataSource, + SIGNAL(positionUpdated(QGeoPositionInfo)), + this, + SLOT(positionUpdated(QGeoPositionInfo))); + // Start listening for position updates + locationDataSource->startUpdates(); + } + else + { + // Not able to obtain the location data source + QgsDebugMsg("No QtLocation Position Source"); + } + } + else + { + // Start listening for position updates + locationDataSource->startUpdates(); + } +} + +void QgsQtLocationConnection::startSatelliteMonitor() +{ + QgsDebugMsg("Starting GPS QtLocation satellite monitor"); + if (!satelliteInfoSource) + { + satelliteInfoSource = QGeoSatelliteInfoSource::createDefaultSource(this); + if (satelliteInfoSource) + { + QgsDebugMsg( "satelliteMonitor started" ); + // Whenever the satellite info source signals that the number of + // satellites in use is updated, the satellitesInUseUpdated function + // is called + QObject::connect(satelliteInfoSource, + SIGNAL(satellitesInUseUpdated( + const QList&)), + this, + SLOT(satellitesInUseUpdated( + const QList&))); + + // Whenever the satellite info source signals that the number of + // satellites in view is updated, the satellitesInViewUpdated function + // is called + QObject::connect(satelliteInfoSource, + SIGNAL(satellitesInViewUpdated( + const QList&)), + this, + SLOT(satellitesInViewUpdated( + const QList&))); + + // Start listening for satellite updates + satelliteInfoSource->startUpdates(); + } + else + { + // Not able to obtain the Satellite data source + QgsDebugMsg("No QtLocation Satellite Source"); + } + } + else + { + // Start listening for position updates + satelliteInfoSource->startUpdates(); + } +} diff --git a/src/core/gps/qgsqtlocationconnection.h b/src/core/gps/qgsqtlocationconnection.h new file mode 100644 index 000000000000..b10c3f931cf9 --- /dev/null +++ b/src/core/gps/qgsqtlocationconnection.h @@ -0,0 +1,62 @@ +/*************************************************************************** + QgsQtLocationConnection.h - description + ------------------- + begin : December 7th, 2011 + copyright : (C) 2011 by Marco Bernasocchi, Bernawebdesign.ch + email : marco at bernawebdesign dot ch + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSQTLOCATIONCONNECTION_H +#define QGSQTLOCATIONCONNECTION_H + +#include "qgsgpsconnection.h" +#include +#include +#include +#include + +QTM_USE_NAMESPACE + +class CORE_EXPORT QgsQtLocationConnection: public QgsGPSConnection +{ + Q_OBJECT + public: + QgsQtLocationConnection(); + ~QgsQtLocationConnection(); + + protected slots: + /**Needed to make QtLocation detected*/ + void broadcastConnectionAvailable( ); + + /**Parse available data source content*/ + void parseData(); + + /**Called when the position updated.*/ + void positionUpdated(const QGeoPositionInfo &info); + + /**Called when the number of satellites in view is updated.*/ + void satellitesInViewUpdated( const QList& satellites ); + + /**Called when the number of satellites in use is updated.*/ + void satellitesInUseUpdated( const QList& satellites ); + + private: + void startGPS(); + void startSatelliteMonitor(); + QString mDevice; + QGeoPositionInfo mInfo; + QPointer locationDataSource; + QPointer satelliteInfoSource; + +}; + +#endif // QGSQTLOCATIONCONNECTION_H diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 96f9ffd88678..2afcb792ad9d 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -36,4 +36,9 @@ IF (WITH_GLOBE) ADD_SUBDIRECTORY(globe) ENDIF (WITH_GLOBE) + +IF (QT_MOBILITY_SENSORS_FOUND) + ADD_SUBDIRECTORY(compass) +ENDIF (QT_MOBILITY_SENSORS_FOUND) + # headers installed in qgis_core target diff --git a/src/plugins/compass/CMakeLists.txt b/src/plugins/compass/CMakeLists.txt new file mode 100644 index 000000000000..d3e68907503d --- /dev/null +++ b/src/plugins/compass/CMakeLists.txt @@ -0,0 +1,51 @@ + +######################################################## +# Files + +SET (COMPASS_SRCS + compass.cpp + qgscompassplugin.cpp + qgscompassplugingui.cpp +) + +SET (COMPASS_UIS qgscompasspluginguibase.ui) + +SET (COMPASS_MOC_HDRS + compass.h + qgscompassplugin.h + qgscompassplugingui.h +) + +SET (COMPASS_RCCS compass.qrc) + +######################################################## +# Build + +QT4_WRAP_UI (COMPASS_UIS_H ${COMPASS_UIS}) + +QT4_WRAP_CPP (COMPASS_MOC_SRCS ${COMPASS_MOC_HDRS}) + +QT4_ADD_RESOURCES(COMPASS_RCC_SRCS ${COMPASS_RCCS}) + +ADD_LIBRARY (compassplugin MODULE ${COMPASS_SRCS} ${COMPASS_MOC_SRCS} ${COMPASS_RCC_SRCS} ${COMPASS_UIS_H}) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_BINARY_DIR} + ../../core ../../core/raster ../../core/renderer ../../core/symbology + ../../gui + .. +) + +TARGET_LINK_LIBRARIES(compassplugin + qgis_core + qgis_gui + ${QT_MOBILITY_SENSORS_LIBRARY} +) + + +######################################################## +# Install + +INSTALL(TARGETS compassplugin + RUNTIME DESTINATION ${QGIS_PLUGIN_DIR} + LIBRARY DESTINATION ${QGIS_PLUGIN_DIR}) diff --git a/src/plugins/compass/compass.cpp b/src/plugins/compass/compass.cpp new file mode 100644 index 000000000000..262d848733e8 --- /dev/null +++ b/src/plugins/compass/compass.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + compass.cpp + Functions: + ------------------- + begin : Jan 28, 2012 + copyright : (C) 2012 by Marco Bernasocchi + email : marco@bernawebdesign.ch + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "compass.h" + +Compass::Compass() +{ +// mRateVal = 0; +// if (mRateVal > 0) +// { +// qDebug() << "Compasssensor setdatarate " << endl; +// mSensor.setDataRate(mRateVal); +// } +// qDebug() << "Data rate 2: " << mSensor.dataRate(); + mSensor.addFilter(this); + start(); +} + +Compass::~Compass() +{ +} + +bool Compass::filter(QCompassReading *reading) +{ +// int diff = ( reading->timestamp() - stamp ); +// stamp = reading->timestamp(); + +// QString str; +// str = QString("%1 deg (%2 CalibLevel)") +// .arg(reading->azimuth(), 3, 'f', 0) +// .arg(reading->calibrationLevel(), 3, 'f', 0); +// qDebug() << str << endl; + + emit azimuthChanged(reading->azimuth(), reading->calibrationLevel()); + return false; // don't store the reading in the sensor +} + +bool Compass::isActive() +{ + return mSensor.isActive(); +} + +bool Compass::start() +{ + mSensor.start(); + if (!mSensor.isActive()) + { + qDebug() << "Compasssensor didn't start!" << endl; + return false; + } + return true; +} + +bool Compass::stop() +{ + mSensor.stop(); + if (mSensor.isActive()) + { + qDebug() << "Compasssensor didn't stop!" << endl; + return false; + } + return true; +} diff --git a/src/plugins/compass/compass.h b/src/plugins/compass/compass.h new file mode 100644 index 000000000000..f93e8de0e2b3 --- /dev/null +++ b/src/plugins/compass/compass.h @@ -0,0 +1,50 @@ +/*************************************************************************** + compass.h + Functions: Reads data from a QtMobility QCompass + ------------------- + begin : Jan 28, 2012 + copyright : (C) 2012 by Marco Bernasocchi + email : marco@bernawebdesign.ch + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef _COMPASS_H__ +#define _COMPASS_H__ + +#include +#include +#include +#include + +QTM_USE_NAMESPACE + +class Compass : public QObject, public QCompassFilter +{ + Q_OBJECT + public: + Compass(); + ~Compass(); + bool filter(QCompassReading *reading); + bool isActive(); + bool start(); + bool stop(); + + private: + qtimestamp stamp; + int mRateVal; + QCompass mSensor; + + signals: + void azimuthChanged(const QVariant &azimuth, const QVariant &calibrationLevel); +}; + +#endif // _COMPASS_H__ diff --git a/src/plugins/compass/compass.qrc b/src/plugins/compass/compass.qrc new file mode 100644 index 000000000000..67ccb7464a74 --- /dev/null +++ b/src/plugins/compass/compass.qrc @@ -0,0 +1,5 @@ + + + icons/mCompassRun.png + + diff --git a/src/plugins/compass/icons/mCompassRun.png b/src/plugins/compass/icons/mCompassRun.png new file mode 100644 index 000000000000..3230c07652cc Binary files /dev/null and b/src/plugins/compass/icons/mCompassRun.png differ diff --git a/src/plugins/compass/qgscompassplugin.cpp b/src/plugins/compass/qgscompassplugin.cpp new file mode 100644 index 000000000000..47b2a4753655 --- /dev/null +++ b/src/plugins/compass/qgscompassplugin.cpp @@ -0,0 +1,252 @@ +/*************************************************************************** + qgscompassplugin.cpp + Functions: + ------------------- + begin : Jan 28, 2012 + copyright : (C) 2012 by Marco Bernasocchi + email : marco@bernawebdesign.ch + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// includes + +#include +#include +#include +#include "qgscompassplugin.h" + +#include +#include +#include +#include +#include +#include "qgscompassplugingui.h" + + +static const QString sName = QObject::tr( "Internal Compass" ); +static const QString sDescription = QObject::tr( "Shows a QtSensors compass reading" ); +static const QString sCategory = QObject::tr( "Plugins" ); +static const QString sPluginVersion = QObject::tr( "Version 0.9" ); +static const QgisPlugin::PLUGINTYPE sPluginType = QgisPlugin::UI; +static const QString sPluginIcon = ":/compass.svn"; + +/** + * Constructor for the plugin. The plugin is passed a pointer to the main app + * and an interface object that provides access to exposed functions in QGIS. + * @param qgis Pointer to the QGIS main window + * @param _qI Pointer to the QGIS interface object + */ +QgsCompassPlugin::QgsCompassPlugin( QgisInterface * themQGisIface ) + : QgisPlugin( sName, sDescription, sCategory, sPluginVersion, sPluginType ), + mQGisIface( themQGisIface ) +{ + /** Initialize the plugin */ + mDock = NULL; +} + +QgsCompassPlugin::~QgsCompassPlugin() +{ +} + +/* Following functions return name, description, version, and type for the plugin */ +QString QgsCompassPlugin::name() +{ + return sName; +} + +QString QgsCompassPlugin::version() +{ + return sPluginVersion; + +} + +QString QgsCompassPlugin::description() +{ + return sDescription; + +} + +QString QgsCompassPlugin::category() +{ + return sCategory; + +} + +int QgsCompassPlugin::type() +{ + return QgisPlugin::UI; +} + +//method defined in interface +void QgsCompassPlugin::help() +{ + //implement me! +} + +/* + * Initialize the GUI interface for the plugin + */ +void QgsCompassPlugin::initGui() +{ + + // Create the action for tool + mActionRunCompass = new QAction( QIcon(), tr( "Show compass" ), this ); + connect( mActionRunCompass, SIGNAL( triggered() ), this, SLOT( run() ) ); + + mActionAboutCompass = new QAction( QIcon(), tr( "&About" ), this ); + connect( mActionAboutCompass, SIGNAL( triggered() ), this, SLOT( about() ) ); + + setCurrentTheme( "" ); + // this is called when the icon theme is changed + connect( mQGisIface, SIGNAL( currentThemeChanged( QString ) ), this, SLOT( setCurrentTheme( QString ) ) ); + + // Add the icon to the toolbar + mQGisIface->pluginToolBar()->addAction( mActionRunCompass ); + //mQGisIface->pluginToolBar()->addAction( mActionAboutCompass ); + mQGisIface->addPluginToMenu(sName, mActionRunCompass ); + mQGisIface->addPluginToMenu(sName, mActionAboutCompass ); + // this is called when the icon theme is changed + +} + +// Slot called when the buffer menu item is activated +void QgsCompassPlugin::run() +{ + if (! mDock ) + { + mDock = new QDockWidget("Internal Compass", mQGisIface->mainWindow() ); + mQgsCompassPluginGui = new QgsCompassPluginGui( mDock ); + mDock->setWidget( mQgsCompassPluginGui ); + mDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); + mQGisIface->addDockWidget( Qt::LeftDockWidgetArea, mDock ); + + } + mDock->show(); + QObject::connect(mDock, SIGNAL(visibilityChanged(bool)), mQgsCompassPluginGui, SLOT(handleVisibilityChanged(bool))); +} + +// Unload the plugin by cleaning up the GUI +void QgsCompassPlugin::unload() +{ + // remove the GUI + mQGisIface->removeToolBarIcon( mActionRunCompass ); + mQGisIface->removePluginMenu( sName, mActionRunCompass ); + + //mQGisIface->removeToolBarIcon( mActionAboutCompass ); + mQGisIface->removePluginMenu( sName, mActionAboutCompass ); + + delete mActionRunCompass; + delete mActionAboutCompass; + delete mDock; +} + +//! Set icons to the current theme +void QgsCompassPlugin::setCurrentTheme( QString ) +{ + mActionRunCompass->setIcon( getThemeIcon( "/mCompassRun.png" ) ); + mActionAboutCompass->setIcon( getThemeIcon( "/mActionAbout.png" ) ); +} + +QIcon QgsCompassPlugin::getThemeIcon( const QString &theName ) +{ + if ( QFile::exists( QgsApplication::activeThemePath() + "/plugins" + theName ) ) + { + return QIcon( QgsApplication::activeThemePath() + "/plugins" + theName ); + } + else if ( QFile::exists( QgsApplication::defaultThemePath() + "/plugins" + theName ) ) + { + return QIcon( QgsApplication::defaultThemePath() + "/plugins" + theName ); + } + else + { + return QIcon( ":/icons" + theName ); + } +} + +void QgsCompassPlugin::about( ) +{ + QString title = QString( "About Internal Compass" ); + // sort by date of contribution + QString text = QString( "
Internal Compass
" + "
%1
" + "

Shows reading of an internal compass using QtSensors
" + "Developer:" + "

    " + "
  1. Marco Bernasocchi" + "
" + "

Homepage:
" + "http://opengis.ch

" + "

Compass calibration:
" + "To calibrate the compass slowly rotate the device three times around each axis or " + "rotate it like a on a Mobius strip.
" + "This Video demonstrates the process " + "(this can be done from within QGIS as well).

" + ).arg( sPluginVersion ); + + // create dynamicaly because on Mac this dialog is modeless + QWidget *w = new QWidget; + w->setAttribute( Qt::WA_DeleteOnClose ); + w->setWindowIcon( getThemeIcon( "/compass.png" ) ); + QMessageBox::about( w, title, text ); +} + +/** + * Required extern functions needed for every plugin + * These functions can be called prior to creating an instance + * of the plugin class + */ +// Class factory to return a new instance of the plugin class +QGISEXTERN QgisPlugin * classFactory( QgisInterface * themQGisIfacePointer ) +{ + return new QgsCompassPlugin( themQGisIfacePointer ); +} +// Return the name of the plugin - note that we do not user class members as +// the class may not yet be insantiated when this method is called. +QGISEXTERN QString name() +{ + return sName; +} + +// Return the description +QGISEXTERN QString description() +{ + return sDescription; +} + +// Return the category +QGISEXTERN QString category() +{ + return sCategory; +} + +// Return the type (either UI or MapLayer plugin) +QGISEXTERN int type() +{ + return sPluginType; +} + +// Return the version number for the plugin +QGISEXTERN QString version() +{ + return sPluginVersion; +} + +QGISEXTERN QString icon() +{ + return sPluginIcon; +} + +// Delete ourself +QGISEXTERN void unload( QgisPlugin * thePluginPointer ) +{ + delete thePluginPointer; +} diff --git a/src/plugins/compass/qgscompassplugin.h b/src/plugins/compass/qgscompassplugin.h new file mode 100644 index 000000000000..5b1d633c347d --- /dev/null +++ b/src/plugins/compass/qgscompassplugin.h @@ -0,0 +1,100 @@ +/*************************************************************************** + qgscompassplugin.h + Functions: + ------------------- + begin : Jan 28, 2012 + copyright : (C) 2012 by Marco Bernasocchi + email : marco@bernawebdesign.ch + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef PLUGIN +#define PLUGIN +#include "../qgisplugin.h" +#include "ui_qgscompasspluginguibase.h" +#include "qgscompassplugingui.h" + +class QgisInterface; + +/** +* \class QgsCompassPlugin +* +*/ +class QgsCompassPlugin: public QObject, public QgisPlugin, private Ui::QgsCompassPluginGuiBase +{ + Q_OBJECT + public: + /** + * Constructor for a plugin. The QgisInterface pointer is passed by + * QGIS when it attempts to instantiate the plugin. + * @param qI Pointer to the QgisInterface object + */ + QgsCompassPlugin( QgisInterface * ); + /** + * Virtual function to return the name of the plugin. The name will be used when presenting a list + * of installable plugins to the user + */ + virtual QString name(); + /** + * Virtual function to return the version of the plugin. + */ + virtual QString version(); + /** + * Virtual function to return a description of the plugins functions + */ + virtual QString description(); + /** + * Virtual function to return a plugin category + */ + virtual QString category(); + /** + * Return the plugin type + */ + virtual int type(); + //! Destructor + virtual ~ QgsCompassPlugin(); + public slots: + //! init the gui + virtual void initGui(); + //! Show the dialog box + void run(); + //! unload the plugin + void unload(); + //! show the help document + void help(); + //! update the plugins theme when the app tells us its theme is changed + void setCurrentTheme( QString theThemeName ); + QIcon getThemeIcon( const QString &theThemeName ); + void about(); + private: + + + //! Name of the plugin + QString pluginNameQString; + //! Version + QString pluginVersionQString; + //! Descrption of the plugin + QString pluginDescriptionQString; + //! Category of the plugin + QString pluginCategoryQString; + //! Plugin type as defined in Plugin::PLUGINTYPE + int pluginType; + //! Pointer to the QGIS interface object + QgisInterface *mQGisIface; + //! Pointer to the QAction object used in the menu and toolbar + QAction *mActionRunCompass; + QAction *mActionAboutCompass; + + QDockWidget *mDock; + QgsCompassPluginGui *mQgsCompassPluginGui; +}; + +#endif diff --git a/src/plugins/compass/qgscompassplugingui.cpp b/src/plugins/compass/qgscompassplugingui.cpp new file mode 100644 index 000000000000..b4bc6b58535b --- /dev/null +++ b/src/plugins/compass/qgscompassplugingui.cpp @@ -0,0 +1,137 @@ +/*************************************************************************** + qgscompassplugingui.cpp + Functions: + ------------------- + begin : Jan 28, 2012 + copyright : (C) 2012 by Marco Bernasocchi + email : marco@bernawebdesign.ch + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgisinterface.h" +//#include "qgscontexthelp.h" +#include "qgslogger.h" +#include + +#include "qgscompassplugingui.h" +#include "compass.h" + +QgsCompassPluginGui::QgsCompassPluginGui( QWidget * parent, Qt::WFlags fl ) + : QWidget( parent, fl ) +{ + setupUi( this ); + + compass = new Compass(); + + if ( ! compass->isActive() ) + { + this->mWarningLabel->setText( "No compass detected" ); + } + + QObject::connect(compass, SIGNAL(azimuthChanged(const QVariant&, const QVariant&)), this, SLOT(handleAzimuth(const QVariant&, const QVariant&))); + } + +QgsCompassPluginGui::~QgsCompassPluginGui() +{ +} + +void QgsCompassPluginGui::handleVisibilityChanged(bool visible) +{ + if (visible) + { + compass->start(); + } + else + { + compass->stop(); + } +} + +void QgsCompassPluginGui::handleAzimuth(const QVariant &azimuth, const QVariant &calLevel) +{ + this->mAzimutDisplay->setText( QString("%1").arg( azimuth.toInt() ) + QString::fromUtf8("°") ); + + //TODO check when https://sourceforge.net/p/necessitas/tickets/153/ is fixed + qreal calibrationLevel = calLevel.toReal() / 3; + if ( calibrationLevel == 1 ) + { + this->mCalibrationLabel->setStyleSheet("Background-color:green"); + } + else if ( calibrationLevel <= 1/3 ) + { + this->mCalibrationLabel->setStyleSheet("Background-color:red"); + this->mWarningLabel->setText( "Compass calibration needed" ); + } + else + { + this->mCalibrationLabel->setStyleSheet("Background-color:yellow"); + } + rotatePixmap( this->mArrowPixmapLabel, QString(":/images/north_arrows/default.png"), -azimuth.toInt() ); +} + +//Copied from QgsDecorationNorthArrowDialog adapted to be portable +void QgsCompassPluginGui::rotatePixmap( QLabel * pixmapLabel, QString myFileNameQString, int theRotationInt ) +{ + QPixmap myQPixmap; + if ( myQPixmap.load( myFileNameQString ) ) + { + QPixmap myPainterPixmap( myQPixmap.height(), myQPixmap.width() ); + myPainterPixmap.fill(); + QPainter myQPainter; + myQPainter.begin( &myPainterPixmap ); + + myQPainter.setRenderHint( QPainter::SmoothPixmapTransform ); + + double centerXDouble = myQPixmap.width() / 2; + double centerYDouble = myQPixmap.height() / 2; + //save the current canvas rotation + myQPainter.save(); + //myQPainter.translate( (int)centerXDouble, (int)centerYDouble ); + + //rotate the canvas + myQPainter.rotate( theRotationInt ); + //work out how to shift the image so that it appears in the center of the canvas + //(x cos a + y sin a - x, -x sin a + y cos a - y) + const double PI = 3.14159265358979323846; + double myRadiansDouble = ( PI / 180 ) * theRotationInt; + int xShift = static_cast(( + ( centerXDouble * cos( myRadiansDouble ) ) + + ( centerYDouble * sin( myRadiansDouble ) ) + ) - centerXDouble ); + int yShift = static_cast(( + ( -centerXDouble * sin( myRadiansDouble ) ) + + ( centerYDouble * cos( myRadiansDouble ) ) + ) - centerYDouble ); + + //draw the pixmap in the proper position + myQPainter.drawPixmap( xShift, yShift, myQPixmap ); + + //unrotate the canvas again + myQPainter.restore(); + myQPainter.end(); + + pixmapLabel->setPixmap( myPainterPixmap ); + } + else + { + QPixmap myPainterPixmap( 200, 200 ); + myPainterPixmap.fill(); + QPainter myQPainter; + myQPainter.begin( &myPainterPixmap ); + QFont myQFont( "time", 12, QFont::Bold ); + myQPainter.setFont( myQFont ); + myQPainter.setPen( Qt::red ); + myQPainter.drawText( 10, 20, tr( "Pixmap not found" ) ); + myQPainter.end(); + pixmapLabel->setPixmap( myPainterPixmap ); + } +} diff --git a/src/plugins/compass/qgscompassplugingui.h b/src/plugins/compass/qgscompassplugingui.h new file mode 100644 index 000000000000..792902a0a4a4 --- /dev/null +++ b/src/plugins/compass/qgscompassplugingui.h @@ -0,0 +1,53 @@ +/*************************************************************************** + qgscompassplugingui.h + Functions: + ------------------- + begin : Jan 28, 2012 + copyright : (C) 2012 by Marco Bernasocchi + email : marco@bernawebdesign.ch + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef PLUGINGUI_H +#define PLUGINGUI_H + +#include "ui_qgscompasspluginguibase.h" +#include "qgscontexthelp.h" + +#include +#include "compass.h" + + +class QgisInterface; + +/** + * \class QgsCompassPluginGui + */ +class QgsCompassPluginGui : public QWidget, private Ui::QgsCompassPluginGuiBase +{ + Q_OBJECT + + public: + QgsCompassPluginGui( QWidget* parent = 0, Qt::WFlags fl = 0 ); + ~QgsCompassPluginGui(); + + private: + QgisInterface * qI; + Compass *compass; + + private slots: +// void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); } + void handleVisibilityChanged(bool visible); + void handleAzimuth(const QVariant &azimuth, const QVariant &calibrationLevel); + void rotatePixmap( QLabel *pixmapLabel, QString myFileNameQString, int theRotationInt ); +}; + +#endif diff --git a/src/plugins/compass/qgscompasspluginguibase.ui b/src/plugins/compass/qgscompasspluginguibase.ui new file mode 100644 index 000000000000..080a74c595b1 --- /dev/null +++ b/src/plugins/compass/qgscompasspluginguibase.ui @@ -0,0 +1,75 @@ + + + QgsCompassPluginGuiBase + + + + 0 + 0 + 251 + 70 + + + + Internal Compass + + + + + + + + Azimut + + + + + + + + 0 + 0 + + + + true + + + + + + + + 10 + 10 + + + + + + + + + + + + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + + + + + + + + + + + diff --git a/src/ui/qgsgpsinformationwidgetbase.ui b/src/ui/qgsgpsinformationwidgetbase.ui index d267913ffdbb..04e6d632f50e 100644 --- a/src/ui/qgsgpsinformationwidgetbase.ui +++ b/src/ui/qgsgpsinformationwidgetbase.ui @@ -247,7 +247,7 @@ gray = no data - 3 + 0 @@ -264,8 +264,8 @@ gray = no data 0 0 - 209 - 501 + 193 + 504 @@ -506,7 +506,7 @@ gray = no data - + Qt::Vertical @@ -522,7 +522,7 @@ gray = no data - + GPS receiver configuration 2D/3D mode: Automatic or Manual @@ -532,14 +532,14 @@ gray = no data - + Mode - + position fix dimensions: 2D, 3D or No fix @@ -549,14 +549,14 @@ gray = no data - + Dimensions - + quality of the position fix: Differential, Non-differential or No position @@ -566,14 +566,14 @@ gray = no data - + Quality - + position fix status: Valid or Invalid @@ -583,14 +583,14 @@ gray = no data - + Status - + number of satellites used in the position fix @@ -600,13 +600,33 @@ gray = no data - + Satellites + + + + + + + + + + H accurancy + + + + + + + V accurancy + + + @@ -635,8 +655,8 @@ gray = no data 0 0 - 209 - 501 + 287 + 638 @@ -691,9 +711,6 @@ gray = no data false - - true - @@ -807,6 +824,13 @@ gray = no data + + + + Internal + + + @@ -1214,12 +1238,12 @@ gray = no data setDisabled(bool) - 167 - 65 + 186 + 140 - 157 - 147 + 196 + 218 @@ -1230,12 +1254,12 @@ gray = no data setEnabled(bool) - 231 - 93 + 250 + 188 - 203 - 147 + 242 + 218 @@ -1246,8 +1270,8 @@ gray = no data setDisabled(bool) - 172 - 79 + 191 + 140 264 @@ -1262,8 +1286,8 @@ gray = no data setDisabled(bool) - 265 - 86 + 278 + 140 264 @@ -1278,8 +1302,8 @@ gray = no data setDisabled(bool) - 265 - 86 + 278 + 140 264 @@ -1294,8 +1318,8 @@ gray = no data setDisabled(bool) - 60 - 104 + 79 + 188 142 @@ -1310,8 +1334,8 @@ gray = no data setDisabled(bool) - 265 - 114 + 278 + 188 264 @@ -1326,8 +1350,8 @@ gray = no data setDisabled(bool) - 265 - 114 + 278 + 188 264 @@ -1342,12 +1366,12 @@ gray = no data setEnabled(bool) - 265 - 114 + 278 + 188 - 235 - 169 + 253 + 218 @@ -1358,12 +1382,12 @@ gray = no data setEnabled(bool) - 265 - 114 + 278 + 188 - 264 - 168 + 277 + 216 @@ -1374,12 +1398,12 @@ gray = no data setDisabled(bool) - 265 - 86 + 278 + 140 - 264 - 168 + 277 + 216 @@ -1390,8 +1414,8 @@ gray = no data setEnabled(bool) - 56 - 190 + 75 + 243 196 @@ -1406,8 +1430,8 @@ gray = no data setEnabled(bool) - 265 - 198 + 278 + 243 264 @@ -1422,8 +1446,8 @@ gray = no data setEnabled(bool) - 265 - 198 + 278 + 243 264 @@ -1438,12 +1462,12 @@ gray = no data setDisabled(bool) - 265 - 198 + 278 + 243 - 235 - 169 + 253 + 218 @@ -1454,12 +1478,12 @@ gray = no data setDisabled(bool) - 265 - 198 + 278 + 243 - 264 - 168 + 277 + 216 @@ -1470,12 +1494,12 @@ gray = no data setEnabled(bool) - 132 - 339 + 151 + 597 - 141 - 360 + 180 + 622 @@ -1486,12 +1510,12 @@ gray = no data setDisabled(bool) - 132 - 320 + 151 + 573 - 141 - 360 + 180 + 622 @@ -1502,12 +1526,12 @@ gray = no data setDisabled(bool) - 132 - 382 + 151 + 652 - 141 - 360 + 180 + 622 @@ -1518,8 +1542,8 @@ gray = no data setDisabled(bool) - 94 - 348 + 130 + 424 122 @@ -1553,9 +1577,89 @@ gray = no data 191 71 + + 109 + 684 + + + + + mRadInternal + toggled(bool) + mGpsdHost + setDisabled(bool) + + + 54 + 154 + + + 99 + 261 + + + + + mRadInternal + toggled(bool) + mGpsdPort + setDisabled(bool) + + + 40 + 160 + + + 100 + 288 + + + + + mRadInternal + toggled(bool) + mGpsdDevice + setDisabled(bool) + + + 27 + 159 + 107 - 563 + 319 + + + + + mRadInternal + toggled(bool) + mCboDevices + setDisabled(bool) + + + 140 + 152 + + + 129 + 211 + + + + + mRadInternal + toggled(bool) + mBtnRefreshDevices + setDisabled(bool) + + + 150 + 153 + + + 172 + 204 diff --git a/src/ui/qgsrasterlayerpropertiesbase.ui b/src/ui/qgsrasterlayerpropertiesbase.ui index c888331e4fd2..39ee8af95471 100644 --- a/src/ui/qgsrasterlayerpropertiesbase.ui +++ b/src/ui/qgsrasterlayerpropertiesbase.ui @@ -25,7 +25,7 @@ true - + 0 @@ -1801,14 +1801,15 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> <tr> <td style="border: none;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> @@ -1818,7 +1819,7 @@ p, li { white-space: pre-wrap; } <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"></p></td></tr></table></body></html> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p></td></tr></table></body></html> @@ -1922,35 +1923,35 @@ p, li { white-space: pre-wrap; } - + Restore Default Style - + Save As Default - + Load Style ... - + Save Style ... - + Qt::Horizontal @@ -1982,7 +1983,6 @@ p, li { white-space: pre-wrap; } leBlueMin leBlueMax sboxThreeBandStdDev - buttonBox leNoDataValue tableTransparency leDisplayName diff --git a/src/ui/qgsvectorlayerpropertiesbase.ui b/src/ui/qgsvectorlayerpropertiesbase.ui index 9333ad311392..81cbe7597b17 100644 --- a/src/ui/qgsvectorlayerpropertiesbase.ui +++ b/src/ui/qgsvectorlayerpropertiesbase.ui @@ -21,7 +21,7 @@ true - + 0 @@ -330,8 +330,8 @@ 0 0 - 736 - 542 + 446 + 481 @@ -1207,7 +1207,7 @@ - + @@ -1239,7 +1239,7 @@ - + Qt::Horizontal @@ -1268,7 +1268,6 @@ leMaximumScale txtSubsetSQL pbnQueryBuilder - buttonBox