Added convenience method snappingUtils() to QgsMapCanvas

Map tools can use canvas.snappingUtils().snapToMap(pt) to do the snapping.
This commit is contained in:
Martin Dobias 2014-12-14 00:31:03 +07:00
parent cf22adc067
commit cd7180ec67
17 changed files with 131 additions and 62 deletions

View File

@ -32,13 +32,6 @@ class QgisInterface : QObject
virtual QgsLayerTreeView* layerTreeView() = 0;
/**
* Get access to snapping utilities - for use in map tools
*
* @note added in 2.8
*/
virtual QgsSnappingUtils* snappingUtils() = 0;
public slots: // TODO: do these functions really need to be slots?
/* Exposed functions */

View File

@ -309,6 +309,23 @@ class QgsMapCanvas : QGraphicsView
* @note added in 2.3 */
QgsPreviewEffect::PreviewMode previewMode() const;
/** Return snapping utility class that is associated with map canvas.
* If no snapping utils instance has been associated previously, an internal will be created for convenience
* (so map tools do not need to test for existence of the instance).
*
* Main canvas in QGIS returns an instance which is always up-to-date with the project's snapping configuration.
* @note added in 2.8
*/
QgsSnappingUtils* snappingUtils() const;
/** Assign an instance of snapping utils to the map canvas.
* The instance is not owned by the canvas, so it is possible to use one instance in multiple canvases.
*
* For main canvas in QGIS, do not associate a different instance from the existing one (it is updated from
* the project's snapping configuration).
* @note added in 2.8
*/
void setSnappingUtils( QgsSnappingUtils* utils );
public slots:
/**Repaints the canvas map*/
@ -437,6 +454,10 @@ class QgsMapCanvas : QGraphicsView
//! @note added in 2.4
void mapUnitsChanged();
//! Emitted when the current layer is changed
//! @note added in 2.8
void currentLayerChanged( QgsMapLayer* layer );
protected:
//! Overridden standard event to be gestures aware
bool event( QEvent * e );

View File

@ -148,6 +148,7 @@
#include "qgslayertreeviewdefaultactions.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmapcanvassnappingutils.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaplayerstyleguiutils.h"
@ -192,7 +193,6 @@
#include "qgsshortcutsmanager.h"
#include "qgssinglebandgrayrenderer.h"
#include "qgssnappingdialog.h"
#include "qgssnappingutils.h"
#include "qgssponsors.h"
#include "qgssvgannotationitem.h"
#include "qgstextannotationitem.h"
@ -405,8 +405,6 @@ void QgisApp::activeLayerChanged( QgsMapLayer* layer )
{
if ( mMapCanvas )
mMapCanvas->setCurrentLayer( layer );
if ( mSnappingUtils )
mSnappingUtils->setCurrentLayer( qobject_cast<QgsVectorLayer*>( layer ) );
}
/**
@ -571,12 +569,11 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
mAdvancedDigitizingDockWidget = new QgsAdvancedDigitizingDockWidget( mMapCanvas, this );
mAdvancedDigitizingDockWidget->setObjectName( "AdvancedDigitizingTools" );
mSnappingUtils = new QgsSnappingUtils( this );
mSnappingUtils = new QgsMapCanvasSnappingUtils( mMapCanvas, this );
mMapCanvas->setSnappingUtils( mSnappingUtils );
connect( QgsProject::instance(), SIGNAL( snapSettingsChanged() ), mSnappingUtils, SLOT( readConfigFromProject() ) );
connect( this, SIGNAL( newProject() ), mSnappingUtils, SLOT( readConfigFromProject() ) );
connect( this, SIGNAL( projectRead() ), mSnappingUtils, SLOT( readConfigFromProject() ) );
connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( updateSnappingUtilsMapSettings() ) );
connect( mMapCanvas, SIGNAL( destinationCrsChanged() ), this, SLOT( updateSnappingUtilsMapSettings() ) );
createActions();
createActionGroups();
@ -4369,11 +4366,6 @@ void QgisApp::updateFilterLegendByMap()
layerTreeView()->layerTreeModel()->setLegendFilterByMap( &mMapCanvas->mapSettings() );
}
void QgisApp::updateSnappingUtilsMapSettings()
{
mSnappingUtils->setMapSettings( mMapCanvas->mapSettings() );
}
void QgisApp::saveMapAsImage()
{
QPair< QString, QString> myFileNameAndFilter = QgisGui::getSaveAsImageName( this, tr( "Choose a file name to save the map image as" ) );

View File

@ -1214,11 +1214,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void updateFilterLegendByMap();
void setFilterLegendByMapEnabled( bool enabled );
public:
QgsSnappingUtils* snappingUtils() { return mSnappingUtils; }
private slots:
void updateSnappingUtilsMapSettings();
/** Make the user feel dizzy */
void dizzy();

View File

@ -88,11 +88,6 @@ QgsLayerTreeView*QgisAppInterface::layerTreeView()
return qgis->layerTreeView();
}
QgsSnappingUtils* QgisAppInterface::snappingUtils()
{
return qgis->snappingUtils();
}
void QgisAppInterface::zoomFull()
{
qgis->zoomFull();

View File

@ -51,8 +51,6 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
QgsLayerTreeView* layerTreeView() override;
QgsSnappingUtils* snappingUtils();
/* Exposed functions */
//! Zoom map to full extent

View File

@ -54,7 +54,7 @@ void QgsMapMouseEvent::setPoint( const QgsPoint& point )
bool QgsMapMouseEvent::snapPoint()
{
mSnapMatch = QgisApp::instance()->snappingUtils()->snapToMap( mMapPoint );
mSnapMatch = mMapTool->canvas()->snappingUtils()->snapToMap( mMapPoint );
mMapPoint = mSnapMatch.isValid() ? mSnapMatch.point() : mOriginalPoint;
return mSnapMatch.isValid();
}

View File

@ -21,6 +21,7 @@
#include "qgsmaptopixel.h"
#include "qgsproject.h"
#include "qgsrubberband.h"
#include "qgssnappingutils.h"
#include <QMouseEvent>
#include <QSettings>
#include <cmath>
@ -31,7 +32,6 @@ QgsMapToolMeasureAngle::QgsMapToolMeasureAngle( QgsMapCanvas* canvas )
, mResultDisplay( 0 )
{
mToolName = tr( "Measure angle" );
mSnapper.setMapCanvas( canvas );
connect( canvas, SIGNAL( destinationCrsChanged() ),
this, SLOT( updateSettings() ) );
@ -143,15 +143,8 @@ void QgsMapToolMeasureAngle::createRubberBand()
QgsPoint QgsMapToolMeasureAngle::snapPoint( const QPoint& p )
{
QList<QgsSnappingResult> snappingResults;
if ( mSnapper.snapToBackgroundLayers( p, snappingResults ) != 0 || snappingResults.size() < 1 )
{
return mCanvas->getCoordinateTransform()->toMapCoordinates( p );
}
else
{
return snappingResults.constBegin()->snappedVertex;
}
QgsPointLocator::Match m = mCanvas->snappingUtils()->snapToMap( p );
return m.isValid() ? m.point() : mCanvas->getCoordinateTransform()->toMapCoordinates( p );
}
void QgsMapToolMeasureAngle::updateSettings()

View File

@ -17,7 +17,6 @@
#define QGSMAPTOOLMEASUREANGLE_H
#include "qgsmaptool.h"
#include "qgsmapcanvassnapper.h"
#include "qgspoint.h"
#include "qgsdistancearea.h"
@ -49,7 +48,6 @@ class APP_EXPORT QgsMapToolMeasureAngle: public QgsMapTool
QList<QgsPoint> mAnglePoints;
QgsRubberBand* mRubberBand;
QgsDisplayAngle* mResultDisplay;
QgsMapCanvasSnapper mSnapper;
/**Creates a new rubber band and deletes the old one*/
void createRubberBand();

View File

@ -20,6 +20,7 @@
#include "qgsmaptopixel.h"
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include "qgssnappingutils.h"
#include "qgstolerance.h"
#include "qgsmeasuredialog.h"
@ -47,7 +48,6 @@ QgsMeasureTool::QgsMeasureTool( QgsMapCanvas* canvas, bool measureArea )
mDialog = new QgsMeasureDialog( this, Qt::WindowStaysOnTopHint );
mDialog->restorePosition();
mSnapper.setMapCanvas( canvas );
connect( canvas, SIGNAL( destinationCrsChanged() ),
this, SLOT( updateSettings() ) );
@ -238,15 +238,9 @@ void QgsMeasureTool::addPoint( QgsPoint &point )
}
}
QgsPoint QgsMeasureTool::snapPoint( const QPoint& p )
{
QList<QgsSnappingResult> snappingResults;
if ( mSnapper.snapToBackgroundLayers( p, snappingResults ) != 0 || snappingResults.size() < 1 )
{
return mCanvas->getCoordinateTransform()->toMapCoordinates( p );
}
else
{
return snappingResults.constBegin()->snappedVertex;
}
QgsPointLocator::Match m = mCanvas->snappingUtils()->snapToMap( p );
return m.isValid() ? m.point() : mCanvas->getCoordinateTransform()->toMapCoordinates( p );
}

View File

@ -97,8 +97,6 @@ class APP_EXPORT QgsMeasureTool : public QgsMapTool
// project projection
bool mWrongProjectProjection;
QgsMapCanvasSnapper mSnapper;
//! Returns the snapped (map) coordinate
//@param p (pixel) coordinate
QgsPoint snapPoint( const QPoint& p );

View File

@ -177,6 +177,7 @@ qgsmapcanvas.cpp
qgsmapcanvasitem.cpp
qgsmapcanvasmap.cpp
qgsmapcanvassnapper.cpp
qgsmapcanvassnappingutils.cpp
qgsmaplayeractionregistry.cpp
qgsmaplayercombobox.cpp
qgsmaplayermodel.cpp
@ -284,6 +285,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsludialog.h
qgsmanageconnectionsdialog.h
qgsmapcanvas.h
qgsmapcanvassnappingutils.h
qgsmaplayeractionregistry.h
qgsmaplayercombobox.h
qgsmaplayermodel.h
@ -442,6 +444,7 @@ SET(QGIS_GUI_HDRS
qgsmapcanvasitem.h
qgsmapcanvasmap.h
qgsmapcanvassnapper.h
qgsmapcanvassnappingutils.h
qgsmaptip.h
qgsmaptoolpan.h
qgsmaptoolzoom.h

View File

@ -78,13 +78,6 @@ class GUI_EXPORT QgisInterface : public QObject
virtual QgsLayerTreeView* layerTreeView() = 0;
/**
* Get access to snapping utilities - for use in map tools
*
* @note added in 2.8
*/
virtual QgsSnappingUtils* snappingUtils() = 0;
public slots: // TODO: do these functions really need to be slots?
/* Exposed functions */

View File

@ -44,6 +44,7 @@ email : sherman at mrcc.com
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmapcanvasmap.h"
#include "qgsmapcanvassnappingutils.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaptoolpan.h"
@ -190,6 +191,7 @@ QgsMapCanvas::QgsMapCanvas( QWidget * parent, const char *name )
, mDrawRenderingStats( false )
, mCache( 0 )
, mPreviewEffect( 0 )
, mSnappingUtils( 0 )
{
setObjectName( name );
mScene = new QGraphicsScene();
@ -340,6 +342,7 @@ QgsMapLayer* QgsMapCanvas::layer( int index )
void QgsMapCanvas::setCurrentLayer( QgsMapLayer* layer )
{
mCurrentLayer = layer;
emit currentLayerChanged( layer );
}
double QgsMapCanvas::scale()
@ -1743,6 +1746,22 @@ QgsPreviewEffect::PreviewMode QgsMapCanvas::previewMode() const
return mPreviewEffect->mode();
}
QgsSnappingUtils* QgsMapCanvas::snappingUtils() const
{
if ( !mSnappingUtils )
{
// associate a dummy instance, but better than null pointer
QgsMapCanvas* c = const_cast<QgsMapCanvas*>( this );
c->mSnappingUtils = new QgsMapCanvasSnappingUtils( c, c );
}
return mSnappingUtils;
}
void QgsMapCanvas::setSnappingUtils( QgsSnappingUtils* utils )
{
mSnappingUtils = utils;
}
void QgsMapCanvas::readProject( const QDomDocument & doc )
{
QDomNodeList nodes = doc.elementsByTagName( "mapcanvas" );

View File

@ -65,6 +65,7 @@ class QgsMapSettings;
class QgsMapCanvasMap;
class QgsMapOverviewCanvas;
class QgsMapTool;
class QgsSnappingUtils;
/** \ingroup gui
* A class that stores visibility and presence in overview flags together
@ -378,6 +379,23 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
* @note added in 2.3 */
QgsPreviewEffect::PreviewMode previewMode() const;
/** Return snapping utility class that is associated with map canvas.
* If no snapping utils instance has been associated previously, an internal will be created for convenience
* (so map tools do not need to test for existence of the instance).
*
* Main canvas in QGIS returns an instance which is always up-to-date with the project's snapping configuration.
* @note added in 2.8
*/
QgsSnappingUtils* snappingUtils() const;
/** Assign an instance of snapping utils to the map canvas.
* The instance is not owned by the canvas, so it is possible to use one instance in multiple canvases.
*
* For main canvas in QGIS, do not associate a different instance from the existing one (it is updated from
* the project's snapping configuration).
* @note added in 2.8
*/
void setSnappingUtils( QgsSnappingUtils* utils );
public slots:
/**Repaints the canvas map*/
@ -517,6 +535,10 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
//! @note added in 2.4
void mapUnitsChanged();
//! Emitted when the current layer is changed
//! @note added in 2.8
void currentLayerChanged( QgsMapLayer* layer );
protected:
#ifdef HAVE_TOUCH
//! Overridden standard event to be gestures aware
@ -652,6 +674,9 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
QgsPreviewEffect* mPreviewEffect;
QgsRectangle imageRect( const QImage& img );
QgsSnappingUtils* mSnappingUtils;
}; // class QgsMapCanvas

View File

@ -0,0 +1,25 @@
#include "qgsmapcanvassnappingutils.h"
#include "qgsmapcanvas.h"
#include "qgsvectorlayer.h"
QgsMapCanvasSnappingUtils::QgsMapCanvasSnappingUtils( QgsMapCanvas* canvas, QObject* parent )
: QgsSnappingUtils( parent )
, mCanvas( canvas )
{
connect( canvas, SIGNAL( extentsChanged() ), this, SLOT( canvasMapSettingsChanged() ) );
connect( canvas, SIGNAL( destinationCrsChanged() ), this, SLOT( canvasMapSettingsChanged() ) );
connect( canvas, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( canvasCurrentLayerChanged() ) );
canvasMapSettingsChanged();
canvasCurrentLayerChanged();
}
void QgsMapCanvasSnappingUtils::canvasMapSettingsChanged()
{
setMapSettings( mCanvas->mapSettings() );
}
void QgsMapCanvasSnappingUtils::canvasCurrentLayerChanged()
{
setCurrentLayer( qobject_cast<QgsVectorLayer*>( mCanvas->currentLayer() ) );
}

View File

@ -0,0 +1,27 @@
#ifndef QGSMAPCANVASSNAPPINGUTILS_H
#define QGSMAPCANVASSNAPPINGUTILS_H
#include "qgssnappingutils.h"
class QgsMapCanvas;
/** Snapping utils instance that is connected to a canvas and updates the configuration
* (map settings + current layer) whenever that is changed in the canvas.
* @note added in 2.8
*/
class GUI_EXPORT QgsMapCanvasSnappingUtils : public QgsSnappingUtils
{
Q_OBJECT
public:
QgsMapCanvasSnappingUtils( QgsMapCanvas* canvas, QObject* parent = 0 );
private slots:
void canvasMapSettingsChanged();
void canvasCurrentLayerChanged();
private:
QgsMapCanvas* mCanvas;
};
#endif // QGSMAPCANVASSNAPPINGUTILS_H