19#include <QStandardItemModel>
20#include <QStandardItem>
64QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent ) : QAbstractItemModel( parent )
65 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
73 if ( !mRenderer->ranges().isEmpty() )
75 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
86 if ( !renderer->
ranges().isEmpty() )
88 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
99void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
101 if ( !mRenderer )
return;
102 int idx = mRenderer->
ranges().size();
103 beginInsertRows( QModelIndex(), idx, idx );
104 mRenderer->addClass( symbol );
108void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
114 int idx = mRenderer->ranges().size();
115 beginInsertRows( QModelIndex(), idx, idx );
116 mRenderer->addClass( range );
120QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
122 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
127 return mRenderer->ranges().value( index.row() );
130Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
132 if ( !index.isValid() )
134 return Qt::ItemIsDropEnabled;
137 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
139 if ( index.column() == 2 )
141 flags |= Qt::ItemIsEditable;
147Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
149 return Qt::MoveAction;
152QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
154 if ( !index.isValid() || !mRenderer )
return QVariant();
158 if ( role == Qt::CheckStateRole && index.column() == 0 )
160 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
162 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
164 switch ( index.column() )
168 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
169 if ( decimalPlaces < 0 ) decimalPlaces = 0;
170 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
173 return range.
label();
178 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
183 else if ( role == Qt::TextAlignmentRole )
185 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) :
static_cast<Qt::Alignment::Int
>( Qt::AlignLeft );
187 else if ( role == Qt::EditRole )
189 switch ( index.column() )
193 return range.
label();
202bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
204 if ( !index.isValid() )
207 if ( index.column() == 0 && role == Qt::CheckStateRole )
209 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
210 emit dataChanged( index, index );
214 if ( role != Qt::EditRole )
217 switch ( index.column() )
222 mRenderer->updateRangeLabel( index.row(), value.toString() );
228 emit dataChanged( index, index );
232QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
234 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
237 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
238 return lst.value( section );
243int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
245 if ( parent.isValid() || !mRenderer )
249 return mRenderer->ranges().size();
252int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
258QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
260 if ( hasIndex( row, column, parent ) )
262 return createIndex( row, column );
264 return QModelIndex();
267QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
270 return QModelIndex();
273QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
276 types << mMimeFormat;
280QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
282 QMimeData *mimeData =
new QMimeData();
283 QByteArray encodedData;
285 QDataStream stream( &encodedData, QIODevice::WriteOnly );
288 const auto constIndexes = indexes;
289 for (
const QModelIndex &index : constIndexes )
291 if ( !index.isValid() || index.column() != 0 )
294 stream << index.row();
296 mimeData->setData( mMimeFormat, encodedData );
300bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
304 if ( action != Qt::MoveAction )
return true;
306 if ( !data->hasFormat( mMimeFormat ) )
return false;
308 QByteArray encodedData = data->data( mMimeFormat );
309 QDataStream stream( &encodedData, QIODevice::ReadOnly );
312 while ( !stream.atEnd() )
319 int to = parent.row();
322 if ( to == -1 ) to = mRenderer->ranges().size();
323 for (
int i = rows.size() - 1; i >= 0; i-- )
325 QgsDebugMsg( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ) );
328 if ( rows[i] < t ) t--;
329 mRenderer->moveClass( rows[i], t );
331 for (
int j = 0; j < i; j++ )
333 if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
336 if ( rows[i] < to ) to--;
338 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
343void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
345 for (
int i = rows.size() - 1; i >= 0; i-- )
347 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
348 mRenderer->deleteClass( rows[i] );
353void QgsGraduatedSymbolRendererModel::removeAllRows()
355 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
356 mRenderer->deleteAllClasses();
360void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
368 mRenderer->sortByValue( order );
370 else if ( column == 2 )
372 mRenderer->sortByLabel( order );
375 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
378void QgsGraduatedSymbolRendererModel::updateSymbology()
380 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
383void QgsGraduatedSymbolRendererModel::updateLabels()
385 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
389QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
393void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
395 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
397 QStyleOption opt( *option );
398 opt.rect.setLeft( 0 );
400 opt.rect.setHeight( 0 );
401 if ( widget ) opt.rect.setRight( widget->width() );
402 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
405 QProxyStyle::drawPrimitive( element, option, painter, widget );
430 expContext << generator->createExpressionContextScope();
462 mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(),
QgsRangeList() );
471 cboSymmetryPoint->setEditable(
true );
472 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
475 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
478 cboGraduatedMode->addItem( icon, it.key(), it.value() );
481 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
482 this->layout()->setContentsMargins( 0, 0, 0, 0 );
484 mModel =
new QgsGraduatedSymbolRendererModel(
this );
487 mExpressionWidget->setLayer(
mLayer );
489 btnChangeGraduatedSymbol->setLayer(
mLayer );
490 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
492 mSizeUnitWidget->setUnits(
494 Qgis::RenderUnit::Millimeters,
495 Qgis::RenderUnit::MapUnits,
496 Qgis::RenderUnit::Pixels,
497 Qgis::RenderUnit::Points,
498 Qgis::RenderUnit::Inches
503 spinPrecision->setClearValue( 4 );
505 spinGraduatedClasses->setShowClearButton(
false );
507 btnColorRamp->setShowRandomColorRamp(
true );
510 std::unique_ptr< QgsColorRamp > colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
513 btnColorRamp->setColorRamp( colorRamp.get() );
518 btnColorRamp->setColorRamp( ramp );
523 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
526 if ( mGraduatedSymbol )
528 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
529 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
531 methodComboBox->blockSignals(
true );
532 methodComboBox->addItem( tr(
"Color" ), ColorMode );
533 switch ( mGraduatedSymbol->type() )
537 methodComboBox->addItem( tr(
"Size" ), SizeMode );
538 minSizeSpinBox->setValue( 1 );
539 maxSizeSpinBox->setValue( 8 );
544 methodComboBox->addItem( tr(
"Size" ), SizeMode );
545 minSizeSpinBox->setValue( .1 );
546 maxSizeSpinBox->setValue( 2 );
552 methodComboBox->hide();
559 methodComboBox->blockSignals(
false );
568 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
575 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::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();
738 if ( nclasses && ( updateCount || ( method && ( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) ) ) )
740 spinGraduatedClasses->setValue( ranges.count() );
744 spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
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() )
780 case Qgis::GraduatedMethod::Color:
782 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
783 if ( mRenderer->sourceColorRamp() )
785 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
789 case Qgis::GraduatedMethod::Size:
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 );
828 mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Color );
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 );
851 mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Size );
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 ) );
882 spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
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 : QList<QLayoutItem *>( {row.labelItem, row.fieldItem} ) )
923 if ( item->widget() )
924 item->widget()->deleteLater();
928 mParameterWidgetWrappers.clear();
936 mModel->updateSymbology();
939 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
952 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
955 mRenderer->setUsingSymbolLevels( enabled );
956 mModel->updateSymbology();
960void QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
969void QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget()
979 mSizeUnitWidget->blockSignals(
true );
980 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
981 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
982 mSizeUnitWidget->blockSignals(
false );
984 QItemSelectionModel *m = viewGraduated->selectionModel();
985 QModelIndexList selectedIndexes = m->selectedRows( 1 );
986 if ( !selectedIndexes.isEmpty() )
988 const auto constSelectedIndexes = selectedIndexes;
989 for (
const QModelIndex &idx : constSelectedIndexes )
993 int rangeIdx = idx.row();
994 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
995 if ( selectedIndexes.count() > 1 )
998 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
1000 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
1006 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1013void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
1015 const QString text = cboSymmetryPoint->lineEdit()->text();
1016 int index = cboSymmetryPoint->findText( text );
1019 cboSymmetryPoint->setCurrentIndex( index );
1023 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1031 mUpdateTimer.start( 500 );
1034void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl( )
1037 if ( mBlockUpdates )
1041 QString attrName = mExpressionWidget->currentField();
1042 int nclasses = spinGraduatedClasses->value();
1044 const QString methodId = cboGraduatedMode->currentData().toString();
1054 double minimum = minVal.toDouble();
1055 double maximum = maxVal.toDouble();
1056 mSymmetryPointValidator->
setBottom( minimum );
1057 mSymmetryPointValidator->
setTop( maximum );
1058 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1066 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1067 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1070 if ( mGroupBoxSymmetric->isChecked() )
1073 bool astride = cbxAstride->isChecked();
1077 QVariantMap parameterValues;
1078 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1083 mRenderer->setClassificationMethod( method );
1086 mRenderer->setClassAttribute( attrName );
1092 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 ) )
1098 if ( methodComboBox->currentData() == ColorMode )
1100 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1103 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1106 mRenderer->setSourceColorRamp( ramp.release() );
1110 mRenderer->setSourceColorRamp(
nullptr );
1113 mRenderer->updateClasses(
mLayer, nclasses );
1115 if ( methodComboBox->currentData() == SizeMode )
1116 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1118 mRenderer->calculateLabelPrecision();
1126 std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
1130 mRenderer->updateColorRamp( ramp.release() );
1131 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1137 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1138 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1143int QgsRendererPropertiesDialog::currentRangeRow()
1145 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1146 if ( !idx.isValid() )
1155 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1157 const auto constSelectedRows = selectedRows;
1158 for (
const QModelIndex &r : constSelectedRows )
1162 rows.append( r.row() );
1171 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1172 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1174 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1183 if ( idx.isValid() && idx.column() == 0 )
1185 if ( idx.isValid() && idx.column() == 1 )
1191 if ( !idx.isValid() )
1194 mRowSelected = idx.row();
1204 std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
1221 if ( !dlg.exec() || !newSymbol )
1226 mGraduatedSymbol = std::move( newSymbol );
1227 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1239 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1240 if ( decimalPlaces < 0 ) decimalPlaces = 0;
1244 if ( dialog.exec() == QDialog::Accepted )
1250 if ( cbxLinkBoundaries->isChecked() )
1254 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1257 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1259 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1263 mHistogramWidget->refresh();
1269 mModel->addClass( mGraduatedSymbol.get() );
1270 mHistogramWidget->refresh();
1278 mModel->deleteRows( classIndexes );
1279 mHistogramWidget->refresh();
1285 mModel->removeAllRows();
1286 mHistogramWidget->refresh();
1293 bool ordered =
true;
1294 for (
int i = 1; i < ranges.size(); ++i )
1296 if ( ranges[i] < ranges[i - 1] )
1313 int result = QMessageBox::warning(
1315 tr(
"Link Class Boundaries" ),
1316 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1317 QMessageBox::Ok | QMessageBox::Cancel );
1318 if ( result != QMessageBox::Ok )
1320 cbxLinkBoundaries->setChecked(
false );
1323 mRenderer->sortByValue();
1327 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1329 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1337 if ( item->column() == 2 )
1339 QString label = item->text();
1340 int idx = item->row();
1341 mRenderer->updateRangeLabel( idx, label );
1347 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1348 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1349 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1350 mRenderer->updateRangeLabels();
1351 mModel->updateLabels();
1359 QItemSelectionModel *m = viewGraduated->selectionModel();
1360 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1361 if ( !selectedIndexes.isEmpty() )
1364 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1365 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1367 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1368 if ( list.size() < 3 )
1393 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1394 if ( decimalPlaces < 0 )
1396 double precision = 1.0 / std::pow( 10, decimalPlaces );
1398 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1402 return it->symbol();
1412 mModel->updateSymbology();
1414 mHistogramWidget->refresh();
1425 viewGraduated->selectionModel()->clear();
1428 cbxLinkBoundaries->setChecked(
false );
1445 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1447 mCopyBuffer.clear();
1450 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1452 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1453 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1455 mModel->addClass( *rIt );
1461void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1464 if ( !ranges.isEmpty() )
1466 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1468 else if ( mRenderer->sourceSymbol() )
1470 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1472 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1475void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1490void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1492 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1502 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1503 for (
const QModelIndex &index : selectedRows )
1505 if ( !index.isValid() )
1508 const int row = index.row();
1509 if ( !mRenderer || mRenderer->ranges().size() <= row )
1512 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1515 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1516 if ( selectedRows.count() > 1 )
1519 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1522 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.
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)
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
QList< QgsRendererRange > QgsRangeList