19#include <QStandardItemModel> 
   20#include <QStandardItem> 
   65QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, QScreen *screen ) : QAbstractItemModel( parent )
 
   66  , mMimeFormat( QStringLiteral( 
"application/x-qgsgraduatedsymbolrendererv2model" ) )
 
   75    if ( !mRenderer->ranges().isEmpty() )
 
   77      beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
 
   88    if ( !renderer->
ranges().isEmpty() )
 
   90      beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
 
  101void QgsGraduatedSymbolRendererModel::addClass( 
QgsSymbol *symbol )
 
  103  if ( !mRenderer ) 
return;
 
  104  int idx = mRenderer->
ranges().size();
 
  105  beginInsertRows( QModelIndex(), idx, idx );
 
  106  mRenderer->addClass( symbol );
 
  110void QgsGraduatedSymbolRendererModel::addClass( 
const QgsRendererRange &range )
 
  116  int idx = mRenderer->ranges().size();
 
  117  beginInsertRows( QModelIndex(), idx, idx );
 
  118  mRenderer->addClass( range );
 
  122QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange( 
const QModelIndex &index )
 
  124  if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
 
  129  return mRenderer->ranges().value( index.row() );
 
  132Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags( 
const QModelIndex &index )
 const 
  134  if ( !index.isValid() )
 
  136    return Qt::ItemIsDropEnabled;
 
  139  Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
 
  141  if ( index.column() == 2 )
 
  143    flags |= Qt::ItemIsEditable;
 
  149Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
 const 
  151  return Qt::MoveAction;
 
  154QVariant QgsGraduatedSymbolRendererModel::data( 
const QModelIndex &index, 
int role )
 const 
  156  if ( !index.isValid() || !mRenderer ) 
return QVariant();
 
  160  if ( role == Qt::CheckStateRole && index.column() == 0 )
 
  162    return range.
renderState() ? Qt::Checked : Qt::Unchecked;
 
  164  else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
 
  166    switch ( index.column() )
 
  170        int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
 
  171        if ( decimalPlaces < 0 ) decimalPlaces = 0;
 
  172        return QString( QLocale().toString( range.
lowerValue(), 
'f', decimalPlaces ) + 
" - " + QLocale().toString( range.
upperValue(), 
'f', decimalPlaces ) );
 
  175        return range.
label();
 
  180  else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
 
  185  else if ( role == Qt::TextAlignmentRole )
 
  187    return ( index.column() == 0 ) ? 
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : 
static_cast<Qt::Alignment::Int
>( Qt::AlignLeft );
 
  189  else if ( role == Qt::EditRole )
 
  191    switch ( index.column() )
 
  195        return range.
label();
 
  204bool QgsGraduatedSymbolRendererModel::setData( 
const QModelIndex &index, 
const QVariant &value, 
int role )
 
  206  if ( !index.isValid() )
 
  209  if ( index.column() == 0 && role == Qt::CheckStateRole )
 
  211    mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
 
  212    emit dataChanged( index, index );
 
  216  if ( role != Qt::EditRole )
 
  219  switch ( index.column() )
 
  224      mRenderer->updateRangeLabel( index.row(), value.toString() );
 
  230  emit dataChanged( index, index );
 
  234QVariant QgsGraduatedSymbolRendererModel::headerData( 
int section, Qt::Orientation orientation, 
int role )
 const 
  236  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
 
  239    lst << tr( 
"Symbol" ) << tr( 
"Values" ) << tr( 
"Legend" );
 
  240    return lst.value( section );
 
  245int QgsGraduatedSymbolRendererModel::rowCount( 
const QModelIndex &parent )
 const 
  247  if ( parent.isValid() || !mRenderer )
 
  251  return mRenderer->ranges().size();
 
  254int QgsGraduatedSymbolRendererModel::columnCount( 
const QModelIndex &index )
 const 
  260QModelIndex QgsGraduatedSymbolRendererModel::index( 
int row, 
int column, 
const QModelIndex &parent )
 const 
  262  if ( hasIndex( row, column, parent ) )
 
  264    return createIndex( row, column );
 
  266  return QModelIndex();
 
  269QModelIndex QgsGraduatedSymbolRendererModel::parent( 
const QModelIndex &index )
 const 
  272  return QModelIndex();
 
  275QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
 const 
  278  types << mMimeFormat;
 
  282QMimeData *QgsGraduatedSymbolRendererModel::mimeData( 
const QModelIndexList &indexes )
 const 
  284  QMimeData *mimeData = 
new QMimeData();
 
  285  QByteArray encodedData;
 
  287  QDataStream stream( &encodedData, QIODevice::WriteOnly );
 
  290  const auto constIndexes = indexes;
 
  291  for ( 
const QModelIndex &index : constIndexes )
 
  293    if ( !index.isValid() || index.column() != 0 )
 
  296    stream << index.row();
 
  298  mimeData->setData( mMimeFormat, encodedData );
 
  302bool QgsGraduatedSymbolRendererModel::dropMimeData( 
const QMimeData *data, Qt::DropAction action, 
int row, 
int column, 
const QModelIndex &parent )
 
  306  if ( action != Qt::MoveAction ) 
return true;
 
  308  if ( !data->hasFormat( mMimeFormat ) ) 
return false;
 
  310  QByteArray encodedData = data->data( mMimeFormat );
 
  311  QDataStream stream( &encodedData, QIODevice::ReadOnly );
 
  314  while ( !stream.atEnd() )
 
  321  int to = parent.row();
 
  324  if ( to == -1 ) to = mRenderer->ranges().size(); 
 
  325  for ( 
int i = rows.size() - 1; i >= 0; i-- )
 
  327    QgsDebugMsgLevel( QStringLiteral( 
"move %1 to %2" ).arg( rows[i] ).arg( to ), 2 );
 
  330    if ( rows[i] < t ) t--;
 
  331    mRenderer->moveClass( rows[i], t );
 
  333    for ( 
int j = 0; j < i; j++ )
 
  335      if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
 
  338    if ( rows[i] < to ) to--;
 
  340  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
 
  345void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
 
  347  for ( 
int i = rows.size() - 1; i >= 0; i-- )
 
  349    beginRemoveRows( QModelIndex(), rows[i], rows[i] );
 
  350    mRenderer->deleteClass( rows[i] );
 
  355void QgsGraduatedSymbolRendererModel::removeAllRows()
 
  357  beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
 
  358  mRenderer->deleteAllClasses();
 
  362void QgsGraduatedSymbolRendererModel::sort( 
int column, Qt::SortOrder order )
 
  370    mRenderer->sortByValue( order );
 
  372  else if ( column == 2 )
 
  374    mRenderer->sortByLabel( order );
 
  377  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
 
  380void QgsGraduatedSymbolRendererModel::updateSymbology()
 
  382  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
 
  385void QgsGraduatedSymbolRendererModel::updateLabels()
 
  387  emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
 
  391QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
 
  395void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element, 
const QStyleOption *option, QPainter *painter, 
const QWidget *widget )
 const 
  397  if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
 
  399    QStyleOption opt( *option );
 
  400    opt.rect.setLeft( 0 );
 
  402    opt.rect.setHeight( 0 );
 
  403    if ( widget ) opt.rect.setRight( widget->width() );
 
  404    QProxyStyle::drawPrimitive( element, &opt, painter, widget );
 
  407  QProxyStyle::drawPrimitive( element, option, painter, widget );
 
  432      expContext << generator->createExpressionContextScope();
 
  464    mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(), 
QgsRangeList() );
 
  473  cboSymmetryPoint->setEditable( 
true );
 
  474  cboSymmetryPoint->setValidator( mSymmetryPointValidator );
 
  477  for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
 
  480    cboGraduatedMode->addItem( icon, it.key(), it.value() );
 
  483  connect( methodComboBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
 
  484  this->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  486  mModel = 
new QgsGraduatedSymbolRendererModel( 
this, screen() );
 
  489  mExpressionWidget->setLayer( 
mLayer );
 
  491  btnChangeGraduatedSymbol->setLayer( 
mLayer );
 
  492  btnChangeGraduatedSymbol->registerExpressionContextGenerator( 
this );
 
  494  mSizeUnitWidget->setUnits(
 
  496    Qgis::RenderUnit::Millimeters,
 
  497    Qgis::RenderUnit::MapUnits,
 
  498    Qgis::RenderUnit::Pixels,
 
  499    Qgis::RenderUnit::Points,
 
  500    Qgis::RenderUnit::Inches
 
  505  spinPrecision->setClearValue( 4 );
 
  507  spinGraduatedClasses->setShowClearButton( 
false );
 
  509  btnColorRamp->setShowRandomColorRamp( 
true );
 
  512  std::unique_ptr< QgsColorRamp > colorRamp( 
QgsProject::instance()->styleSettings()->defaultColorRamp() );
 
  515    btnColorRamp->setColorRamp( colorRamp.get() );
 
  520    btnColorRamp->setColorRamp( ramp );
 
  525  viewGraduated->setStyle( 
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
 
  528  if ( mGraduatedSymbol )
 
  530    btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
 
  531    btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
 
  533    methodComboBox->blockSignals( 
true );
 
  534    methodComboBox->addItem( tr( 
"Color" ), ColorMode );
 
  535    switch ( mGraduatedSymbol->type() )
 
  539        methodComboBox->addItem( tr( 
"Size" ), SizeMode );
 
  540        minSizeSpinBox->setValue( 1 );
 
  541        maxSizeSpinBox->setValue( 8 );
 
  546        methodComboBox->addItem( tr( 
"Size" ), SizeMode );
 
  547        minSizeSpinBox->setValue( .1 );
 
  548        maxSizeSpinBox->setValue( 2 );
 
  554        methodComboBox->hide();
 
  561    methodComboBox->blockSignals( 
false );
 
  570  connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed, 
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
 
  577  connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ), 
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
 
  580  updateMethodParameters();
 
  588  mGroupBoxSymmetric->setCollapsed( 
true ); 
 
  591  QMenu *advMenu = 
new QMenu( 
this );
 
  596    QAction *actionDdsLegend = advMenu->addAction( tr( 
"Data-defined Size Legend…" ) );
 
  598    connect( actionDdsLegend, &QAction::triggered, 
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
 
  601  btnAdvanced->setMenu( advMenu );
 
  603  mHistogramWidget->setLayer( 
mLayer );
 
  604  mHistogramWidget->setRenderer( mRenderer.get() );
 
  608  mExpressionWidget->registerExpressionContextGenerator( 
this );
 
  610  mUpdateTimer.setSingleShot( 
true );
 
  611  mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout, 
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
 
  614void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
 
  616  if ( !mGraduatedSymbol )
 
  618  mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
 
  619  mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
 
  620  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
  627  mParameterWidgetWrappers.clear();
 
  632  return mRenderer.get();
 
  644  delete mActionLevels;
 
  645  mActionLevels = 
nullptr;
 
  666  connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, 
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
 
  668  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
  692  disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, 
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
 
  694  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
  710  int precision = spinPrecision->value() + 2;
 
  711  while ( cboSymmetryPoint->count() )
 
  712    cboSymmetryPoint->removeItem( 0 );
 
  713  for ( 
int i = 0; i < ranges.count() - 1; i++ )
 
  714    cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(), 
'f', 
precision ), ranges.at( i ).upperValue() );
 
  718    int idx = cboGraduatedMode->findData( method->
id() );
 
  720      cboGraduatedMode->setCurrentIndex( idx );
 
  726      cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(), 
'f', method->
labelPrecision() + 2 ) );
 
  733    for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
  737      ppww->setParameterValue( value, 
context );
 
  742  int nclasses = ranges.count();
 
  743  if ( nclasses && ( updateCount || ( method && ( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) ) ) )
 
  745    spinGraduatedClasses->setValue( ranges.count() );
 
  749    spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
 
  753    spinGraduatedClasses->setEnabled( 
true );
 
  757  QString attrName = mRenderer->classAttribute();
 
  758  mExpressionWidget->setField( attrName );
 
  759  mHistogramWidget->setSourceFieldExp( attrName );
 
  762  if ( mRenderer->sourceSymbol() )
 
  764    mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
 
  765    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
 
  768  mModel->setRenderer( mRenderer.get() );
 
  769  viewGraduated->setModel( mModel );
 
  771  connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged, 
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
 
  773  if ( mGraduatedSymbol )
 
  775    mSizeUnitWidget->blockSignals( 
true );
 
  776    mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
 
  777    mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
 
  778    mSizeUnitWidget->blockSignals( 
false );
 
  782  methodComboBox->blockSignals( 
true );
 
  783  switch ( mRenderer->graduatedMethod() )
 
  785    case Qgis::GraduatedMethod::Color:
 
  787      methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
 
  788      if ( mRenderer->sourceColorRamp() )
 
  790        btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
 
  794    case Qgis::GraduatedMethod::Size:
 
  796      methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
 
  797      if ( !mRenderer->ranges().isEmpty() ) 
 
  799        minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
 
  800        maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
 
  805  toggleMethodWidgets( 
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
 
  806  methodComboBox->blockSignals( 
false );
 
  808  viewGraduated->resizeColumnToContents( 0 );
 
  809  viewGraduated->resizeColumnToContents( 1 );
 
  810  viewGraduated->resizeColumnToContents( 2 );
 
  812  mHistogramWidget->refresh();
 
  822  mRenderer->setClassAttribute( 
field );
 
  825void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged( 
int )
 
  827  const MethodMode newMethod = 
static_cast< MethodMode 
>( methodComboBox->currentData().toInt() );
 
  828  toggleMethodWidgets( newMethod );
 
  833      mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Color );
 
  838        QMessageBox::critical( 
this, tr( 
"Select Method" ), tr( 
"No color ramp defined." ) );
 
  841      mRenderer->setSourceColorRamp( ramp );
 
  848      lblColorRamp->setVisible( 
false );
 
  849      btnColorRamp->setVisible( 
false );
 
  850      lblSize->setVisible( 
true );
 
  851      minSizeSpinBox->setVisible( 
true );
 
  852      lblSize->setVisible( 
true );
 
  853      maxSizeSpinBox->setVisible( 
true );
 
  854      mSizeUnitWidget->setVisible( 
true );
 
  856      mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Size );
 
  863void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
 
  865  clearParameterWidgets();
 
  867  const QString methodId = cboGraduatedMode->currentData().toString();
 
  879    QVariant value = method->
parameterValues().value( def->name(), def->defaultValueForGui() );
 
  884    mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
 
  887  spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
 
  890void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
 
  896      lblColorRamp->setVisible( 
true );
 
  897      btnColorRamp->setVisible( 
true );
 
  898      lblSize->setVisible( 
false );
 
  899      minSizeSpinBox->setVisible( 
false );
 
  900      lblSizeTo->setVisible( 
false );
 
  901      maxSizeSpinBox->setVisible( 
false );
 
  902      mSizeUnitWidget->setVisible( 
false );
 
  908      lblColorRamp->setVisible( 
false );
 
  909      btnColorRamp->setVisible( 
false );
 
  910      lblSize->setVisible( 
true );
 
  911      minSizeSpinBox->setVisible( 
true );
 
  912      lblSizeTo->setVisible( 
true );
 
  913      maxSizeSpinBox->setVisible( 
true );
 
  914      mSizeUnitWidget->setVisible( 
true );
 
  920void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
 
  922  while ( mParametersLayout->rowCount() )
 
  924    QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
 
  925    for ( QLayoutItem *item : {row.labelItem, row.fieldItem} )
 
  928        if ( item->widget() )
 
  929          item->widget()->deleteLater();
 
  933  mParameterWidgetWrappers.clear();
 
  941  mModel->updateSymbology();
 
  944  spinGraduatedClasses->setValue( mRenderer->ranges().count() );
 
  957      mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
 
  960  mRenderer->setUsingSymbolLevels( enabled );
 
  961  mModel->updateSymbology();
 
  965void QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector( 
QgsPanelWidget *container )
 
  974void QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget()
 
  984  mSizeUnitWidget->blockSignals( 
true );
 
  985  mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
 
  986  mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
 
  987  mSizeUnitWidget->blockSignals( 
false );
 
  989  QItemSelectionModel *m = viewGraduated->selectionModel();
 
  990  QModelIndexList selectedIndexes = m->selectedRows( 1 );
 
  991  if ( !selectedIndexes.isEmpty() )
 
  993    const auto constSelectedIndexes = selectedIndexes;
 
  994    for ( 
const QModelIndex &idx : constSelectedIndexes )
 
  998        int rangeIdx = idx.row();
 
  999        QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
 
 1000        if ( selectedIndexes.count() > 1 )
 
 1003          newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
 
 1005        mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
 
 1011    mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 1018void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
 
 1020  const QString text = cboSymmetryPoint->lineEdit()->text();
 
 1021  int index = cboSymmetryPoint->findText( text );
 
 1024    cboSymmetryPoint->setCurrentIndex( index );
 
 1028    cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
 
 1036  mUpdateTimer.start( 500 );
 
 1039void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl( )
 
 1042  if ( mBlockUpdates )
 
 1046  QString attrName = mExpressionWidget->currentField();
 
 1047  int nclasses = spinGraduatedClasses->value();
 
 1049  const QString methodId = cboGraduatedMode->currentData().toString();
 
 1059  double minimum = minVal.toDouble();
 
 1060  double maximum = maxVal.toDouble();
 
 1061  mSymmetryPointValidator->
setBottom( minimum );
 
 1062  mSymmetryPointValidator->
setTop( maximum );
 
 1063  mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
 
 1071    if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
 
 1072      cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2., 
'f', method->
labelPrecision() + 2 ) );
 
 1075  if ( mGroupBoxSymmetric->isChecked() )
 
 1078    bool astride = cbxAstride->isChecked();
 
 1082  QVariantMap parameterValues;
 
 1083  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
 1088  mRenderer->setClassificationMethod( method );
 
 1091  mRenderer->setClassAttribute( attrName );
 
 1097    if ( QMessageBox::Cancel == QMessageBox::question( 
this, tr( 
"Apply Classification" ), tr( 
"Natural break classification (Jenks) is O(n2) complexity, your classification may take a long time.\nPress cancel to abort breaks calculation or OK to continue." ), QMessageBox::Cancel, QMessageBox::Ok ) )
 
 1103  if ( methodComboBox->currentData() == ColorMode )
 
 1105    std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
 
 1108      QMessageBox::critical( 
this, tr( 
"Apply Classification" ), tr( 
"No color ramp defined." ) );
 
 1111    mRenderer->setSourceColorRamp( ramp.release() );
 
 1115    mRenderer->setSourceColorRamp( 
nullptr );
 
 1118  mRenderer->updateClasses( 
mLayer, nclasses );
 
 1120  if ( methodComboBox->currentData() == SizeMode )
 
 1121    mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
 
 1123  mRenderer->calculateLabelPrecision();
 
 1131  std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
 
 1135  mRenderer->updateColorRamp( ramp.release() );
 
 1136  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 1142  mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
 
 1143  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 1148int QgsRendererPropertiesDialog::currentRangeRow()
 
 1150  QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
 
 1151  if ( !idx.isValid() )
 
 1160  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1162  const auto constSelectedRows = selectedRows;
 
 1163  for ( 
const QModelIndex &r : constSelectedRows )
 
 1167      rows.append( r.row() );
 
 1176  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1177  QModelIndexList::const_iterator sIt = selectedRows.constBegin();
 
 1179  for ( ; sIt != selectedRows.constEnd(); ++sIt )
 
 1188  if ( idx.isValid() && idx.column() == 0 )
 
 1190  if ( idx.isValid() && idx.column() == 1 )
 
 1196  if ( !idx.isValid() )
 
 1199    mRowSelected = idx.row();
 
 1209  std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
 
 1226    if ( !dlg.exec() || !newSymbol )
 
 1231    mGraduatedSymbol = std::move( newSymbol );
 
 1232    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
 
 1244  int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
 
 1245  if ( decimalPlaces < 0 ) decimalPlaces = 0;
 
 1249  if ( dialog.exec() == QDialog::Accepted )
 
 1255    if ( cbxLinkBoundaries->isChecked() )
 
 1259        mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
 
 1262      if ( rangeIdx < mRenderer->ranges().size() - 1 )
 
 1264        mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
 
 1268  mHistogramWidget->refresh();
 
 1274  mModel->addClass( mGraduatedSymbol.get() );
 
 1275  mHistogramWidget->refresh();
 
 1283  mModel->deleteRows( classIndexes );
 
 1284  mHistogramWidget->refresh();
 
 1290  mModel->removeAllRows();
 
 1291  mHistogramWidget->refresh();
 
 1298  bool ordered = 
true;
 
 1299  for ( 
int i = 1; i < ranges.size(); ++i )
 
 1301    if ( ranges[i] < ranges[i - 1] )
 
 1318      int result = QMessageBox::warning(
 
 1320                     tr( 
"Link Class Boundaries" ),
 
 1321                     tr( 
"Rows will be reordered before linking boundaries. Continue?" ),
 
 1322                     QMessageBox::Ok | QMessageBox::Cancel );
 
 1323      if ( result != QMessageBox::Ok )
 
 1325        cbxLinkBoundaries->setChecked( 
false );
 
 1328      mRenderer->sortByValue();
 
 1332    for ( 
int i = 1; i < mRenderer->ranges().size(); ++i )
 
 1334      mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
 
 1342  if ( item->column() == 2 )
 
 1344    QString label = item->text();
 
 1345    int idx = item->row();
 
 1346    mRenderer->updateRangeLabel( idx, label );
 
 1352  mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
 
 1353  mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
 
 1354  mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
 
 1355  mRenderer->updateRangeLabels();
 
 1356  mModel->updateLabels();
 
 1364  QItemSelectionModel *m = viewGraduated->selectionModel();
 
 1365  QModelIndexList selectedIndexes = m->selectedRows( 1 );
 
 1366  if ( !selectedIndexes.isEmpty() )
 
 1369    QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
 
 1370    for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
 
 1372      QStringList list = m->model()->data( *indexIt ).toString().split( 
' ' );
 
 1373      if ( list.size() < 3 )
 
 1398  int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
 
 1399  if ( decimalPlaces < 0 )
 
 1401  double precision = 1.0 / std::pow( 10, decimalPlaces );
 
 1403  for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
 
 1407      return it->symbol();
 
 1417    mModel->updateSymbology();
 
 1419  mHistogramWidget->refresh();
 
 1430  viewGraduated->selectionModel()->clear();
 
 1433    cbxLinkBoundaries->setChecked( 
false );
 
 1450  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
 
 1452    mCopyBuffer.clear();
 
 1455  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
 
 1457    QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
 
 1458    for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
 
 1460      mModel->addClass( *rIt );
 
 1466void QgsGraduatedSymbolRendererWidget::selectionChanged( 
const QItemSelection &, 
const QItemSelection & )
 
 1469  if ( !ranges.isEmpty() )
 
 1471    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
 
 1473  else if ( mRenderer->sourceSymbol() )
 
 1475    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
 
 1477  btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr( 
"Symbol Settings" ) );
 
 1480void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
 
 1495void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
 
 1497  mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
 
 1507  const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1508  for ( 
const QModelIndex &index : selectedRows )
 
 1510    if ( !index.isValid() )
 
 1513    const int row = index.row();
 
 1514    if ( !mRenderer || mRenderer->ranges().size() <= row )
 
 1517    if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
 
 1520    std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
 
 1521    if ( selectedRows.count() > 1 )
 
 1524      newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
 
 1527    mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
 
static QgsClassificationMethodRegistry * classificationMethodRegistry()
Returns the application's classification methods registry, used in graduated renderer.
 
static const QString METHOD_ID
 
QgsClassificationMethod * method(const QString &id)
Returns a new instance of the method for the given id.
 
QIcon icon(const QString &id) const
Returns the icon for a given method id.
 
QMap< QString, QString > methodNames() const
Returns a map <name, id> of all registered methods.
 
QgsClassificationMethod is an abstract class for implementations of classification methods.
 
double symmetryPoint() const
Returns the symmetry point for symmetric mode.
 
int codeComplexity() const
Code complexity as the exponent in Big O notation.
 
bool symmetricModeEnabled() const
Returns if the symmetric mode is enabled.
 
int labelPrecision() const
Returns the precision for the formatting of the labels.
 
virtual QString id() const =0
The id of the method as saved in the project, must be unique in registry.
 
QVariantMap parameterValues() const
Returns the values of the processing parameters.
 
void setSymmetricMode(bool enabled, double symmetryPoint=0, bool symmetryAstride=false)
Defines if the symmetric mode is enables and configures its parameters.
 
bool symmetryAstride() const
Returns if the symmetric mode is astride if true, it will remove the symmetry point break so that the...
 
static const int MIN_PRECISION
 
QString labelFormat() const
Returns the format of the label for the classes.
 
void setParameterValues(const QVariantMap &values)
Defines the values of the additional parameters.
 
static const int MAX_PRECISION
 
bool labelTrimTrailingZeroes() const
Returns if the trailing 0 are trimmed in the label.
 
QgsProcessingParameterDefinitions parameterDefinitions() const
Returns the list of parameters.
 
bool symmetricModeAvailable() const
Returns if the method supports symmetric calculation.
 
QgsClassificationMethod::MethodProperties flags() const
Returns the classification flags.
 
static const QString METHOD_ID
 
Abstract base class for color ramps.
 
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
 
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
 
void setTop(double top)
Set top range limit.
 
void setMaxDecimals(int maxDecimals)
Sets the number of decimals accepted by the validator to maxDecimals.
 
void setBottom(double bottom)
Set top range limit.
 
Abstract interface for generating an expression context scope.
 
Single scope for storing variables and functions for use within a QgsExpressionContext.
 
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
 
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
 
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
 
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
 
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
 
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
 
@ Date
Date or datetime fields.
 
@ Numeric
All numeric fields.
 
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
 
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
 
static QgsGraduatedSymbolRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
creates a QgsGraduatedSymbolRenderer from an existing renderer.
 
const QgsRangeList & ranges() const
Returns a list of all ranges used in the classification.
 
static QgsProcessingGuiRegistry * processingGuiRegistry()
Returns the global processing gui registry, used for registering the GUI behavior of processing algor...
 
double upperValueDouble() const
Returns the upper value.
 
double lowerValueDouble() const
Returns the lower value.
 
void setLowerValue(const QString &val)
 
void setUpperValue(const QString &val)
 
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
 
The QgsMapSettings class contains configuration for rendering of the map.
 
A marker symbol type, for rendering Point and MultiPoint geometries.
 
Contains information about the context in which a processing algorithm is executed.
 
QgsAbstractProcessingParameterWidgetWrapper * createParameterWidgetWrapper(const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type)
Creates a new parameter widget wrapper for the given parameter.
 
@ Standard
Standard algorithm dialog.
 
Base class for the definition of processing parameters.
 
QVariant defaultValueForGui() const
Returns the default value to use for the parameter in a GUI.
 
QString name() const
Returns the name of the parameter.
 
static QgsProject * instance()
Returns the QgsProject singleton instance.
 
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...
 
QString label() const
Returns the label used for the range.
 
QgsSymbol * symbol() const
Returns the symbol used for the range.
 
bool renderState() const
Returns true if the range should be rendered.
 
double upperValue() const
Returns the upper bound of the range.
 
double lowerValue() const
Returns the lower bound of the range.
 
Stores properties relating to a screen.
 
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
 
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
 
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
 
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
 
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
 
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
 
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
 
Abstract base class for all rendered symbols.
 
void setColor(const QColor &color) const
Sets the color for the symbol.
 
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
 
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
 
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
 
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
 
Represents a vector layer which manages a vector based data sets.
 
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
 
QgsFields fields() const FINAL
Returns the list of fields of this layer.
 
void minimumAndMaximumValue(int index, QVariant &minimum, QVariant &maximum) const
Calculates both the minimum and maximum value for an attribute column.
 
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
 
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
 
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
 
double qgsPermissiveToDouble(QString string, bool &ok)
Converts a string to a double in a permissive way, e.g., allowing for incorrect numbers of digits bet...
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
 
QList< QgsLegendSymbolItem > QgsLegendSymbolList
 
#define QgsDebugMsgLevel(str, level)
 
QList< QgsRendererRange > QgsRangeList