57#include <QStandardItem>
58#include <QStandardItemModel>
62#include "moc_qgsgraduatedsymbolrendererwidget.cpp"
64using namespace Qt::StringLiterals;
70QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, QScreen *screen )
71 : QAbstractItemModel( parent )
72 , mMimeFormat( u
"application/x-qgsgraduatedsymbolrendererv2model"_s )
80 if ( !mRenderer->ranges().isEmpty() )
82 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
93 if ( !renderer->
ranges().isEmpty() )
95 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
101 mRenderer = renderer;
106void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
110 int idx = mRenderer->ranges().size();
111 beginInsertRows( QModelIndex(), idx, idx );
112 mRenderer->addClass( symbol );
116void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
122 int idx = mRenderer->ranges().size();
123 beginInsertRows( QModelIndex(), idx, idx );
124 mRenderer->addClass( range );
128QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
130 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
135 return mRenderer->ranges().value( index.row() );
138Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
141 if ( !index.isValid() )
143 return Qt::ItemIsDropEnabled;
146 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable;
148 if ( index.column() == 2 )
150 flags |= Qt::ItemIsEditable;
156Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
158 return Qt::MoveAction;
161QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
163 if ( !index.isValid() || !mRenderer )
168 if ( role == Qt::CheckStateRole && index.column() == 0 )
170 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
172 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
174 switch ( index.column() )
178 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
179 if ( decimalPlaces < 0 )
181 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
184 return range.
label();
189 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
194 else if ( role == Qt::TextAlignmentRole )
196 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
198 else if ( role == Qt::EditRole )
200 switch ( index.column() )
204 return range.
label();
213bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
215 if ( !index.isValid() )
218 if ( index.column() == 0 && role == Qt::CheckStateRole )
220 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
221 emit dataChanged( index, index );
225 if ( role != Qt::EditRole )
228 switch ( index.column() )
233 mRenderer->updateRangeLabel( index.row(), value.toString() );
239 emit dataChanged( index, index );
243QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
245 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
248 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
249 return lst.value( section );
254int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
256 if ( parent.isValid() || !mRenderer )
260 return mRenderer->ranges().size();
263int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
269QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
271 if ( hasIndex( row, column, parent ) )
273 return createIndex( row, column );
275 return QModelIndex();
278QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
281 return QModelIndex();
284QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
287 types << mMimeFormat;
291QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
293 QMimeData *mimeData =
new QMimeData();
294 QByteArray encodedData;
296 QDataStream stream( &encodedData, QIODevice::WriteOnly );
299 const auto constIndexes = indexes;
300 for (
const QModelIndex &index : constIndexes )
302 if ( !index.isValid() || index.column() != 0 )
305 stream << index.row();
307 mimeData->setData( mMimeFormat, encodedData );
311bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
315 if ( action != Qt::MoveAction )
318 if ( !data->hasFormat( mMimeFormat ) )
321 QByteArray encodedData = data->data( mMimeFormat );
322 QDataStream stream( &encodedData, QIODevice::ReadOnly );
325 while ( !stream.atEnd() )
333 std::sort( rows.begin(), rows.end() );
340 to = mRenderer->ranges().size();
341 for (
int i = rows.size() - 1; i >= 0; i-- )
348 mRenderer->moveClass( rows[i], t );
350 for (
int j = 0; j < i; j++ )
352 if ( to < rows[j] && rows[i] > rows[j] )
359 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
364void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
366 for (
int i = rows.size() - 1; i >= 0; i-- )
368 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
369 mRenderer->deleteClass( rows[i] );
374void QgsGraduatedSymbolRendererModel::removeAllRows()
376 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
377 mRenderer->deleteAllClasses();
381void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
389 mRenderer->sortByValue( order );
391 else if ( column == 2 )
393 mRenderer->sortByLabel( order );
396 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
399void QgsGraduatedSymbolRendererModel::updateSymbology()
401 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
404void QgsGraduatedSymbolRendererModel::updateLabels()
406 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
410QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
414void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
416 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
418 QStyleOption opt( *option );
419 opt.rect.setLeft( 0 );
421 opt.rect.setHeight( 0 );
423 opt.rect.setRight( widget->width() );
424 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
427 QProxyStyle::drawPrimitive( element, option, painter, widget );
443 if (
auto *lMapCanvas =
mContext.mapCanvas() )
445 expContext = lMapCanvas->createExpressionContext();
460 const auto constAdditionalExpressionContextScopes =
mContext.additionalExpressionContextScopes();
480 mRenderer = std::make_unique<QgsGraduatedSymbolRenderer>( QString(),
QgsRangeList() );
482 renderer->copyRendererData( mRenderer.get() );
489 cboSymmetryPoint->setEditable(
true );
490 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
493 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
496 cboGraduatedMode->addItem( icon, it.key(), it.value() );
499 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
500 this->layout()->setContentsMargins( 0, 0, 0, 0 );
502 mModel =
new QgsGraduatedSymbolRendererModel(
this, screen() );
505 mExpressionWidget->setLayer(
mLayer );
507 btnChangeGraduatedSymbol->setLayer(
mLayer );
508 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
514 spinPrecision->setClearValue( 4 );
516 spinGraduatedClasses->setShowClearButton(
false );
518 btnColorRamp->setShowRandomColorRamp(
true );
521 std::unique_ptr<QgsColorRamp> colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
524 btnColorRamp->setColorRamp( colorRamp.get() );
529 btnColorRamp->setColorRamp( ramp );
534 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
537 if ( mGraduatedSymbol )
539 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
540 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
542 methodComboBox->blockSignals(
true );
543 methodComboBox->addItem( tr(
"Color" ), ColorMode );
544 switch ( mGraduatedSymbol->type() )
548 methodComboBox->addItem( tr(
"Size" ), SizeMode );
549 minSizeSpinBox->setValue( 1 );
550 maxSizeSpinBox->setValue( 8 );
555 methodComboBox->addItem( tr(
"Size" ), SizeMode );
556 minSizeSpinBox->setValue( .1 );
557 maxSizeSpinBox->setValue( 2 );
563 methodComboBox->hide();
570 methodComboBox->blockSignals(
false );
579 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
586 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
589 updateMethodParameters();
597 mGroupBoxSymmetric->setCollapsed(
true );
600 QMenu *advMenu =
new QMenu(
this );
605 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
607 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
610 btnAdvanced->setMenu( advMenu );
612 mHistogramWidget->setLayer(
mLayer );
613 mHistogramWidget->setRenderer( mRenderer.get() );
617 mExpressionWidget->registerExpressionContextGenerator(
this );
619 mUpdateTimer.setSingleShot(
true );
620 mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout,
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
623void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
625 if ( !mGraduatedSymbol )
627 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
628 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
629 mRenderer->updateSymbols( mGraduatedSymbol.get() );
636 mParameterWidgetWrappers.clear();
641 return mRenderer.get();
647 btnChangeGraduatedSymbol->setMapCanvas(
context.mapCanvas() );
648 btnChangeGraduatedSymbol->setMessageBar(
context.messageBar() );
653 delete mActionLevels;
654 mActionLevels =
nullptr;
675 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
677 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
701 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
703 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
719 int precision = spinPrecision->value() + 2;
720 while ( cboSymmetryPoint->count() )
721 cboSymmetryPoint->removeItem( 0 );
722 for (
int i = 0; i < ranges.count() - 1; i++ )
723 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f', precision ), ranges.at( i ).upperValue() );
727 int idx = cboGraduatedMode->findData( method->
id() );
729 cboGraduatedMode->setCurrentIndex( idx );
735 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
742 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
746 ppww->setParameterValue( value,
context );
751 int nclasses = ranges.count();
754 spinGraduatedClasses->setValue( ranges.count() );
762 spinGraduatedClasses->setEnabled(
true );
766 QString attrName = mRenderer->classAttribute();
767 mExpressionWidget->setField( attrName );
768 mHistogramWidget->setSourceFieldExp( attrName );
771 if ( mRenderer->sourceSymbol() )
773 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
774 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
777 mModel->setRenderer( mRenderer.get() );
778 viewGraduated->setModel( mModel );
780 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
782 if ( mGraduatedSymbol )
784 mSizeUnitWidget->blockSignals(
true );
785 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
786 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
787 mSizeUnitWidget->blockSignals(
false );
791 methodComboBox->blockSignals(
true );
792 switch ( mRenderer->graduatedMethod() )
796 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
797 if ( mRenderer->sourceColorRamp() )
799 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
805 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
806 if ( !mRenderer->ranges().isEmpty() )
808 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
809 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
814 toggleMethodWidgets(
static_cast<MethodMode
>( methodComboBox->currentData().toInt() ) );
815 methodComboBox->blockSignals(
false );
817 viewGraduated->resizeColumnToContents( 0 );
818 viewGraduated->resizeColumnToContents( 1 );
819 viewGraduated->resizeColumnToContents( 2 );
821 mHistogramWidget->refresh();
831 mRenderer->setClassAttribute( field );
835void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
837 const MethodMode newMethod =
static_cast<MethodMode
>( methodComboBox->currentData().toInt() );
838 toggleMethodWidgets( newMethod );
848 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
851 mRenderer->setSourceColorRamp( ramp );
858 lblColorRamp->setVisible(
false );
859 btnColorRamp->setVisible(
false );
860 lblSize->setVisible(
true );
861 minSizeSpinBox->setVisible(
true );
862 lblSize->setVisible(
true );
863 maxSizeSpinBox->setVisible(
true );
864 mSizeUnitWidget->setVisible(
true );
873void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
875 clearParameterWidgets();
877 const QString methodId = cboGraduatedMode->currentData().toString();
879 Q_ASSERT( mClassificationMethod.get() );
884 for (
const QgsProcessingParameterDefinition *def : mClassificationMethod->parameterDefinitions() )
889 QVariant value = mClassificationMethod->parameterValues().value( def->name(), def->defaultValueForGui() );
894 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
900void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
906 lblColorRamp->setVisible(
true );
907 btnColorRamp->setVisible(
true );
908 lblSize->setVisible(
false );
909 minSizeSpinBox->setVisible(
false );
910 lblSizeTo->setVisible(
false );
911 maxSizeSpinBox->setVisible(
false );
912 mSizeUnitWidget->setVisible(
false );
918 lblColorRamp->setVisible(
false );
919 btnColorRamp->setVisible(
false );
920 lblSize->setVisible(
true );
921 minSizeSpinBox->setVisible(
true );
922 lblSizeTo->setVisible(
true );
923 maxSizeSpinBox->setVisible(
true );
924 mSizeUnitWidget->setVisible(
true );
930void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
932 while ( mParametersLayout->rowCount() )
934 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
935 for ( QLayoutItem *item : { row.labelItem, row.fieldItem } )
938 QWidget *widget = item->widget();
944 mParameterWidgetWrappers.clear();
952 mModel->updateSymbology();
955 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
968 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
971 mRenderer->setUsingSymbolLevels( enabled );
972 mModel->updateSymbology();
978 mGraduatedSymbol.reset( widget->
symbol()->
clone() );
985 mSizeUnitWidget->blockSignals(
true );
986 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
987 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
988 mSizeUnitWidget->blockSignals(
false );
990 QItemSelectionModel *m = viewGraduated->selectionModel();
991 QModelIndexList selectedIndexes = m->selectedRows( 1 );
992 if ( !selectedIndexes.isEmpty() )
994 const auto constSelectedIndexes = selectedIndexes;
995 for (
const QModelIndex &idx : constSelectedIndexes )
999 int rangeIdx = idx.row();
1001 if ( selectedIndexes.count() > 1 )
1004 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
1006 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
1012 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1019void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished()
1021 const QString text = cboSymmetryPoint->lineEdit()->text();
1022 int index = cboSymmetryPoint->findText( text );
1025 cboSymmetryPoint->setCurrentIndex( index );
1029 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1037 mUpdateTimer.start( 500 );
1040void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl()
1042 if ( mBlockUpdates || !mClassificationMethod )
1046 QString attrName = mExpressionWidget->currentField();
1047 int nclasses = spinGraduatedClasses->value();
1055 double minimum = minVal.toDouble();
1056 double maximum = maxVal.toDouble();
1057 mSymmetryPointValidator->
setBottom( minimum );
1058 mSymmetryPointValidator->
setTop( maximum );
1059 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', mClassificationMethod->labelPrecision() + 2 ) );
1070 if ( mGroupBoxSymmetric->isChecked() )
1073 bool astride = cbxAstride->isChecked();
1074 mClassificationMethod->setSymmetricMode(
true, symmetryPoint, astride );
1077 QVariantMap parameterValues;
1078 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1080 mClassificationMethod->setParameterValues( parameterValues );
1083 mRenderer->setClassificationMethod( mClassificationMethod->clone().release() );
1086 mRenderer->setClassAttribute( attrName );
1090 if ( mRenderer->classificationMethod()->codeComplexity() > 1 &&
mLayer->featureCount() > 50000 )
1092 if ( QMessageBox::Cancel
1093 == QMessageBox::question(
1095 tr(
"Apply Classification" ),
1096 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." ),
1097 QMessageBox::Cancel,
1105 if ( methodComboBox->currentData() == ColorMode )
1107 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1110 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1113 mRenderer->setSourceColorRamp( ramp.release() );
1117 mRenderer->setSourceColorRamp(
nullptr );
1121 mRenderer->updateClasses(
mLayer, nclasses, error );
1123 if ( !error.isEmpty() )
1124 QMessageBox::critical(
this, tr(
"Apply Classification" ), error );
1126 if ( methodComboBox->currentData() == SizeMode )
1127 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1129 mRenderer->calculateLabelPrecision();
1137 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1141 mRenderer->updateColorRamp( ramp.release() );
1142 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1148 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1149 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1154int QgsRendererPropertiesDialog::currentRangeRow()
1156 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1157 if ( !idx.isValid() )
1166 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1168 const auto constSelectedRows = selectedRows;
1169 for (
const QModelIndex &r : constSelectedRows )
1173 rows.append( r.row() );
1182 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1183 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1185 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1194 if ( idx.isValid() && idx.column() == 0 )
1196 if ( idx.isValid() && idx.column() == 1 )
1202 if ( !idx.isValid() )
1205 mRowSelected = idx.row();
1214 std::unique_ptr<QgsSymbol> newSymbol( range.
symbol()->
clone() );
1228 if ( !dlg.exec() || !newSymbol )
1233 mGraduatedSymbol = std::move( newSymbol );
1234 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1246 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1247 if ( decimalPlaces < 0 )
1252 if ( dialog.exec() == QDialog::Accepted )
1258 if ( cbxLinkBoundaries->isChecked() )
1262 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1265 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1267 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1271 mHistogramWidget->refresh();
1277 mModel->addClass( mGraduatedSymbol.get() );
1278 mHistogramWidget->refresh();
1285 mModel->deleteRows( classIndexes );
1286 mHistogramWidget->refresh();
1292 mModel->removeAllRows();
1293 mHistogramWidget->refresh();
1300 bool ordered =
true;
1301 for (
int i = 1; i < ranges.size(); ++i )
1303 if ( ranges[i] < ranges[i - 1] )
1320 int result = QMessageBox::warning(
this, tr(
"Link Class Boundaries" ), tr(
"Rows will be reordered before linking boundaries. Continue?" ), QMessageBox::Ok | QMessageBox::Cancel );
1321 if ( result != QMessageBox::Ok )
1323 cbxLinkBoundaries->setChecked(
false );
1326 mRenderer->sortByValue();
1330 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1332 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1340 if ( item->column() == 2 )
1342 QString label = item->text();
1343 int idx = item->row();
1344 mRenderer->updateRangeLabel( idx, label );
1350 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1351 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1352 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1353 mRenderer->updateRangeLabels();
1354 mModel->updateLabels();
1362 QItemSelectionModel *m = viewGraduated->selectionModel();
1363 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1364 if ( !selectedIndexes.isEmpty() )
1367 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1368 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1370 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1371 if ( list.size() < 3 )
1396 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1397 if ( decimalPlaces < 0 )
1399 double precision = 1.0 / std::pow( 10, decimalPlaces );
1401 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1405 return it->symbol();
1415 mModel->updateSymbology();
1417 mHistogramWidget->refresh();
1428 viewGraduated->selectionModel()->clear();
1431 cbxLinkBoundaries->setChecked(
false );
1448 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1450 mCopyBuffer.clear();
1453 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1455 QgsRangeList::iterator rIt = mCopyBuffer.begin();
1456 for ( ; rIt != mCopyBuffer.end(); ++rIt )
1458 rIt->mUuid = QUuid::createUuid().toString();
1459 mModel->addClass( *rIt );
1465void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1468 if ( !ranges.isEmpty() )
1470 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1472 else if ( mRenderer->sourceSymbol() )
1474 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1476 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1479void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1481 QgsMarkerSymbol *s =
static_cast<QgsMarkerSymbol *
>( mGraduatedSymbol.get() );
1493void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1495 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1505 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1506 for (
const QModelIndex &index : selectedRows )
1508 if ( !index.isValid() )
1511 const int row = index.row();
1512 if ( !mRenderer || mRenderer->ranges().size() <= row )
1515 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1518 std::unique_ptr<QgsSymbol> newCatSymbol( tempSymbol->clone() );
1519 if ( selectedRows.count() > 1 )
1522 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1525 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.
@ 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.
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,...
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.
void minimumAndMaximumValue(int index, QVariant &minimum, QVariant &maximum) const
Calculates both the minimum and maximum value for an attribute column.
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