예제 #1
0
void QgsAtlasComposition::updateAtlasMaps()
{
  //update atlas-enabled composer maps
  QList<QgsComposerMap*> maps;
  mComposition->composerItems( maps );
  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
  {
    QgsComposerMap* currentMap = ( *mit );
    if ( !currentMap->atlasDriven() )
    {
      continue;
    }

    currentMap->cache();
  }
}
예제 #2
0
QgsComposerMap* QgsAtlasComposition::composerMap() const
{
  //deprecated method. Until removed just return the first atlas-enabled composer map

  //build a list of composer maps
  QList<QgsComposerMap*> maps;
  mComposition->composerItems( maps );
  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
  {
    QgsComposerMap* currentMap = ( *mit );
    if ( currentMap->atlasDriven() )
    {
      return currentMap;
    }
  }

  return 0;
}
예제 #3
0
void QgsComposerItemWidget::on_mBackgroundColorButton_colorChanged( const QColor& newBackgroundColor )
{
  if ( !mItem )
  {
    return;
  }
  mItem->beginCommand( tr( "Background color changed" ) );
  mItem->setBackgroundColor( newBackgroundColor );

  //if the item is a composer map, we need to regenerate the map image
  //because it usually is cached
  QgsComposerMap* cm = dynamic_cast<QgsComposerMap *>( mItem );
  if ( cm )
  {
    cm->cache();
  }
  mItem->update();
  mItem->endCommand();
}
예제 #4
0
void QgsComposerItemWidget::on_mBackgroundGroupBox_toggled( bool state )
{
  if ( !mItem )
  {
    return;
  }

  mItem->beginCommand( tr( "Item background toggled" ) );
  mItem->setBackgroundEnabled( state );

  //if the item is a composer map, we need to regenerate the map image
  //because it usually is cached
  QgsComposerMap* cm = dynamic_cast<QgsComposerMap *>( mItem );
  if ( cm )
  {
    cm->cache();
  }

  mItem->update();
  mItem->endCommand();
}
예제 #5
0
void QgsAtlasComposition::readXML( const QDomElement& atlasElem, const QDomDocument& )
{
  mEnabled = atlasElem.attribute( "enabled", "false" ) == "true" ? true : false;
  emit toggled( mEnabled );
  if ( !mEnabled )
  {
    emit parameterChanged();
    return;
  }

  // look for stored layer name
  mCoverageLayer = 0;
  QMap<QString, QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers();
  for ( QMap<QString, QgsMapLayer*>::const_iterator it = layers.begin(); it != layers.end(); ++it )
  {
    if ( it.key() == atlasElem.attribute( "coverageLayer" ) )
    {
      mCoverageLayer = dynamic_cast<QgsVectorLayer*>( it.value() );
      break;
    }
  }
  //look for stored composer map, to upgrade pre 2.1 projects
  int composerMapNo = atlasElem.attribute( "composerMap", "-1" ).toInt();
  QgsComposerMap * composerMap = 0;
  if ( composerMapNo != -1 )
  {
    QList<QgsComposerMap*> maps;
    mComposition->composerItems( maps );
    for ( QList<QgsComposerMap*>::iterator it = maps.begin(); it != maps.end(); ++it )
    {
      if (( *it )->id() == composerMapNo )
      {
        composerMap = ( *it );
        composerMap->setAtlasDriven( true );
        break;
      }
    }
  }
  mHideCoverage = atlasElem.attribute( "hideCoverage", "false" ) == "true" ? true : false;

  //upgrade pre 2.1 projects
  double margin = atlasElem.attribute( "margin", "0.0" ).toDouble();
  if ( composerMap && margin != 0 )
  {
    composerMap->setAtlasMargin( margin );
  }
  bool fixedScale = atlasElem.attribute( "fixedScale", "false" ) == "true" ? true : false;
  if ( composerMap && fixedScale )
  {
    composerMap->setAtlasFixedScale( true );
  }

  mSingleFile = atlasElem.attribute( "singleFile", "false" ) == "true" ? true : false;
  mFilenamePattern = atlasElem.attribute( "filenamePattern", "" );

  mSortFeatures = atlasElem.attribute( "sortFeatures", "false" ) == "true" ? true : false;
  if ( mSortFeatures )
  {
    mSortKeyAttributeIdx = atlasElem.attribute( "sortKey", "0" ).toInt();
    mSortAscending = atlasElem.attribute( "sortAscending", "true" ) == "true" ? true : false;
  }
  mFilterFeatures = atlasElem.attribute( "filterFeatures", "false" ) == "true" ? true : false;
  if ( mFilterFeatures )
  {
    mFeatureFilter = atlasElem.attribute( "featureFilter", "" );
  }

  emit parameterChanged();
}
예제 #6
0
bool QgsAtlasComposition::prepareForFeature( const int featureI, const bool updateMaps )
{
  if ( !mCoverageLayer )
  {
    return false;
  }

  if ( mFeatureIds.isEmpty() )
  {
    emit statusMsgChanged( tr( "No matching atlas features" ) );
    return false;
  }

  if ( featureI >= mFeatureIds.size() )
  {
    return false;
  }

  mCurrentFeatureNo = featureI;

  // retrieve the next feature, based on its id
  mCoverageLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureIds[ featureI ].first ) ).nextFeature( mCurrentFeature );

  QgsExpressionContext expressionContext = createExpressionContext();

  // generate filename for current feature
  if ( !evalFeatureFilename( expressionContext ) )
  {
    //error evaluating filename
    return false;
  }

  mGeometryCache.clear();
  emit featureChanged( &mCurrentFeature );
  emit statusMsgChanged( QString( tr( "Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );

  if ( !mCurrentFeature.isValid() )
  {
    //bad feature
    return true;
  }

  if ( !updateMaps )
  {
    //nothing more to do
    return true;
  }

  //update composer maps

  //build a list of atlas-enabled composer maps
  QList<QgsComposerMap*> maps;
  QList<QgsComposerMap*> atlasMaps;
  mComposition->composerItems( maps );
  if ( maps.isEmpty() )
  {
    return true;
  }
  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
  {
    QgsComposerMap* currentMap = ( *mit );
    if ( !currentMap->atlasDriven() )
    {
      continue;
    }
    atlasMaps << currentMap;
  }

  if ( !atlasMaps.isEmpty() )
  {
    //clear the transformed bounds of the previous feature
    mTransformedFeatureBounds = QgsRectangle();

    // compute extent of current feature in the map CRS. This should be set on a per-atlas map basis,
    // but given that it's not currently possible to have maps with different CRSes we can just
    // calculate it once based on the first atlas maps' CRS.
    computeExtent( atlasMaps[0] );
  }

  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
  {
    if (( *mit )->atlasDriven() )
    {
      // map is atlas driven, so update it's bounds (causes a redraw)
      prepareMap( *mit );
    }
    else
    {
      // map is not atlas driven, so manually force a redraw (to reflect possibly atlas
      // dependent symbology)
      ( *mit )->cache();
    }
  }

  return true;
}
예제 #7
0
void QgsAtlasComposition::prepareForFeature( int featureI )
{
  if ( !mCoverageLayer )
  {
    return;
  }

  if ( mFeatureIds.size() == 0 )
  {
    emit statusMsgChanged( tr( "No matching atlas features" ) );
    return;
  }

  // retrieve the next feature, based on its id
  mCoverageLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureIds[ featureI ] ) ).nextFeature( mCurrentFeature );

  QgsExpression::setSpecialColumn( "$atlasfeatureid", mCurrentFeature.id() );
  QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *mCurrentFeature.geometry() ) );
  QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );

  // generate filename for current feature
  evalFeatureFilename();

  // evaluate label expressions
  QList<QgsComposerLabel*> labels;
  mComposition->composerItems( labels );
  for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
  {
    ( *lit )->setExpressionContext( &mCurrentFeature, mCoverageLayer );
  }

  // update shapes (in case they use data defined symbology with atlas properties)
  QList<QgsComposerShape*> shapes;
  mComposition->composerItems( shapes );
  for ( QList<QgsComposerShape*>::iterator lit = shapes.begin(); lit != shapes.end(); ++lit )
  {
    ( *lit )->update();
  }

  // update page background (in case it uses data defined symbology with atlas properties)
  QList<QgsPaperItem*> pages;
  mComposition->composerItems( pages );
  for ( QList<QgsPaperItem*>::iterator pageIt = pages.begin(); pageIt != pages.end(); ++pageIt )
  {
    ( *pageIt )->update();
  }

  emit statusMsgChanged( QString( tr( "Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );

  //update composer maps

  //build a list of atlas-enabled composer maps
  QList<QgsComposerMap*> maps;
  QList<QgsComposerMap*> atlasMaps;
  mComposition->composerItems( maps );
  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
  {
    QgsComposerMap* currentMap = ( *mit );
    if ( !currentMap->atlasDriven() )
    {
      continue;
    }
    atlasMaps << currentMap;
  }

  //clear the transformed bounds of the previous feature
  mTransformedFeatureBounds = QgsRectangle();

  if ( atlasMaps.isEmpty() )
  {
    //no atlas enabled maps
    return;
  }

  // compute extent of current feature in the map CRS. This should be set on a per-atlas map basis,
  // but given that it's not currently possible to have maps with different CRSes we can just
  // calculate it once based on the first atlas maps' CRS.
  computeExtent( atlasMaps[0] );

  //update atlas bounds of every atlas enabled composer map
  for ( QList<QgsComposerMap*>::iterator mit = atlasMaps.begin(); mit != atlasMaps.end(); ++mit )
  {
    prepareMap( *mit );
  }
}
예제 #8
0
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
{
  if ( !composition() )
  {
    return;
  }

  QPointF scenePoint = mapToScene( e->pos() );

  switch ( mCurrentTool )
  {
    case Select:
    {
      QGraphicsView::mouseReleaseEvent( e );
      break;
    }

    case MoveItemContent:
    {
      if ( mMoveContentItem )
      {
        //update map preview if composer map
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
        if ( composerMap )
        {
          composerMap->setOffset( 0, 0 );
        }

        double moveX = scenePoint.x() - mMoveContentStartPos.x();
        double moveY = scenePoint.y() - mMoveContentStartPos.y();

        composition()->beginCommand( mMoveContentItem, tr( "Move item content" ) );
        mMoveContentItem->moveContent( -moveX, -moveY );
        composition()->endCommand();
        mMoveContentItem = 0;
      }
      break;
    }
    case AddArrow:
      if ( composition() )
      {
        QPointF scenePoint = mapToScene( e->pos() );
        QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );
        QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandStartPos, QPointF( snappedScenePoint.x(), snappedScenePoint.y() ), composition() );
        composition()->addComposerArrow( composerArrow );
        scene()->removeItem( mRubberBandLineItem );
        delete mRubberBandLineItem;
        mRubberBandLineItem = 0;
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerArrow, tr( "Arrow added" ) );
      }
      break;

    case AddShape:
      if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
      {
        scene()->removeItem( mRubberBandItem );
        delete mRubberBandItem;
        mRubberBandItem = 0;
        return;
      }
      if ( composition() )
      {
        QgsComposerShape* composerShape = new QgsComposerShape( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height(), composition() );
        composition()->addComposerShape( composerShape );
        scene()->removeItem( mRubberBandItem );
        delete mRubberBandItem;
        mRubberBandItem = 0;
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerShape, tr( "Shape added" ) );
      }
      break;

    case AddMap:
      if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
      {
        if ( mRubberBandItem )
        {
          scene()->removeItem( mRubberBandItem );
          delete mRubberBandItem;
          mRubberBandItem = 0;
        }
        return;
      }
      if ( composition() )
      {
        QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
        composition()->addComposerMap( composerMap );
        scene()->removeItem( mRubberBandItem );
        delete mRubberBandItem;
        mRubberBandItem = 0;
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) );
      }
      break;

    default:
      break;
  }
}
예제 #9
0
void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
{
  if ( !composition() )
  {
    return;
  }

  if ( e->buttons() == Qt::NoButton )
  {
    if ( mCurrentTool == Select )
    {
      QGraphicsView::mouseMoveEvent( e );
    }
  }
  else
  {
    QPointF scenePoint = mapToScene( e->pos() );

    switch ( mCurrentTool )
    {
      case Select:
        QGraphicsView::mouseMoveEvent( e );
        break;

      case AddArrow:
      {
        if ( mRubberBandLineItem )
        {
          mRubberBandLineItem->setLine( mRubberBandStartPos.x(), mRubberBandStartPos.y(),  scenePoint.x(),  scenePoint.y() );
        }
        break;
      }

      case AddMap:
      case AddShape:
        //adjust rubber band item
      {
        double x = 0;
        double y = 0;
        double width = 0;
        double height = 0;

        double dx = scenePoint.x() - mRubberBandStartPos.x();
        double dy = scenePoint.y() - mRubberBandStartPos.y();

        if ( dx < 0 )
        {
          x = scenePoint.x();
          width = -dx;
        }
        else
        {
          x = mRubberBandStartPos.x();
          width = dx;
        }

        if ( dy < 0 )
        {
          y = scenePoint.y();
          height = -dy;
        }
        else
        {
          y = mRubberBandStartPos.y();
          height = dy;
        }

        if ( mRubberBandItem )
        {
          mRubberBandItem->setRect( 0, 0, width, height );
          QTransform t;
          t.translate( x, y );
          mRubberBandItem->setTransform( t );
        }
        break;
      }

      case MoveItemContent:
      {
        //update map preview if composer map
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
        if ( composerMap )
        {
          composerMap->setOffset( scenePoint.x() - mMoveContentStartPos.x(), scenePoint.y() - mMoveContentStartPos.y() );
          composerMap->update();
        }
        break;
      }
      default:
        break;
    }
  }
}
예제 #10
0
void QgsAtlasComposition::readXML( const QDomElement& atlasElem, const QDomDocument& )
{
  mEnabled = atlasElem.attribute( "enabled", "false" ) == "true" ? true : false;
  emit toggled( mEnabled );
  if ( !mEnabled )
  {
    emit parameterChanged();
    return;
  }

  // look for stored layer name
  mCoverageLayer = 0;
  QMap<QString, QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers();
  for ( QMap<QString, QgsMapLayer*>::const_iterator it = layers.begin(); it != layers.end(); ++it )
  {
    if ( it.key() == atlasElem.attribute( "coverageLayer" ) )
    {
      mCoverageLayer = dynamic_cast<QgsVectorLayer*>( it.value() );
      break;
    }
  }
  //look for stored composer map, to upgrade pre 2.1 projects
  int composerMapNo = atlasElem.attribute( "composerMap", "-1" ).toInt();
  QgsComposerMap * composerMap = 0;
  if ( composerMapNo != -1 )
  {
    QList<QgsComposerMap*> maps;
    mComposition->composerItems( maps );
    for ( QList<QgsComposerMap*>::iterator it = maps.begin(); it != maps.end(); ++it )
    {
      if (( *it )->id() == composerMapNo )
      {
        composerMap = ( *it );
        composerMap->setAtlasDriven( true );
        break;
      }
    }
  }
  mHideCoverage = atlasElem.attribute( "hideCoverage", "false" ) == "true" ? true : false;

  //upgrade pre 2.1 projects
  double margin = atlasElem.attribute( "margin", "0.0" ).toDouble();
  if ( composerMap && margin != 0 )
  {
    composerMap->setAtlasMargin( margin );
  }
  bool fixedScale = atlasElem.attribute( "fixedScale", "false" ) == "true" ? true : false;
  if ( composerMap && fixedScale )
  {
    composerMap->setAtlasScalingMode( QgsComposerMap::Fixed );
  }

  mSingleFile = atlasElem.attribute( "singleFile", "false" ) == "true" ? true : false;
  mFilenamePattern = atlasElem.attribute( "filenamePattern", "" );

  mSortFeatures = atlasElem.attribute( "sortFeatures", "false" ) == "true" ? true : false;
  if ( mSortFeatures )
  {
    mSortKeyAttributeName = atlasElem.attribute( "sortKey", "" );
    // since 2.3, the field name is saved instead of the field index
    // following code keeps compatibility with version 2.2 projects
    // to be removed in QGIS 3.0
    bool isIndex;
    int idx = mSortKeyAttributeName.toInt( &isIndex );
    if ( isIndex && mCoverageLayer )
    {
      const QgsFields fields = mCoverageLayer->pendingFields();
      if ( idx >= 0 && idx < fields.count() )
      {
        mSortKeyAttributeName = fields[idx].name();
      }
    }
    mSortAscending = atlasElem.attribute( "sortAscending", "true" ) == "true" ? true : false;
  }
  mFilterFeatures = atlasElem.attribute( "filterFeatures", "false" ) == "true" ? true : false;
  if ( mFilterFeatures )
  {
    mFeatureFilter = atlasElem.attribute( "featureFilter", "" );
  }

  emit parameterChanged();
}
예제 #11
0
QgsComposition* QgsConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
{
  QList<QgsComposerMap*> composerMaps;
  QList<QgsComposerLabel*> composerLabels;

  QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLabels );
  if ( !c )
  {
    return 0;
  }

  QMap< QString, QString >::const_iterator dpiIt = parameterMap.find( "DPI" );
  if ( dpiIt != parameterMap.constEnd() )
  {
    c->setPrintResolution( dpiIt.value().toInt() );
  }

  //replace composer map parameters
  QList<QgsComposerMap*>::iterator mapIt = composerMaps.begin();
  QgsComposerMap* currentMap = 0;
  for ( ; mapIt != composerMaps.end(); ++mapIt )
  {
    currentMap = *mapIt;
    if ( !currentMap )
    {
      continue;
    }

    QString mapId = "MAP" + QString::number( currentMap->id() );
    QMap< QString, QString >::const_iterator extentIt = parameterMap.find( mapId + ":EXTENT" );
    if ( extentIt == parameterMap.constEnd() ) //map extent is mandatory
    {
      //remove map from composition if not referenced by the request
      c->removeItem( *mapIt ); delete( *mapIt ); continue;
    }

    QStringList coordList = extentIt.value().split( "," );
    if ( coordList.size() < 4 )
    {
      c->removeItem( *mapIt ); delete( *mapIt ); continue; //need at least four coordinates
    }

    bool xMinOk, yMinOk, xMaxOk, yMaxOk;
    double xmin = coordList.at( 0 ).toDouble( &xMinOk );
    double ymin = coordList.at( 1 ).toDouble( &yMinOk );
    double xmax = coordList.at( 2 ).toDouble( &xMaxOk );
    double ymax = coordList.at( 3 ).toDouble( &yMaxOk );
    if ( !xMinOk || !yMinOk || !xMaxOk || !yMaxOk )
    {
      c->removeItem( *mapIt ); delete( *mapIt ); continue;
    }

    //Change x- and y- of extent for WMS 1.3.0 and geographic coordinate systems
    QMap<QString, QString>::const_iterator versionIt = parameterMap.find( "VERSION" );
    if ( versionIt != parameterMap.end() )
    {
      if ( mapRenderer && versionIt.value() == "1.3.0" && mapRenderer->destinationCrs().geographicFlag() )
      {
        //switch coordinates of extent
        double tmp;
        tmp = xmin;
        xmin = ymin; ymin = tmp;
        tmp = xmax;
        xmax = ymax; ymax = tmp;
      }
    }
    currentMap->setNewExtent( QgsRectangle( xmin, ymin, xmax, ymax ) );

    //scale
    QMap< QString, QString >::const_iterator scaleIt = parameterMap.find( mapId + ":SCALE" );
    if ( scaleIt != parameterMap.constEnd() )
    {
      bool scaleOk;
      double scale = scaleIt->toDouble( &scaleOk );
      if ( scaleOk )
      {
        currentMap->setNewScale( scale );
      }
    }

    //rotation
    QMap< QString, QString >::const_iterator rotationIt = parameterMap.find( mapId + ":ROTATION" );
    if ( rotationIt != parameterMap.constEnd() )
    {
      bool rotationOk;
      double rotation = rotationIt->toDouble( &rotationOk );
      if ( rotationOk )
      {
        currentMap->setMapRotation( rotation );
      }
    }

    //layers / styles
    QMap< QString, QString >::const_iterator layersIt = parameterMap.find( mapId + ":LAYERS" );
    QMap< QString, QString >::const_iterator stylesIt = parameterMap.find( mapId + ":STYLES" );
    if ( layersIt != parameterMap.constEnd() )
    {
      QStringList layerSet;
      QStringList wmsLayerList = layersIt->split( "," );
      QStringList wmsStyleList;

      if ( stylesIt != parameterMap.constEnd() )
      {
        wmsStyleList = stylesIt->split( "," );
      }
      for ( int i = 0; i < wmsLayerList.size(); ++i )
      {
        QString styleName;
        if ( wmsStyleList.size() > i )
        {
          styleName = wmsStyleList.at( i );
        }
        QList<QgsMapLayer*> layerList = mapLayerFromStyle( wmsLayerList.at( i ), styleName );
        QList<QgsMapLayer*>::const_iterator mapIdIt = layerList.constBegin();
        for ( ; mapIdIt != layerList.constEnd(); ++mapIdIt )
        {
          if ( *mapIdIt )
          {
            layerSet.push_back(( *mapIdIt )->id() );
          }
        }
      }

      currentMap->setLayerSet( layerSet );
      currentMap->setKeepLayerSet( true );
    }

    //grid space x / y
    QMap< QString, QString >::const_iterator gridSpaceXIt = parameterMap.find( mapId + ":GRID_INTERVAL_X" );
    if ( gridSpaceXIt != parameterMap.constEnd() )
    {
      bool intervalXOk;
      double intervalX = gridSpaceXIt->toDouble( &intervalXOk );
      if ( intervalXOk )
      {
        currentMap->setGridIntervalX( intervalX );
      }
    }
    else
    {
      currentMap->setGridIntervalX( 0 );
    }

    QMap< QString, QString >::const_iterator gridSpaceYIt = parameterMap.find( mapId + ":GRID_INTERVAL_Y" );
    if ( gridSpaceYIt != parameterMap.constEnd() )
    {
      bool intervalYOk;
      double intervalY = gridSpaceYIt->toDouble( &intervalYOk );
      if ( intervalYOk )
      {
        currentMap->setGridIntervalY( intervalY );
      }
    }
    else
    {
      currentMap->setGridIntervalY( 0 );
    }
  }

  //replace label text
  QList<QgsComposerLabel*>::const_iterator labelIt = composerLabels.constBegin();
  QgsComposerLabel* currentLabel = 0;

  for ( ; labelIt != composerLabels.constEnd(); ++labelIt )
  {
    currentLabel = *labelIt;
    QMap< QString, QString >::const_iterator titleIt = parameterMap.find( currentLabel->id().toUpper() );
    if ( titleIt == parameterMap.constEnd() )
    {
      //remove exported labels not referenced in the request
      if ( !currentLabel->id().isEmpty() )
      {
        c->removeItem( currentLabel );
        delete( currentLabel );
      }
      continue;
    }

    if ( !titleIt.key().isEmpty() ) //no label text replacement with empty key
    {
      currentLabel->setText( titleIt.value() );
      currentLabel->adjustSizeToText();
    }
  }

  return c;
}
예제 #12
0
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
{
  if ( !composition() )
  {
    return;
  }

  QPoint mousePressStopPoint = e->pos();
  int diffX = mousePressStopPoint.x() - mMousePressStartPos.x();
  int diffY = mousePressStopPoint.y() - mMousePressStartPos.y();

  //was this just a click? or a click and drag?
  bool clickOnly = false;
  if ( qAbs( diffX ) < 2 && qAbs( diffY ) < 2 )
  {
    clickOnly = true;
  }

  QPointF scenePoint = mapToScene( e->pos() );

  if ( mPanning )
  {
    mPanning = false;

    if ( clickOnly && e->button() == Qt::MidButton )
    {
      //middle mouse button click = recenter on point

      //get current visible part of scene
      QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
      QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );
      visibleRect.scale( 1, scenePoint.x(), scenePoint.y() );
      QRectF boundsRect = visibleRect.toRectF();

      //zoom view to fit desired bounds
      fitInView( boundsRect, Qt::KeepAspectRatio );
    }

    //set new cursor
    if ( mCurrentTool == Pan )
    {
      viewport()->setCursor( Qt::OpenHandCursor );
    }
    else
    {
      if ( composition() )
      {
        //allow composer items to change cursor
        composition()->setPreventCursorChange( false );
      }
      viewport()->setCursor( Qt::ArrowCursor );
    }
  }

  if ( mMarqueeSelect )
  {
    endMarqueeSelect( e );
    return;
  }

  switch ( mCurrentTool )
  {
    case Select:
    {
      QGraphicsView::mouseReleaseEvent( e );
      break;
    }

    case Zoom:
    {
      if ( mMarqueeZoom )
      {
        endMarqueeZoom( e );
      }
      break;
    }

    case MoveItemContent:
    {
      if ( mMoveContentItem )
      {
        //update map preview if composer map
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
        if ( composerMap )
        {
          composerMap->setOffset( 0, 0 );
        }

        double moveX = scenePoint.x() - mMoveContentStartPos.x();
        double moveY = scenePoint.y() - mMoveContentStartPos.y();

        composition()->beginCommand( mMoveContentItem, tr( "Move item content" ) );
        mMoveContentItem->moveContent( -moveX, -moveY );
        composition()->endCommand();
        mMoveContentItem = 0;
      }
      break;
    }
    case AddArrow:
      if ( composition() )
      {
        QPointF scenePoint = mapToScene( e->pos() );
        QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );
        QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandStartPos, QPointF( snappedScenePoint.x(), snappedScenePoint.y() ), composition() );
        composition()->addComposerArrow( composerArrow );

        composition()->clearSelection();
        composerArrow->setSelected( true );
        emit selectedItemChanged( composerArrow );

        scene()->removeItem( mRubberBandLineItem );
        delete mRubberBandLineItem;
        mRubberBandLineItem = 0;
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerArrow, tr( "Arrow added" ) );
      }
      break;

    case AddRectangle:
    case AddTriangle:
    case AddEllipse:
      addShape( mCurrentTool );
      break;

    case AddMap:
      if ( !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) )
      {
        removeRubberBand();
        return;
      }
      if ( composition() )
      {
        QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
        composition()->addComposerMap( composerMap );

        composition()->clearSelection();
        composerMap->setSelected( true );
        emit selectedItemChanged( composerMap );

        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) );
      }
      break;

    case AddHtml:
      if ( composition() )
      {
        QgsComposerHtml* composerHtml = new QgsComposerHtml( composition(), true );
        QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Added,
            composerHtml, composition(), tr( "Html item added" ) );
        composition()->undoStack()->push( command );
        QgsComposerFrame* frame = new QgsComposerFrame( composition(), composerHtml, mRubberBandItem->transform().dx(),
            mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(),
            mRubberBandItem->rect().height() );
        composition()->beginMultiFrameCommand( composerHtml, tr( "Html frame added" ) );
        composerHtml->addFrame( frame );
        composition()->endMultiFrameCommand();

        composition()->clearSelection();
        frame->setSelected( true );
        emit selectedItemChanged( frame );

        removeRubberBand();
        emit actionFinished();
      }
    default:
      break;
  }
}
예제 #13
0
bool QgsAtlasComposition::prepareForFeature( int featureI )
{
  if ( !mCoverageLayer )
  {
    return false;
  }

  if ( mFeatureIds.size() == 0 )
  {
    emit statusMsgChanged( tr( "No matching atlas features" ) );
    return false;
  }

  mCurrentFeatureNo = featureI;

  // retrieve the next feature, based on its id
  mCoverageLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureIds[ featureI ] ) ).nextFeature( mCurrentFeature );

  QgsExpression::setSpecialColumn( "$atlasfeatureid", mCurrentFeature.id() );
  QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *mCurrentFeature.geometry() ) );
  QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( mCurrentFeature ) );
  QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );

  // generate filename for current feature
  if ( !evalFeatureFilename() )
  {
    //error evaluating filename
    return false;
  }

  emit featureChanged( &mCurrentFeature );
  emit statusMsgChanged( QString( tr( "Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );

  //update composer maps

  //build a list of atlas-enabled composer maps
  QList<QgsComposerMap*> maps;
  QList<QgsComposerMap*> atlasMaps;
  mComposition->composerItems( maps );
  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
  {
    QgsComposerMap* currentMap = ( *mit );
    if ( !currentMap->atlasDriven() )
    {
      continue;
    }
    atlasMaps << currentMap;
  }

  //clear the transformed bounds of the previous feature
  mTransformedFeatureBounds = QgsRectangle();

  if ( atlasMaps.isEmpty() )
  {
    //no atlas enabled maps
    return true;
  }

  // compute extent of current feature in the map CRS. This should be set on a per-atlas map basis,
  // but given that it's not currently possible to have maps with different CRSes we can just
  // calculate it once based on the first atlas maps' CRS.
  computeExtent( atlasMaps[0] );

  //update atlas bounds of every atlas enabled composer map
  for ( QList<QgsComposerMap*>::iterator mit = atlasMaps.begin(); mit != atlasMaps.end(); ++mit )
  {
    prepareMap( *mit );
  }

  return true;
}
예제 #14
0
void QgsComposerView::keyPressEvent( QKeyEvent * e )
{
  if ( e->key() == Qt::Key_Shift )
  {
    mShiftKeyPressed = true;
  }

  if ( !composition() )
  {
    return;
  }

  QList<QgsComposerItem*> composerItemList = composition()->selectedComposerItems();
  QList<QgsComposerItem*>::iterator itemIt = composerItemList.begin();

  //delete selected items
  if ( e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace )
  {
    for ( ; itemIt != composerItemList.end(); ++itemIt )
    {
      QgsComposerMap* map = dynamic_cast<QgsComposerMap *>( *itemIt );
      if ( !map || !map->isDrawing() ) //don't delete a composer map while it draws
      {
        composition()->removeItem( *itemIt );
        QgsComposerItemGroup* itemGroup = dynamic_cast<QgsComposerItemGroup*>( *itemIt );
        if ( itemGroup && composition() )
        {
          //add add/remove item command for every item in the group
          QUndoCommand* parentCommand = new QUndoCommand( tr( "Remove item group" ) );

          QSet<QgsComposerItem*> groupedItems = itemGroup->items();
          QSet<QgsComposerItem*>::iterator it = groupedItems.begin();
          for ( ; it != groupedItems.end(); ++it )
          {
            QgsAddRemoveItemCommand* subcommand = new QgsAddRemoveItemCommand( QgsAddRemoveItemCommand::Removed, *it, composition(), "", parentCommand );
            connectAddRemoveCommandSignals( subcommand );
            emit itemRemoved( *it );
          }

          composition()->undoStack()->push( parentCommand );
          delete itemGroup;
          emit itemRemoved( itemGroup );
        }
        else
        {
          emit itemRemoved( *itemIt );
          pushAddRemoveCommand( *itemIt, tr( "Item deleted" ), QgsAddRemoveItemCommand::Removed );
        }
      }
    }
  }

  else if ( e->key() == Qt::Key_Left )
  {
    for ( ; itemIt != composerItemList.end(); ++itemIt )
    {
      ( *itemIt )->move( -1.0, 0.0 );
    }
  }
  else if ( e->key() == Qt::Key_Right )
  {
    for ( ; itemIt != composerItemList.end(); ++itemIt )
    {
      ( *itemIt )->move( 1.0, 0.0 );
    }
  }
  else if ( e->key() == Qt::Key_Down )
  {
    for ( ; itemIt != composerItemList.end(); ++itemIt )
    {
      ( *itemIt )->move( 0.0, 1.0 );
    }
  }
  else if ( e->key() == Qt::Key_Up )
  {
    for ( ; itemIt != composerItemList.end(); ++itemIt )
    {
      ( *itemIt )->move( 0.0, -1.0 );
    }
  }
}
예제 #15
0
void QgsAtlasComposition::prepareForFeature( int featureI )
{
  if ( !mCoverageLayer )
  {
    return;
  }

  if ( mFeatureIds.size() == 0 )
  {
    emit statusMsgChanged( tr( "No matching atlas features" ) );
    return;
  }

  // retrieve the next feature, based on its id
  mCoverageLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureIds[ featureI ] ) ).nextFeature( mCurrentFeature );

  QgsExpression::setSpecialColumn( "$atlasfeatureid", mCurrentFeature.id() );
  QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *mCurrentFeature.geometry() ) );
  QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );

  // generate filename for current feature
  evalFeatureFilename();

  // evaluate label expressions
  QList<QgsComposerLabel*> labels;
  mComposition->composerItems( labels );
  for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
  {
    ( *lit )->setExpressionContext( &mCurrentFeature, mCoverageLayer );
  }

  // update shapes (in case they use data defined symbology with atlas properties)
  QList<QgsComposerShape*> shapes;
  mComposition->composerItems( shapes );
  for ( QList<QgsComposerShape*>::iterator lit = shapes.begin(); lit != shapes.end(); ++lit )
  {
    ( *lit )->update();
  }

  // update page background (in case it uses data defined symbology with atlas properties)
  QList<QgsPaperItem*> pages;
  mComposition->composerItems( pages );
  for ( QList<QgsPaperItem*>::iterator pageIt = pages.begin(); pageIt != pages.end(); ++pageIt )
  {
    ( *pageIt )->update();
  }

  emit statusMsgChanged( QString( tr( "Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );

  //update composer maps

  //build a list of atlas-enabled composer maps
  QList<QgsComposerMap*> maps;
  QList<QgsComposerMap*> atlasMaps;
  mComposition->composerItems( maps );
  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
  {
    QgsComposerMap* currentMap = ( *mit );
    if ( !currentMap->atlasDriven() )
    {
      continue;
    }
    atlasMaps << currentMap;
  }

  if ( atlasMaps.isEmpty() )
  {
    //no atlas enabled maps
    return;
  }

  //
  // compute the new extent
  // keep the original aspect ratio
  // and apply a margin

  const QgsCoordinateReferenceSystem& coverage_crs = mCoverageLayer->crs();
  // transformation needed for feature geometries. This should be set on a per-atlas map basis,
  // but given that it's not currently possible to have maps with different CRSes we can just
  // calculate it once based on the first atlas maps' CRS.
  const QgsCoordinateReferenceSystem& destination_crs = atlasMaps[0]->mapRenderer()->destinationCrs();
  mTransform.setSourceCrs( coverage_crs );
  mTransform.setDestCRS( destination_crs );

  // QgsGeometry::boundingBox is expressed in the geometry"s native CRS
  // We have to transform the grometry to the destination CRS and ask for the bounding box
  // Note: we cannot directly take the transformation of the bounding box, since transformations are not linear

  QgsGeometry tgeom( *mCurrentFeature.geometry() );
  tgeom.transform( mTransform );
  mTransformedFeatureBounds = tgeom.boundingBox();

  //update atlas bounds of every atlas enabled composer map
  for ( QList<QgsComposerMap*>::iterator mit = atlasMaps.begin(); mit != atlasMaps.end(); ++mit )
  {
    prepareMap( *mit );
  }
}
예제 #16
0
QgsComposition* QgsProjectParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList ) const
{
  //Create composition from xml
  QDomElement composerElem = composerByName( composerTemplate );
  if ( composerElem.isNull() )
  {
    throw QgsMapServiceException( "Error", "Composer template not found" );
  }

  QDomElement compositionElem = composerElem.firstChildElement( "Composition" );
  if ( compositionElem.isNull() )
  {
    return 0;
  }

  QgsComposition* composition = new QgsComposition( mapRenderer ); //set resolution, paper size from composer element attributes
  if ( !composition->readXML( compositionElem, *mXMLDoc ) )
  {
    delete composition;
    return 0;
  }

  //go through all the item elements and add them to the composition (and to the lists)
  QDomNodeList itemNodes = composerElem.childNodes();
  for ( int i = 0; i < itemNodes.size(); ++i )
  {
    QDomElement currentElem = itemNodes.at( i ).toElement();
    QString elemName = currentElem.tagName();
    if ( elemName == "ComposerMap" )
    {
      QgsComposerMap* map = new QgsComposerMap( composition );
      map->readXML( currentElem, *mXMLDoc );
      composition->addItem( map );
      mapList.push_back( map );
    }
    else if ( elemName == "ComposerLabel" )
    {
      QgsComposerLabel* label = new QgsComposerLabel( composition );
      label->readXML( currentElem, *mXMLDoc );
      composition->addItem( label );
      labelList.push_back( label );
    }
    else if ( elemName == "ComposerLegend" )
    {
      //legend needs to be loaded indirectly to have generic content
      //and to avoid usage of x-server with pixmap icons

      //read full legend from xml
      QgsComposerLegend* legend = new QgsComposerLegend( composition );
      legend->readXML( currentElem, *mXMLDoc );

      //dynamic legend (would be interesting in case of layers dynamically defined in SLD)
      //legend->_readXML( currentElem.firstChildElement( "ComposerItem" ), *mXMLDoc );
      //legend->updateLegend();
      composition->addItem( legend );
    }
    else if ( elemName == "ComposerShape" )
    {
      QgsComposerShape* shape = new QgsComposerShape( composition );
      shape->readXML( currentElem, *mXMLDoc );
      composition->addItem( shape );
    }
    else if ( elemName == "ComposerArrow" )
    {
      QgsComposerArrow* arrow = new QgsComposerArrow( composition );
      arrow->readXML( currentElem, *mXMLDoc );
      composition->addItem( arrow );
    }
    else if ( elemName == "ComposerAttributeTable" )
    {
      QgsComposerAttributeTable* table = new QgsComposerAttributeTable( composition );
      table->readXML( currentElem, *mXMLDoc );
      composition->addItem( table );
    }
  }

  //scalebars and pictures need to be loaded after the maps to receive the correct size / rotation
  for ( int i = 0; i < itemNodes.size(); ++i )
  {
    QDomElement currentElem = itemNodes.at( i ).toElement();
    QString elemName = currentElem.tagName();
    if ( elemName == "ComposerPicture" )
    {
      QgsComposerPicture* picture = new QgsComposerPicture( composition );
      picture->readXML( currentElem, *mXMLDoc );
      //qgis mapserver needs an absolute file path
      picture->setPictureFile( convertToAbsolutePath( picture->pictureFile() ) );
      composition->addItem( picture );
    }
    else if ( elemName == "ComposerScaleBar" )
    {
      QgsComposerScaleBar* bar = new QgsComposerScaleBar( composition );
      bar->readXML( currentElem, *mXMLDoc );
      composition->addItem( bar );
    }
  }

  return composition;
}
예제 #17
0
void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocument& doc, QMap< QgsComposerMap*, int >* mapsToRestore,
                                      bool addUndoCommands, QPointF* pos )
{
  QDomNodeList composerLabelList = elem.elementsByTagName( "ComposerLabel" );
  for ( int i = 0; i < composerLabelList.size(); ++i )
  {
    QDomElement currentComposerLabelElem = composerLabelList.at( i ).toElement();
    QgsComposerLabel* newLabel = new QgsComposerLabel( this );
    newLabel->readXML( currentComposerLabelElem, doc );
    if ( pos )
    {
      newLabel->setItemPosition( pos->x(), pos->y() );
    }
    addComposerLabel( newLabel );
    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newLabel, tr( "Label added" ) );
    }
  }
  // map
  QDomNodeList composerMapList = elem.elementsByTagName( "ComposerMap" );
  for ( int i = 0; i < composerMapList.size(); ++i )
  {
    QDomElement currentComposerMapElem = composerMapList.at( i ).toElement();
    QgsComposerMap* newMap = new QgsComposerMap( this );
    newMap->readXML( currentComposerMapElem, doc );
    newMap->assignFreeId();

    if ( mapsToRestore )
    {
      mapsToRestore->insert( newMap, ( int )( newMap->previewMode() ) );
      newMap->setPreviewMode( QgsComposerMap::Rectangle );
    }
    addComposerMap( newMap, false );

    if ( pos )
    {
      newMap->setItemPosition( pos->x(), pos->y() );
    }

    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newMap, tr( "Map added" ) );
    }
  }
  // arrow
  QDomNodeList composerArrowList = elem.elementsByTagName( "ComposerArrow" );
  for ( int i = 0; i < composerArrowList.size(); ++i )
  {
    QDomElement currentComposerArrowElem = composerArrowList.at( i ).toElement();
    QgsComposerArrow* newArrow = new QgsComposerArrow( this );
    newArrow->readXML( currentComposerArrowElem, doc );
    if ( pos )
    {
      newArrow->setItemPosition( pos->x(), pos->y() );
    }
    addComposerArrow( newArrow );
    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newArrow, tr( "Arrow added" ) );
    }
  }
  // scalebar
  QDomNodeList composerScaleBarList = elem.elementsByTagName( "ComposerScaleBar" );
  for ( int i = 0; i < composerScaleBarList.size(); ++i )
  {
    QDomElement currentComposerScaleBarElem = composerScaleBarList.at( i ).toElement();
    QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( this );
    newScaleBar->readXML( currentComposerScaleBarElem, doc );
    if ( pos )
    {
      newScaleBar->setItemPosition( pos->x(), pos->y() );
    }
    addComposerScaleBar( newScaleBar );
    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newScaleBar, tr( "Scale bar added" ) );
    }
  }
  // shape
  QDomNodeList composerShapeList = elem.elementsByTagName( "ComposerShape" );
  for ( int i = 0; i < composerShapeList.size(); ++i )
  {
    QDomElement currentComposerShapeElem = composerShapeList.at( i ).toElement();
    QgsComposerShape* newShape = new QgsComposerShape( this );
    newShape->readXML( currentComposerShapeElem, doc );
    if ( pos )
    {
      newShape->setItemPosition( pos->x(), pos->y() );
    }
    addComposerShape( newShape );
    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newShape, tr( "Shape added" ) );
    }
  }
  // picture
  QDomNodeList composerPictureList = elem.elementsByTagName( "ComposerPicture" );
  for ( int i = 0; i < composerPictureList.size(); ++i )
  {
    QDomElement currentComposerPictureElem = composerPictureList.at( i ).toElement();
    QgsComposerPicture* newPicture = new QgsComposerPicture( this );
    newPicture->readXML( currentComposerPictureElem, doc );
    if ( pos )
    {
      newPicture->setItemPosition( pos->x(), pos->y() );
    }
    addComposerPicture( newPicture );
    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newPicture, tr( "Picture added" ) );
    }
  }
  // legend
  QDomNodeList composerLegendList = elem.elementsByTagName( "ComposerLegend" );
  for ( int i = 0; i < composerLegendList.size(); ++i )
  {
    QDomElement currentComposerLegendElem = composerLegendList.at( i ).toElement();
    QgsComposerLegend* newLegend = new QgsComposerLegend( this );
    newLegend->readXML( currentComposerLegendElem, doc );
    if ( pos )
    {
      newLegend->setItemPosition( pos->x(), pos->y() );
    }
    addComposerLegend( newLegend );
    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newLegend, tr( "Legend added" ) );
    }
  }
  // table
  QDomNodeList composerTableList = elem.elementsByTagName( "ComposerAttributeTable" );
  for ( int i = 0; i < composerTableList.size(); ++i )
  {
    QDomElement currentComposerTableElem = composerTableList.at( i ).toElement();
    QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( this );
    newTable->readXML( currentComposerTableElem, doc );
    if ( pos )
    {
      newTable->setItemPosition( pos->x(), pos->y() );
    }
    addComposerTable( newTable );
    if ( addUndoCommands )
    {
      pushAddRemoveCommand( newTable, tr( "Table added" ) );
    }
  }
  //html
  QDomNodeList composerHtmlList = elem.elementsByTagName( "ComposerHtml" );
  for ( int i = 0; i < composerHtmlList.size(); ++i )
  {
    QDomElement currentHtmlElem = composerHtmlList.at( i ).toElement();
    QgsComposerHtml* newHtml = new QgsComposerHtml( this, false );
    newHtml->readXML( currentHtmlElem, doc );
    newHtml->setCreateUndoCommands( true );
    this->addMultiFrame( newHtml );
  }
}
예제 #18
0
void QgsComposition::removeComposerItem( QgsComposerItem* item, bool createCommand )
{
  QgsComposerMap* map = dynamic_cast<QgsComposerMap *>( item );
  if ( !map || !map->isDrawing() ) //don't delete a composer map while it draws
  {
    removeItem( item );
    QgsComposerItemGroup* itemGroup = dynamic_cast<QgsComposerItemGroup*>( item );
    if ( itemGroup )
    {
      //add add/remove item command for every item in the group
      QUndoCommand* parentCommand = new QUndoCommand( tr( "Remove item group" ) );

      QSet<QgsComposerItem*> groupedItems = itemGroup->items();
      QSet<QgsComposerItem*>::iterator it = groupedItems.begin();
      for ( ; it != groupedItems.end(); ++it )
      {
        QgsAddRemoveItemCommand* subcommand = new QgsAddRemoveItemCommand( QgsAddRemoveItemCommand::Removed, *it, this, "", parentCommand );
        connectAddRemoveCommandSignals( subcommand );
        emit itemRemoved( *it );
      }

      undoStack()->push( parentCommand );
      delete itemGroup;
      emit itemRemoved( itemGroup );
    }
    else
    {
      bool frameItem = ( item->type() == QgsComposerItem::ComposerFrame );
      QgsComposerMultiFrame* multiFrame = 0;
      if ( createCommand )
      {
        if ( frameItem ) //multiframe tracks item changes
        {
          multiFrame = static_cast<QgsComposerFrame*>( item )->multiFrame();
          item->beginItemCommand( tr( "Frame deleted" ) );
          emit itemRemoved( item );
          item->endItemCommand();
        }
        else
        {
          emit itemRemoved( item );
          pushAddRemoveCommand( item, tr( "Item deleted" ), QgsAddRemoveItemCommand::Removed );
        }
      }
      else
      {
        emit itemRemoved( item );
      }

      //check if there are frames left. If not, remove the multi frame
      if ( frameItem && multiFrame )
      {
        if ( multiFrame->nFrames() < 1 )
        {
          removeMultiFrame( multiFrame );
          if ( createCommand )
          {
            QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Removed,
                multiFrame, this, tr( "Multiframe removed" ) );
            undoStack()->push( command );
          }
          else
          {
            delete multiFrame;
          }
        }
      }
    }
  }
}
예제 #19
0
QgsComposition* QgsConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
{
  QList<QgsComposerMap*> composerMaps;
  QList<QgsComposerLabel*> composerLabels;

  QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLabels );
  if ( !c )
  {
    return 0;
  }

  QMap< QString, QString >::const_iterator dpiIt = parameterMap.find( "DPI" );
  if ( dpiIt != parameterMap.constEnd() )
  {
    c->setPrintResolution( dpiIt.value().toInt() );
  }

  //replace composer map parameters
  QList<QgsComposerMap*>::iterator mapIt = composerMaps.begin();
  QgsComposerMap* currentMap = 0;
  for ( ; mapIt != composerMaps.end(); ++mapIt )
  {
    currentMap = *mapIt;
    if ( !currentMap )
    {
      continue;
    }

    //search composer map title in parameter map-> string
    QMap< QString, QString >::const_iterator titleIt = parameterMap.find( "MAP" + QString::number( currentMap->id() ) );
    if ( titleIt == parameterMap.constEnd() )
    {
      continue;
    }
    QString replaceString = titleIt.value();
    QStringList replacementList = replaceString.split( "/" );

    //get map extent from string
    if ( replacementList.size() > 0 )
    {
      QStringList coordList = replacementList.at( 0 ).split( "," );
      if ( coordList.size() > 3 )
      {
        bool xMinOk, yMinOk, xMaxOk, yMaxOk;
        double xmin = coordList.at( 0 ).toDouble( &xMinOk );
        double ymin = coordList.at( 1 ).toDouble( &yMinOk );
        double xmax = coordList.at( 2 ).toDouble( &xMaxOk );
        double ymax = coordList.at( 3 ).toDouble( &yMaxOk );
        if ( xMinOk && yMinOk && xMaxOk && yMaxOk )
        {
          currentMap->setNewExtent( QgsRectangle( xmin, ymin, xmax, ymax ) );
        }
      }
    }

    //get rotation from string
    if ( replacementList.size() > 1 )
    {
      bool rotationOk;
      double rotation = replacementList.at( 1 ).toDouble( &rotationOk );
      if ( rotationOk )
      {
        currentMap->setMapRotation( rotation );
      }
    }

    //get layer list from string
    if ( replacementList.size() > 2 )
    {
      QStringList layerSet;
      QStringList wmsLayerList = replacementList.at( 2 ).split( "," );
      QStringList wmsStyleList;
      if ( replacementList.size() > 3 )
      {
        wmsStyleList = replacementList.at( 3 ).split( "," );
      }

      for ( int i = 0; i < wmsLayerList.size(); ++i )
      {
        QString styleName;
        if ( wmsStyleList.size() > i )
        {
          styleName = wmsStyleList.at( i );
        }
        QList<QgsMapLayer*> layerList = mapLayerFromStyle( wmsLayerList.at( i ), styleName );
        QList<QgsMapLayer*>::const_iterator mapIdIt = layerList.constBegin();
        for ( ; mapIdIt != layerList.constEnd(); ++mapIdIt )
        {
          if ( *mapIdIt )
          {
            layerSet.push_back(( *mapIdIt )->getLayerID() );
          }
        }
      }

      currentMap->setLayerSet( layerSet );
      currentMap->setKeepLayerSet( true );
    }
  }

  //replace composer label text

  return c;
}
예제 #20
0
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
{
  if ( !composition() )
  {
    return;
  }

  QPointF scenePoint = mapToScene( e->pos() );

  if ( mPanning )
  {
    mPanning = false;

    //set new cursor
    if ( mCurrentTool == Pan )
    {
      viewport()->setCursor( Qt::OpenHandCursor );
    }
    else
    {
      if ( composition() )
      {
        //allow composer items to change cursor
        composition()->setPreventCursorChange( false );
      }
      viewport()->setCursor( Qt::ArrowCursor );
    }
  }

  if ( mMarqueeSelect )
  {
    endMarqueeSelect( e );
    return;
  }

  switch ( mCurrentTool )
  {
    case Select:
    {
      QGraphicsView::mouseReleaseEvent( e );
      break;
    }

    case MoveItemContent:
    {
      if ( mMoveContentItem )
      {
        //update map preview if composer map
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
        if ( composerMap )
        {
          composerMap->setOffset( 0, 0 );
        }

        double moveX = scenePoint.x() - mMoveContentStartPos.x();
        double moveY = scenePoint.y() - mMoveContentStartPos.y();

        composition()->beginCommand( mMoveContentItem, tr( "Move item content" ) );
        mMoveContentItem->moveContent( -moveX, -moveY );
        composition()->endCommand();
        mMoveContentItem = 0;
      }
      break;
    }
    case AddArrow:
      if ( composition() )
      {
        QPointF scenePoint = mapToScene( e->pos() );
        QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );
        QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandStartPos, QPointF( snappedScenePoint.x(), snappedScenePoint.y() ), composition() );
        composition()->addComposerArrow( composerArrow );
        scene()->removeItem( mRubberBandLineItem );
        delete mRubberBandLineItem;
        mRubberBandLineItem = 0;
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerArrow, tr( "Arrow added" ) );
      }
      break;

    case AddRectangle:
    case AddTriangle:
    case AddEllipse:
      addShape( mCurrentTool );
      break;

    case AddMap:
      if ( !mRubberBandItem || mRubberBandItem->rect().width() < 0.1 || mRubberBandItem->rect().width() < 0.1 )
      {
        removeRubberBand();
        return;
      }
      if ( composition() )
      {
        QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
        composition()->addComposerMap( composerMap );
        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) );
      }
      break;

    case AddHtml:
      if ( composition() )
      {
        QgsComposerHtml* composerHtml = new QgsComposerHtml( composition(), true );
        QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Added,
            composerHtml, composition(), tr( "Html item added" ) );
        composition()->undoStack()->push( command );
        QgsComposerFrame* frame = new QgsComposerFrame( composition(), composerHtml, mRubberBandItem->transform().dx(),
            mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(),
            mRubberBandItem->rect().height() );
        composition()->beginMultiFrameCommand( composerHtml, tr( "Html frame added" ) );
        composerHtml->addFrame( frame );
        composition()->endMultiFrameCommand();
        removeRubberBand();
        emit actionFinished();
      }
    default:
      break;
  }
}
예제 #21
0
void QgsComposerView::wheelZoom( QWheelEvent * event )
{
  //get mouse wheel zoom behaviour settings
  QSettings mySettings;
  int wheelAction = mySettings.value( "/qgis/wheel_action", 2 ).toInt();
  double zoomFactor = mySettings.value( "/qgis/zoom_factor", 2 ).toDouble();

  if (( QgsMapCanvas::WheelAction )wheelAction == QgsMapCanvas::WheelNothing )
  {
    return;
  }

  if ( event->modifiers() & Qt::ControlModifier )
  {
    //holding ctrl while wheel zooming results in a finer zoom
    zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 10.0;
  }

  //caculate zoom scale factor
  bool zoomIn = event->delta() > 0;
  double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );

  //get current visible part of scene
  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
  QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );

  //transform the mouse pos to scene coordinates
  QPointF scenePoint = mapToScene( event->pos() );

  //adjust view center according to wheel action setting
  switch (( QgsMapCanvas::WheelAction )wheelAction )
  {
    case QgsMapCanvas::WheelZoomAndRecenter:
    {
      centerOn( scenePoint.x(), scenePoint.y() );
      break;
    }

    case QgsMapCanvas::WheelZoomToMouseCursor:
    {
      QgsPoint oldCenter( visibleRect.center() );
      QgsPoint newCenter( scenePoint.x() + (( oldCenter.x() - scenePoint.x() ) * scaleFactor ),
                          scenePoint.y() + (( oldCenter.y() - scenePoint.y() ) * scaleFactor ) );
      centerOn( newCenter.x(), newCenter.y() );
      break;
    }

    default:
      break;
  }

  //zoom composition
  if ( zoomIn )
  {
    scale( zoomFactor, zoomFactor );
  }
  else
  {
    scale( 1 / zoomFactor, 1 / zoomFactor );
  }

  //update composition for new zoom
  emit zoomLevelChanged();
  updateRulers();
  update();
  //redraw cached map items
  QList<QGraphicsItem *> itemList = composition()->items();
  QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
  for ( ; itemIt != itemList.end(); ++itemIt )
  {
    QgsComposerMap* mypItem = dynamic_cast<QgsComposerMap *>( *itemIt );
    if (( mypItem ) && ( mypItem->previewMode() == QgsComposerMap::Render ) )
    {
      mypItem->updateCachedImage();
    }
  }
}
예제 #22
0
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
{
  if ( !composition() )
  {
    return;
  }

  if ( e->button() != Qt::LeftButton &&
       ( composition()->selectionHandles()->isDragging() || composition()->selectionHandles()->isResizing() ) )
  {
    //ignore clicks while dragging/resizing items
    return;
  }

  QPoint mousePressStopPoint = e->pos();
  int diffX = mousePressStopPoint.x() - mMousePressStartPos.x();
  int diffY = mousePressStopPoint.y() - mMousePressStartPos.y();

  //was this just a click? or a click and drag?
  bool clickOnly = false;
  if ( qAbs( diffX ) < 2 && qAbs( diffY ) < 2 )
  {
    clickOnly = true;
  }

  QPointF scenePoint = mapToScene( e->pos() );

  if ( mMousePanning || mToolPanning )
  {
    mMousePanning = false;
    mToolPanning = false;

    if ( clickOnly && e->button() == Qt::MidButton )
    {
      //middle mouse button click = recenter on point

      //get current visible part of scene
      QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
      QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );
      visibleRect.scale( 1, scenePoint.x(), scenePoint.y() );
      QRectF boundsRect = visibleRect.toRectF();

      //zoom view to fit desired bounds
      fitInView( boundsRect, Qt::KeepAspectRatio );
    }

    //set new cursor
    if ( mCurrentTool != Pan )
    {
      if ( composition() )
      {
        //allow composer items to change cursor
        composition()->setPreventCursorChange( false );
      }
    }
    viewport()->setCursor( defaultCursorForTool( mCurrentTool ) );
  }

  //for every other tool, ignore clicks of non-left button
  if ( e->button() != Qt::LeftButton )
  {
    return;
  }

  if ( mMarqueeSelect )
  {
    endMarqueeSelect( e );
    return;
  }

  switch ( mCurrentTool )
  {
    case Select:
    {
      QGraphicsView::mouseReleaseEvent( e );
      break;
    }

    case Zoom:
    {
      if ( mMarqueeZoom )
      {
        endMarqueeZoom( e );
      }
      break;
    }

    case MoveItemContent:
    {
      if ( mMoveContentItem )
      {
        //update map preview if composer map
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
        if ( composerMap )
        {
          composerMap->setOffset( 0, 0 );
        }

        double moveX = scenePoint.x() - mMoveContentStartPos.x();
        double moveY = scenePoint.y() - mMoveContentStartPos.y();

        composition()->beginCommand( mMoveContentItem, tr( "Move item content" ) );
        mMoveContentItem->moveContent( -moveX, -moveY );
        composition()->endCommand();
        mMoveContentItem = 0;
        mMovingItemContent = false;
      }
      break;
    }
    case AddArrow:
      if ( !composition() || !mRubberBandLineItem )
      {
        scene()->removeItem( mRubberBandLineItem );
        delete mRubberBandLineItem;
        mRubberBandLineItem = 0;
        return;
      }
      else
      {
        QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandLineItem->line().p1(), mRubberBandLineItem->line().p2(), composition() );
        composition()->addComposerArrow( composerArrow );

        composition()->clearSelection();
        composerArrow->setSelected( true );
        emit selectedItemChanged( composerArrow );

        scene()->removeItem( mRubberBandLineItem );
        delete mRubberBandLineItem;
        mRubberBandLineItem = 0;
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerArrow, tr( "Arrow added" ) );
      }
      break;

    case AddRectangle:
    case AddTriangle:
    case AddEllipse:
      addShape( mCurrentTool );
      break;

    case AddMap:
      if ( !composition() || !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) )
      {
        removeRubberBand();
        return;
      }
      else
      {
        QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
        composition()->addComposerMap( composerMap );

        composition()->clearSelection();
        composerMap->setSelected( true );
        emit selectedItemChanged( composerMap );

        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) );
      }
      break;

    case AddPicture:
      if ( !composition() || !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) )
      {
        removeRubberBand();
        return;
      }
      else
      {
        QgsComposerPicture* newPicture = new QgsComposerPicture( composition() );
        newPicture->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ) );
        composition()->addComposerPicture( newPicture );

        composition()->clearSelection();
        newPicture->setSelected( true );
        emit selectedItemChanged( newPicture );

        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( newPicture, tr( "Picture added" ) );
      }
      break;

    case AddLabel:
      if ( !composition() || !mRubberBandItem )
      {
        removeRubberBand();
        return;
      }
      else
      {
        QgsComposerLabel* newLabelItem = new QgsComposerLabel( composition() );
        newLabelItem->setText( tr( "QGIS" ) );
        newLabelItem->adjustSizeToText();

        //make sure label size is sufficient to fit text
        double labelWidth = qMax( mRubberBandItem->rect().width(), newLabelItem->rect().width() );
        double labelHeight = qMax( mRubberBandItem->rect().height(), newLabelItem->rect().height() );
        newLabelItem->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), labelWidth, labelHeight ) );

        composition()->addComposerLabel( newLabelItem );

        composition()->clearSelection();
        newLabelItem->setSelected( true );
        emit selectedItemChanged( newLabelItem );

        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( newLabelItem, tr( "Label added" ) );
      }
      break;

    case AddLegend:
      if ( !composition() || !mRubberBandItem )
      {
        removeRubberBand();
        return;
      }
      else
      {
        QgsComposerLegend* newLegend = new QgsComposerLegend( composition() );
        newLegend->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ) );
        composition()->addComposerLegend( newLegend );
        newLegend->updateLegend();

        composition()->clearSelection();
        newLegend->setSelected( true );
        emit selectedItemChanged( newLegend );

        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( newLegend, tr( "Legend added" ) );
      }
      break;

    case AddTable:
      if ( !composition() || !mRubberBandItem )
      {
        removeRubberBand();
        return;
      }
      else
      {
        QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() );
        newTable->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), qMax( mRubberBandItem->rect().height(), 15.0 ) ) );
        QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems();
        if ( mapItemList.size() > 0 )
        {
          newTable->setComposerMap( mapItemList.at( 0 ) );
        }
        composition()->addComposerTable( newTable );

        composition()->clearSelection();
        newTable->setSelected( true );
        emit selectedItemChanged( newTable );

        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( newTable, tr( "Table added" ) );
      }
      break;

    case AddHtml:
      if ( !composition() || !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) )
      {
        removeRubberBand();
        return;
      }
      else
      {
        QgsComposerHtml* composerHtml = new QgsComposerHtml( composition(), true );
        QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Added,
            composerHtml, composition(), tr( "Html item added" ) );
        composition()->undoStack()->push( command );
        QgsComposerFrame* frame = new QgsComposerFrame( composition(), composerHtml, mRubberBandItem->transform().dx(),
            mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(),
            mRubberBandItem->rect().height() );
        composition()->beginMultiFrameCommand( composerHtml, tr( "Html frame added" ) );
        composerHtml->addFrame( frame );
        composition()->endMultiFrameCommand();

        composition()->clearSelection();
        frame->setSelected( true );
        emit selectedItemChanged( frame );

        removeRubberBand();
        emit actionFinished();
      }
    default:
      break;
  }
}
예제 #23
0
void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
{
  if ( !composition() )
  {
    return;
  }

  mMouseCurrentXY = e->pos();
  //update cursor position in composer status bar
  emit cursorPosChanged( mapToScene( e->pos() ) );

  updateRulers();
  if ( mHorizontalRuler )
  {
    mHorizontalRuler->updateMarker( e->posF() );
  }
  if ( mVerticalRuler )
  {
    mVerticalRuler->updateMarker( e->posF() );
  }

  if ( mPanning )
  {
    //panning, so scroll view
    horizontalScrollBar()->setValue( horizontalScrollBar()->value() - ( e->x() - mMouseLastXY.x() ) );
    verticalScrollBar()->setValue( verticalScrollBar()->value() - ( e->y() - mMouseLastXY.y() ) );
    mMouseLastXY = e->pos();
    return;
  }
  else if ( e->buttons() == Qt::NoButton )
  {
    if ( mCurrentTool == Select )
    {
      QGraphicsView::mouseMoveEvent( e );
    }
  }
  else
  {
    QPointF scenePoint = mapToScene( e->pos() );

    if ( mMarqueeSelect || mMarqueeZoom )
    {
      updateRubberBand( scenePoint );
      return;
    }

    switch ( mCurrentTool )
    {
      case Select:
        QGraphicsView::mouseMoveEvent( e );
        break;

      case AddArrow:
      {
        if ( mRubberBandLineItem )
        {
          mRubberBandLineItem->setLine( mRubberBandStartPos.x(), mRubberBandStartPos.y(),  scenePoint.x(),  scenePoint.y() );
        }
        break;
      }

      case AddMap:
      case AddRectangle:
      case AddTriangle:
      case AddEllipse:
      case AddHtml:
        //adjust rubber band item
      {
        updateRubberBand( scenePoint );
        break;
      }

      case MoveItemContent:
      {
        //update map preview if composer map
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
        if ( composerMap )
        {
          composerMap->setOffset( scenePoint.x() - mMoveContentStartPos.x(), scenePoint.y() - mMoveContentStartPos.y() );
          composerMap->update();
        }
        break;
      }
      default:
        break;
    }
  }
}
예제 #24
0
void QgsComposerView::wheelZoom( QWheelEvent * event )
{
  //get mouse wheel zoom behaviour settings
  QSettings mySettings;
  int wheelAction = mySettings.value( "/qgis/wheel_action", 2 ).toInt();
  double zoomFactor = mySettings.value( "/qgis/zoom_factor", 2 ).toDouble();

  //caculate zoom scale factor
  bool zoomIn = event->delta() > 0;
  double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );

  //get current visible part of scene
  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
  QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );

  //transform the mouse pos to scene coordinates
  QPointF scenePoint = mapToScene( event->pos() );

  //zoom composition, respecting wheel action setting
  switch (( QgsMapCanvas::WheelAction )wheelAction )
  {
    case QgsMapCanvas::WheelZoom:
      // zoom without changing extent
      if ( zoomIn )
      {
        scale( zoomFactor, zoomFactor );
      }
      else
      {
        scale( 1 / zoomFactor, 1 / zoomFactor );
      }
      break;

    case QgsMapCanvas::WheelZoomAndRecenter:
    {
      visibleRect.scale( scaleFactor, scenePoint.x(), scenePoint.y() );
      fitInView( visibleRect.toRectF(), Qt::KeepAspectRatio );
      break;
    }

    case QgsMapCanvas::WheelZoomToMouseCursor:
    {
      QgsPoint oldCenter( visibleRect.center() );
      QgsPoint newCenter( scenePoint.x() + (( oldCenter.x() - scenePoint.x() ) * scaleFactor ),
                          scenePoint.y() + (( oldCenter.y() - scenePoint.y() ) * scaleFactor ) );

      visibleRect.scale( scaleFactor, newCenter.x(), newCenter.y() );
      fitInView( visibleRect.toRectF(), Qt::KeepAspectRatio );
      break;
    }

    case QgsMapCanvas::WheelNothing:
      return;
  }

  //update composition for new zoom
  updateRulers();
  update();
  //redraw cached map items
  QList<QGraphicsItem *> itemList = composition()->items();
  QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
  for ( ; itemIt != itemList.end(); ++itemIt )
  {
    QgsComposerMap* mypItem = dynamic_cast<QgsComposerMap *>( *itemIt );
    if (( mypItem ) && ( mypItem->previewMode() == QgsComposerMap::Render ) )
    {
      mypItem->updateCachedImage();
    }
  }
}