예제 #1
0
QgsLayoutItemLabel::QgsLayoutItemLabel( QgsLayout *layout )
  : QgsLayoutItem( layout )
{
  mDistanceArea.reset( new QgsDistanceArea() );
  mHtmlUnitsToLayoutUnits = htmlUnitsToLayoutUnits();

  //get default layout font from settings
  QgsSettings settings;
  QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).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();

  mWebPage.reset( new QgsWebPage( this ) );
  mWebPage->setIdentifier( tr( "Layout 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 );

  mWebPage->mainFrame()->setZoomFactor( 10.0 );
  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );

  connect( mWebPage.get(), &QWebPage::loadFinished, this, &QgsLayoutItemLabel::loadingHtmlFinished );
}
예제 #2
0
QgsLayoutItemHtml::QgsLayoutItemHtml( QgsLayout *layout )
  : QgsLayoutMultiFrame( layout )
{
  mHtmlUnitsToLayoutUnits = htmlUnitsToLayoutUnits();
  mWebPage = qgis::make_unique< QgsWebPage >();
  mWebPage->setIdentifier( tr( "Layout 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() );

#if 0 //TODO
  if ( mLayout )
  {
    connect( mLayout, &QgsComposition::itemRemoved, this, &QgsComposerMultiFrame::handleFrameRemoval );
  }

  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(), &QgsAtlasComposition::featureChanged, this, &QgsLayoutItemHtml::refreshExpressionContext );
#endif

  mFetcher = new QgsNetworkContentFetcher();
}
예제 #3
0
double QgsLayoutItemHtml::findNearbyPageBreak( double yPos )
{
  if ( !mWebPage || mRenderedPage.isNull() || !mUseSmartBreaks )
  {
    return yPos;
  }

  //convert yPos to pixels
  int idealPos = yPos * htmlUnitsToLayoutUnits();

  //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 * htmlUnitsToLayoutUnits();

  //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 = std::max( 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
  std::sort( 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 ) / htmlUnitsToLayoutUnits();
    }
    minCandidateRow = ( *it ).first;
  }

  //above loop didn't work for some reason
  //return first candidate converted to mm
  return candidates[0].first / htmlUnitsToLayoutUnits();
}