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 );
432 expContext << generator->createExpressionContextScope();
464 mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(),
QgsRangeList() );
473 cboSymmetryPoint->setEditable(
true );
474 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
477 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
480 cboGraduatedMode->addItem( icon, it.key(), it.value() );
483 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
484 this->layout()->setContentsMargins( 0, 0, 0, 0 );
486 mModel =
new QgsGraduatedSymbolRendererModel(
this, screen() );
489 mExpressionWidget->setLayer(
mLayer );
491 btnChangeGraduatedSymbol->setLayer(
mLayer );
492 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
494 mSizeUnitWidget->setUnits(
496 Qgis::RenderUnit::Millimeters,
497 Qgis::RenderUnit::MapUnits,
498 Qgis::RenderUnit::Pixels,
499 Qgis::RenderUnit::Points,
500 Qgis::RenderUnit::Inches
505 spinPrecision->setClearValue( 4 );
507 spinGraduatedClasses->setShowClearButton(
false );
509 btnColorRamp->setShowRandomColorRamp(
true );
512 std::unique_ptr< QgsColorRamp > colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
515 btnColorRamp->setColorRamp( colorRamp.get() );
520 btnColorRamp->setColorRamp( ramp );
525 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
528 if ( mGraduatedSymbol )
530 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
531 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
533 methodComboBox->blockSignals(
true );
534 methodComboBox->addItem( tr(
"Color" ), ColorMode );
535 switch ( mGraduatedSymbol->type() )
539 methodComboBox->addItem( tr(
"Size" ), SizeMode );
540 minSizeSpinBox->setValue( 1 );
541 maxSizeSpinBox->setValue( 8 );
546 methodComboBox->addItem( tr(
"Size" ), SizeMode );
547 minSizeSpinBox->setValue( .1 );
548 maxSizeSpinBox->setValue( 2 );
554 methodComboBox->hide();
561 methodComboBox->blockSignals(
false );
570 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
577 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
580 updateMethodParameters();
588 mGroupBoxSymmetric->setCollapsed(
true );
591 QMenu *advMenu =
new QMenu(
this );
596 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
598 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
601 btnAdvanced->setMenu( advMenu );
603 mHistogramWidget->setLayer(
mLayer );
604 mHistogramWidget->setRenderer( mRenderer.get() );
608 mExpressionWidget->registerExpressionContextGenerator(
this );
610 mUpdateTimer.setSingleShot(
true );
611 mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout,
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
614void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
616 if ( !mGraduatedSymbol )
618 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
619 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
620 mRenderer->updateSymbols( mGraduatedSymbol.get() );
627 mParameterWidgetWrappers.clear();
632 return mRenderer.get();
644 delete mActionLevels;
645 mActionLevels =
nullptr;
666 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
668 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
692 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
694 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
710 int precision = spinPrecision->value() + 2;
711 while ( cboSymmetryPoint->count() )
712 cboSymmetryPoint->removeItem( 0 );
713 for (
int i = 0; i < ranges.count() - 1; i++ )
714 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
718 int idx = cboGraduatedMode->findData( method->
id() );
720 cboGraduatedMode->setCurrentIndex( idx );
726 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
733 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
737 ppww->setParameterValue( value,
context );
742 int nclasses = ranges.count();
743 if ( nclasses && ( updateCount || ( method && ( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) ) ) )
745 spinGraduatedClasses->setValue( ranges.count() );
749 spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
753 spinGraduatedClasses->setEnabled(
true );
757 QString attrName = mRenderer->classAttribute();
758 mExpressionWidget->setField( attrName );
759 mHistogramWidget->setSourceFieldExp( attrName );
762 if ( mRenderer->sourceSymbol() )
764 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
765 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
768 mModel->setRenderer( mRenderer.get() );
769 viewGraduated->setModel( mModel );
771 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
773 if ( mGraduatedSymbol )
775 mSizeUnitWidget->blockSignals(
true );
776 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
777 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
778 mSizeUnitWidget->blockSignals(
false );
782 methodComboBox->blockSignals(
true );
783 switch ( mRenderer->graduatedMethod() )
785 case Qgis::GraduatedMethod::Color:
787 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
788 if ( mRenderer->sourceColorRamp() )
790 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
794 case Qgis::GraduatedMethod::Size:
796 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
797 if ( !mRenderer->ranges().isEmpty() )
799 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
800 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
805 toggleMethodWidgets(
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
806 methodComboBox->blockSignals(
false );
808 viewGraduated->resizeColumnToContents( 0 );
809 viewGraduated->resizeColumnToContents( 1 );
810 viewGraduated->resizeColumnToContents( 2 );
812 mHistogramWidget->refresh();
822 mRenderer->setClassAttribute(
field );
825void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
827 const MethodMode newMethod =
static_cast< MethodMode
>( methodComboBox->currentData().toInt() );
828 toggleMethodWidgets( newMethod );
833 mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Color );
838 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
841 mRenderer->setSourceColorRamp( ramp );
848 lblColorRamp->setVisible(
false );
849 btnColorRamp->setVisible(
false );
850 lblSize->setVisible(
true );
851 minSizeSpinBox->setVisible(
true );
852 lblSize->setVisible(
true );
853 maxSizeSpinBox->setVisible(
true );
854 mSizeUnitWidget->setVisible(
true );
856 mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Size );
863void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
865 clearParameterWidgets();
867 const QString methodId = cboGraduatedMode->currentData().toString();
879 QVariant value = method->
parameterValues().value( def->name(), def->defaultValueForGui() );
884 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
887 spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
890void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
896 lblColorRamp->setVisible(
true );
897 btnColorRamp->setVisible(
true );
898 lblSize->setVisible(
false );
899 minSizeSpinBox->setVisible(
false );
900 lblSizeTo->setVisible(
false );
901 maxSizeSpinBox->setVisible(
false );
902 mSizeUnitWidget->setVisible(
false );
908 lblColorRamp->setVisible(
false );
909 btnColorRamp->setVisible(
false );
910 lblSize->setVisible(
true );
911 minSizeSpinBox->setVisible(
true );
912 lblSizeTo->setVisible(
true );
913 maxSizeSpinBox->setVisible(
true );
914 mSizeUnitWidget->setVisible(
true );
920void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
922 while ( mParametersLayout->rowCount() )
924 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
925 for ( QLayoutItem *item : {row.labelItem, row.fieldItem} )
928 if ( item->widget() )
929 item->widget()->deleteLater();
933 mParameterWidgetWrappers.clear();
941 mModel->updateSymbology();
944 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
957 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
960 mRenderer->setUsingSymbolLevels( enabled );
961 mModel->updateSymbology();
965void QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
974void QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget()
984 mSizeUnitWidget->blockSignals(
true );
985 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
986 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
987 mSizeUnitWidget->blockSignals(
false );
989 QItemSelectionModel *m = viewGraduated->selectionModel();
990 QModelIndexList selectedIndexes = m->selectedRows( 1 );
991 if ( !selectedIndexes.isEmpty() )
993 const auto constSelectedIndexes = selectedIndexes;
994 for (
const QModelIndex &idx : constSelectedIndexes )
998 int rangeIdx = idx.row();
999 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
1000 if ( selectedIndexes.count() > 1 )
1003 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
1005 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
1011 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1018void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
1020 const QString text = cboSymmetryPoint->lineEdit()->text();
1021 int index = cboSymmetryPoint->findText( text );
1024 cboSymmetryPoint->setCurrentIndex( index );
1028 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1036 mUpdateTimer.start( 500 );
1039void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl( )
1042 if ( mBlockUpdates )
1046 QString attrName = mExpressionWidget->currentField();
1047 int nclasses = spinGraduatedClasses->value();
1049 const QString methodId = cboGraduatedMode->currentData().toString();
1059 double minimum = minVal.toDouble();
1060 double maximum = maxVal.toDouble();
1061 mSymmetryPointValidator->
setBottom( minimum );
1062 mSymmetryPointValidator->
setTop( maximum );
1063 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1071 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1072 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1075 if ( mGroupBoxSymmetric->isChecked() )
1078 bool astride = cbxAstride->isChecked();
1082 QVariantMap parameterValues;
1083 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1088 mRenderer->setClassificationMethod( method );
1091 mRenderer->setClassAttribute( attrName );
1097 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 ) )
1103 if ( methodComboBox->currentData() == ColorMode )
1105 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1108 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1111 mRenderer->setSourceColorRamp( ramp.release() );
1115 mRenderer->setSourceColorRamp(
nullptr );
1118 mRenderer->updateClasses(
mLayer, nclasses );
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() );
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 ) decimalPlaces = 0;
1249 if ( dialog.exec() == QDialog::Accepted )
1255 if ( cbxLinkBoundaries->isChecked() )
1259 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1262 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1264 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1268 mHistogramWidget->refresh();
1274 mModel->addClass( mGraduatedSymbol.get() );
1275 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 );
1323 if ( result != QMessageBox::Ok )
1325 cbxLinkBoundaries->setChecked(
false );
1328 mRenderer->sortByValue();
1332 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1334 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1342 if ( item->column() == 2 )
1344 QString label = item->text();
1345 int idx = item->row();
1346 mRenderer->updateRangeLabel( idx, label );
1352 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1353 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1354 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1355 mRenderer->updateRangeLabels();
1356 mModel->updateLabels();
1364 QItemSelectionModel *m = viewGraduated->selectionModel();
1365 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1366 if ( !selectedIndexes.isEmpty() )
1369 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1370 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1372 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1373 if ( list.size() < 3 )
1398 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1399 if ( decimalPlaces < 0 )
1401 double precision = 1.0 / std::pow( 10, decimalPlaces );
1403 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1407 return it->symbol();
1417 mModel->updateSymbology();
1419 mHistogramWidget->refresh();
1430 viewGraduated->selectionModel()->clear();
1433 cbxLinkBoundaries->setChecked(
false );
1450 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1452 mCopyBuffer.clear();
1455 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1457 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1458 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1460 mModel->addClass( *rIt );
1466void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1469 if ( !ranges.isEmpty() )
1471 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1473 else if ( mRenderer->sourceSymbol() )
1475 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1477 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1480void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1495void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1497 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1507 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1508 for (
const QModelIndex &index : selectedRows )
1510 if ( !index.isValid() )
1513 const int row = index.row();
1514 if ( !mRenderer || mRenderer->ranges().size() <= row )
1517 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1520 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1521 if ( selectedRows.count() > 1 )
1524 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1527 mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
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.
QgsProcessingParameterDefinitions parameterDefinitions() const
Returns the list of parameters.
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.
Abstract interface for generating an expression context scope.
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.
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
@ Date
Date or datetime fields.
@ Numeric
All numeric fields.
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 ...
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.
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.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
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