19#include <QStandardItemModel>
20#include <QStandardItem>
30#include "moc_qgsgraduatedsymbolrendererwidget.cpp"
67QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, QScreen *screen )
68 : QAbstractItemModel( parent )
69 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
78 if ( !mRenderer->ranges().isEmpty() )
80 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
91 if ( !renderer->
ranges().isEmpty() )
93 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
104void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
108 int idx = mRenderer->
ranges().size();
109 beginInsertRows( QModelIndex(), idx, idx );
110 mRenderer->addClass( symbol );
114void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
120 int idx = mRenderer->ranges().size();
121 beginInsertRows( QModelIndex(), idx, idx );
122 mRenderer->addClass( range );
126QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
128 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
133 return mRenderer->ranges().value( index.row() );
136Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
139 if ( !index.isValid() )
141 return Qt::ItemIsDropEnabled;
144 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable;
146 if ( index.column() == 2 )
148 flags |= Qt::ItemIsEditable;
154Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
156 return Qt::MoveAction;
159QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
161 if ( !index.isValid() || !mRenderer )
166 if ( role == Qt::CheckStateRole && index.column() == 0 )
168 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
170 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
172 switch ( index.column() )
176 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
177 if ( decimalPlaces < 0 )
179 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
182 return range.
label();
187 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
192 else if ( role == Qt::TextAlignmentRole )
194 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
196 else if ( role == Qt::EditRole )
198 switch ( index.column() )
202 return range.
label();
211bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
213 if ( !index.isValid() )
216 if ( index.column() == 0 && role == Qt::CheckStateRole )
218 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
219 emit dataChanged( index, index );
223 if ( role != Qt::EditRole )
226 switch ( index.column() )
231 mRenderer->updateRangeLabel( index.row(), value.toString() );
237 emit dataChanged( index, index );
241QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
243 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
246 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
247 return lst.value( section );
252int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
254 if ( parent.isValid() || !mRenderer )
258 return mRenderer->ranges().size();
261int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
267QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
269 if ( hasIndex( row, column, parent ) )
271 return createIndex( row, column );
273 return QModelIndex();
276QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
279 return QModelIndex();
282QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
285 types << mMimeFormat;
289QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
291 QMimeData *mimeData =
new QMimeData();
292 QByteArray encodedData;
294 QDataStream stream( &encodedData, QIODevice::WriteOnly );
297 const auto constIndexes = indexes;
298 for (
const QModelIndex &index : constIndexes )
300 if ( !index.isValid() || index.column() != 0 )
303 stream << index.row();
305 mimeData->setData( mMimeFormat, encodedData );
309bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
313 if ( action != Qt::MoveAction )
316 if ( !data->hasFormat( mMimeFormat ) )
319 QByteArray encodedData = data->data( mMimeFormat );
320 QDataStream stream( &encodedData, QIODevice::ReadOnly );
323 while ( !stream.atEnd() )
331 std::sort( rows.begin(), rows.end() );
338 to = mRenderer->ranges().size();
339 for (
int i = rows.size() - 1; i >= 0; i-- )
341 QgsDebugMsgLevel( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ), 2 );
346 mRenderer->moveClass( rows[i], t );
348 for (
int j = 0; j < i; j++ )
350 if ( to < rows[j] && rows[i] > rows[j] )
357 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
362void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
364 for (
int i = rows.size() - 1; i >= 0; i-- )
366 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
367 mRenderer->deleteClass( rows[i] );
372void QgsGraduatedSymbolRendererModel::removeAllRows()
374 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
375 mRenderer->deleteAllClasses();
379void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
387 mRenderer->sortByValue( order );
389 else if ( column == 2 )
391 mRenderer->sortByLabel( order );
394 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
397void QgsGraduatedSymbolRendererModel::updateSymbology()
399 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
402void QgsGraduatedSymbolRendererModel::updateLabels()
404 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
408QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
412void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
414 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
416 QStyleOption opt( *option );
417 opt.rect.setLeft( 0 );
419 opt.rect.setHeight( 0 );
421 opt.rect.setRight( widget->width() );
422 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
425 QProxyStyle::drawPrimitive( element, option, painter, widget );
443 expContext = lMapCanvas->createExpressionContext();
477 mRenderer = std::make_unique<QgsGraduatedSymbolRenderer>( QString(),
QgsRangeList() );
486 cboSymmetryPoint->setEditable(
true );
487 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
490 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
493 cboGraduatedMode->addItem( icon, it.key(), it.value() );
496 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
497 this->layout()->setContentsMargins( 0, 0, 0, 0 );
499 mModel =
new QgsGraduatedSymbolRendererModel(
this, screen() );
502 mExpressionWidget->setLayer(
mLayer );
504 btnChangeGraduatedSymbol->setLayer(
mLayer );
505 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
507 mSizeUnitWidget->setUnits(
518 spinPrecision->setClearValue( 4 );
520 spinGraduatedClasses->setShowClearButton(
false );
522 btnColorRamp->setShowRandomColorRamp(
true );
525 std::unique_ptr<QgsColorRamp> colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
528 btnColorRamp->setColorRamp( colorRamp.get() );
533 btnColorRamp->setColorRamp( ramp );
538 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
541 if ( mGraduatedSymbol )
543 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
544 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
546 methodComboBox->blockSignals(
true );
547 methodComboBox->addItem( tr(
"Color" ), ColorMode );
548 switch ( mGraduatedSymbol->type() )
552 methodComboBox->addItem( tr(
"Size" ), SizeMode );
553 minSizeSpinBox->setValue( 1 );
554 maxSizeSpinBox->setValue( 8 );
559 methodComboBox->addItem( tr(
"Size" ), SizeMode );
560 minSizeSpinBox->setValue( .1 );
561 maxSizeSpinBox->setValue( 2 );
567 methodComboBox->hide();
574 methodComboBox->blockSignals(
false );
583 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
590 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
593 updateMethodParameters();
601 mGroupBoxSymmetric->setCollapsed(
true );
604 QMenu *advMenu =
new QMenu(
this );
609 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
611 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
614 btnAdvanced->setMenu( advMenu );
616 mHistogramWidget->setLayer(
mLayer );
617 mHistogramWidget->setRenderer( mRenderer.get() );
621 mExpressionWidget->registerExpressionContextGenerator(
this );
623 mUpdateTimer.setSingleShot(
true );
624 mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout,
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
627void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
629 if ( !mGraduatedSymbol )
631 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
632 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
633 mRenderer->updateSymbols( mGraduatedSymbol.get() );
640 mParameterWidgetWrappers.clear();
645 return mRenderer.get();
657 delete mActionLevels;
658 mActionLevels =
nullptr;
679 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
681 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
705 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
707 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
723 int precision = spinPrecision->value() + 2;
724 while ( cboSymmetryPoint->count() )
725 cboSymmetryPoint->removeItem( 0 );
726 for (
int i = 0; i < ranges.count() - 1; i++ )
727 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
731 int idx = cboGraduatedMode->findData( method->
id() );
733 cboGraduatedMode->setCurrentIndex( idx );
739 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
746 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
750 ppww->setParameterValue( value,
context );
755 int nclasses = ranges.count();
758 spinGraduatedClasses->setValue( ranges.count() );
766 spinGraduatedClasses->setEnabled(
true );
770 QString attrName = mRenderer->classAttribute();
771 mExpressionWidget->setField( attrName );
772 mHistogramWidget->setSourceFieldExp( attrName );
775 if ( mRenderer->sourceSymbol() )
777 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
778 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
781 mModel->setRenderer( mRenderer.get() );
782 viewGraduated->setModel( mModel );
784 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
786 if ( mGraduatedSymbol )
788 mSizeUnitWidget->blockSignals(
true );
789 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
790 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
791 mSizeUnitWidget->blockSignals(
false );
795 methodComboBox->blockSignals(
true );
796 switch ( mRenderer->graduatedMethod() )
800 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
801 if ( mRenderer->sourceColorRamp() )
803 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
809 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
810 if ( !mRenderer->ranges().isEmpty() )
812 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
813 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
818 toggleMethodWidgets(
static_cast<MethodMode
>( methodComboBox->currentData().toInt() ) );
819 methodComboBox->blockSignals(
false );
821 viewGraduated->resizeColumnToContents( 0 );
822 viewGraduated->resizeColumnToContents( 1 );
823 viewGraduated->resizeColumnToContents( 2 );
825 mHistogramWidget->refresh();
835 mRenderer->setClassAttribute( field );
839void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
841 const MethodMode newMethod =
static_cast<MethodMode
>( methodComboBox->currentData().toInt() );
842 toggleMethodWidgets( newMethod );
852 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
855 mRenderer->setSourceColorRamp( ramp );
862 lblColorRamp->setVisible(
false );
863 btnColorRamp->setVisible(
false );
864 lblSize->setVisible(
true );
865 minSizeSpinBox->setVisible(
true );
866 lblSize->setVisible(
true );
867 maxSizeSpinBox->setVisible(
true );
868 mSizeUnitWidget->setVisible(
true );
877void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
879 clearParameterWidgets();
881 const QString methodId = cboGraduatedMode->currentData().toString();
883 Q_ASSERT( mClassificationMethod.get() );
893 QVariant value = mClassificationMethod->parameterValues().value( def->name(), def->defaultValueForGui() );
898 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
904void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
910 lblColorRamp->setVisible(
true );
911 btnColorRamp->setVisible(
true );
912 lblSize->setVisible(
false );
913 minSizeSpinBox->setVisible(
false );
914 lblSizeTo->setVisible(
false );
915 maxSizeSpinBox->setVisible(
false );
916 mSizeUnitWidget->setVisible(
false );
922 lblColorRamp->setVisible(
false );
923 btnColorRamp->setVisible(
false );
924 lblSize->setVisible(
true );
925 minSizeSpinBox->setVisible(
true );
926 lblSizeTo->setVisible(
true );
927 maxSizeSpinBox->setVisible(
true );
928 mSizeUnitWidget->setVisible(
true );
934void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
936 while ( mParametersLayout->rowCount() )
938 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
939 for ( QLayoutItem *item : { row.labelItem, row.fieldItem } )
942 QWidget *widget = item->widget();
948 mParameterWidgetWrappers.clear();
956 mModel->updateSymbology();
959 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
972 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
975 mRenderer->setUsingSymbolLevels( enabled );
976 mModel->updateSymbology();
982 mGraduatedSymbol.reset( widget->
symbol()->
clone() );
989 mSizeUnitWidget->blockSignals(
true );
990 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
991 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
992 mSizeUnitWidget->blockSignals(
false );
994 QItemSelectionModel *m = viewGraduated->selectionModel();
995 QModelIndexList selectedIndexes = m->selectedRows( 1 );
996 if ( !selectedIndexes.isEmpty() )
998 const auto constSelectedIndexes = selectedIndexes;
999 for (
const QModelIndex &idx : constSelectedIndexes )
1001 if ( idx.isValid() )
1003 int rangeIdx = idx.row();
1004 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
1005 if ( selectedIndexes.count() > 1 )
1008 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
1010 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
1016 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1023void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished()
1025 const QString text = cboSymmetryPoint->lineEdit()->text();
1026 int index = cboSymmetryPoint->findText( text );
1029 cboSymmetryPoint->setCurrentIndex( index );
1033 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1041 mUpdateTimer.start( 500 );
1044void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl()
1046 if ( mBlockUpdates || !mClassificationMethod )
1050 QString attrName = mExpressionWidget->currentField();
1051 int nclasses = spinGraduatedClasses->value();
1059 double minimum = minVal.toDouble();
1060 double maximum = maxVal.toDouble();
1061 mSymmetryPointValidator->
setBottom( minimum );
1062 mSymmetryPointValidator->
setTop( maximum );
1063 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1070 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1071 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', mClassificationMethod->labelPrecision() + 2 ) );
1074 if ( mGroupBoxSymmetric->isChecked() )
1077 bool astride = cbxAstride->isChecked();
1078 mClassificationMethod->setSymmetricMode(
true, symmetryPoint, astride );
1081 QVariantMap parameterValues;
1082 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1083 parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() );
1084 mClassificationMethod->setParameterValues( parameterValues );
1087 mRenderer->setClassificationMethod( mClassificationMethod->clone().release() );
1090 mRenderer->setClassAttribute( attrName );
1094 if ( mRenderer->classificationMethod()->codeComplexity() > 1 &&
mLayer->
featureCount() > 50000 )
1096 if ( QMessageBox::Cancel == QMessageBox::question(
this, tr(
"Apply Classification" ), tr(
"Natural break classification (Jenks) is O(n2) complexity, your classification may take a long time.\nPress cancel to abort breaks calculation or OK to continue." ), QMessageBox::Cancel, QMessageBox::Ok ) )
1102 if ( methodComboBox->currentData() == ColorMode )
1104 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1107 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1110 mRenderer->setSourceColorRamp( ramp.release() );
1114 mRenderer->setSourceColorRamp(
nullptr );
1118 mRenderer->updateClasses(
mLayer, nclasses, error );
1120 if ( !error.isEmpty() )
1121 QMessageBox::critical(
this, tr(
"Apply Classification" ), error );
1123 if ( methodComboBox->currentData() == SizeMode )
1124 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1126 mRenderer->calculateLabelPrecision();
1134 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1138 mRenderer->updateColorRamp( ramp.release() );
1139 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1145 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1146 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1151int QgsRendererPropertiesDialog::currentRangeRow()
1153 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1154 if ( !idx.isValid() )
1163 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1165 const auto constSelectedRows = selectedRows;
1166 for (
const QModelIndex &r : constSelectedRows )
1170 rows.append( r.row() );
1179 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1180 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1182 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1191 if ( idx.isValid() && idx.column() == 0 )
1193 if ( idx.isValid() && idx.column() == 1 )
1199 if ( !idx.isValid() )
1202 mRowSelected = idx.row();
1212 std::unique_ptr<QgsSymbol> newSymbol( range.
symbol()->
clone() );
1226 if ( !dlg.exec() || !newSymbol )
1231 mGraduatedSymbol = std::move( newSymbol );
1232 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1244 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1245 if ( decimalPlaces < 0 )
1250 if ( dialog.exec() == QDialog::Accepted )
1256 if ( cbxLinkBoundaries->isChecked() )
1260 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1263 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1265 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1269 mHistogramWidget->refresh();
1275 mModel->addClass( mGraduatedSymbol.get() );
1276 mHistogramWidget->refresh();
1283 mModel->deleteRows( classIndexes );
1284 mHistogramWidget->refresh();
1290 mModel->removeAllRows();
1291 mHistogramWidget->refresh();
1298 bool ordered =
true;
1299 for (
int i = 1; i < ranges.size(); ++i )
1301 if ( ranges[i] < ranges[i - 1] )
1318 int result = QMessageBox::warning(
1320 tr(
"Link Class Boundaries" ),
1321 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1322 QMessageBox::Ok | QMessageBox::Cancel
1324 if ( result != QMessageBox::Ok )
1326 cbxLinkBoundaries->setChecked(
false );
1329 mRenderer->sortByValue();
1333 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1335 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1343 if ( item->column() == 2 )
1345 QString label = item->text();
1346 int idx = item->row();
1347 mRenderer->updateRangeLabel( idx, label );
1353 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1354 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1355 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1356 mRenderer->updateRangeLabels();
1357 mModel->updateLabels();
1365 QItemSelectionModel *m = viewGraduated->selectionModel();
1366 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1367 if ( !selectedIndexes.isEmpty() )
1370 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1371 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1373 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1374 if ( list.size() < 3 )
1399 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1400 if ( decimalPlaces < 0 )
1402 double precision = 1.0 / std::pow( 10, decimalPlaces );
1404 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1408 return it->symbol();
1418 mModel->updateSymbology();
1420 mHistogramWidget->refresh();
1431 viewGraduated->selectionModel()->clear();
1434 cbxLinkBoundaries->setChecked(
false );
1451 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1453 mCopyBuffer.clear();
1456 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1458 QgsRangeList::iterator rIt = mCopyBuffer.begin();
1459 for ( ; rIt != mCopyBuffer.end(); ++rIt )
1461 rIt->mUuid = QUuid::createUuid().toString();
1462 mModel->addClass( *rIt );
1468void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1471 if ( !ranges.isEmpty() )
1473 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1475 else if ( mRenderer->sourceSymbol() )
1477 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1479 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1482void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1496void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1498 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1508 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1509 for (
const QModelIndex &index : selectedRows )
1511 if ( !index.isValid() )
1514 const int row = index.row();
1515 if ( !mRenderer || mRenderer->ranges().size() <= row )
1518 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1521 std::unique_ptr<QgsSymbol> newCatSymbol( tempSymbol->clone() );
1522 if ( selectedRows.count() > 1 )
1525 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1528 mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
@ Standard
Standard (single-run) algorithm mode.
@ Size
Alter size of symbols.
@ Color
Alter color of symbols.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes)
static QgsClassificationMethodRegistry * classificationMethodRegistry()
Returns the application's classification methods registry, used in graduated renderer.
static const QString METHOD_ID
std::unique_ptr< QgsClassificationMethod > method(const QString &id)
Returns a new instance of the method for the given id.
QIcon icon(const QString &id) const
Returns the icon for a given method id.
QMap< QString, QString > methodNames() const
Returns a map <name, id> of all registered methods.
An abstract class for implementations of classification methods.
double symmetryPoint() const
Returns the symmetry point for symmetric mode.
bool symmetricModeEnabled() const
Returns if the symmetric mode is enabled.
int labelPrecision() const
Returns the precision for the formatting of the labels.
virtual QString id() const =0
The id of the method as saved in the project, must be unique in registry.
QVariantMap parameterValues() const
Returns the values of the processing parameters.
bool symmetryAstride() const
Returns if the symmetric mode is astride if true, it will remove the symmetry point break so that the...
static const int MIN_PRECISION
QString labelFormat() const
Returns the format of the label for the classes.
static const int MAX_PRECISION
bool labelTrimTrailingZeroes() const
Returns if the trailing 0 are trimmed in the label.
@ IgnoresClassCount
The classification method does not compute classes based on a class count.
bool symmetricModeAvailable() const
Returns if the method supports symmetric calculation.
QgsClassificationMethod::MethodProperties flags() const
Returns the classification flags.
static const QString METHOD_ID
Abstract base class for color ramps.
A custom validator which allows entry of doubles in a locale-tolerant way.
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
void setTop(double top)
Set top range limit.
void setMaxDecimals(int maxDecimals)
Sets the number of decimals accepted by the validator to maxDecimals.
void setBottom(double bottom)
Set top range limit.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Abstract base class for all 2D vector feature renderers.
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
@ 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...
A dialog for setting a lower and upper range value.
double upperValueDouble() const
Returns the upper value.
double lowerValueDouble() const
Returns the lower value.
void setLowerValue(const QString &val)
void setUpperValue(const QString &val)
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
Contains configuration for rendering maps.
A marker symbol type, for rendering Point and MultiPoint geometries.
Contains information about the context in which a processing algorithm is executed.
QgsAbstractProcessingParameterWidgetWrapper * createParameterWidgetWrapper(const QgsProcessingParameterDefinition *parameter, Qgis::ProcessingMode type)
Creates a new parameter widget wrapper for the given parameter.
Base class for the definition of processing parameters.
QVariant defaultValueForGui() const
Returns the default value to use for the parameter in a GUI.
QString name() const
Returns the name of the parameter.
static QgsProject * instance()
Returns the QgsProject singleton instance.
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...
Represents a value range for a QgsGraduatedSymbolRenderer.
QString label() const
Returns the label used for the range.
QgsSymbol * symbol() const
Returns the symbol used for the range.
bool renderState() const
Returns true if the range should be rendered.
double upperValue() const
Returns the upper bound of the range.
double lowerValue() const
Returns the lower bound of the range.
Stores properties relating to a screen.
A database of saved style entities, including symbols, color ramps, text formats and others.
static std::unique_ptr< QgsSymbol > symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns an icon preview for a color ramp.
A dialog that can be used to select and build a symbol.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
Abstract base class for all rendered symbols.
void setColor(const QColor &color) const
Sets the color for the symbol.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
void minimumAndMaximumValue(int index, QVariant &minimum, QVariant &maximum) const
Calculates both the minimum and maximum value for an attribute column.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
double qgsPermissiveToDouble(QString string, bool &ok)
Converts a string to a double in a permissive way, e.g., allowing for incorrect numbers of digits bet...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
#define QgsDebugMsgLevel(str, level)
QList< QgsRendererRange > QgsRangeList