QgsComposerLabel::QgsComposerLabel( QgsComposition *composition ): QgsComposerItem( composition ), mHtmlState( 0 ), mHtmlUnitsToMM( 1.0 ), mHtmlLoaded( false ), mMargin( 1.0 ), mFontColor( QColor( 0, 0, 0 ) ), mHAlignment( Qt::AlignLeft ), mVAlignment( Qt::AlignTop ), mExpressionFeature( 0 ), mExpressionLayer( 0 ) { mHtmlUnitsToMM = htmlUnitsToMM(); //get default composer font from settings QSettings settings; QString defaultFontString = settings.value( "/Composer/defaultFont" ).toString(); if ( !defaultFontString.isEmpty() ) { mFont.setFamily( defaultFontString ); } //default to a 10 point font size mFont.setPointSizeF( 10 ); //default to no background setBackgroundEnabled( false ); if ( mComposition && mComposition->atlasMode() == QgsComposition::PreviewAtlas ) { //a label added while atlas preview is enabled needs to have the expression context set, //otherwise fields in the label aren't correctly evaluated until atlas preview feature changes (#9457) setExpressionContext( mComposition->atlasComposition().currentFeature(), mComposition->atlasComposition().coverageLayer() ); } //connect to atlas feature changes //to update the expression context connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshExpressionContext() ) ); }
QgsComposerLabel::QgsComposerLabel( QgsComposition *composition ) : QgsComposerItem( composition ) , mHtmlState( 0 ) , mHtmlUnitsToMM( 1.0 ) , mHtmlLoaded( false ) , mMarginX( 1.0 ) , mMarginY( 1.0 ) , mFontColor( QColor( 0, 0, 0 ) ) , mHAlignment( Qt::AlignLeft ) , mVAlignment( Qt::AlignTop ) , mExpressionLayer( nullptr ) , mDistanceArea( nullptr ) { mDistanceArea = new QgsDistanceArea(); mHtmlUnitsToMM = htmlUnitsToMM(); //get default composer font from settings QSettings settings; QString defaultFontString = settings.value( QStringLiteral( "/Composer/defaultFont" ) ).toString(); if ( !defaultFontString.isEmpty() ) { mFont.setFamily( defaultFontString ); } //default to a 10 point font size mFont.setPointSizeF( 10 ); //default to no background setBackgroundEnabled( false ); //a label added while atlas preview is enabled needs to have the expression context set, //otherwise fields in the label aren't correctly evaluated until atlas preview feature changes (#9457) refreshExpressionContext(); if ( mComposition ) { //connect to atlas feature changes //to update the expression context connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshExpressionContext() ) ); } mWebPage = new QgsWebPage( this ); mWebPage->setIdentifier( tr( "Composer label item" ) ); mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() ); //This makes the background transparent. Found on http://blog.qt.digia.com/blog/2009/06/30/transparent-qwebview-or-qwebpage/ QPalette palette = mWebPage->palette(); palette.setBrush( QPalette::Base, Qt::transparent ); mWebPage->setPalette( palette ); //webPage->setAttribute(Qt::WA_OpaquePaintEvent, false); //this does not compile, why ? mWebPage->mainFrame()->setZoomFactor( 10.0 ); mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff ); mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff ); connect( mWebPage, SIGNAL( loadFinished( bool ) ), SLOT( loadingHtmlFinished( bool ) ) ); }
QgsComposerHtml::QgsComposerHtml( QgsComposition* c, bool createUndoCommands ): QgsComposerMultiFrame( c, createUndoCommands ), mWebPage( 0 ), mLoaded( false ), mHtmlUnitsToMM( 1.0 ) { mHtmlUnitsToMM = htmlUnitsToMM(); mWebPage = new QWebPage(); QObject::connect( mWebPage, SIGNAL( loadFinished( bool ) ), this, SLOT( frameLoaded( bool ) ) ); if ( mComposition ) { QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) ); } }
QgsComposerHtml::QgsComposerHtml( QgsComposition* c, bool createUndoCommands ) : QgsComposerMultiFrame( c, createUndoCommands ) , mContentMode( QgsComposerHtml::Url ) , mWebPage( nullptr ) , mLoaded( false ) , mHtmlUnitsToMM( 1.0 ) , mRenderedPage( nullptr ) , mEvaluateExpressions( true ) , mUseSmartBreaks( true ) , mMaxBreakDistance( 10 ) , mExpressionLayer( nullptr ) , mDistanceArea( nullptr ) , mEnableUserStylesheet( false ) , mFetcher( nullptr ) { mDistanceArea = new QgsDistanceArea(); mHtmlUnitsToMM = htmlUnitsToMM(); mWebPage = new QgsWebPage(); mWebPage->setIdentifier( tr( "Composer HTML item" ) ); mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff ); mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff ); //This makes the background transparent. Found on http://blog.qt.digia.com/blog/2009/06/30/transparent-qwebview-or-qwebpage/ QPalette palette = mWebPage->palette(); palette.setBrush( QPalette::Base, Qt::transparent ); mWebPage->setPalette( palette ); mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() ); QObject::connect( mWebPage, SIGNAL( loadFinished( bool ) ), this, SLOT( frameLoaded( bool ) ) ); if ( mComposition ) { QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) ); } // data defined strings mDataDefinedNames.insert( QgsComposerObject::SourceUrl, QString( "dataDefinedSourceUrl" ) ); if ( mComposition && mComposition->atlasMode() == QgsComposition::PreviewAtlas ) { //a html item added while atlas preview is enabled needs to have the expression context set, //otherwise fields in the html aren't correctly evaluated until atlas preview feature changes (#9457) setExpressionContext( mComposition->atlasComposition().feature(), mComposition->atlasComposition().coverageLayer() ); } //connect to atlas feature changes //to update the expression context connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshExpressionContext() ) ); mFetcher = new QgsNetworkContentFetcher(); connect( mFetcher, SIGNAL( finished() ), this, SLOT( frameLoaded() ) ); }
QgsComposerHtml::QgsComposerHtml( QgsComposition* c, bool createUndoCommands ): QgsComposerMultiFrame( c, createUndoCommands ), mWebPage( 0 ), mLoaded( false ), mHtmlUnitsToMM( 1.0 ), mRenderedPage( 0 ), mUseSmartBreaks( true ), mMaxBreakDistance( 10 ) { mHtmlUnitsToMM = htmlUnitsToMM(); mWebPage = new QWebPage(); mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() ); QObject::connect( mWebPage, SIGNAL( loadFinished( bool ) ), this, SLOT( frameLoaded( bool ) ) ); if ( mComposition ) { QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) ); connect( mComposition, SIGNAL( refreshItemsTriggered() ), this, SLOT( loadHtml() ) ); } }
QgsComposerLabel::QgsComposerLabel( QgsComposition *composition ): QgsComposerItem( composition ), mHtmlState( 0 ), mHtmlUnitsToMM( 1.0 ), mHtmlLoaded( false ), mMargin( 1.0 ), mFontColor( QColor( 0, 0, 0 ) ), mHAlignment( Qt::AlignLeft ), mVAlignment( Qt::AlignTop ), mExpressionFeature( 0 ), mExpressionLayer( 0 ) { mHtmlUnitsToMM = htmlUnitsToMM(); //get default composer font from settings QSettings settings; QString defaultFontString = settings.value( "/Composer/defaultFont" ).toString(); if ( !defaultFontString.isEmpty() ) { mFont.setFamily( defaultFontString ); } //default to a 10 point font size mFont.setPointSizeF( 10 ); }
QgsComposerHtml::QgsComposerHtml( QgsComposition* c, bool createUndoCommands ): QgsComposerMultiFrame( c, createUndoCommands ), mContentMode( QgsComposerHtml::Url ), mWebPage( 0 ), mLoaded( false ), mHtmlUnitsToMM( 1.0 ), mRenderedPage( 0 ), mEvaluateExpressions( true ), mUseSmartBreaks( true ), mMaxBreakDistance( 10 ), mExpressionFeature( 0 ), mExpressionLayer( 0 ), mEnableUserStylesheet( false ) { mHtmlUnitsToMM = htmlUnitsToMM(); mWebPage = new QWebPage(); mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() ); QObject::connect( mWebPage, SIGNAL( loadFinished( bool ) ), this, SLOT( frameLoaded( bool ) ) ); if ( mComposition ) { QObject::connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( handleFrameRemoval( QgsComposerItem* ) ) ); } // data defined strings mDataDefinedNames.insert( QgsComposerObject::SourceUrl, QString( "dataDefinedSourceUrl" ) ); if ( mComposition && mComposition->atlasMode() == QgsComposition::PreviewAtlas ) { //a html item added while atlas preview is enabled needs to have the expression context set, //otherwise fields in the html aren't correctly evaluated until atlas preview feature changes (#9457) setExpressionContext( mComposition->atlasComposition().currentFeature(), mComposition->atlasComposition().coverageLayer() ); } //connect to atlas feature changes //to update the expression context connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshExpressionContext() ) ); }
double QgsComposerHtml::findNearbyPageBreak( double yPos ) { if ( !mWebPage || !mRenderedPage || !mUseSmartBreaks ) { return yPos; } //convert yPos to pixels int idealPos = yPos * htmlUnitsToMM(); //if ideal break pos is past end of page, there's nothing we need to do if ( idealPos >= mRenderedPage->height() ) { return yPos; } int maxSearchDistance = mMaxBreakDistance * htmlUnitsToMM(); //loop through all lines just before ideal break location, up to max distance //of maxSearchDistance int changes = 0; QRgb currentColor; bool currentPixelTransparent = false; bool previousPixelTransparent = false; QRgb pixelColor; QList< QPair<int, int> > candidates; int minRow = qMax( idealPos - maxSearchDistance, 0 ); for ( int candidateRow = idealPos; candidateRow >= minRow; --candidateRow ) { changes = 0; currentColor = qRgba( 0, 0, 0, 0 ); //check all pixels in this line for ( int col = 0; col < mRenderedPage->width(); ++col ) { //count how many times the pixels change color in this row //eventually, we select a row to break at with the minimum number of color changes //since this is likely a line break, or gap between table cells, etc //but very unlikely to be midway through a text line or picture pixelColor = mRenderedPage->pixel( col, candidateRow ); currentPixelTransparent = qAlpha( pixelColor ) == 0; if ( pixelColor != currentColor && !( currentPixelTransparent && previousPixelTransparent ) ) { //color has changed currentColor = pixelColor; changes++; } previousPixelTransparent = currentPixelTransparent; } candidates.append( qMakePair( candidateRow, changes ) ); } //sort candidate rows by number of changes ascending, row number descending qSort( candidates.begin(), candidates.end(), candidateSort ); //first candidate is now the largest row with smallest number of changes //ok, now take the mid point of the best candidate position //we do this so that the spacing between text lines is likely to be split in half //otherwise the html will be broken immediately above a line of text, which //looks a little messy int maxCandidateRow = candidates[0].first; int minCandidateRow = maxCandidateRow + 1; int minCandidateChanges = candidates[0].second; QList< QPair<int, int> >::iterator it; for ( it = candidates.begin(); it != candidates.end(); ++it ) { if (( *it ).second != minCandidateChanges || ( *it ).first != minCandidateRow - 1 ) { //no longer in a consecutive block of rows of minimum pixel color changes //so return the row mid-way through the block //first converting back to mm return ( minCandidateRow + ( maxCandidateRow - minCandidateRow ) / 2 ) / htmlUnitsToMM(); } minCandidateRow = ( *it ).first; } //above loop didn't work for some reason //return first candidate converted to mm return candidates[0].first / htmlUnitsToMM(); }