19#include <QStandardItemModel>
20#include <QStandardItem>
65QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, QScreen *screen ) : QAbstractItemModel( parent )
66 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
75 if ( !mRenderer->ranges().isEmpty() )
77 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
88 if ( !renderer->
ranges().isEmpty() )
90 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
101void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
103 if ( !mRenderer )
return;
104 int idx = mRenderer->
ranges().size();
105 beginInsertRows( QModelIndex(), idx, idx );
106 mRenderer->addClass( symbol );
110void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
116 int idx = mRenderer->ranges().size();
117 beginInsertRows( QModelIndex(), idx, idx );
118 mRenderer->addClass( range );
122QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
124 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
129 return mRenderer->ranges().value( index.row() );
132Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
134 if ( !index.isValid() )
136 return Qt::ItemIsDropEnabled;
139 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
141 if ( index.column() == 2 )
143 flags |= Qt::ItemIsEditable;
149Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
151 return Qt::MoveAction;
154QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
156 if ( !index.isValid() || !mRenderer )
return QVariant();
160 if ( role == Qt::CheckStateRole && index.column() == 0 )
162 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
164 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
166 switch ( index.column() )
170 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
171 if ( decimalPlaces < 0 ) decimalPlaces = 0;
172 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
175 return range.
label();
180 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
185 else if ( role == Qt::TextAlignmentRole )
187 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
189 else if ( role == Qt::EditRole )
191 switch ( index.column() )
195 return range.
label();
204bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
206 if ( !index.isValid() )
209 if ( index.column() == 0 && role == Qt::CheckStateRole )
211 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
212 emit dataChanged( index, index );
216 if ( role != Qt::EditRole )
219 switch ( index.column() )
224 mRenderer->updateRangeLabel( index.row(), value.toString() );
230 emit dataChanged( index, index );
234QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
236 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
239 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
240 return lst.value( section );
245int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
247 if ( parent.isValid() || !mRenderer )
251 return mRenderer->ranges().size();
254int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
260QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
262 if ( hasIndex( row, column, parent ) )
264 return createIndex( row, column );
266 return QModelIndex();
269QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
272 return QModelIndex();
275QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
278 types << mMimeFormat;
282QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
284 QMimeData *mimeData =
new QMimeData();
285 QByteArray encodedData;
287 QDataStream stream( &encodedData, QIODevice::WriteOnly );
290 const auto constIndexes = indexes;
291 for (
const QModelIndex &index : constIndexes )
293 if ( !index.isValid() || index.column() != 0 )
296 stream << index.row();
298 mimeData->setData( mMimeFormat, encodedData );
302bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
306 if ( action != Qt::MoveAction )
return true;
308 if ( !data->hasFormat( mMimeFormat ) )
return false;
310 QByteArray encodedData = data->data( mMimeFormat );
311 QDataStream stream( &encodedData, QIODevice::ReadOnly );
314 while ( !stream.atEnd() )
321 int to = parent.row();
324 if ( to == -1 ) to = mRenderer->ranges().size();
325 for (
int i = rows.size() - 1; i >= 0; i-- )
327 QgsDebugMsgLevel( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ), 2 );
330 if ( rows[i] < t ) t--;
331 mRenderer->moveClass( rows[i], t );
333 for (
int j = 0; j < i; j++ )
335 if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
338 if ( rows[i] < to ) to--;
340 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
345void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
347 for (
int i = rows.size() - 1; i >= 0; i-- )
349 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
350 mRenderer->deleteClass( rows[i] );
355void QgsGraduatedSymbolRendererModel::removeAllRows()
357 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
358 mRenderer->deleteAllClasses();
362void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
370 mRenderer->sortByValue( order );
372 else if ( column == 2 )
374 mRenderer->sortByLabel( order );
377 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
380void QgsGraduatedSymbolRendererModel::updateSymbology()
382 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
385void QgsGraduatedSymbolRendererModel::updateLabels()
387 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
391QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
395void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
397 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
399 QStyleOption opt( *option );
400 opt.rect.setLeft( 0 );
402 opt.rect.setHeight( 0 );
403 if ( widget ) opt.rect.setRight( widget->width() );
404 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
407 QProxyStyle::drawPrimitive( element, option, painter, widget );
425 expContext = lMapCanvas->createExpressionContext();
459 mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(),
QgsRangeList() );
468 cboSymmetryPoint->setEditable(
true );
469 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
472 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
475 cboGraduatedMode->addItem( icon, it.key(), it.value() );
478 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
479 this->layout()->setContentsMargins( 0, 0, 0, 0 );
481 mModel =
new QgsGraduatedSymbolRendererModel(
this, screen() );
484 mExpressionWidget->setLayer(
mLayer );
486 btnChangeGraduatedSymbol->setLayer(
mLayer );
487 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
489 mSizeUnitWidget->setUnits(
500 spinPrecision->setClearValue( 4 );
502 spinGraduatedClasses->setShowClearButton(
false );
504 btnColorRamp->setShowRandomColorRamp(
true );
507 std::unique_ptr< QgsColorRamp > colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
510 btnColorRamp->setColorRamp( colorRamp.get() );
515 btnColorRamp->setColorRamp( ramp );
520 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
523 if ( mGraduatedSymbol )
525 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
526 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
528 methodComboBox->blockSignals(
true );
529 methodComboBox->addItem( tr(
"Color" ), ColorMode );
530 switch ( mGraduatedSymbol->type() )
534 methodComboBox->addItem( tr(
"Size" ), SizeMode );
535 minSizeSpinBox->setValue( 1 );
536 maxSizeSpinBox->setValue( 8 );
541 methodComboBox->addItem( tr(
"Size" ), SizeMode );
542 minSizeSpinBox->setValue( .1 );
543 maxSizeSpinBox->setValue( 2 );
549 methodComboBox->hide();
556 methodComboBox->blockSignals(
false );
565 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
572 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
575 updateMethodParameters();
583 mGroupBoxSymmetric->setCollapsed(
true );
586 QMenu *advMenu =
new QMenu(
this );
591 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
593 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
596 btnAdvanced->setMenu( advMenu );
598 mHistogramWidget->setLayer(
mLayer );
599 mHistogramWidget->setRenderer( mRenderer.get() );
603 mExpressionWidget->registerExpressionContextGenerator(
this );
605 mUpdateTimer.setSingleShot(
true );
606 mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout,
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
609void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
611 if ( !mGraduatedSymbol )
613 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
614 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
615 mRenderer->updateSymbols( mGraduatedSymbol.get() );
622 mParameterWidgetWrappers.clear();
627 return mRenderer.get();
639 delete mActionLevels;
640 mActionLevels =
nullptr;
661 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
663 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
687 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
689 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
705 int precision = spinPrecision->value() + 2;
706 while ( cboSymmetryPoint->count() )
707 cboSymmetryPoint->removeItem( 0 );
708 for (
int i = 0; i < ranges.count() - 1; i++ )
709 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
713 int idx = cboGraduatedMode->findData( method->
id() );
715 cboGraduatedMode->setCurrentIndex( idx );
721 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
728 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
732 ppww->setParameterValue( value,
context );
737 int nclasses = ranges.count();
740 spinGraduatedClasses->setValue( ranges.count() );
748 spinGraduatedClasses->setEnabled(
true );
752 QString attrName = mRenderer->classAttribute();
753 mExpressionWidget->setField( attrName );
754 mHistogramWidget->setSourceFieldExp( attrName );
757 if ( mRenderer->sourceSymbol() )
759 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
760 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
763 mModel->setRenderer( mRenderer.get() );
764 viewGraduated->setModel( mModel );
766 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
768 if ( mGraduatedSymbol )
770 mSizeUnitWidget->blockSignals(
true );
771 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
772 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
773 mSizeUnitWidget->blockSignals(
false );
777 methodComboBox->blockSignals(
true );
778 switch ( mRenderer->graduatedMethod() )
782 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
783 if ( mRenderer->sourceColorRamp() )
785 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
791 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
792 if ( !mRenderer->ranges().isEmpty() )
794 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
795 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
800 toggleMethodWidgets(
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
801 methodComboBox->blockSignals(
false );
803 viewGraduated->resizeColumnToContents( 0 );
804 viewGraduated->resizeColumnToContents( 1 );
805 viewGraduated->resizeColumnToContents( 2 );
807 mHistogramWidget->refresh();
817 mRenderer->setClassAttribute( field );
820void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
822 const MethodMode newMethod =
static_cast< MethodMode
>( methodComboBox->currentData().toInt() );
823 toggleMethodWidgets( newMethod );
833 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
836 mRenderer->setSourceColorRamp( ramp );
843 lblColorRamp->setVisible(
false );
844 btnColorRamp->setVisible(
false );
845 lblSize->setVisible(
true );
846 minSizeSpinBox->setVisible(
true );
847 lblSize->setVisible(
true );
848 maxSizeSpinBox->setVisible(
true );
849 mSizeUnitWidget->setVisible(
true );
858void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
860 clearParameterWidgets();
862 const QString methodId = cboGraduatedMode->currentData().toString();
874 QVariant value = method->
parameterValues().value( def->name(), def->defaultValueForGui() );
879 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
885void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
891 lblColorRamp->setVisible(
true );
892 btnColorRamp->setVisible(
true );
893 lblSize->setVisible(
false );
894 minSizeSpinBox->setVisible(
false );
895 lblSizeTo->setVisible(
false );
896 maxSizeSpinBox->setVisible(
false );
897 mSizeUnitWidget->setVisible(
false );
903 lblColorRamp->setVisible(
false );
904 btnColorRamp->setVisible(
false );
905 lblSize->setVisible(
true );
906 minSizeSpinBox->setVisible(
true );
907 lblSizeTo->setVisible(
true );
908 maxSizeSpinBox->setVisible(
true );
909 mSizeUnitWidget->setVisible(
true );
915void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
917 while ( mParametersLayout->rowCount() )
919 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
920 for ( QLayoutItem *item : {row.labelItem, row.fieldItem} )
923 QWidget *widget = item->widget();
929 mParameterWidgetWrappers.clear();
937 mModel->updateSymbology();
940 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
953 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
956 mRenderer->setUsingSymbolLevels( enabled );
957 mModel->updateSymbology();
963 mGraduatedSymbol.reset( widget->
symbol()->
clone() );
970 mSizeUnitWidget->blockSignals(
true );
971 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
972 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
973 mSizeUnitWidget->blockSignals(
false );
975 QItemSelectionModel *m = viewGraduated->selectionModel();
976 QModelIndexList selectedIndexes = m->selectedRows( 1 );
977 if ( !selectedIndexes.isEmpty() )
979 const auto constSelectedIndexes = selectedIndexes;
980 for (
const QModelIndex &idx : constSelectedIndexes )
984 int rangeIdx = idx.row();
985 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
986 if ( selectedIndexes.count() > 1 )
989 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
991 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
997 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1004void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
1006 const QString text = cboSymmetryPoint->lineEdit()->text();
1007 int index = cboSymmetryPoint->findText( text );
1010 cboSymmetryPoint->setCurrentIndex( index );
1014 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1022 mUpdateTimer.start( 500 );
1025void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl( )
1028 if ( mBlockUpdates )
1032 QString attrName = mExpressionWidget->currentField();
1033 int nclasses = spinGraduatedClasses->value();
1035 const QString methodId = cboGraduatedMode->currentData().toString();
1045 double minimum = minVal.toDouble();
1046 double maximum = maxVal.toDouble();
1047 mSymmetryPointValidator->
setBottom( minimum );
1048 mSymmetryPointValidator->
setTop( maximum );
1049 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1057 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1058 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1061 if ( mGroupBoxSymmetric->isChecked() )
1064 bool astride = cbxAstride->isChecked();
1068 QVariantMap parameterValues;
1069 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1070 parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() );
1074 mRenderer->setClassificationMethod( method );
1077 mRenderer->setClassAttribute( attrName );
1083 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 ) )
1089 if ( methodComboBox->currentData() == ColorMode )
1091 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1094 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1097 mRenderer->setSourceColorRamp( ramp.release() );
1101 mRenderer->setSourceColorRamp(
nullptr );
1105 mRenderer->updateClasses(
mLayer, nclasses, error );
1107 if ( !error.isEmpty() )
1108 QMessageBox::critical(
this, tr(
"Apply Classification" ), error );
1110 if ( methodComboBox->currentData() == SizeMode )
1111 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1113 mRenderer->calculateLabelPrecision();
1121 std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
1125 mRenderer->updateColorRamp( ramp.release() );
1126 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1132 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1133 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1138int QgsRendererPropertiesDialog::currentRangeRow()
1140 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1141 if ( !idx.isValid() )
1150 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1152 const auto constSelectedRows = selectedRows;
1153 for (
const QModelIndex &r : constSelectedRows )
1157 rows.append( r.row() );
1166 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1167 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1169 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1178 if ( idx.isValid() && idx.column() == 0 )
1180 if ( idx.isValid() && idx.column() == 1 )
1186 if ( !idx.isValid() )
1189 mRowSelected = idx.row();
1199 std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
1213 if ( !dlg.exec() || !newSymbol )
1218 mGraduatedSymbol = std::move( newSymbol );
1219 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1231 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1232 if ( decimalPlaces < 0 ) decimalPlaces = 0;
1236 if ( dialog.exec() == QDialog::Accepted )
1242 if ( cbxLinkBoundaries->isChecked() )
1246 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1249 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1251 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1255 mHistogramWidget->refresh();
1261 mModel->addClass( mGraduatedSymbol.get() );
1262 mHistogramWidget->refresh();
1270 mModel->deleteRows( classIndexes );
1271 mHistogramWidget->refresh();
1277 mModel->removeAllRows();
1278 mHistogramWidget->refresh();
1285 bool ordered =
true;
1286 for (
int i = 1; i < ranges.size(); ++i )
1288 if ( ranges[i] < ranges[i - 1] )
1305 int result = QMessageBox::warning(
1307 tr(
"Link Class Boundaries" ),
1308 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1309 QMessageBox::Ok | QMessageBox::Cancel );
1310 if ( result != QMessageBox::Ok )
1312 cbxLinkBoundaries->setChecked(
false );
1315 mRenderer->sortByValue();
1319 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1321 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1329 if ( item->column() == 2 )
1331 QString label = item->text();
1332 int idx = item->row();
1333 mRenderer->updateRangeLabel( idx, label );
1339 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1340 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1341 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1342 mRenderer->updateRangeLabels();
1343 mModel->updateLabels();
1351 QItemSelectionModel *m = viewGraduated->selectionModel();
1352 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1353 if ( !selectedIndexes.isEmpty() )
1356 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1357 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1359 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1360 if ( list.size() < 3 )
1385 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1386 if ( decimalPlaces < 0 )
1388 double precision = 1.0 / std::pow( 10, decimalPlaces );
1390 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1394 return it->symbol();
1404 mModel->updateSymbology();
1406 mHistogramWidget->refresh();
1417 viewGraduated->selectionModel()->clear();
1420 cbxLinkBoundaries->setChecked(
false );
1437 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1439 mCopyBuffer.clear();
1442 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1444 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1445 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1447 mModel->addClass( *rIt );
1453void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1456 if ( !ranges.isEmpty() )
1458 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1460 else if ( mRenderer->sourceSymbol() )
1462 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1464 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1467void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1482void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1484 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1494 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1495 for (
const QModelIndex &index : selectedRows )
1497 if ( !index.isValid() )
1500 const int row = index.row();
1501 if ( !mRenderer || mRenderer->ranges().size() <= row )
1504 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1507 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1508 if ( selectedRows.count() > 1 )
1511 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1514 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
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.
int codeComplexity() const
Code complexity as the exponent in Big O notation.
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.
void setSymmetricMode(bool enabled, double symmetryPoint=0, bool symmetryAstride=false)
Defines if the symmetric mode is enables and configures its 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.
void setParameterValues(const QVariantMap &values)
Defines the values of the additional parameters.
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