19#include <QStandardItemModel>
20#include <QStandardItem>
29#include "moc_qgsgraduatedsymbolrendererwidget.cpp"
66QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, QScreen *screen )
67 : QAbstractItemModel( parent )
68 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
77 if ( !mRenderer->ranges().isEmpty() )
79 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
90 if ( !renderer->
ranges().isEmpty() )
92 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
103void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
107 int idx = mRenderer->
ranges().size();
108 beginInsertRows( QModelIndex(), idx, idx );
109 mRenderer->addClass( symbol );
113void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
119 int idx = mRenderer->ranges().size();
120 beginInsertRows( QModelIndex(), idx, idx );
121 mRenderer->addClass( range );
125QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
127 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
132 return mRenderer->ranges().value( index.row() );
135Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
138 if ( !index.isValid() )
140 return Qt::ItemIsDropEnabled;
143 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable;
145 if ( index.column() == 2 )
147 flags |= Qt::ItemIsEditable;
153Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
155 return Qt::MoveAction;
158QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
160 if ( !index.isValid() || !mRenderer )
165 if ( role == Qt::CheckStateRole && index.column() == 0 )
167 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
169 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
171 switch ( index.column() )
175 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
176 if ( decimalPlaces < 0 )
178 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
181 return range.
label();
186 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
191 else if ( role == Qt::TextAlignmentRole )
193 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
195 else if ( role == Qt::EditRole )
197 switch ( index.column() )
201 return range.
label();
210bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
212 if ( !index.isValid() )
215 if ( index.column() == 0 && role == Qt::CheckStateRole )
217 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
218 emit dataChanged( index, index );
222 if ( role != Qt::EditRole )
225 switch ( index.column() )
230 mRenderer->updateRangeLabel( index.row(), value.toString() );
236 emit dataChanged( index, index );
240QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
242 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
245 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
246 return lst.value( section );
251int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
253 if ( parent.isValid() || !mRenderer )
257 return mRenderer->ranges().size();
260int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
266QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
268 if ( hasIndex( row, column, parent ) )
270 return createIndex( row, column );
272 return QModelIndex();
275QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
278 return QModelIndex();
281QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
284 types << mMimeFormat;
288QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
290 QMimeData *mimeData =
new QMimeData();
291 QByteArray encodedData;
293 QDataStream stream( &encodedData, QIODevice::WriteOnly );
296 const auto constIndexes = indexes;
297 for (
const QModelIndex &index : constIndexes )
299 if ( !index.isValid() || index.column() != 0 )
302 stream << index.row();
304 mimeData->setData( mMimeFormat, encodedData );
308bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
312 if ( action != Qt::MoveAction )
315 if ( !data->hasFormat( mMimeFormat ) )
318 QByteArray encodedData = data->data( mMimeFormat );
319 QDataStream stream( &encodedData, QIODevice::ReadOnly );
322 while ( !stream.atEnd() )
330 std::sort( rows.begin(), rows.end() );
337 to = mRenderer->ranges().size();
338 for (
int i = rows.size() - 1; i >= 0; i-- )
340 QgsDebugMsgLevel( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ), 2 );
345 mRenderer->moveClass( rows[i], t );
347 for (
int j = 0; j < i; j++ )
349 if ( to < rows[j] && rows[i] > rows[j] )
356 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
361void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
363 for (
int i = rows.size() - 1; i >= 0; i-- )
365 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
366 mRenderer->deleteClass( rows[i] );
371void QgsGraduatedSymbolRendererModel::removeAllRows()
373 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
374 mRenderer->deleteAllClasses();
378void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
386 mRenderer->sortByValue( order );
388 else if ( column == 2 )
390 mRenderer->sortByLabel( order );
393 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
396void QgsGraduatedSymbolRendererModel::updateSymbology()
398 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
401void QgsGraduatedSymbolRendererModel::updateLabels()
403 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
407QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
411void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
413 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
415 QStyleOption opt( *option );
416 opt.rect.setLeft( 0 );
418 opt.rect.setHeight( 0 );
420 opt.rect.setRight( widget->width() );
421 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
424 QProxyStyle::drawPrimitive( element, option, painter, widget );
442 expContext = lMapCanvas->createExpressionContext();
476 mRenderer = std::make_unique<QgsGraduatedSymbolRenderer>( QString(),
QgsRangeList() );
485 cboSymmetryPoint->setEditable(
true );
486 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
489 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
492 cboGraduatedMode->addItem( icon, it.key(), it.value() );
495 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
496 this->layout()->setContentsMargins( 0, 0, 0, 0 );
498 mModel =
new QgsGraduatedSymbolRendererModel(
this, screen() );
501 mExpressionWidget->setLayer(
mLayer );
503 btnChangeGraduatedSymbol->setLayer(
mLayer );
504 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
506 mSizeUnitWidget->setUnits(
517 spinPrecision->setClearValue( 4 );
519 spinGraduatedClasses->setShowClearButton(
false );
521 btnColorRamp->setShowRandomColorRamp(
true );
524 std::unique_ptr<QgsColorRamp> colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
527 btnColorRamp->setColorRamp( colorRamp.get() );
532 btnColorRamp->setColorRamp( ramp );
537 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
540 if ( mGraduatedSymbol )
542 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
543 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
545 methodComboBox->blockSignals(
true );
546 methodComboBox->addItem( tr(
"Color" ), ColorMode );
547 switch ( mGraduatedSymbol->type() )
551 methodComboBox->addItem( tr(
"Size" ), SizeMode );
552 minSizeSpinBox->setValue( 1 );
553 maxSizeSpinBox->setValue( 8 );
558 methodComboBox->addItem( tr(
"Size" ), SizeMode );
559 minSizeSpinBox->setValue( .1 );
560 maxSizeSpinBox->setValue( 2 );
566 methodComboBox->hide();
573 methodComboBox->blockSignals(
false );
582 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
589 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
592 updateMethodParameters();
600 mGroupBoxSymmetric->setCollapsed(
true );
603 QMenu *advMenu =
new QMenu(
this );
608 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
610 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
613 btnAdvanced->setMenu( advMenu );
615 mHistogramWidget->setLayer(
mLayer );
616 mHistogramWidget->setRenderer( mRenderer.get() );
620 mExpressionWidget->registerExpressionContextGenerator(
this );
622 mUpdateTimer.setSingleShot(
true );
623 mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout,
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
626void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
628 if ( !mGraduatedSymbol )
630 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
631 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
632 mRenderer->updateSymbols( mGraduatedSymbol.get() );
639 mParameterWidgetWrappers.clear();
644 return mRenderer.get();
656 delete mActionLevels;
657 mActionLevels =
nullptr;
678 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
680 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
704 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
706 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
722 int precision = spinPrecision->value() + 2;
723 while ( cboSymmetryPoint->count() )
724 cboSymmetryPoint->removeItem( 0 );
725 for (
int i = 0; i < ranges.count() - 1; i++ )
726 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
730 int idx = cboGraduatedMode->findData( method->
id() );
732 cboGraduatedMode->setCurrentIndex( idx );
738 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
745 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
749 ppww->setParameterValue( value,
context );
754 int nclasses = ranges.count();
757 spinGraduatedClasses->setValue( ranges.count() );
765 spinGraduatedClasses->setEnabled(
true );
769 QString attrName = mRenderer->classAttribute();
770 mExpressionWidget->setField( attrName );
771 mHistogramWidget->setSourceFieldExp( attrName );
774 if ( mRenderer->sourceSymbol() )
776 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
777 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
780 mModel->setRenderer( mRenderer.get() );
781 viewGraduated->setModel( mModel );
783 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
785 if ( mGraduatedSymbol )
787 mSizeUnitWidget->blockSignals(
true );
788 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
789 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
790 mSizeUnitWidget->blockSignals(
false );
794 methodComboBox->blockSignals(
true );
795 switch ( mRenderer->graduatedMethod() )
799 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
800 if ( mRenderer->sourceColorRamp() )
802 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
808 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
809 if ( !mRenderer->ranges().isEmpty() )
811 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
812 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
817 toggleMethodWidgets(
static_cast<MethodMode
>( methodComboBox->currentData().toInt() ) );
818 methodComboBox->blockSignals(
false );
820 viewGraduated->resizeColumnToContents( 0 );
821 viewGraduated->resizeColumnToContents( 1 );
822 viewGraduated->resizeColumnToContents( 2 );
824 mHistogramWidget->refresh();
834 mRenderer->setClassAttribute( field );
837void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
839 const MethodMode newMethod =
static_cast<MethodMode
>( methodComboBox->currentData().toInt() );
840 toggleMethodWidgets( newMethod );
850 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
853 mRenderer->setSourceColorRamp( ramp );
860 lblColorRamp->setVisible(
false );
861 btnColorRamp->setVisible(
false );
862 lblSize->setVisible(
true );
863 minSizeSpinBox->setVisible(
true );
864 lblSize->setVisible(
true );
865 maxSizeSpinBox->setVisible(
true );
866 mSizeUnitWidget->setVisible(
true );
875void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
877 clearParameterWidgets();
879 const QString methodId = cboGraduatedMode->currentData().toString();
881 Q_ASSERT( mClassificationMethod.get() );
891 QVariant value = mClassificationMethod->parameterValues().value( def->name(), def->defaultValueForGui() );
896 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
902void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
908 lblColorRamp->setVisible(
true );
909 btnColorRamp->setVisible(
true );
910 lblSize->setVisible(
false );
911 minSizeSpinBox->setVisible(
false );
912 lblSizeTo->setVisible(
false );
913 maxSizeSpinBox->setVisible(
false );
914 mSizeUnitWidget->setVisible(
false );
920 lblColorRamp->setVisible(
false );
921 btnColorRamp->setVisible(
false );
922 lblSize->setVisible(
true );
923 minSizeSpinBox->setVisible(
true );
924 lblSizeTo->setVisible(
true );
925 maxSizeSpinBox->setVisible(
true );
926 mSizeUnitWidget->setVisible(
true );
932void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
934 while ( mParametersLayout->rowCount() )
936 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
937 for ( QLayoutItem *item : { row.labelItem, row.fieldItem } )
940 QWidget *widget = item->widget();
946 mParameterWidgetWrappers.clear();
954 mModel->updateSymbology();
957 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
970 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
973 mRenderer->setUsingSymbolLevels( enabled );
974 mModel->updateSymbology();
980 mGraduatedSymbol.reset( widget->
symbol()->
clone() );
987 mSizeUnitWidget->blockSignals(
true );
988 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
989 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
990 mSizeUnitWidget->blockSignals(
false );
992 QItemSelectionModel *m = viewGraduated->selectionModel();
993 QModelIndexList selectedIndexes = m->selectedRows( 1 );
994 if ( !selectedIndexes.isEmpty() )
996 const auto constSelectedIndexes = selectedIndexes;
997 for (
const QModelIndex &idx : constSelectedIndexes )
1001 int rangeIdx = idx.row();
1002 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
1003 if ( selectedIndexes.count() > 1 )
1006 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
1008 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
1014 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1021void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished()
1023 const QString text = cboSymmetryPoint->lineEdit()->text();
1024 int index = cboSymmetryPoint->findText( text );
1027 cboSymmetryPoint->setCurrentIndex( index );
1031 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1039 mUpdateTimer.start( 500 );
1042void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl()
1044 if ( mBlockUpdates || !mClassificationMethod )
1048 QString attrName = mExpressionWidget->currentField();
1049 int nclasses = spinGraduatedClasses->value();
1057 double minimum = minVal.toDouble();
1058 double maximum = maxVal.toDouble();
1059 mSymmetryPointValidator->
setBottom( minimum );
1060 mSymmetryPointValidator->
setTop( maximum );
1061 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1068 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1069 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', mClassificationMethod->labelPrecision() + 2 ) );
1072 if ( mGroupBoxSymmetric->isChecked() )
1075 bool astride = cbxAstride->isChecked();
1076 mClassificationMethod->setSymmetricMode(
true, symmetryPoint, astride );
1079 QVariantMap parameterValues;
1080 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1081 parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() );
1082 mClassificationMethod->setParameterValues( parameterValues );
1085 mRenderer->setClassificationMethod( mClassificationMethod->clone().release() );
1088 mRenderer->setClassAttribute( attrName );
1092 if ( mRenderer->classificationMethod()->codeComplexity() > 1 &&
mLayer->
featureCount() > 50000 )
1094 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 ) )
1100 if ( methodComboBox->currentData() == ColorMode )
1102 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1105 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1108 mRenderer->setSourceColorRamp( ramp.release() );
1112 mRenderer->setSourceColorRamp(
nullptr );
1116 mRenderer->updateClasses(
mLayer, nclasses, error );
1118 if ( !error.isEmpty() )
1119 QMessageBox::critical(
this, tr(
"Apply Classification" ), error );
1121 if ( methodComboBox->currentData() == SizeMode )
1122 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1124 mRenderer->calculateLabelPrecision();
1132 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1136 mRenderer->updateColorRamp( ramp.release() );
1137 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1143 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1144 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1149int QgsRendererPropertiesDialog::currentRangeRow()
1151 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1152 if ( !idx.isValid() )
1161 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1163 const auto constSelectedRows = selectedRows;
1164 for (
const QModelIndex &r : constSelectedRows )
1168 rows.append( r.row() );
1177 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1178 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1180 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1189 if ( idx.isValid() && idx.column() == 0 )
1191 if ( idx.isValid() && idx.column() == 1 )
1197 if ( !idx.isValid() )
1200 mRowSelected = idx.row();
1210 std::unique_ptr<QgsSymbol> newSymbol( range.
symbol()->
clone() );
1224 if ( !dlg.exec() || !newSymbol )
1229 mGraduatedSymbol = std::move( newSymbol );
1230 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1242 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1243 if ( decimalPlaces < 0 )
1248 if ( dialog.exec() == QDialog::Accepted )
1254 if ( cbxLinkBoundaries->isChecked() )
1258 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1261 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1263 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1267 mHistogramWidget->refresh();
1273 mModel->addClass( mGraduatedSymbol.get() );
1274 mHistogramWidget->refresh();
1281 mModel->deleteRows( classIndexes );
1282 mHistogramWidget->refresh();
1288 mModel->removeAllRows();
1289 mHistogramWidget->refresh();
1296 bool ordered =
true;
1297 for (
int i = 1; i < ranges.size(); ++i )
1299 if ( ranges[i] < ranges[i - 1] )
1316 int result = QMessageBox::warning(
1318 tr(
"Link Class Boundaries" ),
1319 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1320 QMessageBox::Ok | QMessageBox::Cancel
1322 if ( result != QMessageBox::Ok )
1324 cbxLinkBoundaries->setChecked(
false );
1327 mRenderer->sortByValue();
1331 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1333 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1341 if ( item->column() == 2 )
1343 QString label = item->text();
1344 int idx = item->row();
1345 mRenderer->updateRangeLabel( idx, label );
1351 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1352 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1353 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1354 mRenderer->updateRangeLabels();
1355 mModel->updateLabels();
1363 QItemSelectionModel *m = viewGraduated->selectionModel();
1364 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1365 if ( !selectedIndexes.isEmpty() )
1368 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1369 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1371 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1372 if ( list.size() < 3 )
1397 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1398 if ( decimalPlaces < 0 )
1400 double precision = 1.0 / std::pow( 10, decimalPlaces );
1402 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1406 return it->symbol();
1416 mModel->updateSymbology();
1418 mHistogramWidget->refresh();
1429 viewGraduated->selectionModel()->clear();
1432 cbxLinkBoundaries->setChecked(
false );
1449 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1451 mCopyBuffer.clear();
1454 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1456 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1457 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
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()
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() );
@ 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.
QgsClassificationMethod is 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.
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
void setTop(double top)
Set top range limit.
void setMaxDecimals(int maxDecimals)
Sets the number of decimals accepted by the validator to maxDecimals.
void setBottom(double bottom)
Set top range limit.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Abstract base class for all 2D vector feature renderers.
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
@ Date
Date or datetime fields.
@ Numeric
All numeric fields.
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
A vector feature renderer which uses numeric attributes to classify features into different ranges.
static QgsGraduatedSymbolRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
creates a QgsGraduatedSymbolRenderer from an existing renderer.
const QgsRangeList & ranges() const
Returns a list of all ranges used in the classification.
static QgsProcessingGuiRegistry * processingGuiRegistry()
Returns the global processing gui registry, used for registering the GUI behavior of processing algor...
double upperValueDouble() const
Returns the upper value.
double lowerValueDouble() const
Returns the lower value.
void setLowerValue(const QString &val)
void setUpperValue(const QString &val)
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
The QgsMapSettings class contains configuration for rendering of the map.
A marker symbol type, for rendering Point and MultiPoint geometries.
Contains information about the context in which a processing algorithm is executed.
QgsAbstractProcessingParameterWidgetWrapper * createParameterWidgetWrapper(const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type)
Creates a new parameter widget wrapper for the given parameter.
@ Standard
Standard algorithm dialog.
Base class for the definition of processing parameters.
QVariant defaultValueForGui() const
Returns the default value to use for the parameter in a GUI.
QString name() const
Returns the name of the parameter.
static QgsProject * instance()
Returns the QgsProject singleton instance.
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...
QString label() const
Returns the label used for the range.
QgsSymbol * symbol() const
Returns the symbol used for the range.
bool renderState() const
Returns true if the range should be rendered.
double upperValue() const
Returns the upper bound of the range.
double lowerValue() const
Returns the lower bound of the range.
Stores properties relating to a screen.
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
A dialog that can be used to select and build a symbol.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
Abstract base class for all rendered symbols.
void setColor(const QColor &color) const
Sets the color for the symbol.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
Represents a vector layer which manages a vector based data sets.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
void minimumAndMaximumValue(int index, QVariant &minimum, QVariant &maximum) const
Calculates both the minimum and maximum value for an attribute column.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
double qgsPermissiveToDouble(QString string, bool &ok)
Converts a string to a double in a permissive way, e.g., allowing for incorrect numbers of digits bet...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
#define QgsDebugMsgLevel(str, level)
QList< QgsRendererRange > QgsRangeList