Skip to content

Commit

Permalink
Consider transparency in composer legend (even though legend items fo…
Browse files Browse the repository at this point in the history
…r transparent layers are problematic because of background). Removed private section from qgslegendmodel.sip as private members cannot be used anyway

git-svn-id: http://svn.osgeo.org/qgis/trunk@11439 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Aug 19, 2009
1 parent 52c420b commit a51fb58
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 50 deletions.
21 changes: 1 addition & 20 deletions python/core/qgslegendmodel.sip
Expand Up @@ -32,23 +32,4 @@ class QgsLegendModel: QStandardItemModel

signals:
void layersChanged();

private:
/**Adds classification items of vector layers
@return 0 in case of success*/
int addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer* vlayer );

/**Adds item of raster layer
@return 0 in case of success*/
int addRasterLayerItem( QStandardItem* layerItem, QgsMapLayer* rlayer );

/**Insert a symbol into QgsLegendModel symbol storage*/
void insertSymbol( QgsSymbol* s );
/**Removes and deletes a symbol*/
void removeSymbol( QgsSymbol* s );
/**Removes and deletes all stored symbols*/
void removeAllSymbols();

/**Creates a model item for a vector symbol. The calling function takes ownership*/
QStandardItem* itemFromSymbol( QgsSymbol* s );
};
};
48 changes: 34 additions & 14 deletions src/core/composer/qgscomposerlegend.cpp
Expand Up @@ -108,6 +108,13 @@ QSizeF QgsComposerLegend::paintAndDetermineSize( QPainter* painter )
if ( currentLayerItem )
{
QString currentLayerId = currentLayerItem->data().toString();
int opacity = 255;
QgsMapLayer* currentLayer = QgsMapLayerRegistry::instance()->mapLayer( currentLayerId );
if ( currentLayer )
{
opacity = currentLayer->getTransparency();
}

if ( visibleLayerIds.contains( currentLayerId ) )
{
//Let the user omit the layer title item by having an empty layer title string
Expand All @@ -126,7 +133,7 @@ QSizeF QgsComposerLegend::paintAndDetermineSize( QPainter* painter )
maxXCoord = std::max( maxXCoord, 2 * mBoxSpace + textWidthMillimeters( mLayerFont, currentLayerItem->text() ) );

//and child items
drawLayerChildItems( painter, currentLayerItem, currentYCoordinate, maxXCoord );
drawLayerChildItems( painter, currentLayerItem, currentYCoordinate, maxXCoord, opacity );
}
}
}
Expand Down Expand Up @@ -170,7 +177,7 @@ void QgsComposerLegend::adjustBoxSize()
}
}

void QgsComposerLegend::drawLayerChildItems( QPainter* p, QStandardItem* layerItem, double& currentYCoord, double& maxXCoord )
void QgsComposerLegend::drawLayerChildItems( QPainter* p, QStandardItem* layerItem, double& currentYCoord, double& maxXCoord, int layerOpacity )
{
if ( !layerItem )
{
Expand Down Expand Up @@ -212,7 +219,7 @@ void QgsComposerLegend::drawLayerChildItems( QPainter* p, QStandardItem* layerIt
if ( symbol ) //item with symbol?
{
//draw symbol
drawSymbol( p, symbol, currentYCoord + ( itemHeight - mSymbolHeight ) / 2, currentXCoord, realSymbolHeight );
drawSymbol( p, symbol, currentYCoord + ( itemHeight - mSymbolHeight ) / 2, currentXCoord, realSymbolHeight, layerOpacity );
realItemHeight = std::max( realSymbolHeight, itemHeight );
currentXCoord += mIconLabelSpace;
}
Expand All @@ -239,7 +246,7 @@ void QgsComposerLegend::drawLayerChildItems( QPainter* p, QStandardItem* layerIt
}
}

void QgsComposerLegend::drawSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight ) const
void QgsComposerLegend::drawSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity ) const
{
if ( !s )
{
Expand All @@ -250,14 +257,14 @@ void QgsComposerLegend::drawSymbol( QPainter* p, QgsSymbol* s, double currentYCo
switch ( symbolType )
{
case QGis::Point:
drawPointSymbol( p, s, currentYCoord, currentXPosition, symbolHeight );
drawPointSymbol( p, s, currentYCoord, currentXPosition, symbolHeight, layerOpacity );
break;
case QGis::Line:
drawLineSymbol( p, s, currentYCoord, currentXPosition );
drawLineSymbol( p, s, currentYCoord, currentXPosition, layerOpacity );
symbolHeight = mSymbolHeight;
break;
case QGis::Polygon:
drawPolygonSymbol( p, s, currentYCoord, currentXPosition );
drawPolygonSymbol( p, s, currentYCoord, currentXPosition, layerOpacity );
symbolHeight = mSymbolHeight;
break;
case QGis::UnknownGeometry:
Expand All @@ -266,7 +273,7 @@ void QgsComposerLegend::drawSymbol( QPainter* p, QgsSymbol* s, double currentYCo
}
}

void QgsComposerLegend::drawPointSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight ) const
void QgsComposerLegend::drawPointSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int opacity ) const
{
if ( !s )
{
Expand All @@ -287,7 +294,7 @@ void QgsComposerLegend::drawPointSymbol( QPainter* p, QgsSymbol* s, double curre
}

//width scale is 1.0
pointImage = s->getPointSymbolAsImage( 1.0, false, Qt::yellow, 1.0, 0.0, rasterScaleFactor );
pointImage = s->getPointSymbolAsImage( 1.0, false, Qt::yellow, 1.0, 0.0, rasterScaleFactor, opacity / 255.0 );

if ( p )
{
Expand All @@ -303,7 +310,7 @@ void QgsComposerLegend::drawPointSymbol( QPainter* p, QgsSymbol* s, double curre
symbolHeight = s->pointSize(); //pointImage.height() / rasterScaleFactor;
}

void QgsComposerLegend::drawLineSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition ) const
void QgsComposerLegend::drawLineSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity ) const
{
if ( !s )
{
Expand All @@ -315,15 +322,19 @@ void QgsComposerLegend::drawLineSymbol( QPainter* p, QgsSymbol* s, double curren
if ( p )
{
p->save();
p->setPen( s->pen() );
QPen symbolPen = s->pen();
QColor penColor = symbolPen.color();
penColor.setAlpha( opacity );
symbolPen.setColor( penColor );
p->setPen( symbolPen );
p->drawLine( QPointF( currentXPosition, yCoord ), QPointF( currentXPosition + mSymbolWidth, yCoord ) );
p->restore();
}

currentXPosition += mSymbolWidth;
}

void QgsComposerLegend::drawPolygonSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition ) const
void QgsComposerLegend::drawPolygonSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity ) const
{
if ( !s )
{
Expand All @@ -332,16 +343,25 @@ void QgsComposerLegend::drawPolygonSymbol( QPainter* p, QgsSymbol* s, double cur

if ( p )
{
//scale brush
//scale brush and set transparencies
QBrush symbolBrush = s->brush();
QColor brushColor = symbolBrush.color();
brushColor.setAlpha( opacity );
symbolBrush.setColor( brushColor );
QPaintDevice* paintDevice = p->device();
if ( paintDevice )
{
double rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4;
QgsRenderer::scaleBrush( symbolBrush, rasterScaleFactor );
}
p->setBrush( symbolBrush );
p->setPen( s->pen() );

QPen symbolPen = s->pen();
QColor penColor = symbolPen.color();
penColor.setAlpha( opacity );
symbolPen.setColor( penColor );
p->setPen( symbolPen );

p->drawRect( QRectF( currentXPosition, currentYCoord, mSymbolWidth, mSymbolHeight ) );
}

Expand Down
11 changes: 6 additions & 5 deletions src/core/composer/qgscomposerlegend.h
Expand Up @@ -127,15 +127,16 @@ class CORE_EXPORT QgsComposerLegend: public QObject, public QgsComposerItem
@param layerItem parent model item (layer)
@param currentYCoord in/out: current y position of legend item
@param maxXCoord in/out: maximum x-coordinate of the whole legend
@param layerOpacity opacity of the corresponding map layer
*/
void drawLayerChildItems( QPainter* p, QStandardItem* layerItem, double& currentYCoord, double& maxXCoord );
void drawLayerChildItems( QPainter* p, QStandardItem* layerItem, double& currentYCoord, double& maxXCoord, int layerOpacity = 255 );

/**Draws a symbol at the current y position and returns the new x position. Returns real symbol height, because for points,
it is possible that it differs from mSymbolHeight*/
void drawSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight ) const;
void drawPointSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight ) const;
void drawLineSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition ) const;
void drawPolygonSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition ) const;
void drawSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity = 255 ) const;
void drawPointSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int opacity = 255 ) const;
void drawLineSymbol( QPainter*, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity = 255 ) const;
void drawPolygonSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, int opacity = 255 ) const;

/**Helper function that lists ids of layers contained in map canvas*/
QStringList layerIdList() const;
Expand Down
39 changes: 29 additions & 10 deletions src/core/composer/qgslegendmodel.cpp
Expand Up @@ -91,6 +91,7 @@ int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer*
{
return 2;
}
int opacity = vectorLayer->getTransparency();

const QgsRenderer* vectorRenderer = vectorLayer->renderer();
if ( !vectorRenderer )
Expand Down Expand Up @@ -127,7 +128,7 @@ int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer*
continue;
}

QStandardItem* currentSymbolItem = itemFromSymbol( *symbolIt );
QStandardItem* currentSymbolItem = itemFromSymbol( *symbolIt, opacity );
if ( !currentSymbolItem )
{
continue;
Expand Down Expand Up @@ -278,6 +279,7 @@ void QgsLegendModel::updateVectorClassificationItem( QStandardItem* classificati
{
return;
}
int opacity = vl->getTransparency();

const QgsRenderer* layerRenderer = vl->renderer();
if ( !layerRenderer )
Expand All @@ -297,7 +299,7 @@ void QgsLegendModel::updateVectorClassificationItem( QStandardItem* classificati
if ( currentSymbol->lowerValue() + " - " + currentSymbol->upperValue() == itemText )
{
removeSymbol( symbol );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol ) );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol, opacity ) );
parentItem->removeRow( classificationItem->row() );
return;
}
Expand All @@ -311,7 +313,7 @@ void QgsLegendModel::updateVectorClassificationItem( QStandardItem* classificati
if ( currentSymbol->lowerValue() == itemText )
{
removeSymbol( symbol );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol ) );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol, opacity ) );
parentItem->removeRow( classificationItem->row() );
return;
}
Expand All @@ -325,7 +327,7 @@ void QgsLegendModel::updateVectorClassificationItem( QStandardItem* classificati
if ( currentSymbol->label() == itemText )
{
removeSymbol( symbol );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol ) );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol, opacity ) );
parentItem->removeRow( classificationItem->row() );
return;
}
Expand Down Expand Up @@ -415,7 +417,7 @@ void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer )
emit layersChanged();
}

QStandardItem* QgsLegendModel::itemFromSymbol( QgsSymbol* s )
QStandardItem* QgsLegendModel::itemFromSymbol( QgsSymbol* s, int opacity )
{
QStandardItem* currentSymbolItem = 0;

Expand Down Expand Up @@ -444,22 +446,39 @@ QStandardItem* QgsLegendModel::itemFromSymbol( QgsSymbol* s )
}

//icon item
QImage symbolImage;
switch ( s->type() )
{
case QGis::Point:
currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage( s->getPointSymbolAsImage() ) ), itemText );
symbolImage = s->getPointSymbolAsImage();
break;
case QGis::Line:
currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage( s->getLineSymbolAsImage() ) ), itemText );
symbolImage = s->getLineSymbolAsImage();
break;
case QGis::Polygon:
currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage( s->getPolygonSymbolAsImage() ) ), itemText );
symbolImage = s->getPolygonSymbolAsImage();
break;
default:
currentSymbolItem = 0;
break;
return 0;
}

if ( opacity != 255 )
{
//todo: manipulate image pixel by pixel...
QRgb oldColor;
for ( int i = 0; i < symbolImage.height(); ++i )
{
QRgb* scanLineBuffer = ( QRgb* ) symbolImage.scanLine( i );
for ( int j = 0; j < symbolImage.width(); ++j )
{
oldColor = symbolImage.pixel( j, i );
scanLineBuffer[j] = qRgba( qRed( oldColor ), qGreen( oldColor ), qBlue( oldColor ), opacity );
}
}
}

currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage( symbolImage ) ), itemText );

if ( !currentSymbolItem )
{
return 0;
Expand Down
2 changes: 1 addition & 1 deletion src/core/composer/qgslegendmodel.h
Expand Up @@ -76,7 +76,7 @@ class CORE_EXPORT QgsLegendModel: public QStandardItemModel
void removeAllSymbols();

/**Creates a model item for a vector symbol. The calling function takes ownership*/
QStandardItem* itemFromSymbol( QgsSymbol* s );
QStandardItem* itemFromSymbol( QgsSymbol* s, int opacity );

/**Keep track of copied symbols to delete them if not used anymore*/
QSet<QgsSymbol*> mSymbols;
Expand Down

0 comments on commit a51fb58

Please sign in to comment.