226 changes: 226 additions & 0 deletions src/core/gps/qgsqtlocationconnection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
/***************************************************************************
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 <QLocalSocket>
#include <QTimer>
#include <QMetaType>

QgsQtLocationConnection::QgsQtLocationConnection( ): QgsGPSConnection( new QLocalSocket() )
{
//needed to fix https://sourceforge.net/p/necessitas/tickets/146/
qRegisterMetaType< QList<QGeoSatelliteInfo> >( "QList<QGeoSatelliteInfo>" );

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<QGeoSatelliteInfo>& 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<QGeoSatelliteInfo>& 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<QGeoSatelliteInfo>& ) ),
this,
SLOT( satellitesInUseUpdated(
const QList<QGeoSatelliteInfo>& ) ) );

// 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<QGeoSatelliteInfo>& ) ),
this,
SLOT( satellitesInViewUpdated(
const QList<QGeoSatelliteInfo>& ) ) );

// 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();
}
}
62 changes: 62 additions & 0 deletions src/core/gps/qgsqtlocationconnection.h
Original file line number Diff line number Diff line change
@@ -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 <QtCore/QPointer>
#include <QtLocation/QGeoPositionInfoSource>
#include <QtLocation/QGeoSatelliteInfo>
#include <QtLocation/QGeoSatelliteInfoSource>

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<QGeoSatelliteInfo>& satellites );

/**Called when the number of satellites in use is updated.*/
void satellitesInUseUpdated( const QList<QGeoSatelliteInfo>& satellites );

private:
void startGPS();
void startSatelliteMonitor();
QString mDevice;
QGeoPositionInfo mInfo;
QPointer<QGeoPositionInfoSource> locationDataSource;
QPointer<QGeoSatelliteInfoSource> satelliteInfoSource;

};

#endif // QGSQTLOCATIONCONNECTION_H
5 changes: 5 additions & 0 deletions src/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ 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

SUBDIRS (heatmap)
51 changes: 51 additions & 0 deletions src/plugins/compass/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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})
79 changes: 79 additions & 0 deletions src/plugins/compass/compass.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
50 changes: 50 additions & 0 deletions src/plugins/compass/compass.h
Original file line number Diff line number Diff line change
@@ -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 <QtGui>
#include <QtCore>
#include <QtSensors/QCompass>
#include <QObject>

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__
5 changes: 5 additions & 0 deletions src/plugins/compass/compass.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>icons/mCompassRun.png</file>
</qresource>
</RCC>
Binary file added src/plugins/compass/icons/mCompassRun.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
252 changes: 252 additions & 0 deletions src/plugins/compass/qgscompassplugin.cpp
Original file line number Diff line number Diff line change
@@ -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 <qgisinterface.h>
#include <qgisgui.h>
#include <qgsapplication.h>
#include "qgscompassplugin.h"

#include <QMenu>
#include <QAction>
#include <QFile>
#include <QToolBar>
#include <QMessageBox>
#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( "<center><b>Internal Compass</b></center>"
"<center>%1</center>"
"<p>Shows reading of an internal compass using QtSensors<br/>"
"<b>Developer:</b>"
"<ol type=disc>"
"<li>Marco Bernasocchi"
"</ol>"
"<p><b>Homepage:</b><br>"
"<a href=\"http://opengis.ch\">http://opengis.ch</a></p>"
"<p><b>Compass calibration:</b><br/>"
"To calibrate the compass slowly rotate the device three times around each axis or "
"rotate it like a on a Mobius strip.<br/>"
"This <a href='http://www.youtube.com/watch?v=oNJJPeoG8lQ'>Video</a> demonstrates the process "
"(this can be done from within QGIS as well).</p>"
).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;
}
100 changes: 100 additions & 0 deletions src/plugins/compass/qgscompassplugin.h
Original file line number Diff line number Diff line change
@@ -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
137 changes: 137 additions & 0 deletions src/plugins/compass/qgscompassplugingui.cpp
Original file line number Diff line number Diff line change
@@ -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 <QPainter>

#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( "<font color='red'>No compass detected</font>" );
}

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( "<font color='red'><a href='http://www.youtube.com/watch?v=oNJJPeoG8lQ'>Compass calibration</a> needed</font>" );
}
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<int>((
( centerXDouble * cos( myRadiansDouble ) ) +
( centerYDouble * sin( myRadiansDouble ) )
) - centerXDouble );
int yShift = static_cast<int>((
( -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 );
}
}
53 changes: 53 additions & 0 deletions src/plugins/compass/qgscompassplugingui.h
Original file line number Diff line number Diff line change
@@ -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 <QtGui/QDockWidget>
#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
75 changes: 75 additions & 0 deletions src/plugins/compass/qgscompasspluginguibase.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsCompassPluginGuiBase</class>
<widget class="QWidget" name="QgsCompassPluginGuiBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>251</width>
<height>70</height>
</rect>
</property>
<property name="windowTitle">
<string>Internal Compass</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="mCompassLabel">
<property name="text">
<string>Azimut</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mAzimutDisplay">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="mCalibrationLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>10</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="mArrowPixmapLabel">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="mWarningLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
264 changes: 184 additions & 80 deletions src/ui/qgsgpsinformationwidgetbase.ui

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions src/ui/qgsrasterlayerpropertiesbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="4">
<item row="1" column="0" colspan="4">
<widget class="QTabWidget" name="tabBar">
<property name="currentIndex">
<number>0</number>
Expand Down Expand Up @@ -1801,14 +1801,15 @@
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;table border=&quot;0&quot; style=&quot;-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;border: none;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
Expand All @@ -1818,7 +1819,7 @@ p, li { white-space: pre-wrap; }
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot;-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';&quot;&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot;-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;&quot;&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
Expand Down Expand Up @@ -1922,35 +1923,35 @@ p, li { white-space: pre-wrap; }
</widget>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QPushButton" name="pbnLoadDefaultStyle">
<property name="text">
<string>Restore Default Style</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QPushButton" name="pbnSaveDefaultStyle">
<property name="text">
<string>Save As Default</string>
</property>
</widget>
</item>
<item row="1" column="2">
<item row="2" column="2">
<widget class="QPushButton" name="pbnLoadStyle">
<property name="text">
<string>Load Style ...</string>
</property>
</widget>
</item>
<item row="1" column="3">
<item row="2" column="3">
<widget class="QPushButton" name="pbnSaveStyleAs">
<property name="text">
<string>Save Style ...</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="4">
<item row="0" column="0" colspan="4">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand Down Expand Up @@ -1982,7 +1983,6 @@ p, li { white-space: pre-wrap; }
<tabstop>leBlueMin</tabstop>
<tabstop>leBlueMax</tabstop>
<tabstop>sboxThreeBandStdDev</tabstop>
<tabstop>buttonBox</tabstop>
<tabstop>leNoDataValue</tabstop>
<tabstop>tableTransparency</tabstop>
<tabstop>leDisplayName</tabstop>
Expand Down
11 changes: 5 additions & 6 deletions src/ui/qgsvectorlayerpropertiesbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
Expand Down Expand Up @@ -330,8 +330,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>746</width>
<height>569</height>
<width>446</width>
<height>481</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
Expand Down Expand Up @@ -1197,7 +1197,7 @@
</widget>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pbnLoadDefaultStyle">
Expand Down Expand Up @@ -1229,7 +1229,7 @@
</item>
</layout>
</item>
<item row="2" column="0">
<item row="0" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand Down Expand Up @@ -1258,7 +1258,6 @@
<tabstop>leMaximumScale</tabstop>
<tabstop>txtSubsetSQL</tabstop>
<tabstop>pbnQueryBuilder</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources>
<include location="../../images/images.qrc"/>
Expand Down