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