void QgsComposerScaleBar::setSceneRect( const QRectF& rectangle ) { QRectF box = mStyle->calculateBoxSize(); if ( rectangle.height() > box.height() ) { //keep user specified item height if higher than minimum scale bar height box.setHeight( rectangle.height() ); } box.moveTopLeft( rectangle.topLeft() ); //update rect for data defined size and position QRectF newRect = evalItemRect( rectangle ); //scale bars have a minimum size, respect that regardless of data defined settings if ( newRect.width() < box.width() ) { newRect.setWidth( box.width() ); } if ( newRect.height() < box.height() ) { newRect.setHeight( box.height() ); } QgsComposerItem::setSceneRect( newRect ); }
void QgsComposerArrow::setSceneRect( const QRectF& rectangle ) { //update rect for data defined size and position QRectF evaluatedRect = evalItemRect( rectangle ); if ( evaluatedRect.width() < 0 ) { mStartXIdx = 1 - mStartXIdx; } if ( evaluatedRect.height() < 0 ) { mStartYIdx = 1 - mStartYIdx; } double margin = computeMarkerMargin(); // Ensure the rectangle is at least as large as needed to include the markers QRectF rect = rectangle.united( QRectF( evaluatedRect.x(), evaluatedRect.y(), 2. * margin, 2. * margin ) ); // Compute new start and stop positions double x[2] = {rect.x(), rect.x() + rect.width()}; double y[2] = {rect.y(), rect.y() + rect.height()}; double xsign = x[mStartXIdx] < x[1 - mStartXIdx] ? 1.0 : -1.0; double ysign = y[mStartYIdx] < y[1 - mStartYIdx] ? 1.0 : -1.0; mStartPoint = QPointF( x[mStartXIdx] + xsign * margin, y[mStartYIdx] + ysign * margin ); mStopPoint = QPointF( x[1 - mStartXIdx] - xsign * margin, y[1 - mStartYIdx] - ysign * margin ); QgsComposerItem::setSceneRect( rect ); }
void QgsComposerAttributeTable::setSceneRect( const QRectF& rectangle ) { //update rect for data defined size and position QRectF evaluatedRect = evalItemRect( rectangle ); QgsComposerItem::setSceneRect( evaluatedRect ); //refresh table attributes, since number of features has likely changed refreshAttributes(); }
void QgsComposerShape::setSceneRect( const QRectF& rectangle ) { // Reimplemented from QgsComposerItem as we need to call updateBoundingRect after the shape's size changes //update rect for data defined size and position QRectF evaluatedRect = evalItemRect( rectangle ); QgsComposerItem::setSceneRect( evaluatedRect ); updateBoundingRect(); update(); }
void QgsComposerItem::updatePagePos( double newPageWidth, double newPageHeight ) { Q_UNUSED( newPageWidth ) QPointF curPagePos = pagePos(); int curPage = page() - 1; double y = curPage * ( newPageHeight + composition()->spaceBetweenPages() ) + curPagePos.y(); QRectF newSceneRect( pos().x(), y, rect().width(), rect().height() ); setSceneRect( evalItemRect( newSceneRect ) ); emit sizeChanged(); }
void QgsComposerLegend::adjustBoxSize() { QgsLegendRenderer legendRenderer( mLegendModel2, mSettings ); QSizeF size = legendRenderer.minimumSize(); QgsDebugMsg( QString( "width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) ); if ( size.isValid() ) { QRectF targetRect = QRectF( pos().x(), pos().y(), size.width(), size.height() ); //set new rect, respecting position mode and data defined size/position setSceneRect( evalItemRect( targetRect, true ) ); } }
void QgsComposerItem::refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property, const QgsExpressionContext *context ) { //maintain 2.10 API //TODO QGIS 3.0 - remove this const QgsExpressionContext* evalContext = context; QScopedPointer< QgsExpressionContext > scopedContext; if ( !evalContext ) { scopedContext.reset( createExpressionContext() ); evalContext = scopedContext.data(); } //update data defined properties and redraw item to match if ( property == QgsComposerObject::PositionX || property == QgsComposerObject::PositionY || property == QgsComposerObject::ItemWidth || property == QgsComposerObject::ItemHeight || property == QgsComposerObject::AllProperties ) { QRectF beforeRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() ); QRectF evaluatedRect = evalItemRect( beforeRect, false, evalContext ); if ( evaluatedRect != beforeRect ) { setSceneRect( evaluatedRect ); } } if ( property == QgsComposerObject::ItemRotation || property == QgsComposerObject::AllProperties ) { refreshRotation( false, true, *evalContext ); } if ( property == QgsComposerObject::Transparency || property == QgsComposerObject::AllProperties ) { refreshTransparency( false, *evalContext ); } if ( property == QgsComposerObject::BlendMode || property == QgsComposerObject::AllProperties ) { refreshBlendMode( *evalContext ); } if ( property == QgsComposerObject::ExcludeFromExports || property == QgsComposerObject::AllProperties ) { bool exclude = mExcludeFromExports; //data defined exclude from exports set? QVariant exprVal; if ( dataDefinedEvaluate( QgsComposerObject::ExcludeFromExports, exprVal, *evalContext ) && !exprVal.isNull() ) { exclude = exprVal.toBool(); } mEvaluatedExcludeFromExports = exclude; } update(); }
void QgsComposerItem::refreshDataDefinedProperty( const QgsComposerObject::DataDefinedProperty property, const QgsExpressionContext *context ) { //maintain 2.10 API //TODO QGIS 3.0 - remove this QgsExpressionContext scopedContext = createExpressionContext(); const QgsExpressionContext *evalContext = context ? context : &scopedContext; //update data defined properties and redraw item to match if ( property == QgsComposerObject::PositionX || property == QgsComposerObject::PositionY || property == QgsComposerObject::ItemWidth || property == QgsComposerObject::ItemHeight || property == QgsComposerObject::AllProperties ) { QRectF beforeRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() ); QRectF evaluatedRect = evalItemRect( beforeRect, false, evalContext ); if ( evaluatedRect != beforeRect ) { setSceneRect( evaluatedRect ); } } if ( property == QgsComposerObject::ItemRotation || property == QgsComposerObject::AllProperties ) { refreshRotation( false, true, *evalContext ); } if ( property == QgsComposerObject::Opacity || property == QgsComposerObject::AllProperties ) { refreshOpacity( false, *evalContext ); } if ( property == QgsComposerObject::BlendMode || property == QgsComposerObject::AllProperties ) { refreshBlendMode( *evalContext ); } if ( property == QgsComposerObject::FrameColor || property == QgsComposerObject::AllProperties ) { refreshFrameColor( false, *evalContext ); } if ( property == QgsComposerObject::BackgroundColor || property == QgsComposerObject::AllProperties ) { refreshBackgroundColor( false, *evalContext ); } if ( property == QgsComposerObject::ExcludeFromExports || property == QgsComposerObject::AllProperties ) { bool exclude = mExcludeFromExports; //data defined exclude from exports set? exclude = mDataDefinedProperties.valueAsBool( QgsComposerObject::ExcludeFromExports, *evalContext, exclude ); mEvaluatedExcludeFromExports = exclude; } update(); }
void QgsComposerLabel::adjustSizeToText() { double textWidth = QgsComposerUtils::textWidthMM( mFont, displayText() ); double fontHeight = QgsComposerUtils::fontHeightMM( mFont ); double penWidth = hasFrame() ? ( pen().widthF() / 2.0 ) : 0; double width = textWidth + 2 * mMarginX + 2 * penWidth + 1; double height = fontHeight + 2 * mMarginY + 2 * penWidth; //keep alignment point constant double xShift = 0; double yShift = 0; itemShiftAdjustSize( width, height, xShift, yShift ); //update rect for data defined size and position QRectF evaluatedRect = evalItemRect( QRectF( pos().x() + xShift, pos().y() + yShift, width, height ) ); setSceneRect( evaluatedRect ); }
void QgsComposerLegend::adjustBoxSize() { if ( !mSizeToContents ) return; if ( !mInitialMapScaleCalculated ) { // this is messy - but until we have painted the item we have no knowledge of the current DPI // and so cannot correctly calculate the map scale. This results in incorrect size calculations // for marker symbols with size in map units, causing the legends to initially expand to huge // sizes if we attempt to calculate the box size first. return; } QgsLegendRenderer legendRenderer( mLegendModel.get(), mSettings ); QSizeF size = legendRenderer.minimumSize(); QgsDebugMsg( QString( "width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) ); if ( size.isValid() ) { QRectF targetRect = QRectF( pos().x(), pos().y(), size.width(), size.height() ); //set new rect, respecting position mode and data defined size/position setSceneRect( evalItemRect( targetRect, true ) ); } }
void QgsComposerTable::adaptItemFrame( const QMap<int, double>& maxWidthMap, const QList<QgsAttributeMap>& attributeMaps ) { //calculate height int n = attributeMaps.size(); double totalHeight = fontAscentMillimeters( mHeaderFont ) + n * fontAscentMillimeters( mContentFont ) + ( n + 1 ) * mLineTextDistance * 2 + ( n + 2 ) * mGridStrokeWidth; //adapt frame to total width double totalWidth = 0; QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin(); for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt ) { totalWidth += maxColWidthIt.value(); } totalWidth += ( 2 * maxWidthMap.size() * mLineTextDistance ); totalWidth += ( maxWidthMap.size() + 1 ) * mGridStrokeWidth; QRectF evaluatedRect = evalItemRect( QRectF( pos().x(), pos().y(), totalWidth, totalHeight ) ); //update rect for data defined size and position QgsComposerItem::setSceneRect( evaluatedRect ); }
void QgsComposerItem::setItemPosition( double x, double y, double width, double height, ItemPositionMode itemPoint, bool posIncludesFrame, int page ) { double upperLeftX = x; double upperLeftY = y; if ( page > 0 ) { double h = composition()->paperHeight() + composition()->spaceBetweenPages(); upperLeftY += ( page - 1 ) * h; } //store the item position mode mLastUsedPositionMode = itemPoint; //adjust x-coordinate if placement is not done to a left point if ( itemPoint == UpperMiddle || itemPoint == Middle || itemPoint == LowerMiddle ) { upperLeftX -= width / 2.0; } else if ( itemPoint == UpperRight || itemPoint == MiddleRight || itemPoint == LowerRight ) { upperLeftX -= width; } //adjust y-coordinate if placement is not done to an upper point if ( itemPoint == MiddleLeft || itemPoint == Middle || itemPoint == MiddleRight ) { upperLeftY -= height / 2.0; } else if ( itemPoint == LowerLeft || itemPoint == LowerMiddle || itemPoint == LowerRight ) { upperLeftY -= height; } if ( posIncludesFrame ) { //adjust position to account for frame size if ( qgsDoubleNear( mEvaluatedItemRotation, 0.0 ) ) { upperLeftX += estimatedFrameBleed(); upperLeftY += estimatedFrameBleed(); } else { //adjust position for item rotation QLineF lineToItemOrigin = QLineF( 0, 0, estimatedFrameBleed(), estimatedFrameBleed() ); lineToItemOrigin.setAngle( -45 - mEvaluatedItemRotation ); upperLeftX += lineToItemOrigin.x2(); upperLeftY += lineToItemOrigin.y2(); } width -= 2 * estimatedFrameBleed(); height -= 2 * estimatedFrameBleed(); } //consider data defined item size and position before finalising rect QRectF newRect = evalItemRect( QRectF( upperLeftX, upperLeftY, width, height ) ); setSceneRect( newRect ); }
void QgsComposerItem::move( double dx, double dy ) { QRectF newSceneRect( pos().x() + dx, pos().y() + dy, rect().width(), rect().height() ); setSceneRect( evalItemRect( newSceneRect ) ); }
bool QgsComposerItem::_readXml( const QDomElement &itemElem, const QDomDocument &doc ) { Q_UNUSED( doc ); if ( itemElem.isNull() ) { return false; } QgsComposerObject::readXml( itemElem, doc ); //rotation setItemRotation( itemElem.attribute( QStringLiteral( "itemRotation" ), QStringLiteral( "0" ) ).toDouble() ); //uuid mUuid = itemElem.attribute( QStringLiteral( "uuid" ), QUuid::createUuid().toString() ); // temporary for groups imported from templates mTemplateUuid = itemElem.attribute( QStringLiteral( "templateUuid" ) ); //id QString id = itemElem.attribute( QStringLiteral( "id" ), QLatin1String( "" ) ); setId( id ); //frame QString frame = itemElem.attribute( QStringLiteral( "frame" ) ); if ( frame.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 ) { mFrame = true; } else { mFrame = false; } //frame QString background = itemElem.attribute( QStringLiteral( "background" ) ); if ( background.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 ) { mBackground = true; } else { mBackground = false; } //position lock for mouse moves/resizes QString positionLock = itemElem.attribute( QStringLiteral( "positionLock" ) ); if ( positionLock.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 ) { setPositionLock( true ); } else { setPositionLock( false ); } //visibility setVisibility( itemElem.attribute( QStringLiteral( "visibility" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) ); //position int page; double x, y, pagex, pagey, width, height; bool xOk, yOk, pageOk, pagexOk, pageyOk, widthOk, heightOk, positionModeOK; x = itemElem.attribute( QStringLiteral( "x" ) ).toDouble( &xOk ); y = itemElem.attribute( QStringLiteral( "y" ) ).toDouble( &yOk ); page = itemElem.attribute( QStringLiteral( "page" ) ).toInt( &pageOk ); pagex = itemElem.attribute( QStringLiteral( "pagex" ) ).toDouble( &pagexOk ); pagey = itemElem.attribute( QStringLiteral( "pagey" ) ).toDouble( &pageyOk ); width = itemElem.attribute( QStringLiteral( "width" ) ).toDouble( &widthOk ); height = itemElem.attribute( QStringLiteral( "height" ) ).toDouble( &heightOk ); mLastUsedPositionMode = static_cast< ItemPositionMode >( itemElem.attribute( QStringLiteral( "positionMode" ) ).toInt( &positionModeOK ) ); if ( !positionModeOK ) { mLastUsedPositionMode = UpperLeft; } if ( pageOk && pagexOk && pageyOk ) { xOk = true; yOk = true; x = pagex; y = ( page - 1 ) * ( mComposition->paperHeight() + composition()->spaceBetweenPages() ) + pagey; } if ( !xOk || !yOk || !widthOk || !heightOk ) { return false; } mLastValidViewScaleFactor = itemElem.attribute( QStringLiteral( "lastValidViewScaleFactor" ), QStringLiteral( "-1" ) ).toDouble(); setZValue( itemElem.attribute( QStringLiteral( "zValue" ) ).toDouble() ); QgsExpressionContext context = createExpressionContext(); //pen QDomNodeList frameColorList = itemElem.elementsByTagName( QStringLiteral( "FrameColor" ) ); if ( !frameColorList.isEmpty() ) { QDomElement frameColorElem = frameColorList.at( 0 ).toElement(); bool redOk, greenOk, blueOk, alphaOk, widthOk; int penRed, penGreen, penBlue, penAlpha; double penWidth; penWidth = itemElem.attribute( QStringLiteral( "outlineWidth" ) ).toDouble( &widthOk ); penRed = frameColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk ); penGreen = frameColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk ); penBlue = frameColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk ); penAlpha = frameColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk ); mFrameJoinStyle = QgsSymbolLayerUtils::decodePenJoinStyle( itemElem.attribute( QStringLiteral( "frameJoinStyle" ), QStringLiteral( "miter" ) ) ); if ( redOk && greenOk && blueOk && alphaOk && widthOk ) { mFrameColor = QColor( penRed, penGreen, penBlue, penAlpha ); mFrameWidth = penWidth; QPen framePen( mFrameColor ); framePen.setWidthF( mFrameWidth ); framePen.setJoinStyle( mFrameJoinStyle ); setPen( framePen ); //apply any data defined settings refreshFrameColor( false, context ); } } //brush QDomNodeList bgColorList = itemElem.elementsByTagName( QStringLiteral( "BackgroundColor" ) ); if ( !bgColorList.isEmpty() ) { QDomElement bgColorElem = bgColorList.at( 0 ).toElement(); bool redOk, greenOk, blueOk, alphaOk; int bgRed, bgGreen, bgBlue, bgAlpha; bgRed = bgColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk ); bgGreen = bgColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk ); bgBlue = bgColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk ); bgAlpha = bgColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk ); if ( redOk && greenOk && blueOk && alphaOk ) { mBackgroundColor = QColor( bgRed, bgGreen, bgBlue, bgAlpha ); setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) ); } //apply any data defined settings refreshBackgroundColor( false, context ); } //blend mode setBlendMode( QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( itemElem.attribute( QStringLiteral( "blendMode" ), QStringLiteral( "0" ) ).toUInt() ) ) ); //opacity if ( itemElem.hasAttribute( QStringLiteral( "opacity" ) ) ) { setItemOpacity( itemElem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1" ) ).toDouble() ); } else { setItemOpacity( 1.0 - itemElem.attribute( QStringLiteral( "transparency" ), QStringLiteral( "0" ) ).toInt() / 100.0 ); } mExcludeFromExports = itemElem.attribute( QStringLiteral( "excludeFromExports" ), QStringLiteral( "0" ) ).toInt(); mEvaluatedExcludeFromExports = mExcludeFromExports; QRectF evaluatedRect = evalItemRect( QRectF( x, y, width, height ) ); setSceneRect( evaluatedRect ); return true; }
void QgsComposerLegend::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget ) { Q_UNUSED( itemStyle ); Q_UNUSED( pWidget ); if ( !painter ) return; if ( !shouldDrawItem() ) { return; } if ( mFilterAskedForUpdate ) { mFilterAskedForUpdate = false; doUpdateFilterByMap(); } int dpi = painter->device()->logicalDpiX(); double dotsPerMM = dpi / 25.4; if ( mComposition ) { mSettings.setUseAdvancedEffects( mComposition->useAdvancedEffects() ); mSettings.setDpi( dpi ); } if ( mComposerMap ) { mSettings.setMmPerMapUnit( mComposerMap->mapUnitsToMM() ); // use a temporary QgsMapSettings to find out real map scale QSizeF mapSizePixels = QSizeF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ); QgsRectangle mapExtent = *mComposerMap->currentMapExtent(); QgsMapSettings ms = mComposerMap->mapSettings( mapExtent, mapSizePixels, dpi ); mSettings.setMapScale( ms.scale() ); } mInitialMapScaleCalculated = true; QgsLegendRenderer legendRenderer( mLegendModel.get(), mSettings ); legendRenderer.setLegendSize( mForceResize && mSizeToContents ? QSize() : rect().size() ); //adjust box if width or height is too small if ( mSizeToContents ) { QSizeF size = legendRenderer.minimumSize(); if ( mForceResize ) { mForceResize = false; //set new rect, respecting position mode and data defined size/position QRectF targetRect = QRectF( pos().x(), pos().y(), size.width(), size.height() ); setSceneRect( evalItemRect( targetRect, true ) ); } else if ( size.height() > rect().height() || size.width() > rect().width() ) { //need to resize box QRectF targetRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() ); if ( size.height() > targetRect.height() ) targetRect.setHeight( size.height() ); if ( size.width() > rect().width() ) targetRect.setWidth( size.width() ); //set new rect, respecting position mode and data defined size/position setSceneRect( evalItemRect( targetRect, true ) ); } } drawBackground( painter ); painter->save(); //antialiasing on painter->setRenderHint( QPainter::Antialiasing, true ); painter->setPen( QPen( QColor( 0, 0, 0 ) ) ); if ( !mSizeToContents ) { // set a clip region to crop out parts of legend which don't fit QRectF thisPaintRect = QRectF( 0, 0, rect().width(), rect().height() ); painter->setClipRect( thisPaintRect ); } legendRenderer.drawLegend( painter ); painter->restore(); //draw frame and selection boxes if necessary drawFrame( painter ); if ( isSelected() ) { drawSelectionBoxes( painter ); } }
void QgsComposerLegend::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget ) { Q_UNUSED( itemStyle ); Q_UNUSED( pWidget ); if ( !painter ) return; if ( !shouldDrawItem() ) { return; } int dpi = painter->device()->logicalDpiX(); double dotsPerMM = dpi / 25.4; if ( mComposition ) { mSettings.setUseAdvancedEffects( mComposition->useAdvancedEffects() ); mSettings.setDpi( dpi ); } if ( mComposerMap ) { mSettings.setMmPerMapUnit( mComposerMap->mapUnitsToMM() ); // use a temporary QgsMapSettings to find out real map scale QgsMapSettings ms = mComposerMap->composition()->mapSettings(); ms.setOutputSize( QSizeF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ).toSize() ); ms.setExtent( *mComposerMap->currentMapExtent() ); ms.setOutputDpi( dpi ); mSettings.setMapScale( ms.scale() ); } drawBackground( painter ); painter->save(); //antialiasing on painter->setRenderHint( QPainter::Antialiasing, true ); painter->setPen( QPen( QColor( 0, 0, 0 ) ) ); QgsLegendRenderer legendRenderer( mLegendModel2, mSettings ); legendRenderer.setLegendSize( rect().size() ); //adjust box if width or height is too small QSizeF size = legendRenderer.minimumSize(); if ( size.height() > rect().height() || size.width() > rect().width() ) { //need to resize box QRectF targetRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() ); if ( size.height() > targetRect.height() ) targetRect.setHeight( size.height() ); if ( size.width() > rect().width() ) targetRect.setWidth( size.width() ); //set new rect, respecting position mode and data defined size/position setSceneRect( evalItemRect( targetRect, true ) ); } legendRenderer.drawLegend( painter ); painter->restore(); //draw frame and selection boxes if necessary drawFrame( painter ); if ( isSelected() ) { drawSelectionBoxes( painter ); } }