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() );
635 mParameterWidgetWrappers.clear();
640 return mRenderer.get();
646 btnChangeGraduatedSymbol->setMapCanvas(
context.mapCanvas() );
647 btnChangeGraduatedSymbol->setMessageBar(
context.messageBar() );
652 delete mActionLevels;
653 mActionLevels =
nullptr;
674 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
676 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
700 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
702 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
718 int precision = spinPrecision->value() + 2;
719 while ( cboSymmetryPoint->count() )
720 cboSymmetryPoint->removeItem( 0 );
721 for (
int i = 0; i < ranges.count() - 1; i++ )
722 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f', precision ), ranges.at( i ).upperValue() );
726 int idx = cboGraduatedMode->findData( method->
id() );
728 cboGraduatedMode->setCurrentIndex( idx );
734 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
741 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
745 ppww->setParameterValue( value,
context );
750 int nclasses = ranges.count();
753 spinGraduatedClasses->setValue( ranges.count() );
761 spinGraduatedClasses->setEnabled(
true );
765 QString attrName = mRenderer->classAttribute();
766 mExpressionWidget->setField( attrName );
767 mHistogramWidget->setSourceFieldExp( attrName );
770 if ( mRenderer->sourceSymbol() )
772 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
773 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
776 mModel->setRenderer( mRenderer.get() );
777 viewGraduated->setModel( mModel );
779 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
781 if ( mGraduatedSymbol )
783 mSizeUnitWidget->blockSignals(
true );
784 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
785 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
786 mSizeUnitWidget->blockSignals(
false );
790 methodComboBox->blockSignals(
true );
791 switch ( mRenderer->graduatedMethod() )
795 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
796 if ( mRenderer->sourceColorRamp() )
798 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
804 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
805 if ( !mRenderer->ranges().isEmpty() )
807 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
808 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
813 toggleMethodWidgets(
static_cast<MethodMode
>( methodComboBox->currentData().toInt() ) );
814 methodComboBox->blockSignals(
false );
816 viewGraduated->resizeColumnToContents( 0 );
817 viewGraduated->resizeColumnToContents( 1 );
818 viewGraduated->resizeColumnToContents( 2 );
820 mHistogramWidget->refresh();
830 mRenderer->setClassAttribute( field );
834void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
836 const MethodMode newMethod =
static_cast<MethodMode
>( methodComboBox->currentData().toInt() );
837 toggleMethodWidgets( newMethod );
847 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
850 mRenderer->setSourceColorRamp( ramp );
857 lblColorRamp->setVisible(
false );
858 btnColorRamp->setVisible(
false );
859 lblSize->setVisible(
true );
860 minSizeSpinBox->setVisible(
true );
861 lblSize->setVisible(
true );
862 maxSizeSpinBox->setVisible(
true );
863 mSizeUnitWidget->setVisible(
true );
872void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
874 clearParameterWidgets();
876 const QString methodId = cboGraduatedMode->currentData().toString();
878 Q_ASSERT( mClassificationMethod.get() );
883 for (
const QgsProcessingParameterDefinition *def : mClassificationMethod->parameterDefinitions() )
888 QVariant value = mClassificationMethod->parameterValues().value( def->name(), def->defaultValueForGui() );
893 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
899void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
905 lblColorRamp->setVisible(
true );
906 btnColorRamp->setVisible(
true );
907 lblSize->setVisible(
false );
908 minSizeSpinBox->setVisible(
false );
909 lblSizeTo->setVisible(
false );
910 maxSizeSpinBox->setVisible(
false );
911 mSizeUnitWidget->setVisible(
false );
917 lblColorRamp->setVisible(
false );
918 btnColorRamp->setVisible(
false );
919 lblSize->setVisible(
true );
920 minSizeSpinBox->setVisible(
true );
921 lblSizeTo->setVisible(
true );
922 maxSizeSpinBox->setVisible(
true );
923 mSizeUnitWidget->setVisible(
true );
929void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
931 while ( mParametersLayout->rowCount() )
933 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
934 for ( QLayoutItem *item : { row.labelItem, row.fieldItem } )
937 QWidget *widget = item->widget();
943 mParameterWidgetWrappers.clear();
951 mModel->updateSymbology();
954 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
967 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
970 mRenderer->setUsingSymbolLevels( enabled );
971 mModel->updateSymbology();
977 mGraduatedSymbol.reset( widget->
symbol()->
clone() );
984 mSizeUnitWidget->blockSignals(
true );
985 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
986 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
987 mSizeUnitWidget->blockSignals(
false );
989 QItemSelectionModel *m = viewGraduated->selectionModel();
990 QModelIndexList selectedIndexes = m->selectedRows( 1 );
991 if ( !selectedIndexes.isEmpty() )
993 const auto constSelectedIndexes = selectedIndexes;
994 for (
const QModelIndex &idx : constSelectedIndexes )
998 int rangeIdx = idx.row();
1000 if ( selectedIndexes.count() > 1 )
1003 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
1005 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
1011 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1018void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished()
1020 const QString text = cboSymmetryPoint->lineEdit()->text();
1021 int index = cboSymmetryPoint->findText( text );
1024 cboSymmetryPoint->setCurrentIndex( index );
1028 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1036 mUpdateTimer.start( 500 );
1039void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl()
1041 if ( mBlockUpdates || !mClassificationMethod )
1045 QString attrName = mExpressionWidget->currentField();
1046 int nclasses = spinGraduatedClasses->value();
1054 double minimum = minVal.toDouble();
1055 double maximum = maxVal.toDouble();
1056 mSymmetryPointValidator->
setBottom( minimum );
1057 mSymmetryPointValidator->
setTop( maximum );
1058 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1065 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1066 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', mClassificationMethod->labelPrecision() + 2 ) );
1069 if ( mGroupBoxSymmetric->isChecked() )
1072 bool astride = cbxAstride->isChecked();
1073 mClassificationMethod->setSymmetricMode(
true, symmetryPoint, astride );
1076 QVariantMap parameterValues;
1077 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1079 mClassificationMethod->setParameterValues( parameterValues );
1082 mRenderer->setClassificationMethod( mClassificationMethod->clone().release() );
1085 mRenderer->setClassAttribute( attrName );
1089 if ( mRenderer->classificationMethod()->codeComplexity() > 1 &&
mLayer->featureCount() > 50000 )
1091 if ( QMessageBox::Cancel
1092 == QMessageBox::question(
1094 tr(
"Apply Classification" ),
1095 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." ),
1096 QMessageBox::Cancel,
1104 if ( methodComboBox->currentData() == ColorMode )
1106 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1109 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1112 mRenderer->setSourceColorRamp( ramp.release() );
1116 mRenderer->setSourceColorRamp(
nullptr );
1120 mRenderer->updateClasses(
mLayer, nclasses, error );
1122 if ( !error.isEmpty() )
1123 QMessageBox::critical(
this, tr(
"Apply Classification" ), error );
1125 if ( methodComboBox->currentData() == SizeMode )
1126 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1128 mRenderer->calculateLabelPrecision();
1136 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1140 mRenderer->updateColorRamp( ramp.release() );
1141 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1147 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1148 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1153int QgsRendererPropertiesDialog::currentRangeRow()
1155 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1156 if ( !idx.isValid() )
1165 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1167 const auto constSelectedRows = selectedRows;
1168 for (
const QModelIndex &r : constSelectedRows )
1172 rows.append( r.row() );
1181 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1182 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1184 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1193 if ( idx.isValid() && idx.column() == 0 )
1195 if ( idx.isValid() && idx.column() == 1 )
1201 if ( !idx.isValid() )
1204 mRowSelected = idx.row();
1213 std::unique_ptr<QgsSymbol> newSymbol( range.
symbol()->
clone() );
1227 if ( !dlg.exec() || !newSymbol )
1232 mGraduatedSymbol = std::move( newSymbol );
1233 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1245 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1246 if ( decimalPlaces < 0 )
1251 if ( dialog.exec() == QDialog::Accepted )
1257 if ( cbxLinkBoundaries->isChecked() )
1261 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1264 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1266 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1270 mHistogramWidget->refresh();
1276 mModel->addClass( mGraduatedSymbol.get() );
1277 mHistogramWidget->refresh();
1284 mModel->deleteRows( classIndexes );
1285 mHistogramWidget->refresh();
1291 mModel->removeAllRows();
1292 mHistogramWidget->refresh();
1299 bool ordered =
true;
1300 for (
int i = 1; i < ranges.size(); ++i )
1302 if ( ranges[i] < ranges[i - 1] )
1319 int result = QMessageBox::warning(
this, tr(
"Link Class Boundaries" ), tr(
"Rows will be reordered before linking boundaries. Continue?" ), QMessageBox::Ok | QMessageBox::Cancel );
1320 if ( result != QMessageBox::Ok )
1322 cbxLinkBoundaries->setChecked(
false );
1325 mRenderer->sortByValue();
1329 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1331 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1339 if ( item->column() == 2 )
1341 QString label = item->text();
1342 int idx = item->row();
1343 mRenderer->updateRangeLabel( idx, label );
1349 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1350 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1351 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1352 mRenderer->updateRangeLabels();
1353 mModel->updateLabels();
1361 QItemSelectionModel *m = viewGraduated->selectionModel();
1362 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1363 if ( !selectedIndexes.isEmpty() )
1366 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1367 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1369 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1370 if ( list.size() < 3 )
1395 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1396 if ( decimalPlaces < 0 )
1398 double precision = 1.0 / std::pow( 10, decimalPlaces );
1400 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1404 return it->symbol();
1414 mModel->updateSymbology();
1416 mHistogramWidget->refresh();
1427 viewGraduated->selectionModel()->clear();
1430 cbxLinkBoundaries->setChecked(
false );
1447 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1449 mCopyBuffer.clear();
1452 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1454 QgsRangeList::iterator rIt = mCopyBuffer.begin();
1455 for ( ; rIt != mCopyBuffer.end(); ++rIt )
1457 rIt->mUuid = QUuid::createUuid().toString();
1458 mModel->addClass( *rIt );
1464void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1467 if ( !ranges.isEmpty() )
1469 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1471 else if ( mRenderer->sourceSymbol() )
1473 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1475 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1478void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1480 QgsMarkerSymbol *s =
static_cast<QgsMarkerSymbol *
>( mGraduatedSymbol.get() );
1492void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1494 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1504 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1505 for (
const QModelIndex &index : selectedRows )
1507 if ( !index.isValid() )
1510 const int row = index.row();
1511 if ( !mRenderer || mRenderer->ranges().size() <= row )
1514 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1517 std::unique_ptr<QgsSymbol> newCatSymbol( tempSymbol->clone() );
1518 if ( selectedRows.count() > 1 )
1521 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1524 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