19#include <QStandardItemModel>
20#include <QStandardItem>
29#include "moc_qgsgraduatedsymbolrendererwidget.cpp"
66QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, QScreen *screen ) : QAbstractItemModel( parent )
67 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
76 if ( !mRenderer->ranges().isEmpty() )
78 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
89 if ( !renderer->
ranges().isEmpty() )
91 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
102void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
104 if ( !mRenderer )
return;
105 int idx = mRenderer->
ranges().size();
106 beginInsertRows( QModelIndex(), idx, idx );
107 mRenderer->addClass( symbol );
111void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
117 int idx = mRenderer->ranges().size();
118 beginInsertRows( QModelIndex(), idx, idx );
119 mRenderer->addClass( range );
123QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
125 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
130 return mRenderer->ranges().value( index.row() );
133Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
135 if ( !index.isValid() )
137 return Qt::ItemIsDropEnabled;
140 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
142 if ( index.column() == 2 )
144 flags |= Qt::ItemIsEditable;
150Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
152 return Qt::MoveAction;
155QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
157 if ( !index.isValid() || !mRenderer )
return QVariant();
161 if ( role == Qt::CheckStateRole && index.column() == 0 )
163 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
165 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
167 switch ( index.column() )
171 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
172 if ( decimalPlaces < 0 ) decimalPlaces = 0;
173 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
176 return range.
label();
181 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
186 else if ( role == Qt::TextAlignmentRole )
188 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) : static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
190 else if ( role == Qt::EditRole )
192 switch ( index.column() )
196 return range.
label();
205bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
207 if ( !index.isValid() )
210 if ( index.column() == 0 && role == Qt::CheckStateRole )
212 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
213 emit dataChanged( index, index );
217 if ( role != Qt::EditRole )
220 switch ( index.column() )
225 mRenderer->updateRangeLabel( index.row(), value.toString() );
231 emit dataChanged( index, index );
235QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
237 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
240 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
241 return lst.value( section );
246int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
248 if ( parent.isValid() || !mRenderer )
252 return mRenderer->ranges().size();
255int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
261QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
263 if ( hasIndex( row, column, parent ) )
265 return createIndex( row, column );
267 return QModelIndex();
270QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
273 return QModelIndex();
276QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
279 types << mMimeFormat;
283QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
285 QMimeData *mimeData =
new QMimeData();
286 QByteArray encodedData;
288 QDataStream stream( &encodedData, QIODevice::WriteOnly );
291 const auto constIndexes = indexes;
292 for (
const QModelIndex &index : constIndexes )
294 if ( !index.isValid() || index.column() != 0 )
297 stream << index.row();
299 mimeData->setData( mMimeFormat, encodedData );
303bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
307 if ( action != Qt::MoveAction )
return true;
309 if ( !data->hasFormat( mMimeFormat ) )
return false;
311 QByteArray encodedData = data->data( mMimeFormat );
312 QDataStream stream( &encodedData, QIODevice::ReadOnly );
315 while ( !stream.atEnd() )
322 int to = parent.row();
325 if ( to == -1 ) to = mRenderer->ranges().size();
326 for (
int i = rows.size() - 1; i >= 0; i-- )
328 QgsDebugMsgLevel( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ), 2 );
331 if ( rows[i] < t ) t--;
332 mRenderer->moveClass( rows[i], t );
334 for (
int j = 0; j < i; j++ )
336 if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
339 if ( rows[i] < to ) to--;
341 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
346void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
348 for (
int i = rows.size() - 1; i >= 0; i-- )
350 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
351 mRenderer->deleteClass( rows[i] );
356void QgsGraduatedSymbolRendererModel::removeAllRows()
358 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
359 mRenderer->deleteAllClasses();
363void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
371 mRenderer->sortByValue( order );
373 else if ( column == 2 )
375 mRenderer->sortByLabel( order );
378 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
381void QgsGraduatedSymbolRendererModel::updateSymbology()
383 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
386void QgsGraduatedSymbolRendererModel::updateLabels()
388 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
392QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
396void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
398 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
400 QStyleOption opt( *option );
401 opt.rect.setLeft( 0 );
403 opt.rect.setHeight( 0 );
404 if ( widget ) opt.rect.setRight( widget->width() );
405 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
408 QProxyStyle::drawPrimitive( element, option, painter, widget );
426 expContext = lMapCanvas->createExpressionContext();
460 mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(),
QgsRangeList() );
469 cboSymmetryPoint->setEditable(
true );
470 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
473 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
476 cboGraduatedMode->addItem( icon, it.key(), it.value() );
479 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
480 this->layout()->setContentsMargins( 0, 0, 0, 0 );
482 mModel =
new QgsGraduatedSymbolRendererModel(
this, screen() );
485 mExpressionWidget->setLayer(
mLayer );
487 btnChangeGraduatedSymbol->setLayer(
mLayer );
488 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
490 mSizeUnitWidget->setUnits(
501 spinPrecision->setClearValue( 4 );
503 spinGraduatedClasses->setShowClearButton(
false );
505 btnColorRamp->setShowRandomColorRamp(
true );
508 std::unique_ptr< QgsColorRamp > colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
511 btnColorRamp->setColorRamp( colorRamp.get() );
516 btnColorRamp->setColorRamp( ramp );
521 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
524 if ( mGraduatedSymbol )
526 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
527 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
529 methodComboBox->blockSignals(
true );
530 methodComboBox->addItem( tr(
"Color" ), ColorMode );
531 switch ( mGraduatedSymbol->type() )
535 methodComboBox->addItem( tr(
"Size" ), SizeMode );
536 minSizeSpinBox->setValue( 1 );
537 maxSizeSpinBox->setValue( 8 );
542 methodComboBox->addItem( tr(
"Size" ), SizeMode );
543 minSizeSpinBox->setValue( .1 );
544 maxSizeSpinBox->setValue( 2 );
550 methodComboBox->hide();
557 methodComboBox->blockSignals(
false );
566 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
573 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
576 updateMethodParameters();
584 mGroupBoxSymmetric->setCollapsed(
true );
587 QMenu *advMenu =
new QMenu(
this );
592 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
594 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
597 btnAdvanced->setMenu( advMenu );
599 mHistogramWidget->setLayer(
mLayer );
600 mHistogramWidget->setRenderer( mRenderer.get() );
604 mExpressionWidget->registerExpressionContextGenerator(
this );
606 mUpdateTimer.setSingleShot(
true );
607 mUpdateTimer.connect( &mUpdateTimer, &QTimer::timeout,
this, &QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl );
610void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
612 if ( !mGraduatedSymbol )
614 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
615 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
616 mRenderer->updateSymbols( mGraduatedSymbol.get() );
623 mParameterWidgetWrappers.clear();
628 return mRenderer.get();
640 delete mActionLevels;
641 mActionLevels =
nullptr;
662 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
664 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
688 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
690 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
706 int precision = spinPrecision->value() + 2;
707 while ( cboSymmetryPoint->count() )
708 cboSymmetryPoint->removeItem( 0 );
709 for (
int i = 0; i < ranges.count() - 1; i++ )
710 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
714 int idx = cboGraduatedMode->findData( method->
id() );
716 cboGraduatedMode->setCurrentIndex( idx );
722 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
729 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
733 ppww->setParameterValue( value,
context );
738 int nclasses = ranges.count();
741 spinGraduatedClasses->setValue( ranges.count() );
749 spinGraduatedClasses->setEnabled(
true );
753 QString attrName = mRenderer->classAttribute();
754 mExpressionWidget->setField( attrName );
755 mHistogramWidget->setSourceFieldExp( attrName );
758 if ( mRenderer->sourceSymbol() )
760 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
761 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
764 mModel->setRenderer( mRenderer.get() );
765 viewGraduated->setModel( mModel );
767 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
769 if ( mGraduatedSymbol )
771 mSizeUnitWidget->blockSignals(
true );
772 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
773 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
774 mSizeUnitWidget->blockSignals(
false );
778 methodComboBox->blockSignals(
true );
779 switch ( mRenderer->graduatedMethod() )
783 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
784 if ( mRenderer->sourceColorRamp() )
786 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
792 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
793 if ( !mRenderer->ranges().isEmpty() )
795 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
796 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
801 toggleMethodWidgets(
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
802 methodComboBox->blockSignals(
false );
804 viewGraduated->resizeColumnToContents( 0 );
805 viewGraduated->resizeColumnToContents( 1 );
806 viewGraduated->resizeColumnToContents( 2 );
808 mHistogramWidget->refresh();
818 mRenderer->setClassAttribute( field );
821void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
823 const MethodMode newMethod =
static_cast< MethodMode
>( methodComboBox->currentData().toInt() );
824 toggleMethodWidgets( newMethod );
834 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
837 mRenderer->setSourceColorRamp( ramp );
844 lblColorRamp->setVisible(
false );
845 btnColorRamp->setVisible(
false );
846 lblSize->setVisible(
true );
847 minSizeSpinBox->setVisible(
true );
848 lblSize->setVisible(
true );
849 maxSizeSpinBox->setVisible(
true );
850 mSizeUnitWidget->setVisible(
true );
859void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
861 clearParameterWidgets();
863 const QString methodId = cboGraduatedMode->currentData().toString();
875 QVariant value = method->
parameterValues().value( def->name(), def->defaultValueForGui() );
880 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
886void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
892 lblColorRamp->setVisible(
true );
893 btnColorRamp->setVisible(
true );
894 lblSize->setVisible(
false );
895 minSizeSpinBox->setVisible(
false );
896 lblSizeTo->setVisible(
false );
897 maxSizeSpinBox->setVisible(
false );
898 mSizeUnitWidget->setVisible(
false );
904 lblColorRamp->setVisible(
false );
905 btnColorRamp->setVisible(
false );
906 lblSize->setVisible(
true );
907 minSizeSpinBox->setVisible(
true );
908 lblSizeTo->setVisible(
true );
909 maxSizeSpinBox->setVisible(
true );
910 mSizeUnitWidget->setVisible(
true );
916void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
918 while ( mParametersLayout->rowCount() )
920 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
921 for ( QLayoutItem *item : {row.labelItem, row.fieldItem} )
924 QWidget *widget = item->widget();
930 mParameterWidgetWrappers.clear();
938 mModel->updateSymbology();
941 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
954 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
957 mRenderer->setUsingSymbolLevels( enabled );
958 mModel->updateSymbology();
964 mGraduatedSymbol.reset( widget->
symbol()->
clone() );
971 mSizeUnitWidget->blockSignals(
true );
972 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
973 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
974 mSizeUnitWidget->blockSignals(
false );
976 QItemSelectionModel *m = viewGraduated->selectionModel();
977 QModelIndexList selectedIndexes = m->selectedRows( 1 );
978 if ( !selectedIndexes.isEmpty() )
980 const auto constSelectedIndexes = selectedIndexes;
981 for (
const QModelIndex &idx : constSelectedIndexes )
985 int rangeIdx = idx.row();
986 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
987 if ( selectedIndexes.count() > 1 )
990 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
992 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
998 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1005void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
1007 const QString text = cboSymmetryPoint->lineEdit()->text();
1008 int index = cboSymmetryPoint->findText( text );
1011 cboSymmetryPoint->setCurrentIndex( index );
1015 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1023 mUpdateTimer.start( 500 );
1026void QgsGraduatedSymbolRendererWidget::classifyGraduatedImpl( )
1029 if ( mBlockUpdates )
1033 QString attrName = mExpressionWidget->currentField();
1034 int nclasses = spinGraduatedClasses->value();
1036 const QString methodId = cboGraduatedMode->currentData().toString();
1046 double minimum = minVal.toDouble();
1047 double maximum = maxVal.toDouble();
1048 mSymmetryPointValidator->
setBottom( minimum );
1049 mSymmetryPointValidator->
setTop( maximum );
1050 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1058 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1059 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1062 if ( mGroupBoxSymmetric->isChecked() )
1065 bool astride = cbxAstride->isChecked();
1069 QVariantMap parameterValues;
1070 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1071 parameterValues.insert( ppww->parameterDefinition()->name(), ppww->parameterValue() );
1075 mRenderer->setClassificationMethod( method );
1078 mRenderer->setClassAttribute( attrName );
1084 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 ) )
1090 if ( methodComboBox->currentData() == ColorMode )
1092 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1095 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1098 mRenderer->setSourceColorRamp( ramp.release() );
1102 mRenderer->setSourceColorRamp(
nullptr );
1106 mRenderer->updateClasses(
mLayer, nclasses, error );
1108 if ( !error.isEmpty() )
1109 QMessageBox::critical(
this, tr(
"Apply Classification" ), error );
1111 if ( methodComboBox->currentData() == SizeMode )
1112 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1114 mRenderer->calculateLabelPrecision();
1122 std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
1126 mRenderer->updateColorRamp( ramp.release() );
1127 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1133 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1134 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1139int QgsRendererPropertiesDialog::currentRangeRow()
1141 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1142 if ( !idx.isValid() )
1151 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1153 const auto constSelectedRows = selectedRows;
1154 for (
const QModelIndex &r : constSelectedRows )
1158 rows.append( r.row() );
1167 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1168 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1170 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1179 if ( idx.isValid() && idx.column() == 0 )
1181 if ( idx.isValid() && idx.column() == 1 )
1187 if ( !idx.isValid() )
1190 mRowSelected = idx.row();
1200 std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
1214 if ( !dlg.exec() || !newSymbol )
1219 mGraduatedSymbol = std::move( newSymbol );
1220 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1232 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1233 if ( decimalPlaces < 0 ) decimalPlaces = 0;
1237 if ( dialog.exec() == QDialog::Accepted )
1243 if ( cbxLinkBoundaries->isChecked() )
1247 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1250 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1252 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1256 mHistogramWidget->refresh();
1262 mModel->addClass( mGraduatedSymbol.get() );
1263 mHistogramWidget->refresh();
1271 mModel->deleteRows( classIndexes );
1272 mHistogramWidget->refresh();
1278 mModel->removeAllRows();
1279 mHistogramWidget->refresh();
1286 bool ordered =
true;
1287 for (
int i = 1; i < ranges.size(); ++i )
1289 if ( ranges[i] < ranges[i - 1] )
1306 int result = QMessageBox::warning(
1308 tr(
"Link Class Boundaries" ),
1309 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1310 QMessageBox::Ok | QMessageBox::Cancel );
1311 if ( result != QMessageBox::Ok )
1313 cbxLinkBoundaries->setChecked(
false );
1316 mRenderer->sortByValue();
1320 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1322 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1330 if ( item->column() == 2 )
1332 QString label = item->text();
1333 int idx = item->row();
1334 mRenderer->updateRangeLabel( idx, label );
1340 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1341 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1342 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1343 mRenderer->updateRangeLabels();
1344 mModel->updateLabels();
1352 QItemSelectionModel *m = viewGraduated->selectionModel();
1353 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1354 if ( !selectedIndexes.isEmpty() )
1357 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1358 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1360 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1361 if ( list.size() < 3 )
1386 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1387 if ( decimalPlaces < 0 )
1389 double precision = 1.0 / std::pow( 10, decimalPlaces );
1391 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1395 return it->symbol();
1405 mModel->updateSymbology();
1407 mHistogramWidget->refresh();
1418 viewGraduated->selectionModel()->clear();
1421 cbxLinkBoundaries->setChecked(
false );
1438 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1440 mCopyBuffer.clear();
1443 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1445 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1446 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1448 mModel->addClass( *rIt );
1454void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1457 if ( !ranges.isEmpty() )
1459 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1461 else if ( mRenderer->sourceSymbol() )
1463 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1465 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1468void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1483void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1485 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1495 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1496 for (
const QModelIndex &index : selectedRows )
1498 if ( !index.isValid() )
1501 const int row = index.row();
1502 if ( !mRenderer || mRenderer->ranges().size() <= row )
1505 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1508 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1509 if ( selectedRows.count() > 1 )
1512 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1515 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