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
137 if ( !index.isValid() )
139 return Qt::ItemIsDropEnabled;
142 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
144 if ( index.column() == 2 )
146 flags |= Qt::ItemIsEditable;
152Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
154 return Qt::MoveAction;
157QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
159 if ( !index.isValid() || !mRenderer )
164 if ( role == Qt::CheckStateRole && index.column() == 0 )
166 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
168 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
170 switch ( index.column() )
174 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
175 if ( decimalPlaces < 0 )
177 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
180 return range.
label();
185 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
190 else if ( role == Qt::TextAlignmentRole )
192 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
194 else if ( role == Qt::EditRole )
196 switch ( index.column() )
200 return range.
label();
209bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
211 if ( !index.isValid() )
214 if ( index.column() == 0 && role == Qt::CheckStateRole )
216 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
217 emit dataChanged( index, index );
221 if ( role != Qt::EditRole )
224 switch ( index.column() )
229 mRenderer->updateRangeLabel( index.row(), value.toString() );
235 emit dataChanged( index, index );
239QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
241 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
244 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
245 return lst.value( section );
250int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
252 if ( parent.isValid() || !mRenderer )
256 return mRenderer->ranges().size();
259int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
265QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
267 if ( hasIndex( row, column, parent ) )
269 return createIndex( row, column );
271 return QModelIndex();
274QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
277 return QModelIndex();
280QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
283 types << mMimeFormat;
287QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
289 QMimeData *mimeData =
new QMimeData();
290 QByteArray encodedData;
292 QDataStream stream( &encodedData, QIODevice::WriteOnly );
295 const auto constIndexes = indexes;
296 for (
const QModelIndex &index : constIndexes )
298 if ( !index.isValid() || index.column() != 0 )
301 stream << index.row();
303 mimeData->setData( mMimeFormat, encodedData );
307bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
311 if ( action != Qt::MoveAction )
314 if ( !data->hasFormat( mMimeFormat ) )
317 QByteArray encodedData = data->data( mMimeFormat );
318 QDataStream stream( &encodedData, QIODevice::ReadOnly );
321 while ( !stream.atEnd() )
328 int to = parent.row();
332 to = mRenderer->ranges().size();
333 for (
int i = rows.size() - 1; i >= 0; i-- )
335 QgsDebugMsgLevel( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ), 2 );
340 mRenderer->moveClass( rows[i], t );
342 for (
int j = 0; j < i; j++ )
344 if ( to < rows[j] && rows[i] > rows[j] )
351 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
356void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
358 for (
int i = rows.size() - 1; i >= 0; i-- )
360 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
361 mRenderer->deleteClass( rows[i] );
366void QgsGraduatedSymbolRendererModel::removeAllRows()
368 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
369 mRenderer->deleteAllClasses();
373void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
381 mRenderer->sortByValue( order );
383 else if ( column == 2 )
385 mRenderer->sortByLabel( order );
388 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
391void QgsGraduatedSymbolRendererModel::updateSymbology()
393 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
396void QgsGraduatedSymbolRendererModel::updateLabels()
398 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
402QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
406void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
408 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
410 QStyleOption opt( *option );
411 opt.rect.setLeft( 0 );
413 opt.rect.setHeight( 0 );
415 opt.rect.setRight( widget->width() );
416 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
419 QProxyStyle::drawPrimitive( element, option, painter, widget );
437 expContext = lMapCanvas->createExpressionContext();
471 mRenderer = std::make_unique<QgsGraduatedSymbolRenderer>( QString(),
QgsRangeList() );
480 cboSymmetryPoint->setEditable(
true );
481 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
484 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
487 cboGraduatedMode->addItem( icon, it.key(), it.value() );
490 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
491 this->layout()->setContentsMargins( 0, 0, 0, 0 );
493 mModel =
new QgsGraduatedSymbolRendererModel(
this, screen() );
496 mExpressionWidget->setLayer(
mLayer );
498 btnChangeGraduatedSymbol->setLayer(
mLayer );
499 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
501 mSizeUnitWidget->setUnits(
512 spinPrecision->setClearValue( 4 );
514 spinGraduatedClasses->setShowClearButton(
false );
516 btnColorRamp->setShowRandomColorRamp(
true );
519 std::unique_ptr<QgsColorRamp> colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
522 btnColorRamp->setColorRamp( colorRamp.get() );
527 btnColorRamp->setColorRamp( ramp );
532 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
535 if ( mGraduatedSymbol )
537 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
538 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
540 methodComboBox->blockSignals(
true );
541 methodComboBox->addItem( tr(
"Color" ), ColorMode );
542 switch ( mGraduatedSymbol->type() )
546 methodComboBox->addItem( tr(
"Size" ), SizeMode );
547 minSizeSpinBox->setValue( 1 );
548 maxSizeSpinBox->setValue( 8 );
553 methodComboBox->addItem( tr(
"Size" ), SizeMode );
554 minSizeSpinBox->setValue( .1 );
555 maxSizeSpinBox->setValue( 2 );
561 methodComboBox->hide();
568 methodComboBox->blockSignals(
false );
577 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
584 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
587 updateMethodParameters();
595 mGroupBoxSymmetric->setCollapsed(
true );
598 QMenu *advMenu =
new QMenu(
this );
603 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
605 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
608 btnAdvanced->setMenu( advMenu );
610 mHistogramWidget->setLayer(
mLayer );
611 mHistogramWidget->setRenderer( mRenderer.get() );
615 mExpressionWidget->registerExpressionContextGenerator(
this );
617 mUpdateTimer.setSingleShot(
true );
618 mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout,
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
621void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
623 if ( !mGraduatedSymbol )
625 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
626 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
627 mRenderer->updateSymbols( mGraduatedSymbol.get() );
634 mParameterWidgetWrappers.clear();
639 return mRenderer.get();
651 delete mActionLevels;
652 mActionLevels =
nullptr;
673 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
675 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
699 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
701 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
717 int precision = spinPrecision->value() + 2;
718 while ( cboSymmetryPoint->count() )
719 cboSymmetryPoint->removeItem( 0 );
720 for (
int i = 0; i < ranges.count() - 1; i++ )
721 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
725 int idx = cboGraduatedMode->findData( method->
id() );
727 cboGraduatedMode->setCurrentIndex( idx );
733 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
740 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
744 ppww->setParameterValue( value,
context );
749 int nclasses = ranges.count();
752 spinGraduatedClasses->setValue( ranges.count() );
760 spinGraduatedClasses->setEnabled(
true );
764 QString attrName = mRenderer->classAttribute();
765 mExpressionWidget->setField( attrName );
766 mHistogramWidget->setSourceFieldExp( attrName );
769 if ( mRenderer->sourceSymbol() )
771 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
772 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
775 mModel->setRenderer( mRenderer.get() );
776 viewGraduated->setModel( mModel );
778 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
780 if ( mGraduatedSymbol )
782 mSizeUnitWidget->blockSignals(
true );
783 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
784 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
785 mSizeUnitWidget->blockSignals(
false );
789 methodComboBox->blockSignals(
true );
790 switch ( mRenderer->graduatedMethod() )
794 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
795 if ( mRenderer->sourceColorRamp() )
797 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
803 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
804 if ( !mRenderer->ranges().isEmpty() )
806 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
807 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
812 toggleMethodWidgets(
static_cast<MethodMode
>( methodComboBox->currentData().toInt() ) );
813 methodComboBox->blockSignals(
false );
815 viewGraduated->resizeColumnToContents( 0 );
816 viewGraduated->resizeColumnToContents( 1 );
817 viewGraduated->resizeColumnToContents( 2 );
819 mHistogramWidget->refresh();
829 mRenderer->setClassAttribute( field );
832void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
834 const MethodMode newMethod =
static_cast<MethodMode
>( methodComboBox->currentData().toInt() );
835 toggleMethodWidgets( newMethod );
845 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
848 mRenderer->setSourceColorRamp( ramp );
855 lblColorRamp->setVisible(
false );
856 btnColorRamp->setVisible(
false );
857 lblSize->setVisible(
true );
858 minSizeSpinBox->setVisible(
true );
859 lblSize->setVisible(
true );
860 maxSizeSpinBox->setVisible(
true );
861 mSizeUnitWidget->setVisible(
true );
870void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
872 clearParameterWidgets();
874 const QString methodId = cboGraduatedMode->currentData().toString();
886 QVariant value = method->parameterValues().value( def->name(), def->defaultValueForGui() );
891 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
897void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
903 lblColorRamp->setVisible(
true );
904 btnColorRamp->setVisible(
true );
905 lblSize->setVisible(
false );
906 minSizeSpinBox->setVisible(
false );
907 lblSizeTo->setVisible(
false );
908 maxSizeSpinBox->setVisible(
false );
909 mSizeUnitWidget->setVisible(
false );
915 lblColorRamp->setVisible(
false );
916 btnColorRamp->setVisible(
false );
917 lblSize->setVisible(
true );
918 minSizeSpinBox->setVisible(
true );
919 lblSizeTo->setVisible(
true );
920 maxSizeSpinBox->setVisible(
true );
921 mSizeUnitWidget->setVisible(
true );
927void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
929 while ( mParametersLayout->rowCount() )
931 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
932 for ( QLayoutItem *item : { row.labelItem, row.fieldItem } )
935 QWidget *widget = item->widget();
941 mParameterWidgetWrappers.clear();
949 mModel->updateSymbology();
952 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
965 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
968 mRenderer->setUsingSymbolLevels( enabled );
969 mModel->updateSymbology();
975 mGraduatedSymbol.reset( widget->
symbol()->
clone() );
982 mSizeUnitWidget->blockSignals(
true );
983 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
984 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
985 mSizeUnitWidget->blockSignals(
false );
987 QItemSelectionModel *m = viewGraduated->selectionModel();
988 QModelIndexList selectedIndexes = m->selectedRows( 1 );
989 if ( !selectedIndexes.isEmpty() )
991 const auto constSelectedIndexes = selectedIndexes;
992 for (
const QModelIndex &idx : constSelectedIndexes )
996 int rangeIdx = idx.row();
997 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
998 if ( selectedIndexes.count() > 1 )
1001 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
1003 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
1009 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1016void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished()
1018 const QString text = cboSymmetryPoint->lineEdit()->text();
1019 int index = cboSymmetryPoint->findText( text );
1022 cboSymmetryPoint->setCurrentIndex( index );
1026 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1034 mUpdateTimer.start( 500 );
1037void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl()
1039 if ( mBlockUpdates )
1043 QString attrName = mExpressionWidget->currentField();
1044 int nclasses = spinGraduatedClasses->value();
1046 const QString methodId = cboGraduatedMode->currentData().toString();
1056 double minimum = minVal.toDouble();
1057 double maximum = maxVal.toDouble();
1058 mSymmetryPointValidator->
setBottom( minimum );
1059 mSymmetryPointValidator->
setTop( maximum );
1060 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1067 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1068 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', method->labelPrecision() + 2 ) );
1071 if ( mGroupBoxSymmetric->isChecked() )
1074 bool astride = cbxAstride->isChecked();
1075 method->setSymmetricMode(
true, symmetryPoint, astride );
1078 QVariantMap parameterValues;
1079 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1080 parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() );
1081 method->setParameterValues( parameterValues );
1084 mRenderer->setClassificationMethod( method.release() );
1087 mRenderer->setClassAttribute( attrName );
1091 if ( mRenderer->classificationMethod()->codeComplexity() > 1 &&
mLayer->
featureCount() > 50000 )
1093 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 ) )
1099 if ( methodComboBox->currentData() == ColorMode )
1101 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1104 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1107 mRenderer->setSourceColorRamp( ramp.release() );
1111 mRenderer->setSourceColorRamp(
nullptr );
1115 mRenderer->updateClasses(
mLayer, nclasses, error );
1117 if ( !error.isEmpty() )
1118 QMessageBox::critical(
this, tr(
"Apply Classification" ), error );
1120 if ( methodComboBox->currentData() == SizeMode )
1121 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1123 mRenderer->calculateLabelPrecision();
1131 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1135 mRenderer->updateColorRamp( ramp.release() );
1136 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1142 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1143 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1148int QgsRendererPropertiesDialog::currentRangeRow()
1150 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1151 if ( !idx.isValid() )
1160 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1162 const auto constSelectedRows = selectedRows;
1163 for (
const QModelIndex &r : constSelectedRows )
1167 rows.append( r.row() );
1176 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1177 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1179 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1188 if ( idx.isValid() && idx.column() == 0 )
1190 if ( idx.isValid() && idx.column() == 1 )
1196 if ( !idx.isValid() )
1199 mRowSelected = idx.row();
1209 std::unique_ptr<QgsSymbol> newSymbol( range.
symbol()->
clone() );
1223 if ( !dlg.exec() || !newSymbol )
1228 mGraduatedSymbol = std::move( newSymbol );
1229 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1241 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1242 if ( decimalPlaces < 0 )
1247 if ( dialog.exec() == QDialog::Accepted )
1253 if ( cbxLinkBoundaries->isChecked() )
1257 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1260 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1262 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1266 mHistogramWidget->refresh();
1272 mModel->addClass( mGraduatedSymbol.get() );
1273 mHistogramWidget->refresh();
1280 mModel->deleteRows( classIndexes );
1281 mHistogramWidget->refresh();
1287 mModel->removeAllRows();
1288 mHistogramWidget->refresh();
1295 bool ordered =
true;
1296 for (
int i = 1; i < ranges.size(); ++i )
1298 if ( ranges[i] < ranges[i - 1] )
1315 int result = QMessageBox::warning(
1317 tr(
"Link Class Boundaries" ),
1318 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1319 QMessageBox::Ok | QMessageBox::Cancel
1321 if ( result != QMessageBox::Ok )
1323 cbxLinkBoundaries->setChecked(
false );
1326 mRenderer->sortByValue();
1330 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1332 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1340 if ( item->column() == 2 )
1342 QString label = item->text();
1343 int idx = item->row();
1344 mRenderer->updateRangeLabel( idx, label );
1350 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1351 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1352 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1353 mRenderer->updateRangeLabels();
1354 mModel->updateLabels();
1362 QItemSelectionModel *m = viewGraduated->selectionModel();
1363 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1364 if ( !selectedIndexes.isEmpty() )
1367 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1368 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1370 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1371 if ( list.size() < 3 )
1396 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1397 if ( decimalPlaces < 0 )
1399 double precision = 1.0 / std::pow( 10, decimalPlaces );
1401 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1405 return it->symbol();
1415 mModel->updateSymbology();
1417 mHistogramWidget->refresh();
1428 viewGraduated->selectionModel()->clear();
1431 cbxLinkBoundaries->setChecked(
false );
1448 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1450 mCopyBuffer.clear();
1453 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1455 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1456 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
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()
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() );
@ 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