QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const {
    if (which != Qt::PreferredSize || constraint.width() == -1)
       return QGraphicsWidget::sizeHint(which, constraint);
    else
       return QSizeF( constraint.width(), constraint.width() );
 }
QPointF reoriginCenterTopLeft(const QPointF& origin,const QSizeF& size)
{
	return realPointAsPixelPosition(origin-QPointF(realAsPixelSize(size.width()/2.0),realAsPixelSize(size.height()/2.0)));
}
QRectF realRectAroundRealPoint(const QSizeF& rectSize)
{
	QPointF topleft = -QPointF(realPointAsPixelPosition(QPointF(rectSize.width()/2.0,rectSize.height()/2.0)));
	return QRectF(topleft,rectSize);
}
Beispiel #4
0
void QSvgText::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    qreal oldOpacity = p->opacity();
    p->setOpacity(oldOpacity * states.fillOpacity);

    // Force the font to have a size of 100 pixels to avoid truncation problems
    // when the font is very small.
    qreal scale = 100.0 / p->font().pointSizeF();
    Qt::Alignment alignment = states.textAnchor;

    QTransform oldTransform = p->worldTransform();
    p->scale(1 / scale, 1 / scale);

    qreal y = 0;
    bool initial = true;
    qreal px = m_coord.x() * scale;
    qreal py = m_coord.y() * scale;
    QSizeF scaledSize = m_size * scale;

    if (m_type == TEXTAREA) {
        if (alignment == Qt::AlignHCenter)
            px += scaledSize.width() / 2;
        else if (alignment == Qt::AlignRight)
            px += scaledSize.width();
    }

    QRectF bounds;
    if (m_size.height() != 0)
        bounds = QRectF(0, py, 1, scaledSize.height()); // x and width are not used.

    bool appendSpace = false;
    QVector<QString> paragraphs;
    QStack<QTextCharFormat> formats;
    QVector<QList<QTextLayout::FormatRange> > formatRanges;
    paragraphs.push_back(QString());
    formatRanges.push_back(QList<QTextLayout::FormatRange>());

    for (int i = 0; i < m_tspans.size(); ++i) {
        if (m_tspans[i] == LINEBREAK) {
            if (m_type == TEXTAREA) {
                if (paragraphs.back().isEmpty()) {
                    QFont font = p->font();
                    font.setPixelSize(font.pointSizeF() * scale);

                    QTextLayout::FormatRange range;
                    range.start = 0;
                    range.length = 1;
                    range.format.setFont(font);
                    formatRanges.back().append(range);

                    paragraphs.back().append(QLatin1Char(' '));;
                }
                appendSpace = false;
                paragraphs.push_back(QString());
                formatRanges.push_back(QList<QTextLayout::FormatRange>());
            }
        } else {
            WhitespaceMode mode = m_tspans[i]->whitespaceMode();
            m_tspans[i]->applyStyle(p, states);

            QFont font = p->font();
            font.setPixelSize(font.pointSizeF() * scale);

            QString newText(m_tspans[i]->text());
            newText.replace(QLatin1Char('\t'), QLatin1Char(' '));
            newText.replace(QLatin1Char('\n'), QLatin1Char(' '));

            bool prependSpace = !appendSpace && !m_tspans[i]->isTspan() && (mode == Default) && !paragraphs.back().isEmpty() && newText.startsWith(QLatin1Char(' '));
            if (appendSpace || prependSpace)
                paragraphs.back().append(QLatin1Char(' '));

            bool appendSpaceNext = (!m_tspans[i]->isTspan() && (mode == Default) && newText.endsWith(QLatin1Char(' ')));

            if (mode == Default) {
                newText = newText.simplified();
                if (newText.isEmpty())
                    appendSpaceNext = false;
            }

            QTextLayout::FormatRange range;
            range.start = paragraphs.back().length();
            range.length = newText.length();
            range.format.setFont(font);
            range.format.setTextOutline(p->pen());
            range.format.setForeground(p->brush());

            if (appendSpace) {
                Q_ASSERT(!formatRanges.back().isEmpty());
                ++formatRanges.back().back().length;
            } else if (prependSpace) {
                --range.start;
                ++range.length;
            }
            formatRanges.back().append(range);

            appendSpace = appendSpaceNext;
            paragraphs.back() += newText;

            m_tspans[i]->revertStyle(p, states);
        }
    }

    if (states.svgFont) {
        // SVG fonts not fully supported...
        QString text = paragraphs.front();
        for (int i = 1; i < paragraphs.size(); ++i) {
            text.append(QLatin1Char('\n'));
            text.append(paragraphs[i]);
        }
        states.svgFont->draw(p, m_coord * scale, text, p->font().pointSizeF() * scale, states.textAnchor);
    } else {
        for (int i = 0; i < paragraphs.size(); ++i) {
            QTextLayout tl(paragraphs[i]);
            QTextOption op = tl.textOption();
            op.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
            tl.setTextOption(op);
            tl.setAdditionalFormats(formatRanges[i]);
            tl.beginLayout();

            forever {
                QTextLine line = tl.createLine();
                if (!line.isValid())
                    break;
                if (m_size.width() != 0)
                    line.setLineWidth(scaledSize.width());
            }
            tl.endLayout();

            bool endOfBoundsReached = false;
            for (int i = 0; i < tl.lineCount(); ++i) {
                QTextLine line = tl.lineAt(i);

                qreal x = 0;
                if (alignment == Qt::AlignHCenter)
                    x -= 0.5 * line.naturalTextWidth();
                else if (alignment == Qt::AlignRight)
                    x -= line.naturalTextWidth();

                if (initial && m_type == TEXT)
                    y -= line.ascent();
                initial = false;

                line.setPosition(QPointF(x, y));

                // Check if the current line fits into the bounding rectangle.
                if ((m_size.width() != 0 && line.naturalTextWidth() > scaledSize.width())
                    || (m_size.height() != 0 && y + line.height() > scaledSize.height())) {
                    // I need to set the bounds height to 'y-epsilon' to avoid drawing the current
                    // line. Since the font is scaled to 100 units, 1 should be a safe epsilon.
                    bounds.setHeight(y - 1);
                    endOfBoundsReached = true;
                    break;
                }

                y += 1.1 * line.height();
            }
            tl.draw(p, QPointF(px, py), QVector<QTextLayout::FormatRange>(), bounds);

            if (endOfBoundsReached)
                break;
        }
    }

    p->setWorldTransform(oldTransform, false);
    p->setOpacity(oldOpacity);
    revertStyle(p, states);
}
static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,
                                              QRectF *rect, Qt::WindowFrameSection section,
                                              const QSizeF &min, const QSizeF &max,
                                              const QGraphicsWidget *widget)
{
    const QRectF proposedRect = *rect;
    qreal width = qBound(min.width(), proposedRect.width(), max.width());
    qreal height = qBound(min.height(), proposedRect.height(), max.height());

    const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
    const bool hasWFH = QGraphicsLayoutItemPrivate::get(widget)->hasWidthForHeight();

    const bool widthChanged = proposedRect.width() != widget->size().width();
    const bool heightChanged = proposedRect.height() != widget->size().height();

    if (hasHFW || hasWFH) {
        if (widthChanged || heightChanged) {
            qreal minExtent;
            qreal maxExtent;
            qreal constraint;
            qreal proposed;
            if (hasHFW) {
                minExtent = min.height();
                maxExtent = max.height();
                constraint = width;
                proposed = proposedRect.height();
            } else {
                // width for height
                minExtent = min.width();
                maxExtent = max.width();
                constraint = height;
                proposed = proposedRect.width();
            }
            if (minimumHeightForWidth(constraint, minExtent, maxExtent, widget, hasHFW) > proposed) {
                QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);
                width = effectiveSize.width();
                height = effectiveSize.height();
            }
        }
    }

    switch (section) {
    case Qt::LeftSection:
        rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
                      qRound(width), startGeometry.height());
        break;
    case Qt::TopLeftSection:
        rect->setRect(startGeometry.right() - qRound(width), startGeometry.bottom() - qRound(height),
                      qRound(width), qRound(height));
        break;
    case Qt::TopSection:
        rect->setRect(startGeometry.left(), startGeometry.bottom() - qRound(height),
                      startGeometry.width(), qRound(height));
        break;
    case Qt::TopRightSection:
        rect->setTop(rect->bottom() - qRound(height));
        rect->setWidth(qRound(width));
        break;
    case Qt::RightSection:
        rect->setWidth(qRound(width));
        break;
    case Qt::BottomRightSection:
        rect->setWidth(qRound(width));
        rect->setHeight(qRound(height));
        break;
    case Qt::BottomSection:
        rect->setHeight(qRound(height));
        break;
    case Qt::BottomLeftSection:
        rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
                      qRound(width), qRound(height));
        break;
    default:
        break;
    }
}
Beispiel #6
0
void QDeclarativeWebView::updateDeclarativeWebViewSize()
{
    QSizeF size = d->view->geometry().size() * contentsScale();
    setImplicitWidth(size.width());
    setImplicitHeight(size.height());
}
Beispiel #7
0
            if ( m_haltFlag )
                return;
        }

        QImage img( d->previewSize, QImage::Format_ARGB32 );
        img.fill( Qt::transparent );
        QPainter p( &img );

        QSvgRenderer renderer( theme.graphicsFilePath() );

        QSizeF size = renderer.boundsOnElement(QStringLiteral("back")).size();
        size.scale( 1.5 * d->baseCardSize.width(), d->baseCardSize.height(), Qt::KeepAspectRatio );

        qreal yPos = ( d->previewSize.height() - size.height() ) / 2;
        qreal spacingWidth = d->baseCardSize.width()
                             * ( d->previewSize.width() - d->previewLayout.size() * size.width() )
                             / ( d->previewSize.width() - d->previewLayout.size() * d->baseCardSize.width() );

        qreal xPos = 0;
        foreach ( const QList<QString> & pile, d->previewLayout )
        {
            foreach ( const QString & card, pile )
            {
                renderer.render( &p, card, QRectF( QPointF( xPos, yPos ), size ) );
                xPos += 0.3 * spacingWidth;
            }
            xPos += 1 * size.width() + ( 0.1 - 0.3 ) * spacingWidth;
        }

        emit previewRendered( theme, img );
    }
QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer,
    QWidget* parent, QgsMapCanvas *canvas )
    : QWidget( parent )
    , mMapCanvas( canvas )
{
  mLayer = layer;
  if ( !layer )
  {
    return;
  }

  setupUi( this );

  // get rid of annoying outer focus rect on Mac
  mDiagramOptionsListWidget->setAttribute( Qt::WA_MacShowFocusRect, false );

  mDiagramTypeComboBox->blockSignals( true );
  QPixmap pix = QgsApplication::getThemePixmap( "diagramNone" );
  mDiagramTypeComboBox->addItem( pix, tr( "No diagrams" ), "None" );
  pix = QgsApplication::getThemePixmap( "pie-chart" );
  mDiagramTypeComboBox->addItem( pix, tr( "Pie chart" ), DIAGRAM_NAME_PIE );
  pix = QgsApplication::getThemePixmap( "text" );
  mDiagramTypeComboBox->addItem( pix, tr( "Text diagram" ), DIAGRAM_NAME_TEXT );
  pix = QgsApplication::getThemePixmap( "histogram" );
  mDiagramTypeComboBox->addItem( pix, tr( "Histogram" ), DIAGRAM_NAME_HISTOGRAM );
  mDiagramTypeComboBox->blockSignals( false );

  mScaleRangeWidget->setMapCanvas( QgisApp::instance()->mapCanvas() );
  mSizeFieldExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, mLayer );

  mBackgroundColorButton->setColorDialogTitle( tr( "Select background color" ) );
  mBackgroundColorButton->setAllowAlpha( true );
  mBackgroundColorButton->setContext( "symbology" );
  mBackgroundColorButton->setShowNoColor( true );
  mBackgroundColorButton->setNoColorString( tr( "Transparent background" ) );
  mDiagramPenColorButton->setColorDialogTitle( tr( "Select pen color" ) );
  mDiagramPenColorButton->setAllowAlpha( true );
  mDiagramPenColorButton->setContext( "symbology" );
  mDiagramPenColorButton->setShowNoColor( true );
  mDiagramPenColorButton->setNoColorString( tr( "Transparent outline" ) );

  mMaxValueSpinBox->setShowClearButton( false );

  connect( mFixedSizeRadio, SIGNAL( toggled( bool ) ), this, SLOT( scalingTypeChanged() ) );
  connect( mAttributeBasedScalingRadio, SIGNAL( toggled( bool ) ), this, SLOT( scalingTypeChanged() ) );

  mDiagramUnitComboBox->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit << QgsSymbolV2::Pixel );
  mDiagramLineUnitComboBox->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit << QgsSymbolV2::Pixel );

  QGis::GeometryType layerType = layer->geometryType();
  if ( layerType == QGis::UnknownGeometry || layerType == QGis::NoGeometry )
  {
    mDiagramTypeComboBox->setEnabled( false );
    mDiagramFrame->setEnabled( false );
  }

  //insert placement options
  mPlacementComboBox->blockSignals( true );
  switch ( layerType )
  {
    case QGis::Point:
      mPlacementComboBox->addItem( tr( "Around Point" ), QgsDiagramLayerSettings::AroundPoint );
      mPlacementComboBox->addItem( tr( "Over Point" ), QgsDiagramLayerSettings::OverPoint );
      mLinePlacementFrame->setVisible( false );
      break;
    case QGis::Line:
      mPlacementComboBox->addItem( tr( "Around Line" ), QgsDiagramLayerSettings::Line );
      mPlacementComboBox->addItem( tr( "Over Line" ), QgsDiagramLayerSettings::Horizontal );
      mLinePlacementFrame->setVisible( true );
      break;
    case QGis::Polygon:
      mPlacementComboBox->addItem( tr( "Around Centroid" ), QgsDiagramLayerSettings::AroundPoint );
      mPlacementComboBox->addItem( tr( "Over Centroid" ), QgsDiagramLayerSettings::OverPoint );
      mPlacementComboBox->addItem( tr( "Perimeter" ), QgsDiagramLayerSettings::Line );
      mPlacementComboBox->addItem( tr( "Inside Polygon" ), QgsDiagramLayerSettings::Horizontal );
      mLinePlacementFrame->setVisible( false );
      break;
    default:
      break;
  }
  mPlacementComboBox->blockSignals( false );

  mLabelPlacementComboBox->addItem( tr( "Height" ), QgsDiagramSettings::Height );
  mLabelPlacementComboBox->addItem( tr( "x-height" ), QgsDiagramSettings::XHeight );

  mScaleDependencyComboBox->addItem( tr( "Area" ), true );
  mScaleDependencyComboBox->addItem( tr( "Diameter" ), false );

  mDataDefinedXComboBox->addItem( tr( "None" ), -1 );
  mDataDefinedYComboBox->addItem( tr( "None" ), -1 );

  mAngleOffsetComboBox->addItem( tr( "Top" ), 90 * 16 );
  mAngleOffsetComboBox->addItem( tr( "Right" ), 0 );
  mAngleOffsetComboBox->addItem( tr( "Bottom" ), 270 * 16 );
  mAngleOffsetComboBox->addItem( tr( "Left" ), 180 * 16 );

  mDataDefinedVisibilityComboBox->addItem( tr( "None" ), -1 );

  QSettings settings;

  // reset horiz strech of left side of options splitter (set to 1 for previewing in Qt Designer)
  QSizePolicy policy( mDiagramOptionsListFrame->sizePolicy() );
  policy.setHorizontalStretch( 0 );
  mDiagramOptionsListFrame->setSizePolicy( policy );
  if ( !settings.contains( QString( "/Windows/Diagrams/OptionsSplitState" ) ) )
  {
    // set left list widget width on intial showing
    QList<int> splitsizes;
    splitsizes << 115;
    mDiagramOptionsSplitter->setSizes( splitsizes );
  }

  // restore dialog, splitters and current tab
  mDiagramOptionsSplitter->restoreState( settings.value( QString( "/Windows/Diagrams/OptionsSplitState" ) ).toByteArray() );
  mDiagramOptionsListWidget->setCurrentRow( settings.value( QString( "/Windows/Diagrams/Tab" ), 0 ).toInt() );

  // field combo and expression button
  mSizeFieldExpressionWidget->setLayer( mLayer );
  QgsDistanceArea myDa;
  myDa.setSourceCrs( mLayer->crs().srsid() );
  myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() );
  myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
  mSizeFieldExpressionWidget->setGeomCalculator( myDa );

  //insert all attributes into the combo boxes
  const QgsFields& layerFields = layer->fields();
  for ( int idx = 0; idx < layerFields.count(); ++idx )
  {
    QTreeWidgetItem *newItem = new QTreeWidgetItem( mAttributesTreeWidget );
    QString name = QString( "\"%1\"" ).arg( layerFields[idx].name() );
    newItem->setText( 0, name );
    newItem->setData( 0, Qt::UserRole, name );
    newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );

    mDataDefinedXComboBox->addItem( layerFields[idx].name(), idx );
    mDataDefinedYComboBox->addItem( layerFields[idx].name(), idx );
    mDataDefinedVisibilityComboBox->addItem( layerFields[idx].name(), idx );
  }

  const QgsDiagramRendererV2* dr = layer->diagramRenderer();
  if ( !dr ) //no diagram renderer yet, insert reasonable default
  {
    mDiagramTypeComboBox->blockSignals( true );
    mDiagramTypeComboBox->setCurrentIndex( 0 );
    mDiagramTypeComboBox->blockSignals( false );
    mFixedSizeRadio->setChecked( true );
    mDiagramUnitComboBox->setUnit( QgsSymbolV2::MM );
    mDiagramLineUnitComboBox->setUnit( QgsSymbolV2::MM );
    mLabelPlacementComboBox->setCurrentIndex( mLabelPlacementComboBox->findText( tr( "x-height" ) ) );
    mDiagramSizeSpinBox->setEnabled( true );
    mDiagramSizeSpinBox->setValue( 15 );
    mLinearScaleFrame->setEnabled( false );
    mIncreaseMinimumSizeSpinBox->setEnabled( false );
    mIncreaseMinimumSizeLabel->setEnabled( false );
    mBarWidthSpinBox->setValue( 5 );
    mScaleVisibilityGroupBox->setChecked( layer->hasScaleBasedVisibility() );
    mScaleRangeWidget->setScaleRange( 1.0 / layer->maximumScale(), 1.0 / layer->minimumScale() ); // caution: layer uses scale denoms, widget uses true scales
    mShowAllCheckBox->setChecked( true );
    mDataDefinedVisibilityGroupBox->setChecked( false );
    mCheckBoxAttributeLegend->setChecked( true );
    mCheckBoxSizeLegend->setChecked( false );
    mSizeLegendSymbol.reset( QgsMarkerSymbolV2::createSimple( QgsStringMap() ) );

    switch ( layerType )
    {
      case QGis::Point:
        mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( QgsDiagramLayerSettings::AroundPoint ) );
        break;
      case QGis::Line:
        mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( QgsDiagramLayerSettings::Line ) );
        chkLineAbove->setChecked( true );
        chkLineBelow->setChecked( false );
        chkLineOn->setChecked( false );
        chkLineOrientationDependent->setChecked( false );
        break;
      case QGis::Polygon:
        mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( QgsDiagramLayerSettings::AroundPoint ) );
        break;
      case QGis::UnknownGeometry:
      case QGis::NoGeometry:
        break;
    }
    mBackgroundColorButton->setColor( QColor( 255, 255, 255, 255 ) );
    //force a refresh of widget status to match diagram type
    on_mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
  }
  else // already a diagram renderer present
  {
    //single category renderer or interpolated one?
    if ( dr->rendererName() == "SingleCategory" )
    {
      mFixedSizeRadio->setChecked( true );
    }
    else
    {
      mAttributeBasedScalingRadio->setChecked( true );
    }
    mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() );
    mLinearScaleFrame->setEnabled( mAttributeBasedScalingRadio->isChecked() );
    mCheckBoxAttributeLegend->setChecked( dr->attributeLegend() );
    mCheckBoxSizeLegend->setChecked( dr->sizeLegend() );
    mSizeLegendSymbol.reset( dr->sizeLegendSymbol() ? dr->sizeLegendSymbol()->clone() : QgsMarkerSymbolV2::createSimple( QgsStringMap() ) );
    QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mSizeLegendSymbol.data(), mButtonSizeLegendSymbol->iconSize() );
    mButtonSizeLegendSymbol->setIcon( icon );

    //assume single category or linearly interpolated diagram renderer for now
    QList<QgsDiagramSettings> settingList = dr->diagramSettings();
    if ( !settingList.isEmpty() )
    {
      mDiagramFrame->setEnabled( settingList.at( 0 ).enabled );
      mDiagramFont = settingList.at( 0 ).font;
      QSizeF size = settingList.at( 0 ).size;
      mBackgroundColorButton->setColor( settingList.at( 0 ).backgroundColor );
      mTransparencySpinBox->setValue( settingList.at( 0 ).transparency * 100.0 / 255.0 );
      mTransparencySlider->setValue( mTransparencySpinBox->value() );
      mDiagramPenColorButton->setColor( settingList.at( 0 ).penColor );
      mPenWidthSpinBox->setValue( settingList.at( 0 ).penWidth );
      mDiagramSizeSpinBox->setValue(( size.width() + size.height() ) / 2.0 );
      // caution: layer uses scale denoms, widget uses true scales
      mScaleRangeWidget->setScaleRange( 1.0 / ( settingList.at( 0 ).maxScaleDenominator > 0 ? settingList.at( 0 ).maxScaleDenominator : layer->maximumScale() ),
                                        1.0 / ( settingList.at( 0 ).minScaleDenominator > 0 ? settingList.at( 0 ).minScaleDenominator : layer->minimumScale() ) );
      mScaleVisibilityGroupBox->setChecked( settingList.at( 0 ).scaleBasedVisibility );
      mDiagramUnitComboBox->setUnit( settingList.at( 0 ).sizeType );
      mDiagramUnitComboBox->setMapUnitScale( settingList.at( 0 ).sizeScale );
      mDiagramLineUnitComboBox->setUnit( settingList.at( 0 ).lineSizeUnit );
      mDiagramLineUnitComboBox->setMapUnitScale( settingList.at( 0 ).lineSizeScale );

      if ( settingList.at( 0 ).labelPlacementMethod == QgsDiagramSettings::Height )
      {
        mLabelPlacementComboBox->setCurrentIndex( 0 );
      }
      else
      {
        mLabelPlacementComboBox->setCurrentIndex( 1 );
      }

      mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).angleOffset ) );

      mOrientationLeftButton->setProperty( "direction", QgsDiagramSettings::Left );
      mOrientationRightButton->setProperty( "direction", QgsDiagramSettings::Right );
      mOrientationUpButton->setProperty( "direction", QgsDiagramSettings::Up );
      mOrientationDownButton->setProperty( "direction", QgsDiagramSettings::Down );
      switch ( settingList.at( 0 ).diagramOrientation )
      {
        case QgsDiagramSettings::Left:
          mOrientationLeftButton->setChecked( true );
          break;

        case QgsDiagramSettings::Right:
          mOrientationRightButton->setChecked( true );
          break;

        case QgsDiagramSettings::Up:
          mOrientationUpButton->setChecked( true );
          break;

        case QgsDiagramSettings::Down:
          mOrientationDownButton->setChecked( true );
          break;
      }

      mBarWidthSpinBox->setValue( settingList.at( 0 ).barWidth );

      mIncreaseSmallDiagramsCheck->setChecked( settingList.at( 0 ).minimumSize != 0 );
      mIncreaseMinimumSizeSpinBox->setEnabled( mIncreaseSmallDiagramsCheck->isChecked() );
      mIncreaseMinimumSizeLabel->setEnabled( mIncreaseSmallDiagramsCheck->isChecked() );

      mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize );

      if ( settingList.at( 0 ).scaleByArea )
      {
        mScaleDependencyComboBox->setCurrentIndex( 0 );
      }
      else
      {
        mScaleDependencyComboBox->setCurrentIndex( 1 );
      }

      QList< QColor > categoryColors = settingList.at( 0 ).categoryColors;
      QList< QString > categoryAttributes = settingList.at( 0 ).categoryAttributes;
      QList< QString > categoryLabels = settingList.at( 0 ).categoryLabels;
      QList< QString >::const_iterator catIt = categoryAttributes.constBegin();
      QList< QColor >::const_iterator coIt = categoryColors.constBegin();
      QList< QString >::const_iterator labIt = categoryLabels.constBegin();
      for ( ; catIt != categoryAttributes.constEnd(); ++catIt, ++coIt, ++labIt )
      {
        QTreeWidgetItem *newItem = new QTreeWidgetItem( mDiagramAttributesTreeWidget );
        newItem->setText( 0, *catIt );
        newItem->setData( 0, Qt::UserRole, *catIt );
        newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );
        QColor col( *coIt );
        col.setAlpha( 255 );
        newItem->setBackground( 1, QBrush( col ) );
        newItem->setText( 2, *labIt );
        newItem->setFlags( newItem->flags() | Qt::ItemIsEditable );
      }
    }

    if ( dr->rendererName() == "LinearlyInterpolated" )
    {
      const QgsLinearlyInterpolatedDiagramRenderer* lidr = dynamic_cast<const QgsLinearlyInterpolatedDiagramRenderer*>( dr );
      if ( lidr )
      {
        mDiagramSizeSpinBox->setEnabled( false );
        mLinearScaleFrame->setEnabled( true );
        mMaxValueSpinBox->setValue( lidr->upperValue() );
        mSizeSpinBox->setValue(( lidr->upperSize().width() + lidr->upperSize().height() ) / 2 );
        if ( lidr->classificationAttributeIsExpression() )
        {
          mSizeFieldExpressionWidget->setField( lidr->classificationAttributeExpression() );
        }
        else
        {
          mSizeFieldExpressionWidget->setField( mLayer->fields().at( lidr->classificationAttribute() ).name() );
        }
      }
    }

    const QgsDiagramLayerSettings *dls = layer->diagramLayerSettings();
    if ( dls )
    {
      mDiagramDistanceSpinBox->setValue( dls->distance() );
      mPrioritySlider->setValue( dls->getPriority() );
      mZIndexSpinBox->setValue( dls->getZIndex() );
      mDataDefinedXComboBox->setCurrentIndex( mDataDefinedXComboBox->findData( dls->xPosColumn ) );
      mDataDefinedYComboBox->setCurrentIndex( mDataDefinedYComboBox->findData( dls->yPosColumn ) );
      if ( dls->xPosColumn != -1 || dls->yPosColumn != -1 )
      {
        mDataDefinedPositionGroupBox->setChecked( true );
      }
      mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( dls->getPlacement() ) );

      chkLineAbove->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::AboveLine );
      chkLineBelow->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::BelowLine );
      chkLineOn->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::OnLine );
      if ( !( dls->linePlacementFlags() & QgsDiagramLayerSettings::MapOrientation ) )
        chkLineOrientationDependent->setChecked( true );

      mShowAllCheckBox->setChecked( dls->showAllDiagrams() );
      mDataDefinedVisibilityComboBox->setCurrentIndex( mDataDefinedVisibilityComboBox->findData( dls->showColumn ) );
      if ( dls->showColumn != -1 )
      {
        mDataDefinedVisibilityGroupBox->setChecked( true );
      }
    }

    if ( dr->diagram() )
    {
      mDiagramType = dr->diagram()->diagramName();

      mDiagramTypeComboBox->blockSignals( true );
      mDiagramTypeComboBox->setCurrentIndex( settingList.at( 0 ).enabled ? mDiagramTypeComboBox->findData( mDiagramType ) : 0 );
      mDiagramTypeComboBox->blockSignals( false );
      //force a refresh of widget status to match diagram type
      on_mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() );
      if ( mDiagramTypeComboBox->currentIndex() == -1 )
      {
        QMessageBox::warning( this, tr( "Unknown diagram type." ),
                              tr( "The diagram type '%1' is unknown. A default type is selected for you." ).arg( mDiagramType ), QMessageBox::Ok );
        mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( DIAGRAM_NAME_PIE ) );
      }
    }
  } // if ( !dr )

  connect( mAddAttributeExpression, SIGNAL( clicked() ), this, SLOT( showAddAttributeExpressionDialog() ) );
  connect( mTransparencySlider, SIGNAL( valueChanged( int ) ), mTransparencySpinBox, SLOT( setValue( int ) ) );
  connect( mTransparencySpinBox, SIGNAL( valueChanged( int ) ), mTransparencySlider, SLOT( setValue( int ) ) );
}
Beispiel #9
0
/*!
   \return Icon representing the curve on the legend

   \param index Index of the legend entry 
                ( ignored as there is only one )
   \param size Icon size

   \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
 */
QwtGraphic QwtPlotCurve::legendIcon( int index, 
    const QSizeF &size ) const
{
    Q_UNUSED( index );

    if ( size.isEmpty() )
        return QwtGraphic();

    QwtGraphic graphic;
    graphic.setDefaultSize( size );
    graphic.setRenderHint( QwtGraphic::RenderPensUnscaled, true );

    QPainter painter( &graphic );
    painter.setRenderHint( QPainter::Antialiasing,
        testRenderHint( QwtPlotItem::RenderAntialiased ) );

    if ( d_data->legendAttributes == 0 ||
        d_data->legendAttributes & QwtPlotCurve::LegendShowBrush )
    {
        QBrush brush = d_data->brush;

        if ( brush.style() == Qt::NoBrush &&
            d_data->legendAttributes == 0 )
        {
            if ( style() != QwtPlotCurve::NoCurve )
            {
                brush = QBrush( pen().color() );
            }
            else if ( d_data->symbol &&
                ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
            {
                brush = QBrush( d_data->symbol->pen().color() );
            }
        }

        if ( brush.style() != Qt::NoBrush )
        {
            QRectF r( 0, 0, size.width(), size.height() );
            painter.fillRect( r, brush );
        }
    }

    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine )
    {
        if ( pen() != Qt::NoPen )
        {
            QPen pn = pen();
            pn.setCapStyle( Qt::FlatCap );

            painter.setPen( pn );

            const double y = 0.5 * size.height();
            QwtPainter::drawLine( &painter, 0.0, y, size.width(), y );
        }
    }

    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
    {
        if ( d_data->symbol )
        {
            QRectF r( 0, 0, size.width(), size.height() );
            d_data->symbol->drawSymbol( &painter, r );
        }
    }

    return graphic;
}
Beispiel #10
0
void ShaderLibrary::setUniformVariable(GLuint /*program*/, GLint location, QSizeF const& value)
{
   glUniform2f(location, value.width(), value.height());
}
Beispiel #11
0
QRectF CurveItem::Marker::boundingRect() const
{
    return QRectF(-markerSize.width() / 2, -markerSize.height() / 2, markerSize.width(), markerSize.height());
}
Beispiel #12
0
/*!
    Returns the size that will be used if the width of the label is \a
    w. If \a w is -1, the sizeHint() is returned. If \a w is 0 minimumSizeHint() is returned
*/
QSize QLabelPrivate::sizeForWidth(int w) const
{
    Q_Q(const QLabel);
    if(q->minimumWidth() > 0)
        w = qMax(w, q->minimumWidth());
    QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);

    QRect br;

    int hextra = 2 * margin;
    int vextra = hextra;
    QFontMetrics fm = q->fontMetrics();

    if (pixmap && !pixmap->isNull()) {
        br = pixmap->rect();
        br.setSize(br.size() / pixmap->devicePixelRatio());
#ifndef QT_NO_PICTURE
    } else if (picture && !picture->isNull()) {
        br = picture->boundingRect();
#endif
#if QT_CONFIG(movie)
    } else if (movie && !movie->currentPixmap().isNull()) {
        br = movie->currentPixmap().rect();
        br.setSize(br.size() / movie->currentPixmap().devicePixelRatio());
#endif
    } else if (isTextLabel) {
        int align = QStyle::visualAlignment(textDirection(), QFlag(this->align));
        // Add indentation
        int m = indent;

        if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
            m = fm.width(QLatin1Char('x')) - margin*2;
        if (m > 0) {
            if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
                hextra += m;
            if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
                vextra += m;
        }

        if (control) {
            ensureTextLayouted();
            const qreal oldTextWidth = control->textWidth();
            // Calculate the length of document if w is the width
            if (align & Qt::TextWordWrap) {
                if (w >= 0) {
                    w = qMax(w-hextra-contentsMargin.width(), 0); // strip margin and indent
                    control->setTextWidth(w);
                } else {
                    control->adjustSize();
                }
            } else {
                control->setTextWidth(-1);
            }

            QSizeF controlSize = control->size();
            br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height())));

            // restore state
            control->setTextWidth(oldTextWidth);
        } else {
            // Turn off center alignment in order to avoid rounding errors for centering,
            // since centering involves a division by 2. At the end, all we want is the size.
            int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
            if (hasShortcut) {
                flags |= Qt::TextShowMnemonic;
                QStyleOption opt;
                opt.initFrom(q);
                if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
                    flags |= Qt::TextHideMnemonic;
            }

            bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
            if (tryWidth)
                w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width());
            else if (w < 0)
                w = 2000;
            w -= (hextra + contentsMargin.width());
            br = fm.boundingRect(0, 0, w ,2000, flags, text);
            if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
                br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
            if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
                br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
        }
    } else {
        br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
    }

    const QSize contentsSize(br.width() + hextra, br.height() + vextra);
    return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
}
Beispiel #13
0
void QgsLayoutItemLegend::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
{
  if ( !painter )
    return;

  if ( mFilterAskedForUpdate )
  {
    mFilterAskedForUpdate = false;
    doUpdateFilterByMap();
  }

  int dpi = painter->device()->logicalDpiX();
  double dotsPerMM = dpi / 25.4;

  if ( mLayout )
  {
    mSettings.setUseAdvancedEffects( mLayout->renderContext().flags() & QgsLayoutRenderContext::FlagUseAdvancedEffects );
    mSettings.setDpi( dpi );
  }
  if ( mMap && mLayout )
  {
    mSettings.setMmPerMapUnit( mLayout->convertFromLayoutUnits( mMap->mapUnitsToLayoutUnits(), QgsUnitTypes::LayoutMillimeters ).length() );

    // use a temporary QgsMapSettings to find out real map scale
    QSizeF mapSizePixels = QSizeF( mMap->rect().width() * dotsPerMM, mMap->rect().height() * dotsPerMM );
    QgsRectangle mapExtent = mMap->extent();

    QgsMapSettings ms = mMap->mapSettings( mapExtent, mapSizePixels, dpi, false );
    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
      QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( size, sizeWithUnits().units() );
      attemptResize( newSize );
    }
    else if ( size.height() > rect().height() || size.width() > rect().width() )
    {
      //need to resize box
      QSizeF targetSize = rect().size();
      if ( size.height() > targetSize.height() )
        targetSize.setHeight( size.height() );
      if ( size.width() > targetSize.width() )
        targetSize.setWidth( size.width() );

      QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( targetSize, sizeWithUnits().units() );
      //set new rect, respecting position mode and data defined size/position
      attemptResize( newSize );
    }
  }
  QgsLayoutItem::paint( painter, itemStyle, pWidget );
}
Beispiel #14
0
QVariant Property::convert(QVariant &value, QVariant::Type type) {

	QVariant::Type v_type = value.type(); /// current variant type
	QVariant c_value; /// converted value
	QSize size;
	QSizeF sizef;
	QRect rect;
	QRectF rectf;
	QString string;
	QStringList str_parts; /// Parts of string when parsing a string

	c_value = value;

	// Parse variant
	switch (v_type) {
		case QVariant::Size:
			size = value.toSize();
			switch (type) {
				case QVariant::String:
					c_value = QVariant(QString("%1,%2").arg(size.width()).arg(size.height()));
					break;
				default:
					break;
			}
			break;
		case QVariant::SizeF:
			sizef = value.toSizeF();
			switch (type) {
				case QVariant::String:
					c_value = QVariant(QString("%1,%2").arg(sizef.width()).arg(sizef.height()));
					break;
				default:
					break;
			}
			break;
		case QVariant::Rect:
			rect = value.toRect();
			switch (type) {
				case QVariant::String:
					c_value = QVariant(QString("%1,%2,%3,%4").arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height()));
					break;
				default:
					break;
				}
			break;
		case QVariant::RectF:
			rectf = value.toRectF();
			switch (type) {
				case QVariant::String:
					c_value = QVariant(QString("%1,%2,%3,%4").arg(rectf.x()).arg(rectf.y()).arg(rectf.width()).arg(rectf.height()));
					break;
				default:
					break;
			}
			break;

		case QVariant::String:
			string = value.toString();
			str_parts = string.split(",");
			switch(type) {
				case QVariant::Rect:
					rect = QRect(str_parts[0].toInt(), str_parts[1].toInt(), str_parts[2].toInt(), str_parts[3].toInt());
					c_value = QVariant(rect);
					break;
				case QVariant::RectF:
					rectf = QRectF(str_parts[0].toFloat(), str_parts[1].toFloat(), str_parts[2].toFloat(), str_parts[3].toFloat());
					c_value = QVariant(rectf);
					break;
				case QVariant::Size:
					size = QSize(str_parts[0].toInt(), str_parts[1].toInt());
					c_value = QVariant(size);
					break;
				case QVariant::SizeF:
					sizef = QSizeF(str_parts[0].toFloat(), str_parts[1].toFloat());
					c_value = QVariant(sizef);
					break;
				default:
					break;
			}
			break;

		default: // No (known) need for processing
			break;
	}
	return c_value;
}
Beispiel #15
0
static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,
                                              QRectF *rect, Qt::WindowFrameSection section,
                                              const QSizeF &min, const QSizeF &max,
                                              const QGraphicsWidget *widget)
{
    const QRectF proposedRect = *rect;
    qreal width = qBound(min.width(), proposedRect.width(), max.width());
    qreal height = qBound(min.height(), proposedRect.height(), max.height());

    QSizePolicy sp = widget->sizePolicy();
    if (const QGraphicsLayout *l = widget->layout()) {
        sp = l->sizePolicy();
    }
    const bool hasHFW = sp.hasHeightForWidth(); // || sp.hasWidthForHeight();

    const bool widthChanged = proposedRect.width() < widget->size().width();
    const bool heightChanged = proposedRect.height() < widget->size().height();

    if (hasHFW) {
        if (widthChanged || heightChanged) {
            const qreal minh = min.height();
            const qreal maxh = max.height();
            const qreal proposedHFW = minimumHeightForWidth(width, minh, maxh, widget);
            if (proposedHFW > proposedRect.height()) {
                QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);
                width = effectiveSize.width();
                height = effectiveSize.height();
            }
        }
    }

    switch (section) {
    case Qt::LeftSection:
        rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
                      qRound(width), startGeometry.height());
        break;
    case Qt::TopLeftSection:
        rect->setRect(startGeometry.right() - qRound(width), startGeometry.bottom() - qRound(height),
                      qRound(width), qRound(height));
        break;
    case Qt::TopSection:
        rect->setRect(startGeometry.left(), startGeometry.bottom() - qRound(height),
                      startGeometry.width(), qRound(height));
        break;
    case Qt::TopRightSection:
        rect->setTop(rect->bottom() - qRound(height));
        rect->setWidth(qRound(width));
        break;
    case Qt::RightSection:
        rect->setWidth(qRound(width));
        break;
    case Qt::BottomRightSection:
        rect->setWidth(qRound(width));
        rect->setHeight(qRound(height));
        break;
    case Qt::BottomSection:
        rect->setHeight(qRound(height));
        break;
    case Qt::BottomLeftSection:
        rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
                      qRound(width), qRound(height));
        break;
    default:
        break;
    }
}
Beispiel #16
0
static inline QSize qCeiling(const QSizeF &s)
{
    return QSize(qCeil(s.width()), qCeil(s.height()));
}
Beispiel #17
0
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 );
  }
}
Beispiel #18
0
bool ChartShape::Private::loadOdfLabel(KoShape *label, KoXmlElement &labelElement, KoShapeLoadingContext &context)
{
    TextLabelData *labelData = qobject_cast<TextLabelData*>(label->userData());
    if (!labelData)
        return false;

    // Following will always return false cause KoTextShapeData::loadOdf will try to load
    // a frame while our text:p is not within a frame. So, let's just not call loadOdf then...
    //label->loadOdf(labelElement, context);

    // 1. set the text
    KoXmlElement  pElement = KoXml::namedItemNS(labelElement, KoXmlNS::text, "p");

    QTextDocument* doc = labelData->document();
    doc->setPlainText(pElement.text());

    // 2. set the position
    QPointF pos = label->position();
    bool posChanged = false;
    if (labelElement.hasAttributeNS(KoXmlNS::svg, "x")) {
        pos.setX(KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "x", QString())));
        posChanged = true;
    }
    if (labelElement.hasAttributeNS(KoXmlNS::svg, "y")) {
        pos.setY(KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "y", QString())));
        posChanged = true;
    }
    if (posChanged) {
        label->setPosition(pos);
    }

    // 3. set the styles
    if (labelElement.hasAttributeNS(KoXmlNS::chart, "style-name")) {
        KoStyleStack &styleStack = context.odfLoadingContext().styleStack();
        styleStack.clear();
        context.odfLoadingContext().fillStyleStack(labelElement, KoXmlNS::chart, "style-name", "chart");

        styleStack.setTypeProperties("chart");
        if (styleStack.hasProperty(KoXmlNS::style, "rotation-angle")) {
            qreal rotationAngle = 360 - KoUnit::parseValue(styleStack.property(KoXmlNS::style, "rotation-angle"));
            label->rotate(rotationAngle);
        }

        styleStack.setTypeProperties("text");

        if (styleStack.hasProperty(KoXmlNS::fo, "font-size")) {
            const qreal fontSize = KoUnit::parseValue(styleStack.property(KoXmlNS::fo, "font-size"));
            QFont font = doc->defaultFont();
            font.setPointSizeF(fontSize);
            doc->setDefaultFont(font);
        }

        if (styleStack.hasProperty(KoXmlNS::fo, "font-family")) {
            const QString fontFamily = styleStack.property(KoXmlNS::fo, "font-family");
            QFont font = doc->defaultFont();
            font.setFamily(fontFamily);
            doc->setDefaultFont(font);
        }
    }

    // 4. set the size
    if (labelElement.hasAttributeNS(KoXmlNS::svg, "width")
        && labelElement.hasAttributeNS(KoXmlNS::svg, "height"))
    {
        const qreal width = KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "width"));
        const qreal height = KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "height"));
        label->setSize(QSizeF(width, height));
    } else {
        QSizeF size = shape->size();
        QRect r = QFontMetrics(doc->defaultFont()).boundingRect(
                        labelData->shapeMargins().left, labelData->shapeMargins().top,
                        qMax(CM_TO_POINT(5), qreal(size.width() - pos.x() * 2.0 - labelData->shapeMargins().right)),
                        qMax(CM_TO_POINT(0.6), qreal(size.height() - labelData->shapeMargins().bottom)),
                        Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, doc->toPlainText());
        label->setSize(r.size());
    }

    return true;
}
Beispiel #19
0
void IconViewWidget::setSize(const QSizeF & size)
{
    m_iconScene->setParentSize(size);
    resize(size.width(), size.height());
}
Beispiel #20
0
void qDrawRoundedCorners(QPainter *p, qreal x1, qreal y1, qreal x2, qreal y2,
                         const QSizeF& r1, const QSizeF& r2,
                         Edge edge, BorderStyle s, QBrush c)
{
    const qreal pw = (edge == TopEdge || edge == BottomEdge) ? y2-y1 : x2-x1;
    if (s == BorderStyle_Double) {
        qreal wby3 = pw/3;
        switch (edge) {
        case TopEdge:
        case BottomEdge:
            qDrawRoundedCorners(p, x1, y1, x2, y1+wby3, r1, r2, edge, BorderStyle_Solid, c);
            qDrawRoundedCorners(p, x1, y2-wby3, x2, y2, r1, r2, edge, BorderStyle_Solid, c);
            break;
        case LeftEdge:
            qDrawRoundedCorners(p, x1, y1+1, x1+wby3, y2, r1, r2, LeftEdge, BorderStyle_Solid, c);
            qDrawRoundedCorners(p, x2-wby3, y1+1, x2, y2, r1, r2, LeftEdge, BorderStyle_Solid, c);
            break;
        case RightEdge:
            qDrawRoundedCorners(p, x1, y1+1, x1+wby3, y2, r1, r2, RightEdge, BorderStyle_Solid, c);
            qDrawRoundedCorners(p, x2-wby3, y1+1, x2, y2, r1, r2, RightEdge, BorderStyle_Solid, c);
            break;
        default:
            break;
        }
        return;
    } else if (s == BorderStyle_Ridge || s == BorderStyle_Groove) {
        BorderStyle s1, s2;
        if (s == BorderStyle_Groove) {
            s1 = BorderStyle_Inset;
            s2 = BorderStyle_Outset;
        } else {
            s1 = BorderStyle_Outset;
            s2 = BorderStyle_Inset;
        }
        int pwby2 = qRound(pw/2);
        switch (edge) {
        case TopEdge:
            qDrawRoundedCorners(p, x1, y1, x2, y1 + pwby2, r1, r2, TopEdge, s1, c);
            qDrawRoundedCorners(p, x1, y1 + pwby2, x2, y2, r1, r2, TopEdge, s2, c);
            break;
        case BottomEdge:
            qDrawRoundedCorners(p, x1, y1 + pwby2, x2, y2, r1, r2, BottomEdge, s1, c);
            qDrawRoundedCorners(p, x1, y1, x2, y2-pwby2, r1, r2, BottomEdge, s2, c);
            break;
        case LeftEdge:
            qDrawRoundedCorners(p, x1, y1, x1 + pwby2, y2, r1, r2, LeftEdge, s1, c);
            qDrawRoundedCorners(p, x1 + pwby2, y1, x2, y2, r1, r2, LeftEdge, s2, c);
            break;
        case RightEdge:
            qDrawRoundedCorners(p, x1 + pwby2, y1, x2, y2, r1, r2, RightEdge, s1, c);
            qDrawRoundedCorners(p, x1, y1, x2 - pwby2, y2, r1, r2, RightEdge, s2, c);
            break;
        default:
            break;
        }
    } else if ((s == BorderStyle_Outset && (edge == TopEdge || edge == LeftEdge))
            || (s == BorderStyle_Inset && (edge == BottomEdge || edge == RightEdge)))
            c = c.color().lighter();

    p->save();
    qreal pwby2 = pw/2;
    p->setBrush(Qt::NoBrush);
    QPen pen = qPenFromStyle(c, pw, s);
    pen.setCapStyle(Qt::SquareCap); // this eliminates the offby1 errors that we might hit below
    p->setPen(pen);
    switch (edge) {
    case TopEdge:
        if (!r1.isEmpty())
            p->drawArc(QRectF(x1 - r1.width() + pwby2, y1 + pwby2,
                              2*r1.width() - pw, 2*r1.height() - pw), 135*16, -45*16);
        if (!r2.isEmpty())
            p->drawArc(QRectF(x2 - r2.width() + pwby2, y1 + pwby2,
                       2*r2.width() - pw, 2*r2.height() - pw), 45*16, 45*16);
        break;
    case BottomEdge:
        if (!r1.isEmpty())
            p->drawArc(QRectF(x1 - r1.width() + pwby2, y2 - 2*r1.height() + pwby2,
                              2*r1.width() - pw, 2*r1.height() - pw), -90 * 16, -45 * 16);
        if (!r2.isEmpty())
            p->drawArc(QRectF(x2 - r2.width() + pwby2, y2 - 2*r2.height() + pwby2,
                       2*r2.width() - pw, 2*r2.height() - pw), -90 * 16, 45 * 16);
        break;
    case LeftEdge:
        if (!r1.isEmpty())
            p->drawArc(QRectF(x1 + pwby2, y1 - r1.height() + pwby2,
                       2*r1.width() - pw, 2*r1.height() - pw), 135*16, 45*16);
        if (!r2.isEmpty())
            p->drawArc(QRectF(x1 + pwby2, y2 - r2.height() + pwby2,
                       2*r2.width() - pw, 2*r2.height() - pw), 180*16, 45*16);
        break;
    case RightEdge:
        if (!r1.isEmpty())
            p->drawArc(QRectF(x2 - 2*r1.width() + pwby2, y1 - r1.height() + pwby2,
                       2*r1.width() - pw, 2*r1.height() - pw), 45*16, -45*16);
        if (!r2.isEmpty())
            p->drawArc(QRectF(x2 - 2*r2.width() + pwby2, y2 - r2.height() + pwby2,
                       2*r2.width() - pw, 2*r2.height() - pw), 315*16, 45*16);
        break;
    default:
        break;
    }
    p->restore();
}
Beispiel #21
0
void QgsDecorationCopyright::render( QPainter * theQPainter )
{
  //Large IF statement to enable/disable copyright label
  if ( enabled() )
  {
    // need width/height of paint device
    int myHeight = theQPainter->device()->height();
    int myWidth = theQPainter->device()->width();

    QTextDocument text;
    text.setDefaultFont( mQFont );
    // To set the text color in a QTextDocument we use a CSS style
    QString style = "<style type=\"text/css\"> p {color: " +
                    mLabelQColor.name() + "}</style>";
    text.setHtml( style + "<p>" + mLabelQString + "</p>" );
    QSizeF size = text.size();

    float myXOffset( 0 ), myYOffset( 0 );

    // Set  margin according to selected units
    switch ( mMarginUnit )
    {
      case QgsUnitTypes::RenderMillimeters:
      {
        int myPixelsInchX = theQPainter->device()->logicalDpiX();
        int myPixelsInchY = theQPainter->device()->logicalDpiY();
        myXOffset = myPixelsInchX * INCHES_TO_MM * mMarginHorizontal;
        myYOffset = myPixelsInchY * INCHES_TO_MM * mMarginVertical;
        break;
      }

      case QgsUnitTypes::RenderPixels:
        myXOffset = mMarginHorizontal;
        myYOffset = mMarginVertical;
        break;

      case QgsUnitTypes::RenderPercentage:
        myXOffset = (( myWidth - size.width() ) / 100. ) * mMarginHorizontal;
        myYOffset = (( myHeight - size.height() ) / 100. ) * mMarginVertical;
        break;

      default:  // Use default of top left
        break;
    }
    //Determine placement of label from form combo box
    switch ( mPlacement )
    {
      case BottomLeft: // Bottom Left. myXOffset is set above
        myYOffset = myHeight - myYOffset - size.height();
        break;
      case TopLeft: // Top left. Already setup above
        break;
      case TopRight: // Top Right. myYOffset is set above
        myXOffset = myWidth - myXOffset - size.width();
        break;
      case BottomRight: // Bottom Right
        //Define bottom right hand corner start point
        myYOffset = myHeight - myYOffset - size.height();
        myXOffset = myWidth - myXOffset - size.width();
        break;
      default:
        QgsDebugMsg( QString( "Unknown placement index of %1" ).arg( static_cast<int>( mPlacement ) ) );
    }

    //Paint label to canvas
    QMatrix worldMatrix = theQPainter->worldMatrix();
    theQPainter->translate( myXOffset, myYOffset );
    text.drawContents( theQPainter );
    // Put things back how they were
    theQPainter->setWorldMatrix( worldMatrix );
  }
}
std::unique_ptr<QgsMarkerSymbolLayer> backgroundToMarkerLayer( const QgsTextBackgroundSettings &settings )
{
  std::unique_ptr<QgsMarkerSymbolLayer> layer;
  switch ( settings.type() )
  {
    case QgsTextBackgroundSettings::ShapeSVG:
    {
      QgsSvgMarkerSymbolLayer *svg = new QgsSvgMarkerSymbolLayer( settings.svgFile() );
      svg->setStrokeWidth( settings.strokeWidth() );
      svg->setStrokeWidthUnit( settings.strokeWidthUnit() );
      layer.reset( svg );
      break;
    }
    case QgsTextBackgroundSettings::ShapeCircle:
    case QgsTextBackgroundSettings::ShapeEllipse:
    case QgsTextBackgroundSettings::ShapeRectangle:
    case QgsTextBackgroundSettings::ShapeSquare:
    {
      QgsSimpleMarkerSymbolLayer *marker = new QgsSimpleMarkerSymbolLayer();
      // default value
      QgsSimpleMarkerSymbolLayerBase::Shape shape = QgsSimpleMarkerSymbolLayerBase::Diamond;
      switch ( settings.type() )
      {
        case QgsTextBackgroundSettings::ShapeCircle:
        case QgsTextBackgroundSettings::ShapeEllipse:
          shape = QgsSimpleMarkerSymbolLayerBase::Circle;
          break;
        case QgsTextBackgroundSettings::ShapeRectangle:
        case QgsTextBackgroundSettings::ShapeSquare:
          shape = QgsSimpleMarkerSymbolLayerBase::Square;
          break;
        case QgsTextBackgroundSettings::ShapeSVG:
          break;
      }

      marker->setShape( shape );
      marker->setStrokeWidth( settings.strokeWidth() );
      marker->setStrokeWidthUnit( settings.strokeWidthUnit() );
      layer.reset( marker );
    }
  }
  layer->setEnabled( true );
  // a marker does not have a size x and y, just a size (and it should be at least one)
  QSizeF size = settings.size();
  layer->setSize( std::max( 1., std::max( size.width(), size.height() ) ) );
  layer->setSizeUnit( settings.sizeUnit() );
  // fill and stroke
  QColor fillColor = settings.fillColor();
  QColor strokeColor = settings.strokeColor();
  if ( settings.opacity() < 1 )
  {
    int alpha = std::round( settings.opacity() * 255 );
    fillColor.setAlpha( alpha );
    strokeColor.setAlpha( alpha );
  }
  layer->setFillColor( fillColor );
  layer->setStrokeColor( strokeColor );
  // rotation
  if ( settings.rotationType() == QgsTextBackgroundSettings::RotationFixed )
  {
    layer->setAngle( settings.rotation() );
  }
  // offset
  layer->setOffset( settings.offset() );
  layer->setOffsetUnit( settings.offsetUnit() );

  return layer;
}
QgsLabelFeature *QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature &feat, QgsRenderContext &context, const QgsGeometry &obstacleGeometry )
{
  const QgsMapSettings &mapSettings = mEngine->mapSettings();

  const QgsDiagramRenderer *dr = mSettings.renderer();
  if ( dr )
  {
    QList<QgsDiagramSettings> settingList = dr->diagramSettings();
    if ( !settingList.isEmpty() && settingList.at( 0 ).scaleBasedVisibility )
    {
      double maxScale = settingList.at( 0 ).maximumScale;
      if ( maxScale > 0 && context.rendererScale() < maxScale )
      {
        return nullptr;
      }

      double minScale = settingList.at( 0 ).minimumScale;
      if ( minScale > 0 && context.rendererScale() > minScale )
      {
        return nullptr;
      }
    }
  }

  // data defined show diagram? check this before doing any other processing
  if ( !mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::Show, context.expressionContext(), true ) )
    return nullptr;

  // data defined obstacle?
  bool isObstacle = mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::IsObstacle, context.expressionContext(), mSettings.isObstacle() );

  //convert geom to geos
  QgsGeometry geom = feat.geometry();
  QgsGeometry extentGeom = QgsGeometry::fromRect( mapSettings.visibleExtent() );
  if ( !qgsDoubleNear( mapSettings.rotation(), 0.0 ) )
  {
    //PAL features are prerotated, so extent also needs to be unrotated
    extentGeom.rotate( -mapSettings.rotation(), mapSettings.visibleExtent().center() );
  }

  geos::unique_ptr geomCopy;
  std::unique_ptr<QgsGeometry> scopedPreparedGeom;
  if ( QgsPalLabeling::geometryRequiresPreparation( geom, context, mSettings.coordinateTransform(), extentGeom ) )
  {
    scopedPreparedGeom.reset( new QgsGeometry( QgsPalLabeling::prepareGeometry( geom, context, mSettings.coordinateTransform(), extentGeom ) ) );
    QgsGeometry *preparedGeom = scopedPreparedGeom.get();
    if ( preparedGeom->isNull() )
      return nullptr;
    geomCopy = QgsGeos::asGeos( *preparedGeom );
  }
  else
  {
    geomCopy = QgsGeos::asGeos( geom );
  }

  if ( !geomCopy )
    return nullptr; // invalid geometry

  geos::unique_ptr geosObstacleGeomClone;
  std::unique_ptr<QgsGeometry> scopedObstacleGeom;
  if ( isObstacle && obstacleGeometry && QgsPalLabeling::geometryRequiresPreparation( obstacleGeometry, context, mSettings.coordinateTransform(), extentGeom ) )
  {
    QgsGeometry preparedObstacleGeom = QgsPalLabeling::prepareGeometry( obstacleGeometry, context, mSettings.coordinateTransform(), extentGeom );
    geosObstacleGeomClone = QgsGeos::asGeos( preparedObstacleGeom );
  }
  else if ( mSettings.isObstacle() && !obstacleGeometry.isNull() )
  {
    geosObstacleGeomClone = QgsGeos::asGeos( obstacleGeometry );
  }

  double diagramWidth = 0;
  double diagramHeight = 0;
  if ( dr )
  {
    QSizeF diagSize = dr->sizeMapUnits( feat, context );
    if ( diagSize.isValid() )
    {
      diagramWidth = diagSize.width();
      diagramHeight = diagSize.height();
    }
  }

  //  feature to the layer
  bool alwaysShow = mSettings.showAllDiagrams();
  context.expressionContext().setOriginalValueVariable( alwaysShow );
  alwaysShow = mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::AlwaysShow, context.expressionContext(), alwaysShow );

  // new style data defined position
  bool ddPos = false;
  double ddPosX = 0.0;
  double ddPosY = 0.0;
  if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::PositionX )
       && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::PositionX ).isActive()
       && mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::PositionY )
       && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::PositionY ).isActive() )
  {
    ddPosX = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::PositionX, context.expressionContext(), std::numeric_limits<double>::quiet_NaN() );
    ddPosY = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::PositionY, context.expressionContext(), std::numeric_limits<double>::quiet_NaN() );

    ddPos = !std::isnan( ddPosX ) && !std::isnan( ddPosY );

    if ( ddPos )
    {
      QgsCoordinateTransform ct = mSettings.coordinateTransform();
      if ( ct.isValid() && !ct.isShortCircuited() )
      {
        double z = 0;
        ct.transformInPlace( ddPosX, ddPosY, z );
      }
      //data defined diagram position is always centered
      ddPosX -= diagramWidth / 2.0;
      ddPosY -= diagramHeight / 2.0;
    }
  }

  QgsDiagramLabelFeature *lf = new QgsDiagramLabelFeature( feat.id(), std::move( geomCopy ), QSizeF( diagramWidth, diagramHeight ) );
  lf->setHasFixedPosition( ddPos );
  lf->setFixedPosition( QgsPointXY( ddPosX, ddPosY ) );
  lf->setHasFixedAngle( true );
  lf->setFixedAngle( 0 );
  lf->setAlwaysShow( alwaysShow );
  lf->setIsObstacle( isObstacle );
  if ( geosObstacleGeomClone )
  {
    lf->setObstacleGeometry( std::move( geosObstacleGeomClone ) );
  }

  if ( dr )
  {
    //append the diagram attributes to lbl
    lf->setAttributes( feat.attributes() );
  }

  // data defined priority?
  if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::Priority )
       && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::Priority ).isActive() )
  {
    context.expressionContext().setOriginalValueVariable( mSettings.priority() );
    double priorityD = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Priority, context.expressionContext(), mSettings.priority() );
    priorityD = qBound( 0.0, priorityD, 10.0 );
    priorityD = 1 - priorityD / 10.0; // convert 0..10 --> 1..0
    lf->setPriority( priorityD );
  }

  // z-Index
  double zIndex = mSettings.zIndex();
  if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::ZIndex )
       && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::ZIndex ).isActive() )
  {
    context.expressionContext().setOriginalValueVariable( zIndex );
    zIndex = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::ZIndex, context.expressionContext(), zIndex );
  }
  lf->setZIndex( zIndex );

  // label distance
  QgsPointXY ptZero = mapSettings.mapToPixel().toMapCoordinates( 0, 0 );
  QgsPointXY ptOne = mapSettings.mapToPixel().toMapCoordinates( 1, 0 );
  double dist = mSettings.distance();

  if ( mSettings.dataDefinedProperties().hasProperty( QgsDiagramLayerSettings::Distance )
       && mSettings.dataDefinedProperties().property( QgsDiagramLayerSettings::Distance ).isActive() )
  {
    context.expressionContext().setOriginalValueVariable( dist );
    dist = mSettings.dataDefinedProperties().valueAsDouble( QgsDiagramLayerSettings::Distance, context.expressionContext(), dist );
  }

  dist *= ptOne.distance( ptZero );

  lf->setDistLabel( dist );
  return lf;
}
void QgsAbstractVectorLayerLabeling::writeTextSymbolizer( QDomNode &parent, QgsPalLayerSettings &settings, const QgsStringMap &props ) const
{
  QDomDocument doc = parent.ownerDocument();

  // text symbolizer
  QDomElement textSymbolizerElement = doc.createElement( QStringLiteral( "se:TextSymbolizer" ) );
  parent.appendChild( textSymbolizerElement );

  // label
  QgsTextFormat format = settings.format();
  QFont font = format.font();
  QDomElement labelElement = doc.createElement( QStringLiteral( "se:Label" ) );
  textSymbolizerElement.appendChild( labelElement );
  if ( settings.isExpression )
  {
    labelElement.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( settings.getLabelExpression()->dump() ) ) );
    labelElement.appendChild( doc.createTextNode( "Placeholder" ) );
  }
  else
  {
    if ( font.capitalization() == QFont::AllUppercase )
    {
      appendSimpleFunction( doc, labelElement, QStringLiteral( "strToUpperCase" ), settings.fieldName );
    }
    else if ( font.capitalization() == QFont::AllLowercase )
    {
      appendSimpleFunction( doc, labelElement, QStringLiteral( "strToLowerCase" ), settings.fieldName );
    }
    else if ( font.capitalization() == QFont::Capitalize )
    {
      appendSimpleFunction( doc, labelElement, QStringLiteral( "strCapitalize" ), settings.fieldName );
    }
    else
    {
      QDomElement propertyNameElement = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
      propertyNameElement.appendChild( doc.createTextNode( settings.fieldName ) );
      labelElement.appendChild( propertyNameElement );
    }
  }

  // font
  QDomElement fontElement = doc.createElement( QStringLiteral( "se:Font" ) );
  textSymbolizerElement.appendChild( fontElement );
  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-family" ), font.family() ) );
  double fontSize = QgsSymbolLayerUtils::rescaleUom( format.size(), format.sizeUnit(), props );
  fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-size" ), QString::number( fontSize ) ) );
  if ( format.font().italic() )
  {
    fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-style" ), QStringLiteral( "italic" ) ) );
  }
  if ( format.font().bold() )
  {
    fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-weight" ), QStringLiteral( "bold" ) ) );
  }

  // label placement
  QDomElement labelPlacement = doc.createElement( QStringLiteral( "se:LabelPlacement" ) );
  textSymbolizerElement.appendChild( labelPlacement );
  double maxDisplacement = 0;
  double repeatDistance = 0;
  switch ( settings.placement )
  {
    case QgsPalLayerSettings::OverPoint:
    {
      QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
      labelPlacement.appendChild( pointPlacement );
      // anchor point
      QPointF anchor = quadOffsetToSldAnchor( settings.quadOffset );
      QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, anchor );
      // displacement
      if ( settings.xOffset > 0 || settings.yOffset > 0 )
      {
        QgsUnitTypes::RenderUnit offsetUnit =  settings.offsetUnits;
        double dx = QgsSymbolLayerUtils::rescaleUom( settings.xOffset, offsetUnit, props );
        double dy = QgsSymbolLayerUtils::rescaleUom( settings.yOffset, offsetUnit, props );
        QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( dx, dy ) );
      }
      // rotation
      if ( settings.angleOffset != 0 )
      {
        QDomElement rotation = doc.createElement( "se:Rotation" );
        pointPlacement.appendChild( rotation );
        rotation.appendChild( doc.createTextNode( QString::number( settings.angleOffset ) ) );
      }
    }
    break;
    case QgsPalLayerSettings::AroundPoint:
    case QgsPalLayerSettings::OrderedPositionsAroundPoint:
    {
      QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
      labelPlacement.appendChild( pointPlacement );

      // SLD cannot do either, but let's do a best effort setting the distance using
      // anchor point and displacement
      QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0, 0.5 ) );
      QgsUnitTypes::RenderUnit distUnit = settings.distUnits;
      double radius = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
      double offset = std::sqrt( radius * radius / 2 ); // make it start top/right
      maxDisplacement = radius + 1; // lock the distance
      QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( offset, offset ) );
    }
    break;
    case QgsPalLayerSettings::Horizontal:
    case QgsPalLayerSettings::Free:
    {
      // still a point placement (for "free" it's a fallback, there is no SLD equivalent)
      QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
      labelPlacement.appendChild( pointPlacement );
      QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0.5, 0.5 ) );
      QgsUnitTypes::RenderUnit distUnit = settings.distUnits;
      double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
      QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( 0, dist ) );
      break;
    }
    case QgsPalLayerSettings::Line:
    case QgsPalLayerSettings::Curved:
    case QgsPalLayerSettings::PerimeterCurved:
    {
      QDomElement linePlacement = doc.createElement( "se:LinePlacement" );
      labelPlacement.appendChild( linePlacement );

      // perpendicular distance if required
      if ( settings.dist > 0 )
      {
        QgsUnitTypes::RenderUnit distUnit = settings.distUnits;
        double dist = QgsSymbolLayerUtils::rescaleUom( settings.dist, distUnit, props );
        QDomElement perpendicular = doc.createElement( "se:PerpendicularOffset" );
        linePlacement.appendChild( perpendicular );
        perpendicular.appendChild( doc.createTextNode( qgsDoubleToString( dist, 2 ) ) );
      }

      // repeat distance if required
      if ( settings.repeatDistance > 0 )
      {
        QDomElement repeat = doc.createElement( "se:Repeat" );
        linePlacement.appendChild( repeat );
        repeat.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
        QDomElement gap = doc.createElement( "se:Gap" );
        linePlacement.appendChild( gap );
        repeatDistance = QgsSymbolLayerUtils::rescaleUom( settings.repeatDistance, settings.repeatDistanceUnit, props );
        gap.appendChild( doc.createTextNode( qgsDoubleToString( repeatDistance, 2 ) ) );
      }

      // always generalized
      QDomElement generalize = doc.createElement( "se:GeneralizeLine" );
      linePlacement.appendChild( generalize );
      generalize.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
    }
    break;
  }

  // halo
  QgsTextBufferSettings buffer = format.buffer();
  if ( buffer.enabled() )
  {
    QDomElement haloElement = doc.createElement( QStringLiteral( "se:Halo" ) );
    textSymbolizerElement.appendChild( haloElement );

    QDomElement radiusElement = doc.createElement( QStringLiteral( "se:Radius" ) );
    haloElement.appendChild( radiusElement );
    // the SLD uses a radius, which is actually half of the link thickness the buffer size specifies
    double radius = QgsSymbolLayerUtils::rescaleUom( buffer.size(), buffer.sizeUnit(), props ) / 2;
    radiusElement.appendChild( doc.createTextNode( qgsDoubleToString( radius ) ) );

    QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
    haloElement.appendChild( fillElement );
    fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), buffer.color().name() ) );
    if ( buffer.opacity() != 1 )
    {
      fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( buffer.opacity() ) ) );
    }
  }

  // fill
  QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
  textSymbolizerElement.appendChild( fillElement );
  fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), format.color().name() ) );
  if ( format.opacity() != 1 )
  {
    fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( format.opacity() ) ) );
  }

  // background graphic (not supported by SE 1.1, but supported by the GeoTools ecosystem as an extension)
  QgsTextBackgroundSettings background = format.background();
  if ( background.enabled() )
  {
    std::unique_ptr<QgsMarkerSymbolLayer> layer = backgroundToMarkerLayer( background );
    layer->writeSldMarker( doc, textSymbolizerElement, props );
  }

  // priority and zIndex, the default values are 0 and 5 in qgis (and between 0 and 10),
  // in the GeoTools ecosystem there is a single priority value set at 1000 by default
  if ( settings.priority != 5 || settings.zIndex > 0 )
  {
    QDomElement priorityElement = doc.createElement( QStringLiteral( "se:Priority" ) );
    textSymbolizerElement.appendChild( priorityElement );
    int priority = 500 + 1000 * settings.zIndex + ( settings.priority - 5 ) * 100;
    if ( settings.priority == 0 && settings.zIndex > 0 )
    {
      // small adjustment to make sure labels in z index n+1 are all above level n despite the priority value
      priority += 1;
    }
    priorityElement.appendChild( doc.createTextNode( QString::number( priority ) ) );
  }

  // vendor options for text appearance
  if ( font.underline() )
  {
    QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "underlineText" ), QStringLiteral( "true" ) );
    textSymbolizerElement.appendChild( vo );
  }
  if ( font.strikeOut() )
  {
    QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "strikethroughText" ), QStringLiteral( "true" ) );
    textSymbolizerElement.appendChild( vo );
  }
  // vendor options for text positioning
  if ( maxDisplacement > 0 )
  {
    QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxDisplacement" ), qgsDoubleToString( maxDisplacement, 2 ) );
    textSymbolizerElement.appendChild( vo );
  }
  if ( settings.placement == QgsPalLayerSettings::Curved || settings.placement == QgsPalLayerSettings::PerimeterCurved )
  {
    QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "followLine" ), QStringLiteral( "true" ) );
    textSymbolizerElement.appendChild( vo );
    if ( settings.maxCurvedCharAngleIn > 0 || settings.maxCurvedCharAngleOut > 0 )
    {
      // SLD has no notion for this, the GeoTools ecosystem can only do a single angle
      double angle = std::min( std::fabs( settings.maxCurvedCharAngleIn ), std::fabs( settings.maxCurvedCharAngleOut ) );
      QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxAngleDelta" ), qgsDoubleToString( angle ) );
      textSymbolizerElement.appendChild( vo );
    }
  }
  if ( repeatDistance > 0 )
  {
    QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "repeat" ), qgsDoubleToString( repeatDistance, 2 ) );
    textSymbolizerElement.appendChild( vo );
  }
  // miscellaneous options
  if ( settings.displayAll )
  {
    QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "conflictResolution" ), QStringLiteral( "false" ) );
    textSymbolizerElement.appendChild( vo );
  }
  if ( settings.upsidedownLabels == QgsPalLayerSettings::ShowAll )
  {
    QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "forceLeftToRight" ), QStringLiteral( "false" ) );
    textSymbolizerElement.appendChild( vo );
  }
  if ( settings.mergeLines )
  {
    QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "group" ), QStringLiteral( "yes" ) );
    textSymbolizerElement.appendChild( vo );
    if ( settings.labelPerPart )
    {
      QDomElement vo =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "labelAllGroup" ), QStringLiteral( "true" ) );
      textSymbolizerElement.appendChild( vo );
    }
  }
  // background symbol resize handling
  if ( background.enabled() )
  {
    // enable resizing if needed
    switch ( background.sizeType() )
    {
      case QgsTextBackgroundSettings::SizeBuffer:
      {
        QString resizeType;
        if ( background.type() == QgsTextBackgroundSettings::ShapeRectangle || background.type() == QgsTextBackgroundSettings::ShapeEllipse )
        {
          resizeType = QStringLiteral( "stretch" );
        }
        else
        {
          resizeType = QStringLiteral( "proportional" );
        }
        QDomElement voResize =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-resize" ), resizeType );
        textSymbolizerElement.appendChild( voResize );

        // now hadle margin
        QSizeF size = background.size();
        if ( size.width() > 0 || size.height() > 0 )
        {
          double x = QgsSymbolLayerUtils::rescaleUom( size.width(), background.sizeUnit(), props );
          double y = QgsSymbolLayerUtils::rescaleUom( size.height(), background.sizeUnit(), props );
          // in case of ellipse qgis pads the size generously to make sure the text is inside the ellipse
          // the following seems to do the trick and keep visual output similar
          if ( background.type() == QgsTextBackgroundSettings::ShapeEllipse )
          {
            x += fontSize / 2;
            y += fontSize;
          }
          QString resizeSpec = QString( "%1 %2" ).arg( qgsDoubleToString( x, 2 ), qgsDoubleToString( y, 2 ) );
          QDomElement voMargin =  QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-margin" ), resizeSpec );
          textSymbolizerElement.appendChild( voMargin );
        }
        break;
      }
      case QgsTextBackgroundSettings::SizeFixed:
      case QgsTextBackgroundSettings::SizePercent:
        // nothing to do here
        break;
    }
  }
}
QPointF positionFromSizeF(const QSizeF& s)
{
	return positionFromSize(QSize(realAsPixelPosition(s.width()),realAsPixelPosition(s.height())));
}
Beispiel #26
0
void DeckViewScene::rearrangeItems()
{
    const int spacing = CARD_HEIGHT / 3;
    QList<DeckViewCardContainer *> contList = cardContainers.values();
    
    // Initialize space requirements
    QList<QList<QPair<int, int> > > rowsAndColsList;
    QList<QList<int> > cardCountList;
    for (int i = 0; i < contList.size(); ++i) {
        QList<QPair<int, int> > rowsAndCols = contList[i]->getRowsAndCols();
        rowsAndColsList.append(rowsAndCols);
        
        cardCountList.append(QList<int>());
        for (int j = 0; j < rowsAndCols.size(); ++j)
            cardCountList[i].append(rowsAndCols[j].second);
    }
    
    qreal totalHeight, totalWidth;
    for (;;) {
        // Calculate total size before this iteration
        totalHeight = -spacing;
        totalWidth = 0;
        for (int i = 0; i < contList.size(); ++i) {
            QSizeF contSize = contList[i]->calculateBoundingRect(rowsAndColsList[i]);
            totalHeight += contSize.height() + spacing;
            if (contSize.width() > totalWidth)
                totalWidth = contSize.width();
        }
        
        // We're done when the aspect ratio shifts from too high to too low.
        if (totalWidth / totalHeight <= optimalAspectRatio)
            break;
        
        // Find category with highest column count
        int maxIndex1 = -1, maxIndex2 = -1, maxCols = 0;
        for (int i = 0; i < rowsAndColsList.size(); ++i)
            for (int j = 0; j < rowsAndColsList[i].size(); ++j)
                if (rowsAndColsList[i][j].second > maxCols) {
                    maxIndex1 = i;
                    maxIndex2 = j;
                    maxCols = rowsAndColsList[i][j].second;
                }
        
        // Add row to category
        const int maxRows = rowsAndColsList[maxIndex1][maxIndex2].first;
        const int maxCardCount = cardCountList[maxIndex1][maxIndex2];
        rowsAndColsList[maxIndex1][maxIndex2] = QPair<int, int>(maxRows + 1, (int) ceil((qreal) maxCardCount / (qreal) (maxRows + 1)));
    }
    
    totalHeight = -spacing;
    for (int i = 0; i < contList.size(); ++i) {
        DeckViewCardContainer *c = contList[i];
        c->rearrangeItems(rowsAndColsList[i]);
        c->setPos(0, totalHeight + spacing);
        totalHeight += c->boundingRect().height() + spacing;
    }
    
    totalWidth = totalHeight * optimalAspectRatio;
    for (int i = 0; i < contList.size(); ++i)
        contList[i]->setWidth(totalWidth);
    
    setSceneRect(QRectF(0, 0, totalWidth, totalHeight));
}
//rounds-down, to be logically equivalent to AsPixelPosition (yes, it's a little weird due to 'size' in the name)
QSizeF fractionalSizeF(const QSizeF& size,const qreal wFractional, const qreal hFractional)
{
	if (isZeroF(wFractional) || isZeroF(hFractional))
		return size;
	return QSizeF(roundDownF(size.width()/wFractional),roundDownF(size.height()/hFractional));
}
void KStandardItemListWidget::updatePixmapCache()
{
    // Precondition: Requires already updated m_textPos values to calculate
    // the remaining height when the alignment is vertical.

    const QSizeF widgetSize = size();
    const bool iconOnTop = (m_layout == IconsLayout);
    const KItemListStyleOption& option = styleOption();
    const qreal padding = option.padding;

    const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : option.iconSize;
    const int maxIconHeight = option.iconSize;

    const QHash<QByteArray, QVariant> values = data();

    bool updatePixmap = (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight);
    if (!updatePixmap && m_dirtyContent) {
        updatePixmap = m_dirtyContentRoles.isEmpty()
                       || m_dirtyContentRoles.contains("iconPixmap")
                       || m_dirtyContentRoles.contains("iconName")
                       || m_dirtyContentRoles.contains("iconOverlays");
    }

    if (updatePixmap) {
        m_pixmap = values["iconPixmap"].value<QPixmap>();
        if (m_pixmap.isNull()) {
            // Use the icon that fits to the MIME-type
            QString iconName = values["iconName"].toString();
            if (iconName.isEmpty()) {
                // The icon-name has not been not resolved by KFileItemModelRolesUpdater,
                // use a generic icon as fallback
                iconName = QLatin1String("unknown");
            }
            m_pixmap = pixmapForIcon(iconName, maxIconHeight);
        } else if (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight) {
            // A custom pixmap has been applied. Assure that the pixmap
            // is scaled to the maximum available size.
            KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight));
        }

        const QStringList overlays = values["iconOverlays"].toStringList();

        // Strangely KFileItem::overlays() returns empty string-values, so
        // we need to check first whether an overlay must be drawn at all.
        // It is more efficient to do it here, as KIconLoader::drawOverlays()
        // assumes that an overlay will be drawn and has some additional
        // setup time.
        foreach (const QString& overlay, overlays) {
            if (!overlay.isEmpty()) {
                // There is at least one overlay, draw all overlays above m_pixmap
                // and cancel the check
                KIconLoader::global()->drawOverlays(overlays, m_pixmap, KIconLoader::Desktop);
                break;
            }
        }

        if (m_isCut) {
            KIconEffect* effect = KIconLoader::global()->iconEffect();
            m_pixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
        }

        if (m_isHidden) {
            KIconEffect::semiTransparent(m_pixmap);
        }

        if (isSelected()) {
            const QColor color = palette().brush(QPalette::Normal, QPalette::Highlight).color();
            QImage image = m_pixmap.toImage();
            KIconEffect::colorize(image, color, 1.0f);
            m_pixmap = QPixmap::fromImage(image);
        }
    }

    if (!m_overlay.isNull()) {
        QPainter painter(&m_pixmap);
        painter.drawPixmap(0, m_pixmap.height() - m_overlay.height(), m_overlay);
    }

    int scaledIconSize = 0;
    if (iconOnTop) {
        const TextInfo* textInfo = m_textInfo.value("text");
        scaledIconSize = static_cast<int>(textInfo->pos.y() - 2 * padding);
    } else {
        const int textRowsCount = (m_layout == CompactLayout) ? visibleRoles().count() : 1;
        const qreal requiredTextHeight = textRowsCount * m_customizedFontMetrics.height();
        scaledIconSize = (requiredTextHeight < maxIconHeight) ?
                           widgetSize.height() - 2 * padding : maxIconHeight;
    }

    const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : scaledIconSize;
    const int maxScaledIconHeight = scaledIconSize;

    m_scaledPixmapSize = m_pixmap.size();
    m_scaledPixmapSize.scale(maxScaledIconWidth, maxScaledIconHeight, Qt::KeepAspectRatio);

    if (iconOnTop) {
        // Center horizontally and align on bottom within the icon-area
        m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
        m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
    } else {
        // Center horizontally and vertically within the icon-area
        const TextInfo* textInfo = m_textInfo.value("text");
        m_pixmapPos.setX(textInfo->pos.x() - 2 * padding
                         - (scaledIconSize + m_scaledPixmapSize.width()) / 2);
        m_pixmapPos.setY(padding
                         + (scaledIconSize - m_scaledPixmapSize.height()) / 2);
    }

    m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));

    // Prepare the pixmap that is used when the item gets hovered
    if (isHovered()) {
        m_hoverPixmap = m_pixmap;
        KIconEffect* effect = KIconLoader::global()->iconEffect();
        // In the KIconLoader terminology, active = hover.
        if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
            m_hoverPixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::ActiveState);
        } else {
            m_hoverPixmap = m_pixmap;
        }
    } else if (hoverOpacity() <= 0.0) {
        // No hover animation is ongoing. Clear m_hoverPixmap to save memory.
        m_hoverPixmap = QPixmap();
    }
}
quint32 howManyFitHorizontally(const QSizeF& cellSizeF,const QSizeF& areaSizeF)
{
	return howManyFitHorizontally(areaSizeF.width(),cellSizeF.width());
}
/*virtual*/
void ListItemContainer::adjustVisibleContainerSize(const QSizeF &size)
{
    m_layout->setPreferredWidth(size.width());
}