19#include <QStandardItemModel> 
   20#include <QStandardItem> 
   30#include "moc_qgsgraduatedsymbolrendererwidget.cpp" 
   67QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, QScreen *screen )
 
   68  : QAbstractItemModel( parent )
 
   69  , mMimeFormat( QStringLiteral( 
"application/x-qgsgraduatedsymbolrendererv2model" ) )
 
   78    if ( !mRenderer->ranges().isEmpty() )
 
   80      beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
 
   91    if ( !renderer->
ranges().isEmpty() )
 
   93      beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
 
  104void QgsGraduatedSymbolRendererModel::addClass( 
QgsSymbol *symbol )
 
  108  int idx = mRenderer->
ranges().size();
 
  109  beginInsertRows( QModelIndex(), idx, idx );
 
  110  mRenderer->addClass( symbol );
 
  114void QgsGraduatedSymbolRendererModel::addClass( 
const QgsRendererRange &range )
 
  120  int idx = mRenderer->ranges().size();
 
  121  beginInsertRows( QModelIndex(), idx, idx );
 
  122  mRenderer->addClass( range );
 
  126QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange( 
const QModelIndex &index )
 
  128  if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
 
  133  return mRenderer->ranges().value( index.row() );
 
  136Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags( 
const QModelIndex &index )
 const 
  139  if ( !index.isValid() )
 
  141    return Qt::ItemIsDropEnabled;
 
  144  Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable;
 
  146  if ( index.column() == 2 )
 
  148    flags |= Qt::ItemIsEditable;
 
  154Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
 const 
  156  return Qt::MoveAction;
 
  159QVariant QgsGraduatedSymbolRendererModel::data( 
const QModelIndex &index, 
int role )
 const 
  161  if ( !index.isValid() || !mRenderer )
 
  166  if ( role == Qt::CheckStateRole && index.column() == 0 )
 
  168    return range.
renderState() ? Qt::Checked : Qt::Unchecked;
 
  170  else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
 
  172    switch ( index.column() )
 
  176        int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
 
  177        if ( decimalPlaces < 0 )
 
  179        return QString( QLocale().toString( range.
lowerValue(), 
'f', decimalPlaces ) + 
" - " + QLocale().toString( range.
upperValue(), 
'f', decimalPlaces ) );
 
  182        return range.
label();
 
  187  else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
 
  192  else if ( role == Qt::TextAlignmentRole )
 
  194    return ( index.column() == 0 ) ? 
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
 
  196  else if ( role == Qt::EditRole )
 
  198    switch ( index.column() )
 
  202        return range.
label();
 
  211bool QgsGraduatedSymbolRendererModel::setData( 
const QModelIndex &index, 
const QVariant &value, 
int role )
 
  213  if ( !index.isValid() )
 
  216  if ( index.column() == 0 && role == Qt::CheckStateRole )
 
  218    mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
 
  219    emit dataChanged( index, index );
 
  223  if ( role != Qt::EditRole )
 
  226  switch ( index.column() )
 
  231      mRenderer->updateRangeLabel( index.row(), value.toString() );
 
  237  emit dataChanged( index, index );
 
  241QVariant QgsGraduatedSymbolRendererModel::headerData( 
int section, Qt::Orientation orientation, 
int role )
 const 
  243  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
 
  246    lst << tr( 
"Symbol" ) << tr( 
"Values" ) << tr( 
"Legend" );
 
  247    return lst.value( section );
 
  252int QgsGraduatedSymbolRendererModel::rowCount( 
const QModelIndex &parent )
 const 
  254  if ( parent.isValid() || !mRenderer )
 
  258  return mRenderer->ranges().size();
 
  261int QgsGraduatedSymbolRendererModel::columnCount( 
const QModelIndex &index )
 const 
  267QModelIndex QgsGraduatedSymbolRendererModel::index( 
int row, 
int column, 
const QModelIndex &parent )
 const 
  269  if ( hasIndex( row, column, parent ) )
 
  271    return createIndex( row, column );
 
  273  return QModelIndex();
 
  276QModelIndex QgsGraduatedSymbolRendererModel::parent( 
const QModelIndex &index )
 const 
  279  return QModelIndex();
 
  282QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
 const 
  285  types << mMimeFormat;
 
  289QMimeData *QgsGraduatedSymbolRendererModel::mimeData( 
const QModelIndexList &indexes )
 const 
  291  QMimeData *mimeData = 
new QMimeData();
 
  292  QByteArray encodedData;
 
  294  QDataStream stream( &encodedData, QIODevice::WriteOnly );
 
  297  const auto constIndexes = indexes;
 
  298  for ( 
const QModelIndex &index : constIndexes )
 
  300    if ( !index.isValid() || index.column() != 0 )
 
  303    stream << index.row();
 
  305  mimeData->setData( mMimeFormat, encodedData );
 
  309bool QgsGraduatedSymbolRendererModel::dropMimeData( 
const QMimeData *data, Qt::DropAction action, 
int row, 
int column, 
const QModelIndex &parent )
 
  313  if ( action != Qt::MoveAction )
 
  316  if ( !data->hasFormat( mMimeFormat ) )
 
  319  QByteArray encodedData = data->data( mMimeFormat );
 
  320  QDataStream stream( &encodedData, QIODevice::ReadOnly );
 
  323  while ( !stream.atEnd() )
 
  331  std::sort( rows.begin(), rows.end() );
 
  338    to = mRenderer->ranges().size(); 
 
  339  for ( 
int i = rows.size() - 1; i >= 0; i-- )
 
  341    QgsDebugMsgLevel( QStringLiteral( 
"move %1 to %2" ).arg( rows[i] ).arg( to ), 2 );
 
  346    mRenderer->moveClass( rows[i], t );
 
  348    for ( 
int j = 0; j < i; j++ )
 
  350      if ( to < rows[j] && rows[i] > rows[j] )
 
  357  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
 
  362void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
 
  364  for ( 
int i = rows.size() - 1; i >= 0; i-- )
 
  366    beginRemoveRows( QModelIndex(), rows[i], rows[i] );
 
  367    mRenderer->deleteClass( rows[i] );
 
  372void QgsGraduatedSymbolRendererModel::removeAllRows()
 
  374  beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
 
  375  mRenderer->deleteAllClasses();
 
  379void QgsGraduatedSymbolRendererModel::sort( 
int column, Qt::SortOrder order )
 
  387    mRenderer->sortByValue( order );
 
  389  else if ( column == 2 )
 
  391    mRenderer->sortByLabel( order );
 
  394  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
 
  397void QgsGraduatedSymbolRendererModel::updateSymbology()
 
  399  emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
 
  402void QgsGraduatedSymbolRendererModel::updateLabels()
 
  404  emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
 
  408QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
 
  412void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element, 
const QStyleOption *option, QPainter *painter, 
const QWidget *widget )
 const 
  414  if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
 
  416    QStyleOption opt( *option );
 
  417    opt.rect.setLeft( 0 );
 
  419    opt.rect.setHeight( 0 );
 
  421      opt.rect.setRight( widget->width() );
 
  422    QProxyStyle::drawPrimitive( element, &opt, painter, widget );
 
  425  QProxyStyle::drawPrimitive( element, option, painter, widget );
 
  443    expContext = lMapCanvas->createExpressionContext();
 
 
  477    mRenderer = std::make_unique<QgsGraduatedSymbolRenderer>( QString(), 
QgsRangeList() );
 
  486  cboSymmetryPoint->setEditable( 
true );
 
  487  cboSymmetryPoint->setValidator( mSymmetryPointValidator );
 
  490  for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
 
  493    cboGraduatedMode->addItem( icon, it.key(), it.value() );
 
  496  connect( methodComboBox, 
static_cast<void ( QComboBox::* )( 
int )
>( &QComboBox::currentIndexChanged ), 
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
 
  497  this->layout()->setContentsMargins( 0, 0, 0, 0 );
 
  499  mModel = 
new QgsGraduatedSymbolRendererModel( 
this, screen() );
 
  502  mExpressionWidget->setLayer( 
mLayer );
 
  504  btnChangeGraduatedSymbol->setLayer( 
mLayer );
 
  505  btnChangeGraduatedSymbol->registerExpressionContextGenerator( 
this );
 
  507  mSizeUnitWidget->setUnits(
 
  518  spinPrecision->setClearValue( 4 );
 
  520  spinGraduatedClasses->setShowClearButton( 
false );
 
  522  btnColorRamp->setShowRandomColorRamp( 
true );
 
  525  std::unique_ptr<QgsColorRamp> colorRamp( 
QgsProject::instance()->styleSettings()->defaultColorRamp() );
 
  528    btnColorRamp->setColorRamp( colorRamp.get() );
 
  533    btnColorRamp->setColorRamp( ramp );
 
  538  viewGraduated->setStyle( 
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
 
  541  if ( mGraduatedSymbol )
 
  543    btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
 
  544    btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
 
  546    methodComboBox->blockSignals( 
true );
 
  547    methodComboBox->addItem( tr( 
"Color" ), ColorMode );
 
  548    switch ( mGraduatedSymbol->type() )
 
  552        methodComboBox->addItem( tr( 
"Size" ), SizeMode );
 
  553        minSizeSpinBox->setValue( 1 );
 
  554        maxSizeSpinBox->setValue( 8 );
 
  559        methodComboBox->addItem( tr( 
"Size" ), SizeMode );
 
  560        minSizeSpinBox->setValue( .1 );
 
  561        maxSizeSpinBox->setValue( 2 );
 
  567        methodComboBox->hide();
 
  574    methodComboBox->blockSignals( 
false );
 
  583  connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed, 
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
 
  590  connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ), 
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
 
  593  updateMethodParameters();
 
  601  mGroupBoxSymmetric->setCollapsed( 
true ); 
 
  604  QMenu *advMenu = 
new QMenu( 
this );
 
  609    QAction *actionDdsLegend = advMenu->addAction( tr( 
"Data-defined Size Legend…" ) );
 
  611    connect( actionDdsLegend, &QAction::triggered, 
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
 
  614  btnAdvanced->setMenu( advMenu );
 
  616  mHistogramWidget->setLayer( 
mLayer );
 
  617  mHistogramWidget->setRenderer( mRenderer.get() );
 
  621  mExpressionWidget->registerExpressionContextGenerator( 
this );
 
  623  mUpdateTimer.setSingleShot( 
true );
 
  624  mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout, 
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
 
 
  627void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
 
  629  if ( !mGraduatedSymbol )
 
  631  mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
 
  632  mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
 
  633  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
  640  mParameterWidgetWrappers.clear();
 
 
  645  return mRenderer.get();
 
 
  657  delete mActionLevels;
 
  658  mActionLevels = 
nullptr;
 
 
  679  connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, 
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
 
  681  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
 
  705  disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished, 
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
 
  707  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
 
  723  int precision = spinPrecision->value() + 2;
 
  724  while ( cboSymmetryPoint->count() )
 
  725    cboSymmetryPoint->removeItem( 0 );
 
  726  for ( 
int i = 0; i < ranges.count() - 1; i++ )
 
  727    cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(), 
'f', 
precision ), ranges.at( i ).upperValue() );
 
  731    int idx = cboGraduatedMode->findData( method->
id() );
 
  733      cboGraduatedMode->setCurrentIndex( idx );
 
  739      cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(), 
'f', method->
labelPrecision() + 2 ) );
 
  746    for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
  750      ppww->setParameterValue( value, 
context );
 
  755  int nclasses = ranges.count();
 
  758    spinGraduatedClasses->setValue( ranges.count() );
 
  766    spinGraduatedClasses->setEnabled( 
true );
 
  770  QString attrName = mRenderer->classAttribute();
 
  771  mExpressionWidget->setField( attrName );
 
  772  mHistogramWidget->setSourceFieldExp( attrName );
 
  775  if ( mRenderer->sourceSymbol() )
 
  777    mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
 
  778    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
 
  781  mModel->setRenderer( mRenderer.get() );
 
  782  viewGraduated->setModel( mModel );
 
  784  connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged, 
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
 
  786  if ( mGraduatedSymbol )
 
  788    mSizeUnitWidget->blockSignals( 
true );
 
  789    mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
 
  790    mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
 
  791    mSizeUnitWidget->blockSignals( 
false );
 
  795  methodComboBox->blockSignals( 
true );
 
  796  switch ( mRenderer->graduatedMethod() )
 
  800      methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
 
  801      if ( mRenderer->sourceColorRamp() )
 
  803        btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
 
  809      methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
 
  810      if ( !mRenderer->ranges().isEmpty() ) 
 
  812        minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
 
  813        maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
 
  818  toggleMethodWidgets( 
static_cast<MethodMode
>( methodComboBox->currentData().toInt() ) );
 
  819  methodComboBox->blockSignals( 
false );
 
  821  viewGraduated->resizeColumnToContents( 0 );
 
  822  viewGraduated->resizeColumnToContents( 1 );
 
  823  viewGraduated->resizeColumnToContents( 2 );
 
  825  mHistogramWidget->refresh();
 
 
  835  mRenderer->setClassAttribute( field );
 
 
  839void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged( 
int )
 
  841  const MethodMode newMethod = 
static_cast<MethodMode
>( methodComboBox->currentData().toInt() );
 
  842  toggleMethodWidgets( newMethod );
 
  852        QMessageBox::critical( 
this, tr( 
"Select Method" ), tr( 
"No color ramp defined." ) );
 
  855      mRenderer->setSourceColorRamp( ramp );
 
  862      lblColorRamp->setVisible( 
false );
 
  863      btnColorRamp->setVisible( 
false );
 
  864      lblSize->setVisible( 
true );
 
  865      minSizeSpinBox->setVisible( 
true );
 
  866      lblSize->setVisible( 
true );
 
  867      maxSizeSpinBox->setVisible( 
true );
 
  868      mSizeUnitWidget->setVisible( 
true );
 
  877void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
 
  879  clearParameterWidgets();
 
  881  const QString methodId = cboGraduatedMode->currentData().toString();
 
  883  Q_ASSERT( mClassificationMethod.get() );
 
  893    QVariant value = mClassificationMethod->parameterValues().value( def->name(), def->defaultValueForGui() );
 
  898    mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
 
  904void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
 
  910      lblColorRamp->setVisible( 
true );
 
  911      btnColorRamp->setVisible( 
true );
 
  912      lblSize->setVisible( 
false );
 
  913      minSizeSpinBox->setVisible( 
false );
 
  914      lblSizeTo->setVisible( 
false );
 
  915      maxSizeSpinBox->setVisible( 
false );
 
  916      mSizeUnitWidget->setVisible( 
false );
 
  922      lblColorRamp->setVisible( 
false );
 
  923      btnColorRamp->setVisible( 
false );
 
  924      lblSize->setVisible( 
true );
 
  925      minSizeSpinBox->setVisible( 
true );
 
  926      lblSizeTo->setVisible( 
true );
 
  927      maxSizeSpinBox->setVisible( 
true );
 
  928      mSizeUnitWidget->setVisible( 
true );
 
  934void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
 
  936  while ( mParametersLayout->rowCount() )
 
  938    QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
 
  939    for ( QLayoutItem *item : { row.labelItem, row.fieldItem } )
 
  942        QWidget *widget = item->widget();
 
  948  mParameterWidgetWrappers.clear();
 
  956  mModel->updateSymbology();
 
  959  spinGraduatedClasses->setValue( mRenderer->ranges().count() );
 
 
  972      mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
 
  975  mRenderer->setUsingSymbolLevels( enabled );
 
  976  mModel->updateSymbology();
 
 
  982  mGraduatedSymbol.reset( widget->
symbol()->
clone() );
 
  989  mSizeUnitWidget->blockSignals( 
true );
 
  990  mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
 
  991  mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
 
  992  mSizeUnitWidget->blockSignals( 
false );
 
  994  QItemSelectionModel *m = viewGraduated->selectionModel();
 
  995  QModelIndexList selectedIndexes = m->selectedRows( 1 );
 
  996  if ( !selectedIndexes.isEmpty() )
 
  998    const auto constSelectedIndexes = selectedIndexes;
 
  999    for ( 
const QModelIndex &idx : constSelectedIndexes )
 
 1001      if ( idx.isValid() )
 
 1003        int rangeIdx = idx.row();
 
 1004        QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
 
 1005        if ( selectedIndexes.count() > 1 )
 
 1008          newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
 
 1010        mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
 
 1016    mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 
 1023void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished()
 
 1025  const QString text = cboSymmetryPoint->lineEdit()->text();
 
 1026  int index = cboSymmetryPoint->findText( text );
 
 1029    cboSymmetryPoint->setCurrentIndex( index );
 
 1033    cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
 
 1041  mUpdateTimer.start( 500 );
 
 
 1044void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl()
 
 1046  if ( mBlockUpdates || !mClassificationMethod )
 
 1050  QString attrName = mExpressionWidget->currentField();
 
 1051  int nclasses = spinGraduatedClasses->value();
 
 1059  double minimum = minVal.toDouble();
 
 1060  double maximum = maxVal.toDouble();
 
 1061  mSymmetryPointValidator->
setBottom( minimum );
 
 1062  mSymmetryPointValidator->
setTop( maximum );
 
 1063  mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
 
 1070    if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
 
 1071      cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2., 
'f', mClassificationMethod->labelPrecision() + 2 ) );
 
 1074  if ( mGroupBoxSymmetric->isChecked() )
 
 1077    bool astride = cbxAstride->isChecked();
 
 1078    mClassificationMethod->setSymmetricMode( 
true, symmetryPoint, astride );
 
 1081  QVariantMap parameterValues;
 
 1082  for ( 
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
 
 1083    parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() );
 
 1084  mClassificationMethod->setParameterValues( parameterValues );
 
 1087  mRenderer->setClassificationMethod( mClassificationMethod->clone().release() );
 
 1090  mRenderer->setClassAttribute( attrName );
 
 1094  if ( mRenderer->classificationMethod()->codeComplexity() > 1 && 
mLayer->
featureCount() > 50000 )
 
 1096    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 ) )
 
 1102  if ( methodComboBox->currentData() == ColorMode )
 
 1104    std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
 
 1107      QMessageBox::critical( 
this, tr( 
"Apply Classification" ), tr( 
"No color ramp defined." ) );
 
 1110    mRenderer->setSourceColorRamp( ramp.release() );
 
 1114    mRenderer->setSourceColorRamp( 
nullptr );
 
 1118  mRenderer->updateClasses( 
mLayer, nclasses, error );
 
 1120  if ( !error.isEmpty() )
 
 1121    QMessageBox::critical( 
this, tr( 
"Apply Classification" ), error );
 
 1123  if ( methodComboBox->currentData() == SizeMode )
 
 1124    mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
 
 1126  mRenderer->calculateLabelPrecision();
 
 1134  std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
 
 1138  mRenderer->updateColorRamp( ramp.release() );
 
 1139  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 
 1145  mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
 
 1146  mRenderer->updateSymbols( mGraduatedSymbol.get() );
 
 
 1151int QgsRendererPropertiesDialog::currentRangeRow()
 
 1153  QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
 
 1154  if ( !idx.isValid() )
 
 1163  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1165  const auto constSelectedRows = selectedRows;
 
 1166  for ( 
const QModelIndex &r : constSelectedRows )
 
 1170      rows.append( r.row() );
 
 
 1179  QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1180  QModelIndexList::const_iterator sIt = selectedRows.constBegin();
 
 1182  for ( ; sIt != selectedRows.constEnd(); ++sIt )
 
 
 1191  if ( idx.isValid() && idx.column() == 0 )
 
 1193  if ( idx.isValid() && idx.column() == 1 )
 
 
 1199  if ( !idx.isValid() )
 
 1202    mRowSelected = idx.row();
 
 
 1212  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 )
 
 1250  if ( dialog.exec() == QDialog::Accepted )
 
 1256    if ( cbxLinkBoundaries->isChecked() )
 
 1260        mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
 
 1263      if ( rangeIdx < mRenderer->ranges().size() - 1 )
 
 1265        mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
 
 1269  mHistogramWidget->refresh();
 
 
 1275  mModel->addClass( mGraduatedSymbol.get() );
 
 1276  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
 
 1324      if ( result != QMessageBox::Ok )
 
 1326        cbxLinkBoundaries->setChecked( 
false );
 
 1329      mRenderer->sortByValue();
 
 1333    for ( 
int i = 1; i < mRenderer->ranges().size(); ++i )
 
 1335      mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
 
 
 1343  if ( item->column() == 2 )
 
 1345    QString label = item->text();
 
 1346    int idx = item->row();
 
 1347    mRenderer->updateRangeLabel( idx, label );
 
 
 1353  mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
 
 1354  mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
 
 1355  mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
 
 1356  mRenderer->updateRangeLabels();
 
 1357  mModel->updateLabels();
 
 
 1365  QItemSelectionModel *m = viewGraduated->selectionModel();
 
 1366  QModelIndexList selectedIndexes = m->selectedRows( 1 );
 
 1367  if ( !selectedIndexes.isEmpty() )
 
 1370    QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
 
 1371    for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
 
 1373      QStringList list = m->model()->data( *indexIt ).toString().split( 
' ' );
 
 1374      if ( list.size() < 3 )
 
 
 1399  int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
 
 1400  if ( decimalPlaces < 0 )
 
 1402  double precision = 1.0 / std::pow( 10, decimalPlaces );
 
 1404  for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
 
 1408      return it->symbol();
 
 
 1418    mModel->updateSymbology();
 
 1420  mHistogramWidget->refresh();
 
 
 1431  viewGraduated->selectionModel()->clear();
 
 1434    cbxLinkBoundaries->setChecked( 
false );
 
 
 1451  if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
 
 1453    mCopyBuffer.clear();
 
 1456  else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
 
 1458    QgsRangeList::iterator rIt = mCopyBuffer.begin();
 
 1459    for ( ; rIt != mCopyBuffer.end(); ++rIt )
 
 1461      rIt->mUuid = QUuid::createUuid().toString();
 
 1462      mModel->addClass( *rIt );
 
 
 1468void QgsGraduatedSymbolRendererWidget::selectionChanged( 
const QItemSelection &, 
const QItemSelection & )
 
 1471  if ( !ranges.isEmpty() )
 
 1473    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
 
 1475  else if ( mRenderer->sourceSymbol() )
 
 1477    whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
 
 1479  btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr( 
"Symbol Settings" ) );
 
 1482void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
 
 1496void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
 
 1498  mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
 
 1508  const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
 
 1509  for ( 
const QModelIndex &index : selectedRows )
 
 1511    if ( !index.isValid() )
 
 1514    const int row = index.row();
 
 1515    if ( !mRenderer || mRenderer->ranges().size() <= row )
 
 1518    if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
 
 1521    std::unique_ptr<QgsSymbol> newCatSymbol( tempSymbol->clone() );
 
 1522    if ( selectedRows.count() > 1 )
 
 1525      newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
 
 1528    mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
 
 
@ Standard
Standard (single-run) algorithm mode.
 
@ 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
 
std::unique_ptr< 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.
 
An abstract class for implementations of classification methods.
 
double symmetryPoint() const
Returns the symmetry point for symmetric mode.
 
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.
 
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.
 
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.
 
A custom validator which allows entry of doubles in a locale-tolerant way.
 
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.
 
@ 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...
 
A dialog for setting a lower and upper range value.
 
double upperValueDouble() const
Returns the upper value.
 
double lowerValueDouble() const
Returns the lower value.
 
void setLowerValue(const QString &val)
 
void setUpperValue(const QString &val)
 
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
 
Contains configuration for rendering maps.
 
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, Qgis::ProcessingMode type)
Creates a new parameter widget wrapper for the given parameter.
 
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,...
 
Represents a value range for a QgsGraduatedSymbolRenderer.
 
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.
 
A database of saved style entities, including symbols, color ramps, text formats and others.
 
static std::unique_ptr< 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 dataset.
 
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