Quantum GIS API Documentation  1.8
src/gui/qgsmapoverviewcanvas.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                            qgsmapoverviewcanvas.cpp
00003                       Map canvas subclassed for overview
00004                               -------------------
00005     begin                : 09/14/2005
00006     copyright            : (C) 2005 by Martin Dobias
00007     email                : won.der at centrum.sk
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 
00019 #include "qgsmapcanvas.h"
00020 #include "qgsmaprenderer.h"
00021 #include "qgsmapoverviewcanvas.h"
00022 #include "qgsmaptopixel.h"
00023 
00024 #include <QPainter>
00025 #include <QPaintEvent>
00026 #include <QResizeEvent>
00027 #include <QMouseEvent>
00028 #include "qgslogger.h"
00029 #include <limits.h>
00030 
00032 class QgsPanningWidget : public QWidget
00033 {
00034   public:
00035     QgsPanningWidget( QWidget* parent )
00036         : QWidget( parent )
00037     {
00038       setObjectName( "panningWidget" );
00039       setMinimumSize( 5, 5 );
00040       setAttribute( Qt::WA_NoSystemBackground );
00041     }
00042 
00043     void resizeEvent( QResizeEvent* r )
00044     {
00045       QSize s = r->size();
00046       QRegion reg( 0, 0, s.width(), s.height() );
00047       QRegion reg2( 2, 2, s.width() - 4, s.height() - 4 );
00048       QRegion reg3 = reg.subtract( reg2 );
00049       setMask( reg3 );
00050     }
00051 
00052 
00053     void paintEvent( QPaintEvent* pe )
00054     {
00055       Q_UNUSED( pe );
00056 
00057       QRect r( QPoint( 0, 0 ), size() );
00058       QPainter p;
00059       p.begin( this );
00060       p.setPen( Qt::red );
00061       p.setBrush( Qt::red );
00062       p.drawRect( r );
00063       p.end();
00064     }
00065 
00066 };
00067 
00068 
00069 
00070 QgsMapOverviewCanvas::QgsMapOverviewCanvas( QWidget * parent, QgsMapCanvas* mapCanvas )
00071     : QWidget( parent ), mMapCanvas( mapCanvas )
00072 {
00073   setObjectName( "theOverviewCanvas" );
00074   mPanningWidget = new QgsPanningWidget( this );
00075 
00076   mMapRenderer = new QgsMapRenderer;
00077   mMapRenderer->enableOverviewMode();
00078 
00079   setBackgroundColor( palette().window().color() );
00080 }
00081 
00082 QgsMapOverviewCanvas::~QgsMapOverviewCanvas()
00083 {
00084   delete mMapRenderer;
00085 }
00086 
00087 void QgsMapOverviewCanvas::resizeEvent( QResizeEvent* e )
00088 {
00089   mNewSize = e->size();
00090 }
00091 
00092 void QgsMapOverviewCanvas::paintEvent( QPaintEvent* pe )
00093 {
00094   if ( mNewSize.isValid() )
00095   {
00096     mPixmap = QPixmap( mNewSize );
00097     mMapRenderer->setOutputSize( mNewSize, mPixmap.logicalDpiX() );
00098     mNewSize = QSize();
00099     refresh();
00100   }
00101 
00102   QPainter paint( this );
00103   paint.drawPixmap( pe->rect().topLeft(), mPixmap, pe->rect() );
00104 }
00105 
00106 
00107 void QgsMapOverviewCanvas::drawExtentRect()
00108 {
00109   const QgsRectangle& extent = mMapCanvas->extent();
00110 
00111   // show only when valid extent is set
00112   if ( extent.isEmpty() )
00113   {
00114     mPanningWidget->hide();
00115     return;
00116   }
00117 
00118   const QgsMapToPixel* cXf = mMapRenderer->coordinateTransform();
00119   QgsPoint ll( extent.xMinimum(), extent.yMinimum() );
00120   QgsPoint ur( extent.xMaximum(), extent.yMaximum() );
00121   if ( cXf )
00122   {
00123     // transform the points before drawing
00124     cXf->transform( &ll );
00125     cXf->transform( &ur );
00126   }
00127 
00128 #if 0
00129   // test whether panning widget should be drawn
00130   bool show = false;
00131   if ( ur.x() >= 0 && ur.x() < width() )
00132     show = true;
00133   if ( ll.x() >= 0 && ll.x() < width() )
00134     show = true;
00135   if ( ur.y() >= 0 && ur.y() < height() )
00136     show = true;
00137   if ( ll.y() >= 0 && ll.y() < height() )
00138     show = true;
00139   if ( !show )
00140   {
00141     QgsDebugMsg( "panning: extent out of overview area" );
00142     mPanningWidget->hide();
00143     return;
00144   }
00145 #endif
00146 
00147   // round values
00148   int x1 = static_cast<int>( ur.x() + 0.5 ), x2 = static_cast<int>( ll.x() + 0.5 );
00149   int y1 = static_cast<int>( ur.y() + 0.5 ), y2 = static_cast<int>( ll.y() + 0.5 );
00150 
00151   if ( x1 > x2 )
00152     std::swap( x1, x2 );
00153   if ( y1 > y2 )
00154     std::swap( y1, y2 );
00155 
00156 #ifdef Q_WS_MAC
00157   // setGeometry (Qt 4.2) is causing Mac window corruption (decorations
00158   // are drawn at odd locations) if both coords are at limit. This may
00159   // have something to do with Qt calculating dimensions as x2 - x1 + 1.
00160   // (INT_MAX - INT_MIN + 1 is UINT_MAX + 1)
00161   if ( x1 == INT_MIN && x2 == INT_MAX )
00162     x1 += 1;  // x2 -= 1 works too
00163   if ( y1 == INT_MIN && y2 == INT_MAX )
00164     y1 += 1;
00165 #endif
00166 
00167   QRect r( x1, y1, x2 - x1 + 1, y2 - y1 + 1 );
00168 
00169   // allow for 5 pixel minimum widget size
00170   if ( r.width() < 5 && x1 > INT_MIN + 2 ) // make sure no underflow occurs (2 is largest adjustment)
00171   {
00172     r.setX( r.x() - (( 5 - r.width() ) / 2 ) );  // adjust x  by 1/2 the difference of calculated and min. width
00173     r.setWidth( 5 );
00174   }
00175   if ( r.height() < 5 && y1 > INT_MIN + 2 )
00176   {
00177     r.setY( r.y() - (( 5 - r.height() ) / 2 ) );  // adjust y
00178     r.setHeight( 5 );
00179   }
00180 
00181   QgsDebugMsg( QString( "panning: extent to widget: [%1,%2] [%3x%4]" ).arg( x1 ).arg( y1 ).arg( r.width() ).arg( r.height() ) );
00182 
00183   mPanningWidget->setGeometry( r );
00184   mPanningWidget->show(); // show if hidden
00185 }
00186 
00187 
00188 void QgsMapOverviewCanvas::mousePressEvent( QMouseEvent * e )
00189 {
00190 //  if (mPanningWidget->isHidden())
00191 //    return;
00192 
00193   // set offset in panning widget if inside it
00194   // for better experience with panning :)
00195   if ( mPanningWidget->geometry().contains( e->pos() ) )
00196   {
00197     mPanningCursorOffset = e->pos() - mPanningWidget->pos();
00198   }
00199   else
00200   {
00201     // use center of the panning widget if outside
00202     QSize s = mPanningWidget->size();
00203     mPanningCursorOffset = QPoint( s.width() / 2, s.height() / 2 );
00204   }
00205   updatePanningWidget( e->pos() );
00206 }
00207 
00208 
00209 void QgsMapOverviewCanvas::mouseReleaseEvent( QMouseEvent * e )
00210 {
00211 //  if (mPanningWidget->isHidden())
00212 //    return;
00213 
00214   if ( e->button() == Qt::LeftButton )
00215   {
00216     // set new extent
00217     const QgsMapToPixel* cXf = mMapRenderer->coordinateTransform();
00218     QRect rect = mPanningWidget->geometry();
00219 
00220     QgsPoint center = cXf->toMapCoordinates( rect.center() );
00221     QgsRectangle oldExtent = mMapCanvas->extent();
00222     QgsRectangle ext;
00223     ext.setXMinimum( center.x() - oldExtent.width() / 2 );
00224     ext.setXMaximum( center.x() + oldExtent.width() / 2 );
00225     ext.setYMinimum( center.y() - oldExtent.height() / 2 );
00226     ext.setYMaximum( center.y() + oldExtent.height() / 2 );
00227 
00228     QgsDebugMsg( QString( "panning: new position: [%1,%2] [%3x%4]" ).arg( rect.left() ).arg( rect.top() ).arg( rect.width() ).arg( rect.height() ) );
00229 
00230     mMapCanvas->setExtent( ext );
00231     mMapCanvas->refresh();
00232   }
00233 }
00234 
00235 
00236 void QgsMapOverviewCanvas::mouseMoveEvent( QMouseEvent * e )
00237 {
00238   // move with panning widget if tracking cursor
00239   if (( e->buttons() & Qt::LeftButton ) == Qt::LeftButton )
00240   {
00241     updatePanningWidget( e->pos() );
00242   }
00243 }
00244 
00245 
00246 void QgsMapOverviewCanvas::updatePanningWidget( const QPoint& pos )
00247 {
00248 //  if (mPanningWidget->isHidden())
00249 //    return;
00250   mPanningWidget->move( pos.x() - mPanningCursorOffset.x(), pos.y() - mPanningCursorOffset.y() );
00251 }
00252 
00253 
00254 void QgsMapOverviewCanvas::refresh()
00255 {
00256   if ( mPixmap.isNull() || mPixmap.paintingActive() )
00257     return;
00258 
00259   mPixmap.fill( mBgColor ); //palette().color(backgroundRole());
00260 
00261   QPainter painter;
00262   painter.begin( &mPixmap );
00263 
00264   // antialiasing
00265   if ( mAntiAliasing )
00266     painter.setRenderHint( QPainter::Antialiasing );
00267 
00268   // render image
00269   mMapRenderer->render( &painter );
00270 
00271   painter.end();
00272 
00273   // schedule repaint
00274   update();
00275 
00276   // update panning widget
00277   drawExtentRect();
00278 }
00279 
00280 
00281 void QgsMapOverviewCanvas::setBackgroundColor( const QColor& color )
00282 {
00283   mBgColor = color;
00284 
00285   // set erase color
00286   QPalette palette;
00287   palette.setColor( backgroundRole(), color );
00288   setPalette( palette );
00289 }
00290 
00291 void QgsMapOverviewCanvas::setLayerSet( const QStringList& layerSet )
00292 {
00293   mMapRenderer->setLayerSet( layerSet );
00294 }
00295 
00296 void QgsMapOverviewCanvas::updateFullExtent( const QgsRectangle& rect )
00297 {
00298   mMapRenderer->setExtent( rect );
00299   drawExtentRect();
00300 }
00301 
00302 void QgsMapOverviewCanvas::hasCrsTransformEnabled( bool flag )
00303 {
00304   mMapRenderer->setProjectionsEnabled( flag );
00305 }
00306 
00307 void QgsMapOverviewCanvas::destinationSrsChanged()
00308 {
00309   const QgsCoordinateReferenceSystem& srs = mMapCanvas->mapRenderer()->destinationCrs();
00310   mMapRenderer->setDestinationCrs( srs );
00311 }
00312 
00313 QStringList& QgsMapOverviewCanvas::layerSet()
00314 {
00315   return mMapRenderer->layerSet();
00316 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines