QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsmapcanvas.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmapcanvas.cpp - description
3  -------------------
4 begin : Sun Jun 30 2002
5 copyright : (C) 2002 by Gary E.Sherman
6 email : sherman at mrcc.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 
19 #include <QtGlobal>
20 #include <QApplication>
21 #include <QCursor>
22 #include <QDir>
23 #include <QFile>
24 #include <QGraphicsItem>
25 #include <QGraphicsScene>
26 #include <QGraphicsView>
27 #include <QKeyEvent>
28 #include <QMouseEvent>
29 #include <QPainter>
30 #include <QPaintEvent>
31 #include <QPixmap>
32 #include <QRect>
33 #include <QSettings>
34 #include <QTextStream>
35 #include <QResizeEvent>
36 #include <QString>
37 #include <QStringList>
38 #include <QWheelEvent>
39 
40 #include "qgis.h"
41 #include "qgsapplication.h"
42 #include "qgscrscache.h"
44 #include "qgslogger.h"
45 #include "qgsmapcanvas.h"
46 #include "qgsmapcanvasmap.h"
47 #include "qgsmaplayer.h"
48 #include "qgsmaplayerregistry.h"
49 #include "qgsmaptoolpan.h"
50 #include "qgsmaptoolzoom.h"
51 #include "qgsmaptopixel.h"
52 #include "qgsmapoverviewcanvas.h"
53 #include "qgsmaprenderer.h"
54 #include "qgsmaprenderercache.h"
58 #include "qgsmessagelog.h"
59 #include "qgsmessageviewer.h"
60 #include "qgspallabeling.h"
61 #include "qgsproject.h"
62 #include "qgsrubberband.h"
63 #include "qgsvectorlayer.h"
64 #include <math.h>
65 
66 
69 {
70  public:
71 
73 
76 
78  QPoint mouseLastXY;
79 
82 
85 
86 };
87 
88 
89 
91  : QObject( canvas )
92  , mCanvas( canvas )
93  , mRenderer( renderer )
94  , mSyncingExtent( false )
95 {
96  connect( mCanvas, SIGNAL( extentsChanged() ), this, SLOT( onExtentC2R() ) );
97  connect( mRenderer, SIGNAL( extentsChanged() ), this, SLOT( onExtentR2C() ) );
98 
99  connect( mCanvas, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsC2R() ) );
100  connect( mRenderer, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsR2C() ) );
101 
102  connect( mCanvas, SIGNAL( hasCrsTransformEnabledChanged( bool ) ), this, SLOT( onCrsTransformC2R() ) );
103  connect( mRenderer, SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( onCrsTransformR2C() ) );
104 
105  connect( mCanvas, SIGNAL( destinationCrsChanged() ), this, SLOT( onDestCrsC2R() ) );
106  connect( mRenderer, SIGNAL( destinationSrsChanged() ), this, SLOT( onDestCrsR2C() ) );
107 
108  connect( mCanvas, SIGNAL( layersChanged() ), this, SLOT( onLayersC2R() ) );
109  // TODO: layers R2C ? (should not happen!)
110 
111 }
112 
114 {
115  // protection against possible bounce back
116  if ( mSyncingExtent )
117  return;
118 
119  mSyncingExtent = true;
121  mSyncingExtent = false;
122 }
123 
125 {
126  // protection against possible bounce back
127  if ( mSyncingExtent )
128  return;
129 
130  mSyncingExtent = true;
132  mSyncingExtent = false;
133 }
134 
136 {
138 }
139 
141 {
143 }
144 
146 {
148 }
149 
151 {
153 }
154 
156 {
158 }
159 
161 {
163 }
164 
166 {
168 }
169 
170 
171 
172 QgsMapCanvas::QgsMapCanvas( QWidget * parent, const char *name )
173  : QGraphicsView( parent )
174  , mCanvasProperties( new CanvasProperties )
175  , mJob( 0 )
176  , mJobCancelled( false )
177  , mLabelingResults( 0 )
178  , mUseParallelRendering( false )
179  , mDrawRenderingStats( false )
180  , mCache( 0 )
181  , mPreviewEffect( 0 )
182 {
183  setObjectName( name );
184  mScene = new QGraphicsScene();
185  setScene( mScene );
186  setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
187  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
188  mLastExtentIndex = -1;
189  mCurrentLayer = NULL;
190  mMapOverview = NULL;
191  mMapTool = NULL;
192  mLastNonZoomMapTool = NULL;
193 
194  mFrozen = false;
195  mRefreshScheduled = false;
196 
198 
199  // by default, the canvas is rendered
200  mRenderFlag = true;
201 
202  setMouseTracking( true );
203  setFocusPolicy( Qt::StrongFocus );
204 
206 
207  mResizeTimer = new QTimer( this );
208  mResizeTimer->setSingleShot( true );
209  connect( mResizeTimer, SIGNAL( timeout() ), this, SLOT( refresh() ) );
210 
211  // create map canvas item which will show the map
212  mMap = new QgsMapCanvasMap( this );
213  mScene->addItem( mMap );
214 
215  // project handling
216  connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ),
217  this, SLOT( readProject( const QDomDocument & ) ) );
218  connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ),
219  this, SLOT( writeProject( QDomDocument & ) ) );
220 
223 
224  // class that will sync most of the changes between canvas and (legacy) map renderer
225  // it is parented to map canvas, will be deleted automatically
227 
228  QSize s = viewport()->size();
231  setSceneRect( 0, 0, s.width(), s.height() );
232  mScene->setSceneRect( QRectF( 0, 0, s.width(), s.height() ) );
233 
234  moveCanvasContents( true );
235 
236  connect( &mMapUpdateTimer, SIGNAL( timeout() ), SLOT( mapUpdateTimeout() ) );
237  mMapUpdateTimer.setInterval( 250 );
238 
239 #ifdef Q_OS_WIN
240  // Enable touch event on Windows.
241  // Qt on Windows needs to be told it can take touch events or else it ignores them.
242  grabGesture( Qt::PinchGesture );
243  viewport()->setAttribute( Qt::WA_AcceptTouchEvents );
244 #endif
245 
246  mPreviewEffect = new QgsPreviewEffect( this );
247  viewport()->setGraphicsEffect( mPreviewEffect );
248 
249  setInteractive( false );
250 
251  refresh();
252 
253 } // QgsMapCanvas ctor
254 
255 
257 {
258  if ( mMapTool )
259  {
260  mMapTool->deactivate();
261  mMapTool = NULL;
262  }
263  mLastNonZoomMapTool = NULL;
264 
265  // delete canvas items prior to deleteing the canvas
266  // because they might try to update canvas when it's
267  // already being destructed, ends with segfault
268  QList<QGraphicsItem*> list = mScene->items();
269  QList<QGraphicsItem*>::iterator it = list.begin();
270  while ( it != list.end() )
271  {
272  QGraphicsItem* item = *it;
273  delete item;
274  ++it;
275  }
276 
277  mScene->deleteLater(); // crashes in python tests on windows
278 
279  delete mMapRenderer;
280  // mCanvasProperties auto-deleted via std::auto_ptr
281  // CanvasProperties struct has its own dtor for freeing resources
282 
283  if ( mJob )
284  {
285  mJob->cancel();
286  Q_ASSERT( mJob == 0 );
287  }
288 
289  delete mCache;
290 
291  delete mLabelingResults;
292 
293 } // dtor
294 
296 {
298 
299  if ( mMapOverview )
300  mMapOverview->enableAntiAliasing( theFlag );
301 } // anti aliasing
302 
303 void QgsMapCanvas::useImageToRender( bool theFlag )
304 {
305  Q_UNUSED( theFlag );
306 }
307 
309 {
310  return mMap;
311 }
312 
314 {
315  return mMapRenderer;
316 }
317 
318 
320 {
321  const QStringList& layers = mapSettings().layers();
322  if ( index >= 0 && index < ( int ) layers.size() )
323  return QgsMapLayerRegistry::instance()->mapLayer( layers[index] );
324  else
325  return NULL;
326 }
327 
328 
330 {
332 }
333 
335 {
336  return mapSettings().scale();
337 } // scale
338 
339 void QgsMapCanvas::setDirty( bool dirty )
340 {
341  if ( dirty )
342  refresh();
343 }
344 
346 {
347  return false;
348 }
349 
350 
351 
353 {
354  return mJob != 0;
355 } // isDrawing
356 
357 
358 // return the current coordinate transform based on the extents and
359 // device size
361 {
362  return &mapSettings().mapToPixel();
363 }
364 
365 void QgsMapCanvas::setLayerSet( QList<QgsMapCanvasLayer> &layers )
366 {
367  // create layer set
368  QStringList layerSet, layerSetOverview;
369 
370  int i;
371  for ( i = 0; i < layers.size(); i++ )
372  {
373  QgsMapCanvasLayer &lyr = layers[i];
374  if ( !lyr.layer() )
375  {
376  continue;
377  }
378 
379  if ( lyr.isVisible() )
380  {
381  layerSet.push_back( lyr.layer()->id() );
382  }
383 
384  if ( lyr.isInOverview() )
385  {
386  layerSetOverview.push_back( lyr.layer()->id() );
387  }
388  }
389 
390  const QStringList& layerSetOld = mapSettings().layers();
391 
392  bool layerSetChanged = layerSetOld != layerSet;
393 
394  // update only if needed
395  if ( layerSetChanged )
396  {
397  QgsDebugMsg( "Layers changed to: " + layerSet.join( ", " ) );
398 
399  for ( i = 0; i < layerCount(); i++ )
400  {
401  // Add check if vector layer when disconnecting from selectionChanged slot
402  // Ticket #811 - racicot
404  if ( !currentLayer )
405  continue;
406  disconnect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
407  QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
408  if ( isVectLyr )
409  {
410  disconnect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
411  }
412  }
413 
414  mSettings.setLayers( layerSet );
415 
416  for ( i = 0; i < layerCount(); i++ )
417  {
418  // Add check if vector layer when connecting to selectionChanged slot
419  // Ticket #811 - racicot
421  connect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
422  QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
423  if ( isVectLyr )
424  {
425  connect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
426  }
427  }
428 
430 
431  QgsDebugMsg( "Layers have changed, refreshing" );
432  emit layersChanged();
433 
434  refresh();
435  }
436 
437  if ( mMapOverview )
438  {
439  const QStringList& layerSetOvOld = mMapOverview->layerSet();
440  if ( layerSetOvOld != layerSetOverview )
441  {
442  mMapOverview->setLayerSet( layerSetOverview );
443  }
444 
445  // refresh overview maplayers even if layer set is the same
446  // because full extent might have changed
447  updateOverview();
448  }
449 } // setLayerSet
450 
452 {
453  if ( mMapOverview )
454  {
455  // disconnect old map overview if exists
456  disconnect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
457  mMapOverview, SLOT( hasCrsTransformEnabled( bool ) ) );
458  disconnect( this, SIGNAL( destinationCrsChanged() ),
459  mMapOverview, SLOT( destinationSrsChanged() ) );
460 
461  // map overview is not owned by map canvas so don't delete it...
462  }
463 
464  mMapOverview = overview;
465 
466  if ( overview )
467  {
468  // connect to the map render to copy its projection settings
469  connect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
470  overview, SLOT( hasCrsTransformEnabled( bool ) ) );
471  connect( this, SIGNAL( destinationCrsChanged() ),
472  overview, SLOT( destinationSrsChanged() ) );
473  }
474 }
475 
477 {
478  return mSettings;
479 }
480 
482 {
483  if ( mSettings.hasCrsTransformEnabled() == enabled )
484  return;
485 
487 
489 
490  refresh();
491 
492  emit hasCrsTransformEnabledChanged( enabled );
493 }
494 
496 {
497  if ( mSettings.destinationCrs() == crs )
498  return;
499 
501  {
502  // try to reproject current extent to the new one
503  QgsRectangle rect;
504  if ( !mSettings.visibleExtent().isEmpty() )
505  {
506  QgsCoordinateTransform transform( mSettings.destinationCrs(), crs );
507  rect = transform.transformBoundingBox( mSettings.visibleExtent() );
508  }
509  if ( !rect.isEmpty() )
510  {
511  setExtent( rect );
512  }
513 
514  QgsDebugMsg( "refreshing after destination CRS changed" );
515  refresh();
516  }
517 
519 
521 
522  emit destinationCrsChanged();
523 }
524 
526 {
527  return mLabelingResults;
528 }
529 
531 {
532  if ( enabled == isCachingEnabled() )
533  return;
534 
535  if ( enabled )
536  {
538  }
539  else
540  {
541  delete mCache;
542  mCache = 0;
543  }
544 }
545 
547 {
548  return mCache != 0;
549 }
550 
552 {
553  if ( mCache )
554  mCache->clear();
555 }
556 
558 {
559  mUseParallelRendering = enabled;
560 }
561 
563 {
564  return mUseParallelRendering;
565 }
566 
567 void QgsMapCanvas::setMapUpdateInterval( int timeMiliseconds )
568 {
569  mMapUpdateTimer.setInterval( timeMiliseconds );
570 }
571 
573 {
574  return mMapUpdateTimer.interval();
575 }
576 
577 
579 {
580  // redraw overview
581  if ( mMapOverview )
582  {
584  }
585 }
586 
587 
589 {
590  return mCurrentLayer;
591 }
592 
593 
595 {
596  if ( !mSettings.hasValidSettings() )
597  {
598  QgsDebugMsg( "CANVAS refresh - invalid settings -> nothing to do" );
599  return;
600  }
601 
602  if ( !mRenderFlag || mFrozen ) // do we really need two flags controlling rendering?
603  {
604  QgsDebugMsg( "CANVAS render flag off" );
605  return;
606  }
607 
608  if ( mRefreshScheduled )
609  {
610  QgsDebugMsg( "CANVAS refresh already scheduled" );
611  return;
612  }
613 
614  mRefreshScheduled = true;
615 
616  QgsDebugMsg( "CANVAS refresh scheduling" );
617 
618  // schedule a refresh
619  QTimer::singleShot( 1, this, SLOT( refreshMap() ) );
620 } // refresh
621 
623 {
624  Q_ASSERT( mRefreshScheduled );
625 
626  QgsDebugMsg( "CANVAS refresh!" );
627 
628  stopRendering(); // if any...
629 
630  // from now on we can accept refresh requests again
631  mRefreshScheduled = false;
632 
633  //update $map variable to canvas
634  QgsExpression::setSpecialColumn( "$map", tr( "canvas" ) );
635 
636  // create the renderer job
637  Q_ASSERT( mJob == 0 );
638  mJobCancelled = false;
639  if ( mUseParallelRendering )
641  else
643  connect( mJob, SIGNAL( finished() ), SLOT( rendererJobFinished() ) );
644  mJob->setCache( mCache );
645 
646  QStringList layersForGeometryCache;
647  foreach ( QString id, mSettings.layers() )
648  {
649  if ( QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( id ) ) )
650  {
651  if ( vl->isEditable() )
652  layersForGeometryCache << id;
653  }
654  }
655  mJob->setRequestedGeometryCacheForLayers( layersForGeometryCache );
656 
657  mJob->start();
658 
659  mMapUpdateTimer.start();
660 
661  emit renderStarting();
662 }
663 
664 
666 {
667  QgsDebugMsg( QString( "CANVAS finish! %1" ).arg( !mJobCancelled ) );
668 
669  mMapUpdateTimer.stop();
670 
671  // TODO: would be better to show the errors in message bar
672  foreach ( const QgsMapRendererJob::Error& error, mJob->errors() )
673  {
674  QgsMessageLog::logMessage( error.layerID + " :: " + error.message, tr( "Rendering" ) );
675  }
676 
677  if ( !mJobCancelled )
678  {
679  // take labeling results before emitting renderComplete, so labeling map tools
680  // connected to signal work with correct results
681  delete mLabelingResults;
683 
684  QImage img = mJob->renderedImage();
685 
686  // emit renderComplete to get our decorations drawn
687  QPainter p( &img );
688  emit renderComplete( &p );
689 
690  QSettings settings;
691  if ( settings.value( "/Map/logCanvasRefreshEvent", false ).toBool() )
692  {
693  QString logMsg = tr( "Canvas refresh: %1 ms" ).arg( mJob->renderingTime() );
694  QgsMessageLog::logMessage( logMsg, tr( "Rendering" ) );
695  }
696 
697  if ( mDrawRenderingStats )
698  {
699  int w = img.width(), h = img.height();
700  QFont fnt = p.font();
701  fnt.setBold( true );
702  p.setFont( fnt );
703  int lh = p.fontMetrics().height() * 2;
704  QRect r( 0, h - lh, w, lh );
705  p.setPen( Qt::NoPen );
706  p.setBrush( QColor( 0, 0, 0, 110 ) );
707  p.drawRect( r );
708  p.setPen( Qt::white );
709  QString msg = QString( "%1 :: %2 ms" ).arg( mUseParallelRendering ? "PARALLEL" : "SEQUENTIAL" ).arg( mJob->renderingTime() );
710  p.drawText( r, msg, QTextOption( Qt::AlignCenter ) );
711  }
712 
713  p.end();
714 
716  }
717 
718  // now we are in a slot called from mJob - do not delete it immediately
719  // so the class is still valid when the execution returns to the class
720  mJob->deleteLater();
721  mJob = 0;
722 
723  emit mapCanvasRefreshed();
724 }
725 
727 {
729 }
730 
731 
733 {
734  if ( mJob )
735  {
736  QgsDebugMsg( "CANVAS stop rendering!" );
737  mJobCancelled = true;
738  mJob->cancel();
739  Q_ASSERT( mJob == 0 ); // no need to delete here: already deleted in finished()
740  }
741 }
742 
744 {
745 }
746 
747 //the format defaults to "PNG" if not specified
748 void QgsMapCanvas::saveAsImage( QString theFileName, QPixmap * theQPixmap, QString theFormat )
749 {
750  //
751  //check if the optional QPaintDevice was supplied
752  //
753  if ( theQPixmap != NULL )
754  {
755  // render
756  QPainter painter;
757  painter.begin( theQPixmap );
758  QgsMapRendererCustomPainterJob job( mSettings, &painter );
759  job.start();
760  job.waitForFinished();
761  emit renderComplete( &painter );
762  painter.end();
763 
764  theQPixmap->save( theFileName, theFormat.toLocal8Bit().data() );
765  }
766  else //use the map view
767  {
768  mMap->contentImage().save( theFileName, theFormat.toLocal8Bit().data() );
769  }
770  //create a world file to go with the image...
772  QString myHeader;
773  // note: use 17 places of precision for all numbers output
774  //Pixel XDim
775  myHeader += qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
776  //Rotation on y axis - hard coded
777  myHeader += "0 \r\n";
778  //Rotation on x axis - hard coded
779  myHeader += "0 \r\n";
780  //Pixel YDim - almost always negative - see
781  //http://en.wikipedia.org/wiki/World_file#cite_note-2
782  myHeader += "-" + qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
783  //Origin X (center of top left cell)
784  myHeader += qgsDoubleToString( myRect.xMinimum() + ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
785  //Origin Y (center of top left cell)
786  myHeader += qgsDoubleToString( myRect.yMaximum() - ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
787  QFileInfo myInfo = QFileInfo( theFileName );
788  // allow dotted names
789  QString myWorldFileName = myInfo.absolutePath() + "/" + myInfo.completeBaseName() + "." + theFormat + "w";
790  QFile myWorldFile( myWorldFileName );
791  if ( !myWorldFile.open( QIODevice::WriteOnly ) ) //don't use QIODevice::Text
792  {
793  return;
794  }
795  QTextStream myStream( &myWorldFile );
796  myStream << myHeader;
797 } // saveAsImage
798 
799 
800 
802 {
803  return mapSettings().visibleExtent();
804 } // extent
805 
807 {
808  return mapSettings().fullExtent();
809 } // extent
810 
811 
813 {
814  QgsRectangle current = extent();
815 
816  if ( r == current )
817  return;
818 
819  if ( r.isEmpty() )
820  {
821  QgsDebugMsg( "Empty extent - keeping old extent with new center!" );
822  QgsRectangle e( QgsPoint( r.center().x() - current.width() / 2.0, r.center().y() - current.height() / 2.0 ),
823  QgsPoint( r.center().x() + current.width() / 2.0, r.center().y() + current.height() / 2.0 ) );
824  mSettings.setExtent( e );
825  }
826  else
827  {
828  mSettings.setExtent( r );
829  }
830  emit extentsChanged();
831  updateScale();
832  if ( mLastExtent.size() > 20 )
833  mLastExtent.removeAt( 0 );
834 
835  //clear all extent items after current index
836  for ( int i = mLastExtent.size() - 1; i > mLastExtentIndex; i-- )
837  {
838  mLastExtent.removeAt( i );
839  }
840 
841  mLastExtent.append( extent() ) ;
842 
843  // adjust history to no more than 20
844  if ( mLastExtent.size() > 20 )
845  {
846  mLastExtent.removeAt( 0 );
847  }
848 
849  // the last item is the current extent
850  mLastExtentIndex = mLastExtent.size() - 1;
851 
852  // update controls' enabled state
853  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
854  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
855  // notify canvas items of change
857 
858 } // setExtent
859 
860 
862 {
863  emit scaleChanged( mapSettings().scale() );
864 }
865 
866 
868 {
869  refresh();
870 } // clear
871 
872 
873 
875 {
877  // If the full extent is an empty set, don't do the zoom
878  if ( !extent.isEmpty() )
879  {
880  // Add a 5% margin around the full extent
881  extent.scale( 1.05 );
882  setExtent( extent );
883  }
884  refresh();
885 
886 } // zoomToFullExtent
887 
888 
889 
891 {
892  if ( mLastExtentIndex > 0 )
893  {
896  emit extentsChanged();
897  updateScale();
898  refresh();
899  // update controls' enabled state
900  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
901  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
902  // notify canvas items of change
904  }
905 
906 } // zoomToPreviousExtent
907 
909 {
910  if ( mLastExtentIndex < mLastExtent.size() - 1 )
911  {
914  emit extentsChanged();
915  updateScale();
916  refresh();
917  // update controls' enabled state
918  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
919  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
920  // notify canvas items of change
922  }
923 }// zoomToNextExtent
924 
926 {
927  mLastExtent.clear(); // clear the zoom history list
928  mLastExtent.append( extent() ) ; // set the current extent in the list
929  mLastExtentIndex = mLastExtent.size() - 1;
930  // update controls' enabled state
933 }// clearExtentHistory
934 
935 
937 {
939 }
940 
942 {
943  if ( layer == NULL )
944  {
945  // use current layer by default
946  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
947  }
948 
949  if ( layer == NULL )
950  {
951  return;
952  }
953 
954  if ( layer->selectedFeatureCount() == 0 )
955  {
956  return;
957  }
958 
960 
961  // no selected features, only one selected point feature
962  //or two point features with the same x- or y-coordinates
963  if ( rect.isEmpty() )
964  {
965  // zoom in
966  QgsPoint c = rect.center();
967  rect = extent();
968  rect.scale( 1.0, &c );
969  }
970  //zoom to an area
971  else
972  {
973  // Expand rect to give a bit of space around the selected
974  // objects so as to keep them clear of the map boundaries
975  // The same 5% should apply to all margins.
976  rect.scale( 1.05 );
977  }
978 
979  setExtent( rect );
980  refresh();
981 } // zoomToSelected
982 
984 {
985  if ( layer == NULL )
986  {
987  // use current layer by default
988  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
989  }
990 
991  if ( layer == NULL )
992  {
993  return;
994  }
995 
996  if ( layer->selectedFeatureCount() == 0 )
997  {
998  return;
999  }
1000 
1002  setExtent( QgsRectangle( rect.center(), rect.center() ) );
1003  refresh();
1004 } // panToSelected
1005 
1006 void QgsMapCanvas::keyPressEvent( QKeyEvent * e )
1007 {
1008  if ( mCanvasProperties->mouseButtonDown || mCanvasProperties->panSelectorDown )
1009  {
1010  emit keyPressed( e );
1011  return;
1012  }
1013 
1014  QPainter paint;
1015  QPen pen( Qt::gray );
1016  QgsPoint ll, ur;
1017 
1018  if ( ! mCanvasProperties->mouseButtonDown )
1019  {
1020  // Don't want to interfer with mouse events
1021 
1022  QgsRectangle currentExtent = mapSettings().visibleExtent();
1023  double dx = qAbs(( currentExtent.xMaximum() - currentExtent.xMinimum() ) / 4 );
1024  double dy = qAbs(( currentExtent.yMaximum() - currentExtent.yMinimum() ) / 4 );
1025 
1026  switch ( e->key() )
1027  {
1028  case Qt::Key_Left:
1029  QgsDebugMsg( "Pan left" );
1030 
1031  currentExtent.setXMinimum( currentExtent.xMinimum() - dx );
1032  currentExtent.setXMaximum( currentExtent.xMaximum() - dx );
1033  setExtent( currentExtent );
1034  refresh();
1035  break;
1036 
1037  case Qt::Key_Right:
1038  QgsDebugMsg( "Pan right" );
1039 
1040  currentExtent.setXMinimum( currentExtent.xMinimum() + dx );
1041  currentExtent.setXMaximum( currentExtent.xMaximum() + dx );
1042  setExtent( currentExtent );
1043  refresh();
1044  break;
1045 
1046  case Qt::Key_Up:
1047  QgsDebugMsg( "Pan up" );
1048 
1049  currentExtent.setYMaximum( currentExtent.yMaximum() + dy );
1050  currentExtent.setYMinimum( currentExtent.yMinimum() + dy );
1051  setExtent( currentExtent );
1052  refresh();
1053  break;
1054 
1055  case Qt::Key_Down:
1056  QgsDebugMsg( "Pan down" );
1057 
1058  currentExtent.setYMaximum( currentExtent.yMaximum() - dy );
1059  currentExtent.setYMinimum( currentExtent.yMinimum() - dy );
1060  setExtent( currentExtent );
1061  refresh();
1062  break;
1063 
1064 
1065 
1066  case Qt::Key_Space:
1067  QgsDebugMsg( "Pressing pan selector" );
1068 
1069  //mCanvasProperties->dragging = true;
1070  if ( ! e->isAutoRepeat() )
1071  {
1072  mCanvasProperties->panSelectorDown = true;
1073  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1074  }
1075  break;
1076 
1077  case Qt::Key_PageUp:
1078  QgsDebugMsg( "Zoom in" );
1079  zoomIn();
1080  break;
1081 
1082  case Qt::Key_PageDown:
1083  QgsDebugMsg( "Zoom out" );
1084  zoomOut();
1085  break;
1086 
1087 #if 0
1088  case Qt::Key_P:
1090  refresh();
1091  break;
1092 
1093  case Qt::Key_S:
1095  refresh();
1096  break;
1097 #endif
1098 
1099  default:
1100  // Pass it on
1101  if ( mMapTool )
1102  {
1103  mMapTool->keyPressEvent( e );
1104  }
1105  else e->ignore();
1106 
1107  QgsDebugMsg( "Ignoring key: " + QString::number( e->key() ) );
1108  }
1109  }
1110 
1111  emit keyPressed( e );
1112 
1113 } //keyPressEvent()
1114 
1115 void QgsMapCanvas::keyReleaseEvent( QKeyEvent * e )
1116 {
1117  QgsDebugMsg( "keyRelease event" );
1118 
1119  switch ( e->key() )
1120  {
1121  case Qt::Key_Space:
1122  if ( !e->isAutoRepeat() && mCanvasProperties->panSelectorDown )
1123  {
1124  QgsDebugMsg( "Releasing pan selector" );
1125 
1126  mCanvasProperties->panSelectorDown = false;
1127  panActionEnd( mCanvasProperties->mouseLastXY );
1128  }
1129  break;
1130 
1131  default:
1132  // Pass it on
1133  if ( mMapTool )
1134  {
1135  mMapTool->keyReleaseEvent( e );
1136  }
1137  else e->ignore();
1138 
1139  QgsDebugMsg( "Ignoring key release: " + QString::number( e->key() ) );
1140  }
1141 
1142  emit keyReleased( e );
1143 
1144 } //keyReleaseEvent()
1145 
1146 
1148 {
1149  // call handler of current map tool
1150  if ( mMapTool )
1152 } // mouseDoubleClickEvent
1153 
1154 
1155 void QgsMapCanvas::mousePressEvent( QMouseEvent * e )
1156 {
1157  //use middle mouse button for panning, map tools won't receive any events in that case
1158  if ( e->button() == Qt::MidButton )
1159  {
1160  mCanvasProperties->panSelectorDown = true;
1161  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1162  }
1163  else
1164  {
1165 
1166  // call handler of current map tool
1167  if ( mMapTool )
1168  mMapTool->canvasPressEvent( e );
1169  }
1170 
1171  if ( mCanvasProperties->panSelectorDown )
1172  {
1173  return;
1174  }
1175 
1176  mCanvasProperties->mouseButtonDown = true;
1177  mCanvasProperties->rubberStartPoint = e->pos();
1178 
1179 } // mousePressEvent
1180 
1181 
1182 void QgsMapCanvas::mouseReleaseEvent( QMouseEvent * e )
1183 {
1184  //use middle mouse button for panning, map tools won't receive any events in that case
1185  if ( e->button() == Qt::MidButton )
1186  {
1187  mCanvasProperties->panSelectorDown = false;
1188  panActionEnd( mCanvasProperties->mouseLastXY );
1189  }
1190  else
1191  {
1192  // call handler of current map tool
1193  if ( mMapTool )
1194  {
1195  // right button was pressed in zoom tool? return to previous non zoom tool
1196  if ( e->button() == Qt::RightButton && mMapTool->isTransient() )
1197  {
1198  QgsDebugMsg( "Right click in map tool zoom or pan, last tool is " +
1199  QString( mLastNonZoomMapTool ? "not null." : "null." ) );
1200 
1201  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1202 
1203  // change to older non-zoom tool
1204  if ( mLastNonZoomMapTool
1205  && ( !mLastNonZoomMapTool->isEditTool() || ( vlayer && vlayer->isEditable() ) ) )
1206  {
1208  mLastNonZoomMapTool = NULL;
1209  setMapTool( t );
1210  }
1211  return;
1212  }
1214  }
1215  }
1216 
1217 
1218  mCanvasProperties->mouseButtonDown = false;
1219 
1220  if ( mCanvasProperties->panSelectorDown )
1221  return;
1222 
1223 } // mouseReleaseEvent
1224 
1225 void QgsMapCanvas::resizeEvent( QResizeEvent * e )
1226 {
1227  QGraphicsView::resizeEvent( e );
1228  mResizeTimer->start( 500 );
1229 
1230  QSize lastSize = viewport()->size();
1231 
1232  mSettings.setOutputSize( lastSize );
1234 
1235  mScene->setSceneRect( QRectF( 0, 0, lastSize.width(), lastSize.height() ) );
1236 
1237  moveCanvasContents( true );
1238 
1239  // notify canvas items of change
1241 
1242  updateScale();
1243 
1244  //refresh();
1245 
1246  emit extentsChanged();
1247 }
1248 
1249 void QgsMapCanvas::paintEvent( QPaintEvent *e )
1250 {
1251  // no custom event handling anymore
1252 
1253  QGraphicsView::paintEvent( e );
1254 } // paintEvent
1255 
1257 {
1258  QList<QGraphicsItem*> list = mScene->items();
1259  QList<QGraphicsItem*>::iterator it = list.begin();
1260  while ( it != list.end() )
1261  {
1262  QgsMapCanvasItem* item = dynamic_cast<QgsMapCanvasItem *>( *it );
1263 
1264  if ( item )
1265  {
1266  item->updatePosition();
1267  }
1268 
1269  ++it;
1270  }
1271 }
1272 
1273 
1274 void QgsMapCanvas::wheelEvent( QWheelEvent *e )
1275 {
1276  // Zoom the map canvas in response to a mouse wheel event. Moving the
1277  // wheel forward (away) from the user zooms in
1278 
1279  QgsDebugMsg( "Wheel event delta " + QString::number( e->delta() ) );
1280 
1281  if ( mMapTool )
1282  {
1283  mMapTool->wheelEvent( e );
1284  }
1285 
1286  if ( QgsApplication::keyboardModifiers() )
1287  {
1288  // leave the wheel for map tools if any modifier pressed
1289  return;
1290  }
1291 
1292  switch ( mWheelAction )
1293  {
1294  case WheelZoom:
1295  // zoom without changing extent
1296  if ( e->delta() > 0 )
1297  zoomIn();
1298  else
1299  zoomOut();
1300  break;
1301 
1302  case WheelZoomAndRecenter:
1303  // zoom and don't change extent
1304  zoomWithCenter( e->x(), e->y(), e->delta() > 0 );
1305  break;
1306 
1308  {
1309  // zoom map to mouse cursor
1310  double scaleFactor = e->delta() > 0 ? 1 / mWheelZoomFactor : mWheelZoomFactor;
1311 
1312  QgsPoint oldCenter( mapSettings().visibleExtent().center() );
1313  QgsPoint mousePos( getCoordinateTransform()->toMapPoint( e->x(), e->y() ) );
1314  QgsPoint newCenter( mousePos.x() + (( oldCenter.x() - mousePos.x() ) * scaleFactor ),
1315  mousePos.y() + (( oldCenter.y() - mousePos.y() ) * scaleFactor ) );
1316 
1317  // same as zoomWithCenter (no coordinate transformations are needed)
1319  extent.scale( scaleFactor, &newCenter );
1320  setExtent( extent );
1321  refresh();
1322  break;
1323  }
1324 
1325  case WheelNothing:
1326  // well, nothing!
1327  break;
1328  }
1329 }
1330 
1331 void QgsMapCanvas::setWheelAction( WheelAction action, double factor )
1332 {
1333  mWheelAction = action;
1334  mWheelZoomFactor = factor;
1335 }
1336 
1338 {
1340 }
1341 
1343 {
1345 }
1346 
1347 void QgsMapCanvas::zoomScale( double newScale )
1348 {
1349  zoomByFactor( newScale / scale() );
1350 }
1351 
1352 void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
1353 {
1354  double scaleFactor = ( zoomIn ? 1 / mWheelZoomFactor : mWheelZoomFactor );
1355 
1356  // transform the mouse pos to map coordinates
1357  QgsPoint center = getCoordinateTransform()->toMapPoint( x, y );
1359  r.scale( scaleFactor, &center );
1360  setExtent( r );
1361  refresh();
1362 }
1363 
1364 void QgsMapCanvas::mouseMoveEvent( QMouseEvent * e )
1365 {
1366  mCanvasProperties->mouseLastXY = e->pos();
1367 
1368  if ( mCanvasProperties->panSelectorDown )
1369  {
1370  panAction( e );
1371  }
1372  else
1373  {
1374  // call handler of current map tool
1375  if ( mMapTool )
1376  mMapTool->canvasMoveEvent( e );
1377  }
1378 
1379  // show x y on status bar
1380  QPoint xy = e->pos();
1382  emit xyCoordinates( coord );
1383 } // mouseMoveEvent
1384 
1385 
1386 
1389 {
1390  if ( !tool )
1391  return;
1392 
1393  if ( mMapTool )
1394  {
1395  disconnect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1396  mMapTool->deactivate();
1397  }
1398 
1399  if ( tool->isTransient() && mMapTool && !mMapTool->isTransient() )
1400  {
1401  // if zoom or pan tool will be active, save old tool
1402  // to bring it back on right click
1403  // (but only if it wasn't also zoom or pan tool)
1405  }
1406  else
1407  {
1408  mLastNonZoomMapTool = NULL;
1409  }
1410 
1411  QgsMapTool* oldTool = mMapTool;
1412 
1413  // set new map tool and activate it
1414  mMapTool = tool;
1415  if ( mMapTool )
1416  {
1417  connect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1418  mMapTool->activate();
1419  }
1420 
1421  emit mapToolSet( mMapTool );
1422  emit mapToolSet( mMapTool, oldTool );
1423 } // setMapTool
1424 
1426 {
1427  if ( mMapTool && mMapTool == tool )
1428  {
1429  mMapTool->deactivate();
1430  mMapTool = NULL;
1431  emit mapToolSet( NULL );
1432  emit mapToolSet( NULL, mMapTool );
1433  setCursor( Qt::ArrowCursor );
1434  }
1435 
1436  if ( mLastNonZoomMapTool && mLastNonZoomMapTool == tool )
1437  {
1438  mLastNonZoomMapTool = NULL;
1439  }
1440 }
1441 
1443 void QgsMapCanvas::setCanvasColor( const QColor & theColor )
1444 {
1445  // background of map's pixmap
1446  mSettings.setBackgroundColor( theColor );
1447 
1448  // background of the QGraphicsView
1449  QBrush bgBrush( theColor );
1450  setBackgroundBrush( bgBrush );
1451 #if 0
1452  QPalette palette;
1453  palette.setColor( backgroundRole(), theColor );
1454  setPalette( palette );
1455 #endif
1456 
1457  // background of QGraphicsScene
1458  mScene->setBackgroundBrush( bgBrush );
1459 } // setBackgroundColor
1460 
1462 {
1463  return mScene->backgroundBrush().color();
1464 }
1465 
1466 void QgsMapCanvas::setSelectionColor( const QColor& color )
1467 {
1468  mSettings.setSelectionColor( color );
1469 }
1470 
1472 {
1473  return mapSettings().layers().size();
1474 } // layerCount
1475 
1476 
1477 QList<QgsMapLayer*> QgsMapCanvas::layers() const
1478 {
1479  QList<QgsMapLayer*> lst;
1480  foreach ( QString layerID, mapSettings().layers() )
1481  {
1483  if ( layer )
1484  lst.append( layer );
1485  }
1486  return lst;
1487 }
1488 
1489 
1491 {
1492  // called when a layer has changed visibility setting
1493 
1494  refresh();
1495 
1496 } // layerStateChange
1497 
1498 
1499 
1500 void QgsMapCanvas::freeze( bool frz )
1501 {
1502  mFrozen = frz;
1503 } // freeze
1504 
1506 {
1507  return mFrozen;
1508 } // freeze
1509 
1510 
1512 {
1514  return mMap->paintDevice();
1516 }
1517 
1519 {
1520  return mapSettings().mapUnitsPerPixel();
1521 } // mapUnitsPerPixel
1522 
1523 
1525 {
1526  if ( mSettings.mapUnits() == u )
1527  return;
1528 
1529  QgsDebugMsg( "Setting map units to " + QString::number( static_cast<int>( u ) ) );
1530  mSettings.setMapUnits( u );
1531 
1532  updateScale();
1533 
1534  refresh(); // this will force the scale bar to be updated
1535 
1536  emit mapUnitsChanged();
1537 }
1538 
1539 
1541 {
1542  return mapSettings().mapUnits();
1543 }
1544 
1545 
1546 void QgsMapCanvas::setRenderFlag( bool theFlag )
1547 {
1548  mRenderFlag = theFlag;
1549 
1550  if ( mRenderFlag )
1551  {
1552  refresh();
1553  }
1554  else
1555  stopRendering();
1556 }
1557 
1558 void QgsMapCanvas::connectNotify( const char * signal )
1559 {
1560  Q_UNUSED( signal );
1561  QgsDebugMsg( "QgsMapCanvas connected to " + QString( signal ) );
1562 } //connectNotify
1563 
1564 
1566 {
1568  return;
1569 
1570  QString destAuthId = mSettings.destinationCrs().authid();
1571  foreach ( QString layerID, mSettings.layers() )
1572  {
1574  if ( !layer )
1575  continue;
1576 
1577  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
1578  if ( vl && vl->geometryType() == QGis::NoGeometry )
1579  continue;
1580 
1581  // if there are more options, ask the user which datum transform to use
1583  getDatumTransformInfo( layer, layer->crs().authid(), destAuthId );
1584  }
1585 }
1586 
1587 
1588 
1590 {
1591  return mMapTool;
1592 }
1593 
1594 void QgsMapCanvas::panActionEnd( QPoint releasePoint )
1595 {
1596  // move map image and other items to standard position
1597  moveCanvasContents( true ); // true means reset
1598 
1599  // use start and end box points to calculate the extent
1600  QgsPoint start = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
1601  QgsPoint end = getCoordinateTransform()->toMapCoordinates( releasePoint );
1602 
1603  double dx = qAbs( end.x() - start.x() );
1604  double dy = qAbs( end.y() - start.y() );
1605 
1606  // modify the extent
1608 
1609  if ( end.x() < start.x() )
1610  {
1611  r.setXMinimum( r.xMinimum() + dx );
1612  r.setXMaximum( r.xMaximum() + dx );
1613  }
1614  else
1615  {
1616  r.setXMinimum( r.xMinimum() - dx );
1617  r.setXMaximum( r.xMaximum() - dx );
1618  }
1619 
1620  if ( end.y() < start.y() )
1621  {
1622  r.setYMaximum( r.yMaximum() + dy );
1623  r.setYMinimum( r.yMinimum() + dy );
1624 
1625  }
1626  else
1627  {
1628  r.setYMaximum( r.yMaximum() - dy );
1629  r.setYMinimum( r.yMinimum() - dy );
1630 
1631  }
1632 
1633  setExtent( r );
1634 
1635  r = mapSettings().visibleExtent();
1636 
1637  refresh();
1638 }
1639 
1640 void QgsMapCanvas::panAction( QMouseEvent * e )
1641 {
1642  Q_UNUSED( e );
1643 
1644  // move all map canvas items
1646 }
1647 
1649 {
1650  QPoint pnt( 0, 0 );
1651  if ( !reset )
1652  pnt += mCanvasProperties->mouseLastXY - mCanvasProperties->rubberStartPoint;
1653 
1654  setSceneRect( -pnt.x(), -pnt.y(), viewport()->size().width(), viewport()->size().height() );
1655 }
1656 
1658 {
1659  Q_UNUSED( mapLayer );
1660 }
1661 
1663 {
1664  return mCanvasProperties->mouseLastXY;
1665 }
1666 
1667 void QgsMapCanvas::setPreviewModeEnabled( bool previewEnabled )
1668 {
1669  if ( !mPreviewEffect )
1670  {
1671  return;
1672  }
1673 
1674  mPreviewEffect->setEnabled( previewEnabled );
1675 }
1676 
1678 {
1679  if ( !mPreviewEffect )
1680  {
1681  return false;
1682  }
1683 
1684  return mPreviewEffect->isEnabled();
1685 }
1686 
1688 {
1689  if ( !mPreviewEffect )
1690  {
1691  return;
1692  }
1693 
1694  mPreviewEffect->setMode( mode );
1695 }
1696 
1698 {
1699  if ( !mPreviewEffect )
1700  {
1702  }
1703 
1704  return mPreviewEffect->mode();
1705 }
1706 
1707 void QgsMapCanvas::readProject( const QDomDocument & doc )
1708 {
1709  QDomNodeList nodes = doc.elementsByTagName( "mapcanvas" );
1710  if ( nodes.count() )
1711  {
1712  QDomNode node = nodes.item( 0 );
1713 
1714  QgsMapSettings tmpSettings;
1715  tmpSettings.readXML( node );
1716  setMapUnits( tmpSettings.mapUnits() );
1718  setDestinationCrs( tmpSettings.destinationCrs() );
1719  setExtent( tmpSettings.extent() );
1721 
1722  clearExtentHistory(); // clear the extent history on project load
1723  }
1724  else
1725  {
1726  QgsDebugMsg( "Couldn't read mapcanvas information from project" );
1727  }
1728 }
1729 
1730 void QgsMapCanvas::writeProject( QDomDocument & doc )
1731 {
1732  // create node "mapcanvas" and call mMapRenderer->writeXML()
1733 
1734  QDomNodeList nl = doc.elementsByTagName( "qgis" );
1735  if ( !nl.count() )
1736  {
1737  QgsDebugMsg( "Unable to find qgis element in project file" );
1738  return;
1739  }
1740  QDomNode qgisNode = nl.item( 0 ); // there should only be one, so zeroth element ok
1741 
1742  QDomElement mapcanvasNode = doc.createElement( "mapcanvas" );
1743  qgisNode.appendChild( mapcanvasNode );
1744 
1745  mSettings.writeXML( mapcanvasNode, doc );
1746  // TODO: store only units, extent, projections, dest CRS
1747 }
1748 
1750 void QgsMapCanvas::getDatumTransformInfo( const QgsMapLayer* ml, const QString& srcAuthId, const QString& destAuthId )
1751 {
1752  if ( !ml )
1753  {
1754  return;
1755  }
1756 
1757  //check if default datum transformation available
1758  QSettings s;
1759  QString settingsString = "/Projections/" + srcAuthId + "//" + destAuthId;
1760  QVariant defaultSrcTransform = s.value( settingsString + "_srcTransform" );
1761  QVariant defaultDestTransform = s.value( settingsString + "_destTransform" );
1762  if ( defaultSrcTransform.isValid() && defaultDestTransform.isValid() )
1763  {
1764  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1765  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1766  return;
1767  }
1768 
1769  const QgsCoordinateReferenceSystem& srcCRS = QgsCRSCache::instance()->crsByAuthId( srcAuthId );
1770  const QgsCoordinateReferenceSystem& destCRS = QgsCRSCache::instance()->crsByAuthId( destAuthId );
1771 
1772  if ( !s.value( "/Projections/showDatumTransformDialog", false ).toBool() )
1773  {
1774  // just use the default transform
1775  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1776  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1777  return;
1778  }
1779 
1780  //get list of datum transforms
1781  QList< QList< int > > dt = QgsCoordinateTransform::datumTransformations( srcCRS, destCRS );
1782  if ( dt.size() < 2 )
1783  {
1784  return;
1785  }
1786 
1787  //if several possibilities: present dialog
1788  QgsDatumTransformDialog d( ml->name(), dt );
1789  d.setDatumTransformInfo( srcCRS.authid(), destCRS.authid() );
1790  if ( d.exec() == QDialog::Accepted )
1791  {
1792  int srcTransform = -1;
1793  int destTransform = -1;
1794  QList<int> t = d.selectedDatumTransform();
1795  if ( t.size() > 0 )
1796  {
1797  srcTransform = t.at( 0 );
1798  }
1799  if ( t.size() > 1 )
1800  {
1801  destTransform = t.at( 1 );
1802  }
1803  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1804  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1805  if ( d.rememberSelection() )
1806  {
1807  s.setValue( settingsString + "_srcTransform", srcTransform );
1808  s.setValue( settingsString + "_destTransform", destTransform );
1809  }
1810  }
1811  else
1812  {
1813  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1814  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1815  }
1816 }
1817 
1818 void QgsMapCanvas::zoomByFactor( double scaleFactor , const QgsPoint* center )
1819 {
1821  r.scale( scaleFactor, center );
1822  setExtent( r );
1823  refresh();
1824 }
1825 
1827 {
1828  // Find out which layer it was that sent the signal.
1829  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
1830  emit selectionChanged( layer );
1831  refresh();
1832 }
1833 
1834 void QgsMapCanvas::dragEnterEvent( QDragEnterEvent * e )
1835 {
1836  // By default graphics view delegates the drag events to graphics items.
1837  // But we do not want that and by ignoring the drag enter we let the
1838  // parent (e.g. QgisApp) to handle drops of map layers etc.
1839  e->ignore();
1840 }
1841 
1843 {
1844  QgsDebugMsg( "maptool destroyed" );
1845  mMapTool = 0;
1846 }
1847 
1848 #ifdef HAVE_TOUCH
1849 bool QgsMapCanvas::event( QEvent * e )
1850 {
1851  bool done = false;
1852  if ( e->type() == QEvent::Gesture )
1853  {
1854  // call handler of current map tool
1855  if ( mMapTool )
1856  {
1857  done = mMapTool->gestureEvent( static_cast<QGestureEvent*>( e ) );
1858  }
1859  }
1860  else
1861  {
1862  // pass other events to base class
1863  done = QGraphicsView::event( e );
1864  }
1865  return done;
1866 }
1867 #endif
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
QgsMapCanvasMap * mMap
owns pixmap with rendered map and controls rendering
Definition: qgsmapcanvas.h:571
void zoomToSelected(QgsVectorLayer *layer=NULL)
Zoom to the extent of the selected features of current (vector) layer.
void setRequestedGeometryCacheForLayers(const QStringList &layerIds)
Set which vector layers should be cached while rendering.
void updateCanvasItemPositions()
called on resize or changed extent to notify canvas items to change their rectangle ...
QgsMapSettings mSettings
encompases all map settings necessary for map rendering
Definition: qgsmapcanvas.h:565
bool mDrawRenderingStats
Whether to add rendering stats to the rendered image.
Definition: qgsmapcanvas.h:623
void setParallelRenderingEnabled(bool enabled)
Set whether the layers are rendered in parallel or sequentially.
const QgsDatumTransformStore & datumTransformStore() const
static unsigned index
void mapUpdateTimeout()
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
QPoint mouseLastXY
Last seen point of the mouse.
virtual QColor canvasColor() const
Read property of QColor bgColor.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:48
Job implementation that renders everything sequentially using a custom painter.
const QgsCoordinateReferenceSystem & crsByAuthId(const QString &authid)
Returns the CRS for authid, e.g.
bool isEmpty() const
test if rectangle is empty.
void zoomToNextExtent()
Zoom to the next extent (view)
QGraphicsScene * mScene
graphics scene manages canvas items
Definition: qgsmapcanvas.h:589
void zoomWithCenter(int x, int y, bool zoomIn)
Zooms in/out with a given center.
Q_DECL_DEPRECATED bool isDirty() const
Return the state of the canvas (dirty or not)
void freeze(bool frz=true)
virtual void setCanvasColor(const QColor &_newVal)
Write property of QColor bgColor.
void enableOverviewMode(QgsMapOverviewCanvas *overview)
QTimer * mResizeTimer
Definition: qgsmapcanvas.h:628
double scale() const
Return the calculated scale of the map.
void zoomByFactor(double scaleFactor, const QgsPoint *center=0)
Zoom with the factor supplied.
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
bool hasEntryForLayer(QgsMapLayer *layer) const
int layerCount() const
return number of layers on the map
bool mUseParallelRendering
Whether layers are rendered sequentially or in parallel.
Definition: qgsmapcanvas.h:620
A widget that displays an overview map.
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:169
void clearExtentHistory()
void readXML(QDomNode &theNode)
QgsRectangle fullExtent() const
returns current extent of layer set
QgsMapRenderer * mMapRenderer
all map rendering is done in this class
Definition: qgsmapcanvas.h:568
bool mouseButtonDown
Flag to indicate status of mouse button.
static QList< QList< int > > datumTransformations(const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS)
Returns list of datum transformations for the given src and dest CRS.
bool mRefreshScheduled
Flag that allows squashing multiple refresh() calls into just one delayed rendering job...
Definition: qgsmapcanvas.h:580
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:194
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
UnitType
Map units that qgis supports.
Definition: qgis.h:229
void stopRendering()
stop rendering (if there is any right now)
virtual void canvasMoveEvent(QMouseEvent *e)
Mouse move event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:138
void mouseReleaseEvent(QMouseEvent *e)
Overridden mouse release event.
QgsRectangle extent() const
returns current extent
void setExtent(const QgsRectangle &r)
Set the extent of the map canvas.
void addLayerCoordinateTransform(const QString &layerId, const QString &srcAuthId, const QString &destAuthId, int srcDatumTransform=-1, int destDatumTransform=-1)
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:439
An abstract class for items that can be placed on the map canvas.
A class that stores visibility and presence in overview flags together with pointer to the layer...
Definition: qgsmapcanvas.h:74
bool hasCrsTransformEnabled()
A simple helper method to find out if on the fly projections are enabled or not.
void setCurrentLayer(QgsMapLayer *layer)
bool previewModeEnabled() const
Returns whether a preview mode is enabled for the map canvas.
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
QList< QgsMapLayer * > layers() const
return list of layers within map canvas. Added in v1.5
void moveCanvasContents(bool reset=false)
called when panning is in action, reset indicates end of panning
WheelAction mWheelAction
Mouse wheel action.
Definition: qgsmapcanvas.h:605
bool isVisible() const
Definition: qgsmapcanvas.h:83
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
QgsRectangle layerExtentToOutputExtent(QgsMapLayer *theLayer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
void readProject(const QDomDocument &)
called to read map canvas settings from project
bool panSelectorDown
Flag to indicate the pan selector key is held down by user.
QgsMapOverviewCanvas * mMapOverview
map overview widget - it's controlled by QgsMapCanvas
Definition: qgsmapcanvas.h:574
void refresh()
Repaints the canvas map.
void renderComplete(QPainter *)
Emitted when the canvas has rendered.
void setProjectionsEnabled(bool enabled)
sets whether to use projections for this layer set
~QgsMapCanvas()
Destructor.
const QgsMapToPixel & mapToPixel() const
void keyReleaseEvent(QKeyEvent *e)
Overridden key release event.
QgsMapTool * mapTool()
Returns the currently active tool.
void setLayerSet(const QStringList &layers)
change current layer set
virtual void canvasDoubleClickEvent(QMouseEvent *e)
Mouse double click event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:143
const QgsLabelingResults * labelingResults() const
Get access to the labeling results (may be null)
A non GUI class for rendering a map layer set onto a QPainter.
virtual void canvasPressEvent(QMouseEvent *e)
Mouse press event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:148
void setLayers(const QStringList &layers)
Set list of layer IDs for map rendering.
void resizeEvent(QResizeEvent *e)
Overridden resize event.
QgsMapTool * mMapTool
pointer to current map tool
Definition: qgsmapcanvas.h:592
virtual QImage renderedImage()=0
Get a preview/resulting image.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:104
double x() const
Definition: qgspoint.h:110
void zoomLastStatusChanged(bool)
Emitted when zoom last status changed.
A graphics effect which can be applied to a widget to simulate various printing and color blindness m...
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void updateScale()
Emits signal scaleChanged to update scale in main window.
void mouseDoubleClickEvent(QMouseEvent *e)
Overridden mouse double click event.
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
The QgsMapSettings class contains configuration for rendering of the map.
QgsMapLayer * mCurrentLayer
current layer in legend
Definition: qgsmapcanvas.h:586
void setDatumTransformInfo(const QString &srcCRSauthId, const QString &destCRSauthId)
void hasCrsTransformEnabledChanged(bool flag)
Emitted when on-the-fly projection has been turned on/off.
void setMapTool(QgsMapTool *mapTool)
Sets the map tool currently being used on the canvas.
void enableAntiAliasing(bool flag)
const QString & name() const
Get the display name of the layer.
virtual void activate()
called when set as currently active map tool
Definition: qgsmaptool.cpp:77
void paintEvent(QPaintEvent *e)
Overridden paint event.
void setCrsTransformEnabled(bool enabled)
sets whether to use projections for this layer set
QgsMapRenderer * mRenderer
Definition: qgsmapcanvas.h:667
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:33
virtual void keyReleaseEvent(QKeyEvent *e)
Key event for overriding.
Definition: qgsmaptool.cpp:168
int outputDpi() const
Return DPI used for conversion between real world units (e.g.
Q_DECL_DEPRECATED void showError(QgsMapLayer *mapLayer)
A rectangular graphics item representing the map on the canvas.
Q_DECL_DEPRECATED void clear()
Clear the map canvas.
void addEntry(const QString &layerId, const QString &srcAuthId, const QString &destAuthId, int srcDatumTransform, int destDatumTransform)
int mLastExtentIndex
Definition: qgsmapcanvas.h:599
void mapCanvasRefreshed()
Emitted when canvas finished a refresh request.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:199
double scale()
Get the last reported scale of the canvas.
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:184
void zoomNextStatusChanged(bool)
Emitted when zoom next status changed.
QgsMapTool * mLastNonZoomMapTool
previous tool if current is for zooming/panning
Definition: qgsmapcanvas.h:595
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
void clearCache()
Make sure to remove any rendered images from cache (does nothing if cache is not enabled) ...
void mousePressEvent(QMouseEvent *e)
Overridden mouse press event.
void setMapUnits(QGis::UnitType u)
Set units of map's geographical coordinates - used for scale calculation.
virtual void waitForFinished()
Block until the job has finished.
Job implementation that renders all layers in parallel.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
void panToSelected(QgsVectorLayer *layer=NULL)
Pan to the selected features of current (vector) layer keeping same extent.
void setLayerSet(QList< QgsMapCanvasLayer > &layers)
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:174
QgsMapCanvas * mCanvas
Definition: qgsmapcanvas.h:666
void keyReleased(QKeyEvent *e)
Emit key release event.
Q_DECL_DEPRECATED QPaintDevice & paintDevice()
void mapToolDestroyed()
called when current maptool is destroyed
bool setExtent(const QgsRectangle &extent)
sets extent and checks whether suitable (returns false if not)
Enable anti-aliasin for map rendering.
void setMapUnits(QGis::UnitType u)
void getDatumTransformInfo(const QgsMapLayer *ml, const QString &srcAuthId, const QString &destAuthId)
ask user about datum transformation
Q_DECL_DEPRECATED QPaintDevice & canvasPaintDevice()
Accessor for the canvas paint device.
double mapUnitsPerPixel() const
Return the distance in geographical coordinates that equals to one pixel in the map.
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Definition: qgsmaplayer.cpp:95
void wheelEvent(QWheelEvent *e)
Overridden mouse wheel event.
void destinationCrsChanged()
Emitted when map CRS has changed.
int mapUpdateInterval() const
Find out how often map preview should be updated while it is being rendered (in milliseconds) ...
void updateDatumTransformEntries()
Make sure the datum transform store is properly populated.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
void setRenderFlag(bool theFlag)
Whether to suppress rendering or not.
QGis::UnitType mapUnits() const
Get units of map's geographical coordinates - used for scale calculation.
QGis::UnitType mapUnits() const
Get the current canvas map units.
virtual void start()
Start the rendering job and immediately return.
void setOutputSize(QSize size, int dpi)
void setCachingEnabled(bool enabled)
Set whether to cache images of rendered layers.
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:93
virtual bool isEditTool()
Check whether this MapTool performs an edit operation.
Definition: qgsmaptool.cpp:190
QgsMapCanvasMap * map()
void setPreviewMode(QgsPreviewEffect::PreviewMode mode)
Sets a preview mode for the map canvas.
virtual void wheelEvent(QWheelEvent *e)
Mouse wheel event for overriding.
Definition: qgsmaptool.cpp:158
void refresh()
renders overview and updates panning widget
void setMode(PreviewMode mode)
Sets the mode for the preview effect, which controls how the effect modifies a widgets appearance...
void renderStarting()
Emitted when the canvas is about to be rendered.
A class to represent a point geometry.
Definition: qgspoint.h:63
void saveAsImage(QString theFileName, QPixmap *QPixmap=0, QString="PNG")
Save the convtents of the map canvas to disk as an image.
void keyPressed(QKeyEvent *e)
Emit key press event.
QgsMapRendererQImageJob * mJob
Job that takes care of map rendering in background.
Definition: qgsmapcanvas.h:611
void zoomOut()
Zoom out with fixed factor.
QgsPreviewEffect::PreviewMode previewMode() const
Returns the current preview mode for the map canvas.
Enable drawing of vertex markers for layers in editing mode.
void zoomToPreviousExtent()
Zoom to the previous extent (view)
void xyCoordinates(const QgsPoint &p)
emits current mouse position
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs, bool refreshCoordinateTransformInfo=true, bool transformExtent=true)
sets destination coordinate reference system
bool isDrawing()
Find out whether rendering is in progress.
QgsLabelingResults * mLabelingResults
Labeling results from the recently rendered map.
Definition: qgsmapcanvas.h:617
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:316
void setPreviewModeEnabled(bool previewEnabled)
Enables a preview mode for the map canvas.
virtual void start()=0
Start the rendering job and immediately return.
QPoint mouseLastXY()
returns last position of mouse cursor
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
void setWheelAction(WheelAction action, double factor=2)
set wheel action and zoom factor (should be greater than 1)
void selectionChanged(QgsMapLayer *layer)
Emitted when selection in any layer gets changed.
virtual void keyPressEvent(QKeyEvent *e)
Key event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:163
bool isCachingEnabled() const
Check whether images of rendered layers are curerently being cached.
QgsPoint toMapCoordinates(int x, int y) const
void clear()
invalidate the cache contents
Abstract base class for all map tools.
Definition: qgsmaptool.h:48
void selectionChangedSlot()
Receives signal about selection change, and pass it on with layer info.
Job implementation that renders everything sequentially in one thread.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:440
QTimer mMapUpdateTimer
Timer that periodically fires while map rendering is in progress to update the visible map...
Definition: qgsmapcanvas.h:608
double mWheelZoomFactor
Scale factor multiple for default zoom in/out.
Definition: qgsmapcanvas.h:602
bool mFrozen
Flag indicating if the map canvas is frozen.
Definition: qgsmapcanvas.h:577
void setBackgroundColor(const QColor &color)
Set the background color of the map.
QImage contentImage() const
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
Q_DECL_DEPRECATED void useImageToRender(bool theFlag)
Select which Qt class to render with.
void setContent(const QImage &image, const QgsRectangle &rect)
bool isInOverview() const
Definition: qgsmapcanvas.h:84
QgsMapRendererCache * mCache
Optionally use cache with rendered map layers for the current map settings.
Definition: qgsmapcanvas.h:626
virtual void canvasReleaseEvent(QMouseEvent *e)
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:153
void setSelectionColor(const QColor &color)
Set color that is used for drawing of selected vector features.
void setLayerSet(const QStringList &layerSet)
updates layer set for overview
void setOutputSize(const QSize &size)
Set the size of the resulting map image.
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:179
void writeProject(QDomDocument &)
called to write map canvas settings to project
void panAction(QMouseEvent *event)
Called when mouse is moving and pan is activated.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:362
Q_DECL_DEPRECATED QgsMapRenderer * mapRenderer()
void zoomToFullExtent()
Zoom to the full extent of all layers.
QgsPreviewEffect * mPreviewEffect
Definition: qgsmapcanvas.h:630
bool mRenderFlag
determines whether user has requested to suppress rendering
Definition: qgsmapcanvas.h:583
Class for storing a coordinate reference system (CRS)
void setExtent(const QgsRectangle &rect)
Set coordinates of the rectangle which should be rendered.
QgsMapCanvasRendererSync(QgsMapCanvas *canvas, QgsMapRenderer *renderer)
QgsRectangle extent() const
Return geographical coordinates of the rectangle that should be rendered.
void zoomScale(double scale)
Zoom to a specific scale.
Class for doing transforms between two map coordinate systems.
const QgsMapToPixel * getCoordinateTransform()
Get the current coordinate transform.
void scaleChanged(double)
Emitted when the scale of the map changes.
virtual bool isTransient()
Check whether this MapTool performs a zoom or pan operation.
Definition: qgsmaptool.cpp:185
double y() const
Definition: qgspoint.h:118
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
virtual void cancel()=0
Stop the rendering job - does not return until the job has terminated.
QStringList layers() const
Get list of layer IDs for map rendering The layers are stored in the reverse order of how they are re...
void enableAntiAliasing(bool theFlag)
used to determine if anti-aliasing is enabled or not
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
void setSelectionColor(const QColor &color)
Set color of selected vector features.
void setMapUpdateInterval(int timeMiliseconds)
Set how often map preview should be updated while it is being rendered (in milliseconds) ...
void layerStateChange()
This slot is connected to the visibility change of one or more layers.
void rendererJobFinished()
called when a renderer job has finished successfully or when it was cancelled
Enable vector simplification and other rendering optimizations.
Class that stores computed placement from labeling engine.
QgsRectangle extent() const
Returns the current zoom exent of the map canvas.
This class is responsible for keeping cache of rendered images of individual layers.
QgsMapCanvas(QWidget *parent=0, const char *name=0)
Constructor.
void setMapUnits(QGis::UnitType mapUnits)
Set map units (needed by project properties dialog)
void updateOverview()
bool isParallelRenderingEnabled() const
Check whether the layers are rendered in parallel or sequentially.
void connectNotify(const char *signal)
debugging member invoked when a connect() is made to this object
PreviewMode mode() const
Returns the mode used for the preview effect.
Q_DECL_DEPRECATED void setDirty(bool _dirty)
Flag the canvas as dirty and needed a refresh.
static void setSpecialColumn(const QString &name, QVariant value)
Assign a special column.
QPoint rubberStartPoint
Beginning point of a rubber band.
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
Class that does synchronization between QgsMapCanvas and its associated QgsMapRenderer: ...
Definition: qgsmapcanvas.h:644
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:204
virtual QgsLabelingResults * takeLabelingResults()=0
Get pointer to internal labeling engine (in order to get access to the results)
void zoomIn()
Zoom in with fixed factor.
virtual bool isEditable() const
Returns true if the provider is in editing mode.
QGis::UnitType mapUnits() const
Represents a vector layer which manages a vector based data sets.
virtual void updatePosition()
called on changed extent or resize event to update position of the item
int selectedFeatureCount()
The number of features that are selected in this layer.
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:189
QList< QgsRectangle > mLastExtent
recently used extent
Definition: qgsmapcanvas.h:598
static QgsCRSCache * instance()
Definition: qgscrscache.cpp:85
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:214
QgsMapLayer * layer()
Definition: qgsmapcanvas.h:86
void extentsChanged()
Emitted when the extents of the map change.
int renderingTime() const
Find out how log it took to finish the job (in miliseconds)
std::auto_ptr< CanvasProperties > mCanvasProperties
Handle pattern for implementation object.
Definition: qgsmapcanvas.h:541
void mouseMoveEvent(QMouseEvent *e)
Overridden mouse move event.
bool mJobCancelled
Flag determining whether the active job has been cancelled.
Definition: qgsmapcanvas.h:614
QgsMapLayer * layer(int index)
return the map layer at position index in the layer stack
Q_DECL_DEPRECATED void updateMap()
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:164
void keyPressEvent(QKeyEvent *e)
Overridden key press event.
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:209
void dragEnterEvent(QDragEnterEvent *e)
Overridden drag enter event.
QgsPoint toMapPoint(double x, double y) const
void setCrsTransformEnabled(bool enabled)
sets whether to use projections for this layer set
void panActionEnd(QPoint releasePoint)
Ends pan action and redraws the canvas.
void mapUnitsChanged()
Emmitted when map units are changed.
QStringList layerSet() const
QgsRectangle fullExtent() const
Returns the combined exent for all layers on the map canvas.
void layersChanged()
Emitted when a new set of layers has been received.
QgsRectangle boundingBoxOfSelected()
Returns the bounding box of the selected features.
#define tr(sourceText)
void writeXML(QDomNode &theNode, QDomDocument &theDoc)
void mapToolSet(QgsMapTool *tool)
Emit map tool changed event.
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.