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 );
 
  425    expContext = lMapCanvas->createExpressionContext();
 
 
  459    mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(), 
QgsRangeList() );
 
  468  cboSymmetryPoint->setEditable( 
true );
 
  469  cboSymmetryPoint->setValidator( mSymmetryPointValidator );
 
  472  for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
 
  475    cboGraduatedMode->addItem( icon, it.key(), it.value() );
 
  478  connect( methodComboBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
 
  479  this->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  481  mModel = 
new QgsGraduatedSymbolRendererModel( 
this, screen() );
 
  484  mExpressionWidget->setLayer( 
mLayer );
 
  486  btnChangeGraduatedSymbol->setLayer( 
mLayer );
 
  487  btnChangeGraduatedSymbol->registerExpressionContextGenerator( 
this );
 
  489  mSizeUnitWidget->setUnits(
 
  500  spinPrecision->setClearValue( 4 );
 
  502  spinGraduatedClasses->setShowClearButton( 
false );
 
  504  btnColorRamp->setShowRandomColorRamp( 
true );
 
  507  std::unique_ptr< QgsColorRamp > colorRamp( 
QgsProject::instance()->styleSettings()->defaultColorRamp() );
 
  510    btnColorRamp->setColorRamp( colorRamp.get() );
 
  515    btnColorRamp->setColorRamp( ramp );
 
  520  viewGraduated->setStyle( 
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
 
  523  if ( mGraduatedSymbol )
 
  525    btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
 
  526    btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
 
  528    methodComboBox->blockSignals( 
true );
 
  529    methodComboBox->addItem( tr( 
"Color" ), ColorMode );
 
  530    switch ( mGraduatedSymbol->type() )
 
  534        methodComboBox->addItem( tr( 
"Size" ), SizeMode );
 
  535        minSizeSpinBox->setValue( 1 );
 
  536        maxSizeSpinBox->setValue( 8 );
 
  541        methodComboBox->addItem( tr( 
"Size" ), SizeMode );
 
  542        minSizeSpinBox->setValue( .1 );
 
  543        maxSizeSpinBox->setValue( 2 );
 
  549        methodComboBox->hide();
 
  556    methodComboBox->blockSignals( 
false );
 
  565  connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed, 
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
 
  572  connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ), 
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
 
  575  updateMethodParameters();
 
  583  mGroupBoxSymmetric->setCollapsed( 
true ); 
 
  586  QMenu *advMenu = 
new QMenu( 
this );
 
  591    QAction *actionDdsLegend = advMenu->addAction( tr( 
"Data-defined Size Legend…" ) );
 
  593    connect( actionDdsLegend, &QAction::triggered, 
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
 
  596  btnAdvanced->setMenu( advMenu );
 
  598  mHistogramWidget->setLayer( 
mLayer );
 
  599  mHistogramWidget->setRenderer( mRenderer.get() );
 
  603  mExpressionWidget->registerExpressionContextGenerator( 
this );
 
  605  mUpdateTimer.setSingleShot( 
true );
 
  606  mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout, 
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
 
 
  609void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
 
  611  if ( !mGraduatedSymbol )
 
  613  mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
 
  614  mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
 
  615  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
  622  mParameterWidgetWrappers.clear();
 
 
  627  return mRenderer.get();
 
 
  639  delete mActionLevels;
 
  640  mActionLevels = 
nullptr;
 
 
  661  connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, 
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
 
  663  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
 
  687  disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, 
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
 
  689  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
 
  705  int precision = spinPrecision->value() + 2;
 
  706  while ( cboSymmetryPoint->count() )
 
  707    cboSymmetryPoint->removeItem( 0 );
 
  708  for ( 
int i = 0; i < ranges.count() - 1; i++ )
 
  709    cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(), 
'f', 
precision ), ranges.at( i ).upperValue() );
 
  713    int idx = cboGraduatedMode->findData( method->
id() );
 
  715      cboGraduatedMode->setCurrentIndex( idx );
 
  721      cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(), 
'f', method->
labelPrecision() + 2 ) );
 
  728    for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
  732      ppww->setParameterValue( value, 
context );
 
  737  int nclasses = ranges.count();
 
  740    spinGraduatedClasses->setValue( ranges.count() );
 
  748    spinGraduatedClasses->setEnabled( 
true );
 
  752  QString attrName = mRenderer->classAttribute();
 
  753  mExpressionWidget->setField( attrName );
 
  754  mHistogramWidget->setSourceFieldExp( attrName );
 
  757  if ( mRenderer->sourceSymbol() )
 
  759    mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
 
  760    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
 
  763  mModel->setRenderer( mRenderer.get() );
 
  764  viewGraduated->setModel( mModel );
 
  766  connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged, 
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
 
  768  if ( mGraduatedSymbol )
 
  770    mSizeUnitWidget->blockSignals( 
true );
 
  771    mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
 
  772    mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
 
  773    mSizeUnitWidget->blockSignals( 
false );
 
  777  methodComboBox->blockSignals( 
true );
 
  778  switch ( mRenderer->graduatedMethod() )
 
  782      methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
 
  783      if ( mRenderer->sourceColorRamp() )
 
  785        btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
 
  791      methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
 
  792      if ( !mRenderer->ranges().isEmpty() ) 
 
  794        minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
 
  795        maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
 
  800  toggleMethodWidgets( 
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
 
  801  methodComboBox->blockSignals( 
false );
 
  803  viewGraduated->resizeColumnToContents( 0 );
 
  804  viewGraduated->resizeColumnToContents( 1 );
 
  805  viewGraduated->resizeColumnToContents( 2 );
 
  807  mHistogramWidget->refresh();
 
 
  817  mRenderer->setClassAttribute( field );
 
 
  820void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged( 
int )
 
  822  const MethodMode newMethod = 
static_cast< MethodMode 
>( methodComboBox->currentData().toInt() );
 
  823  toggleMethodWidgets( newMethod );
 
  833        QMessageBox::critical( 
this, tr( 
"Select Method" ), tr( 
"No color ramp defined." ) );
 
  836      mRenderer->setSourceColorRamp( ramp );
 
  843      lblColorRamp->setVisible( 
false );
 
  844      btnColorRamp->setVisible( 
false );
 
  845      lblSize->setVisible( 
true );
 
  846      minSizeSpinBox->setVisible( 
true );
 
  847      lblSize->setVisible( 
true );
 
  848      maxSizeSpinBox->setVisible( 
true );
 
  849      mSizeUnitWidget->setVisible( 
true );
 
  858void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
 
  860  clearParameterWidgets();
 
  862  const QString methodId = cboGraduatedMode->currentData().toString();
 
  874    QVariant value = method->
parameterValues().value( def->name(), def->defaultValueForGui() );
 
  879    mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
 
  885void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
 
  891      lblColorRamp->setVisible( 
true );
 
  892      btnColorRamp->setVisible( 
true );
 
  893      lblSize->setVisible( 
false );
 
  894      minSizeSpinBox->setVisible( 
false );
 
  895      lblSizeTo->setVisible( 
false );
 
  896      maxSizeSpinBox->setVisible( 
false );
 
  897      mSizeUnitWidget->setVisible( 
false );
 
  903      lblColorRamp->setVisible( 
false );
 
  904      btnColorRamp->setVisible( 
false );
 
  905      lblSize->setVisible( 
true );
 
  906      minSizeSpinBox->setVisible( 
true );
 
  907      lblSizeTo->setVisible( 
true );
 
  908      maxSizeSpinBox->setVisible( 
true );
 
  909      mSizeUnitWidget->setVisible( 
true );
 
  915void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
 
  917  while ( mParametersLayout->rowCount() )
 
  919    QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
 
  920    for ( QLayoutItem *item : {row.labelItem, row.fieldItem} )
 
  923        QWidget *widget = item->widget();
 
  929  mParameterWidgetWrappers.clear();
 
  937  mModel->updateSymbology();
 
  940  spinGraduatedClasses->setValue( mRenderer->ranges().count() );
 
 
  953      mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
 
  956  mRenderer->setUsingSymbolLevels( enabled );
 
  957  mModel->updateSymbology();
 
 
  963  mGraduatedSymbol.reset( widget->
symbol()->
clone() );
 
  970  mSizeUnitWidget->blockSignals( 
true );
 
  971  mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
 
  972  mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
 
  973  mSizeUnitWidget->blockSignals( 
false );
 
  975  QItemSelectionModel *m = viewGraduated->selectionModel();
 
  976  QModelIndexList selectedIndexes = m->selectedRows( 1 );
 
  977  if ( !selectedIndexes.isEmpty() )
 
  979    const auto constSelectedIndexes = selectedIndexes;
 
  980    for ( 
const QModelIndex &idx : constSelectedIndexes )
 
  984        int rangeIdx = idx.row();
 
  985        QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
 
  986        if ( selectedIndexes.count() > 1 )
 
  989          newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
 
  991        mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
 
  997    mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 
 1004void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
 
 1006  const QString text = cboSymmetryPoint->lineEdit()->text();
 
 1007  int index = cboSymmetryPoint->findText( text );
 
 1010    cboSymmetryPoint->setCurrentIndex( index );
 
 1014    cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
 
 1022  mUpdateTimer.start( 500 );
 
 
 1025void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl( )
 
 1028  if ( mBlockUpdates )
 
 1032  QString attrName = mExpressionWidget->currentField();
 
 1033  int nclasses = spinGraduatedClasses->value();
 
 1035  const QString methodId = cboGraduatedMode->currentData().toString();
 
 1045  double minimum = minVal.toDouble();
 
 1046  double maximum = maxVal.toDouble();
 
 1047  mSymmetryPointValidator->
setBottom( minimum );
 
 1048  mSymmetryPointValidator->
setTop( maximum );
 
 1049  mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
 
 1057    if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
 
 1058      cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2., 
'f', method->
labelPrecision() + 2 ) );
 
 1061  if ( mGroupBoxSymmetric->isChecked() )
 
 1064    bool astride = cbxAstride->isChecked();
 
 1068  QVariantMap parameterValues;
 
 1069  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
 1070    parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() );
 
 1074  mRenderer->setClassificationMethod( method );
 
 1077  mRenderer->setClassAttribute( attrName );
 
 1083    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 ) )
 
 1089  if ( methodComboBox->currentData() == ColorMode )
 
 1091    std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
 
 1094      QMessageBox::critical( 
this, tr( 
"Apply Classification" ), tr( 
"No color ramp defined." ) );
 
 1097    mRenderer->setSourceColorRamp( ramp.release() );
 
 1101    mRenderer->setSourceColorRamp( 
nullptr );
 
 1105  mRenderer->updateClasses( 
mLayer, nclasses, error );
 
 1107  if ( !error.isEmpty() )
 
 1108    QMessageBox::critical( 
this, tr( 
"Apply Classification" ), error );
 
 1110  if ( methodComboBox->currentData() == SizeMode )
 
 1111    mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
 
 1113  mRenderer->calculateLabelPrecision();
 
 1121  std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
 
 1125  mRenderer->updateColorRamp( ramp.release() );
 
 1126  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 
 1132  mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
 
 1133  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 
 1138int QgsRendererPropertiesDialog::currentRangeRow()
 
 1140  QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
 
 1141  if ( !idx.isValid() )
 
 1150  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1152  const auto constSelectedRows = selectedRows;
 
 1153  for ( 
const QModelIndex &r : constSelectedRows )
 
 1157      rows.append( r.row() );
 
 
 1166  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1167  QModelIndexList::const_iterator sIt = selectedRows.constBegin();
 
 1169  for ( ; sIt != selectedRows.constEnd(); ++sIt )
 
 
 1178  if ( idx.isValid() && idx.column() == 0 )
 
 1180  if ( idx.isValid() && idx.column() == 1 )
 
 
 1186  if ( !idx.isValid() )
 
 1189    mRowSelected = idx.row();
 
 
 1199  std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
 
 1213    if ( !dlg.exec() || !newSymbol )
 
 1218    mGraduatedSymbol = std::move( newSymbol );
 
 1219    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
 
 
 1231  int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
 
 1232  if ( decimalPlaces < 0 ) decimalPlaces = 0;
 
 1236  if ( dialog.exec() == QDialog::Accepted )
 
 1242    if ( cbxLinkBoundaries->isChecked() )
 
 1246        mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
 
 1249      if ( rangeIdx < mRenderer->ranges().size() - 1 )
 
 1251        mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
 
 1255  mHistogramWidget->refresh();
 
 
 1261  mModel->addClass( mGraduatedSymbol.get() );
 
 1262  mHistogramWidget->refresh();
 
 
 1270  mModel->deleteRows( classIndexes );
 
 1271  mHistogramWidget->refresh();
 
 
 1277  mModel->removeAllRows();
 
 1278  mHistogramWidget->refresh();
 
 
 1285  bool ordered = 
true;
 
 1286  for ( 
int i = 1; i < ranges.size(); ++i )
 
 1288    if ( ranges[i] < ranges[i - 1] )
 
 
 1305      int result = QMessageBox::warning(
 
 1307                     tr( 
"Link Class Boundaries" ),
 
 1308                     tr( 
"Rows will be reordered before linking boundaries. Continue?" ),
 
 1309                     QMessageBox::Ok | QMessageBox::Cancel );
 
 1310      if ( result != QMessageBox::Ok )
 
 1312        cbxLinkBoundaries->setChecked( 
false );
 
 1315      mRenderer->sortByValue();
 
 1319    for ( 
int i = 1; i < mRenderer->ranges().size(); ++i )
 
 1321      mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
 
 
 1329  if ( item->column() == 2 )
 
 1331    QString label = item->text();
 
 1332    int idx = item->row();
 
 1333    mRenderer->updateRangeLabel( idx, label );
 
 
 1339  mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
 
 1340  mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
 
 1341  mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
 
 1342  mRenderer->updateRangeLabels();
 
 1343  mModel->updateLabels();
 
 
 1351  QItemSelectionModel *m = viewGraduated->selectionModel();
 
 1352  QModelIndexList selectedIndexes = m->selectedRows( 1 );
 
 1353  if ( !selectedIndexes.isEmpty() )
 
 1356    QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
 
 1357    for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
 
 1359      QStringList list = m->model()->data( *indexIt ).toString().split( 
' ' );
 
 1360      if ( list.size() < 3 )
 
 
 1385  int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
 
 1386  if ( decimalPlaces < 0 )
 
 1388  double precision = 1.0 / std::pow( 10, decimalPlaces );
 
 1390  for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
 
 1394      return it->symbol();
 
 
 1404    mModel->updateSymbology();
 
 1406  mHistogramWidget->refresh();
 
 
 1417  viewGraduated->selectionModel()->clear();
 
 1420    cbxLinkBoundaries->setChecked( 
false );
 
 
 1437  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
 
 1439    mCopyBuffer.clear();
 
 1442  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
 
 1444    QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
 
 1445    for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
 
 1447      mModel->addClass( *rIt );
 
 
 1453void QgsGraduatedSymbolRendererWidget::selectionChanged( 
const QItemSelection &, 
const QItemSelection & )
 
 1456  if ( !ranges.isEmpty() )
 
 1458    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
 
 1460  else if ( mRenderer->sourceSymbol() )
 
 1462    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
 
 1464  btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr( 
"Symbol Settings" ) );
 
 1467void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
 
 1482void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
 
 1484  mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
 
 1494  const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1495  for ( 
const QModelIndex &index : selectedRows )
 
 1497    if ( !index.isValid() )
 
 1500    const int row = index.row();
 
 1501    if ( !mRenderer || mRenderer->ranges().size() <= row )
 
 1504    if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
 
 1507    std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
 
 1508    if ( selectedRows.count() > 1 )
 
 1511      newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
 
 1514    mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
 
 
@ Size
Alter size of symbols.
 
@ Color
Alter color of symbols.
 
@ Millimeters
Millimeters.
 
@ Points
Points (e.g., for font sizes)
 
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.
 
@ IgnoresClassCount
The classification method does not compute classes based on a class count.
 
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.
 
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.
 
Abstract base class for all 2D vector feature renderers.
 
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
 
@ Date
Date or datetime fields.
 
@ Numeric
All numeric fields.
 
Q_INVOKABLE 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 ...
 
A vector feature renderer which uses numeric attributes to classify features into different ranges.
 
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.
 
A dialog that can be used to select and build a symbol.
 
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.
 
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