18 #include <QMessageBox>
19 #include <QStandardItemModel>
20 #include <QStandardItem>
63 QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent ) : QAbstractItemModel( parent )
64 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
72 if ( !mRenderer->ranges().isEmpty() )
74 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
85 if ( !renderer->
ranges().isEmpty() )
87 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
98 void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
100 if ( !mRenderer )
return;
101 int idx = mRenderer->
ranges().size();
102 beginInsertRows( QModelIndex(), idx, idx );
103 mRenderer->addClass( symbol );
107 void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
113 int idx = mRenderer->ranges().size();
114 beginInsertRows( QModelIndex(), idx, idx );
115 mRenderer->addClass( range );
119 QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
121 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
126 return mRenderer->ranges().value( index.row() );
129 Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
131 if ( !index.isValid() )
133 return Qt::ItemIsDropEnabled;
136 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
138 if ( index.column() == 2 )
140 flags |= Qt::ItemIsEditable;
146 Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
148 return Qt::MoveAction;
151 QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
153 if ( !index.isValid() || !mRenderer )
return QVariant();
157 if ( role == Qt::CheckStateRole && index.column() == 0 )
159 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
161 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
163 switch ( index.column() )
167 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
168 if ( decimalPlaces < 0 ) decimalPlaces = 0;
169 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
172 return range.
label();
177 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
182 else if ( role == Qt::TextAlignmentRole )
184 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) :
static_cast<Qt::Alignment::Int
>( Qt::AlignLeft );
186 else if ( role == Qt::EditRole )
188 switch ( index.column() )
192 return range.
label();
201 bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
203 if ( !index.isValid() )
206 if ( index.column() == 0 && role == Qt::CheckStateRole )
208 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
209 emit dataChanged( index, index );
213 if ( role != Qt::EditRole )
216 switch ( index.column() )
221 mRenderer->updateRangeLabel( index.row(), value.toString() );
227 emit dataChanged( index, index );
231 QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
233 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
236 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
237 return lst.value( section );
242 int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
244 if ( parent.isValid() || !mRenderer )
248 return mRenderer->ranges().size();
251 int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
257 QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
259 if ( hasIndex( row, column, parent ) )
261 return createIndex( row, column );
263 return QModelIndex();
266 QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
269 return QModelIndex();
272 QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
275 types << mMimeFormat;
279 QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
281 QMimeData *mimeData =
new QMimeData();
282 QByteArray encodedData;
284 QDataStream stream( &encodedData, QIODevice::WriteOnly );
287 const auto constIndexes = indexes;
288 for (
const QModelIndex &index : constIndexes )
290 if ( !index.isValid() || index.column() != 0 )
293 stream << index.row();
295 mimeData->setData( mMimeFormat, encodedData );
299 bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
303 if ( action != Qt::MoveAction )
return true;
305 if ( !data->hasFormat( mMimeFormat ) )
return false;
307 QByteArray encodedData = data->data( mMimeFormat );
308 QDataStream stream( &encodedData, QIODevice::ReadOnly );
311 while ( !stream.atEnd() )
318 int to = parent.row();
321 if ( to == -1 ) to = mRenderer->ranges().size();
322 for (
int i = rows.size() - 1; i >= 0; i-- )
324 QgsDebugMsg( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ) );
327 if ( rows[i] < t ) t--;
328 mRenderer->moveClass( rows[i], t );
330 for (
int j = 0; j < i; j++ )
332 if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
335 if ( rows[i] < to ) to--;
337 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
342 void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
344 for (
int i = rows.size() - 1; i >= 0; i-- )
346 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
347 mRenderer->deleteClass( rows[i] );
352 void QgsGraduatedSymbolRendererModel::removeAllRows()
354 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
355 mRenderer->deleteAllClasses();
359 void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
367 mRenderer->sortByValue( order );
369 else if ( column == 2 )
371 mRenderer->sortByLabel( order );
374 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
377 void QgsGraduatedSymbolRendererModel::updateSymbology()
379 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
382 void QgsGraduatedSymbolRendererModel::updateLabels()
384 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
388 QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
392 void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
394 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
396 QStyleOption opt( *option );
397 opt.rect.setLeft( 0 );
399 opt.rect.setHeight( 0 );
400 if ( widget ) opt.rect.setRight( widget->width() );
401 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
404 QProxyStyle::drawPrimitive( element, option, painter, widget );
429 expContext << generator->createExpressionContextScope();
461 mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(),
QgsRangeList() );
470 cboSymmetryPoint->setEditable(
true );
471 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
474 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
477 cboGraduatedMode->addItem( icon, it.key(), it.value() );
480 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
481 this->layout()->setContentsMargins( 0, 0, 0, 0 );
483 mModel =
new QgsGraduatedSymbolRendererModel(
this );
486 mExpressionWidget->setLayer(
mLayer );
488 btnChangeGraduatedSymbol->setLayer(
mLayer );
489 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
496 spinPrecision->setClearValue( 4 );
498 spinGraduatedClasses->setShowClearButton(
false );
500 btnColorRamp->setShowRandomColorRamp(
true );
503 QString defaultColorRamp =
QgsProject::instance()->
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ), QString() );
504 if ( !defaultColorRamp.isEmpty() )
506 btnColorRamp->setColorRampFromName( defaultColorRamp );
511 btnColorRamp->setColorRamp( ramp );
516 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
519 if ( mGraduatedSymbol )
521 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
522 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
524 methodComboBox->blockSignals(
true );
525 methodComboBox->addItem( tr(
"Color" ), ColorMode );
526 switch ( mGraduatedSymbol->type() )
530 methodComboBox->addItem( tr(
"Size" ), SizeMode );
531 minSizeSpinBox->setValue( 1 );
532 maxSizeSpinBox->setValue( 8 );
537 methodComboBox->addItem( tr(
"Size" ), SizeMode );
538 minSizeSpinBox->setValue( .1 );
539 maxSizeSpinBox->setValue( 2 );
545 methodComboBox->hide();
552 methodComboBox->blockSignals(
false );
561 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
568 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
576 mGroupBoxSymmetric->setCollapsed(
true );
579 QMenu *advMenu =
new QMenu(
this );
584 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
586 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
589 btnAdvanced->setMenu( advMenu );
591 mHistogramWidget->setLayer(
mLayer );
592 mHistogramWidget->setRenderer( mRenderer.get() );
596 mExpressionWidget->registerExpressionContextGenerator(
this );
599 void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
601 if ( !mGraduatedSymbol )
603 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
604 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
605 mRenderer->updateSymbols( mGraduatedSymbol.get() );
612 mParameterWidgetWrappers.clear();
617 return mRenderer.get();
629 delete mActionLevels;
630 mActionLevels =
nullptr;
651 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
653 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
677 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
679 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
694 int precision = spinPrecision->value() + 2;
695 while ( cboSymmetryPoint->count() )
696 cboSymmetryPoint->removeItem( 0 );
697 for (
int i = 0; i < ranges.count() - 1; i++ )
698 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
702 int idx = cboGraduatedMode->findData( method->
id() );
704 cboGraduatedMode->setCurrentIndex( idx );
710 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
717 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
721 ppww->setParameterValue( value,
context );
726 int nclasses = ranges.count();
727 if ( nclasses && updateCount )
729 spinGraduatedClasses->setValue( ranges.count() );
733 QString attrName = mRenderer->classAttribute();
734 mExpressionWidget->setField( attrName );
735 mHistogramWidget->setSourceFieldExp( attrName );
738 if ( mRenderer->sourceSymbol() )
740 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
741 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
744 mModel->setRenderer( mRenderer.get() );
745 viewGraduated->setModel( mModel );
747 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
749 if ( mGraduatedSymbol )
751 mSizeUnitWidget->blockSignals(
true );
752 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
753 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
754 mSizeUnitWidget->blockSignals(
false );
758 methodComboBox->blockSignals(
true );
759 switch ( mRenderer->graduatedMethod() )
763 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
764 if ( mRenderer->sourceColorRamp() )
766 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
772 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
773 if ( !mRenderer->ranges().isEmpty() )
775 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
776 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
781 toggleMethodWidgets(
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
782 methodComboBox->blockSignals(
false );
784 viewGraduated->resizeColumnToContents( 0 );
785 viewGraduated->resizeColumnToContents( 1 );
786 viewGraduated->resizeColumnToContents( 2 );
788 mHistogramWidget->refresh();
796 mRenderer->setClassAttribute(
field );
799 void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
801 const MethodMode newMethod =
static_cast< MethodMode
>( methodComboBox->currentData().toInt() );
802 toggleMethodWidgets( newMethod );
812 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
815 mRenderer->setSourceColorRamp( ramp );
822 lblColorRamp->setVisible(
false );
823 btnColorRamp->setVisible(
false );
824 lblSize->setVisible(
true );
825 minSizeSpinBox->setVisible(
true );
826 lblSize->setVisible(
true );
827 maxSizeSpinBox->setVisible(
true );
828 mSizeUnitWidget->setVisible(
true );
837 void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
839 clearParameterWidgets();
841 const QString methodId = cboGraduatedMode->currentData().toString();
853 QVariant value = method->
parameterValues().value( def->name(), def->defaultValueForGui() );
858 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
862 void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
868 lblColorRamp->setVisible(
true );
869 btnColorRamp->setVisible(
true );
870 lblSize->setVisible(
false );
871 minSizeSpinBox->setVisible(
false );
872 lblSizeTo->setVisible(
false );
873 maxSizeSpinBox->setVisible(
false );
874 mSizeUnitWidget->setVisible(
false );
880 lblColorRamp->setVisible(
false );
881 btnColorRamp->setVisible(
false );
882 lblSize->setVisible(
true );
883 minSizeSpinBox->setVisible(
true );
884 lblSizeTo->setVisible(
true );
885 maxSizeSpinBox->setVisible(
true );
886 mSizeUnitWidget->setVisible(
true );
892 void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
894 while ( mParametersLayout->rowCount() )
896 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
897 for ( QLayoutItem *item : QList<QLayoutItem *>( {row.labelItem, row.fieldItem} ) )
900 if ( item->widget() )
901 item->widget()->deleteLater();
905 mParameterWidgetWrappers.clear();
913 mModel->updateSymbology();
916 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
929 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
932 mRenderer->setUsingSymbolLevels( enabled );
933 mModel->updateSymbology();
937 void QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
946 void QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget()
956 mSizeUnitWidget->blockSignals(
true );
957 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
958 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
959 mSizeUnitWidget->blockSignals(
false );
961 QItemSelectionModel *m = viewGraduated->selectionModel();
962 QModelIndexList selectedIndexes = m->selectedRows( 1 );
963 if ( !selectedIndexes.isEmpty() )
965 const auto constSelectedIndexes = selectedIndexes;
966 for (
const QModelIndex &idx : constSelectedIndexes )
970 int rangeIdx = idx.row();
971 QgsSymbol *newRangeSymbol = mGraduatedSymbol->clone();
972 if ( selectedIndexes.count() > 1 )
975 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
977 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
983 mRenderer->updateSymbols( mGraduatedSymbol.get() );
990 void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
992 const QString text = cboSymmetryPoint->lineEdit()->text();
993 int index = cboSymmetryPoint->findText( text );
996 cboSymmetryPoint->setCurrentIndex( index );
1000 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1010 QString attrName = mExpressionWidget->currentField();
1011 int nclasses = spinGraduatedClasses->value();
1013 const QString methodId = cboGraduatedMode->currentData().toString();
1023 double minimum = minVal.toDouble();
1024 double maximum = maxVal.toDouble();
1025 mSymmetryPointValidator->
setBottom( minimum );
1026 mSymmetryPointValidator->
setTop( maximum );
1027 mSymmetryPointValidator->
setMaxDecimals( spinPrecision->value() );
1035 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1036 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1039 if ( mGroupBoxSymmetric->isChecked() )
1042 bool astride = cbxAstride->isChecked();
1046 QVariantMap parameterValues;
1047 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1052 mRenderer->setClassificationMethod( method );
1055 mRenderer->setClassAttribute( attrName );
1061 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 ) )
1067 if ( methodComboBox->currentData() == ColorMode )
1069 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1072 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1075 mRenderer->setSourceColorRamp( ramp.release() );
1079 mRenderer->setSourceColorRamp(
nullptr );
1082 mRenderer->updateClasses(
mLayer, nclasses );
1084 if ( methodComboBox->currentData() == SizeMode )
1085 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1087 mRenderer->calculateLabelPrecision();
1095 std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
1099 mRenderer->updateColorRamp( ramp.release() );
1100 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1106 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1107 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1112 int QgsRendererPropertiesDialog::currentRangeRow()
1114 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1115 if ( !idx.isValid() )
1124 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1126 const auto constSelectedRows = selectedRows;
1127 for (
const QModelIndex &r : constSelectedRows )
1131 rows.append( r.row() );
1140 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1141 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1143 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1152 if ( idx.isValid() && idx.column() == 0 )
1154 if ( idx.isValid() && idx.column() == 1 )
1160 if ( !idx.isValid() )
1163 mRowSelected = idx.row();
1173 std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
1190 if ( !dlg.exec() || !newSymbol )
1195 mGraduatedSymbol = std::move( newSymbol );
1196 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1208 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1209 if ( decimalPlaces < 0 ) decimalPlaces = 0;
1213 if ( dialog.exec() == QDialog::Accepted )
1222 mRenderer->updateRangeUpperValue( rangeIdx, upperValue );
1223 mRenderer->updateRangeLowerValue( rangeIdx, lowerValue );
1226 if ( cbxLinkBoundaries->isChecked() )
1230 mRenderer->updateRangeUpperValue( rangeIdx - 1, lowerValue );
1233 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1235 mRenderer->updateRangeLowerValue( rangeIdx + 1, upperValue );
1239 mHistogramWidget->refresh();
1245 mModel->addClass( mGraduatedSymbol.get() );
1246 mHistogramWidget->refresh();
1254 mModel->deleteRows( classIndexes );
1255 mHistogramWidget->refresh();
1261 mModel->removeAllRows();
1262 mHistogramWidget->refresh();
1269 bool ordered =
true;
1270 for (
int i = 1; i < ranges.size(); ++i )
1272 if ( ranges[i] < ranges[i - 1] )
1289 int result = QMessageBox::warning(
1291 tr(
"Link Class Boundaries" ),
1292 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1293 QMessageBox::Ok | QMessageBox::Cancel );
1294 if ( result != QMessageBox::Ok )
1296 cbxLinkBoundaries->setChecked(
false );
1299 mRenderer->sortByValue();
1303 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1305 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1313 if ( item->column() == 2 )
1315 QString label = item->text();
1316 int idx = item->row();
1317 mRenderer->updateRangeLabel( idx, label );
1323 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1324 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1325 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1326 mRenderer->updateRangeLabels();
1327 mModel->updateLabels();
1335 QItemSelectionModel *m = viewGraduated->selectionModel();
1336 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1337 if ( !selectedIndexes.isEmpty() )
1340 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1341 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1343 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1344 if ( list.size() < 3 )
1369 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1370 if ( decimalPlaces < 0 )
1372 double precision = 1.0 / std::pow( 10, decimalPlaces );
1374 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1378 return it->symbol();
1388 mModel->updateSymbology();
1390 mHistogramWidget->refresh();
1401 viewGraduated->selectionModel()->clear();
1404 cbxLinkBoundaries->setChecked(
false );
1421 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1423 mCopyBuffer.clear();
1426 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1428 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1429 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1431 mModel->addClass( *rIt );
1437 void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1440 if ( !ranges.isEmpty() )
1442 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1444 else if ( mRenderer->sourceSymbol() )
1446 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1448 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1451 void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1466 void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1468 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1478 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1479 for (
const QModelIndex &index : selectedRows )
1481 if ( !index.isValid() )
1484 const int row = index.row();
1485 if ( !mRenderer || mRenderer->ranges().size() <= row )
1488 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1491 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1492 if ( selectedRows.count() > 1 )
1495 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1498 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.
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
static QgsProcessingGuiRegistry * processingGuiRegistry()
Returns the global processing gui registry, used for registering the GUI behavior of processing algor...
QString upperValue() const
QString lowerValue() const
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.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...
QgsSymbol * symbol() const
double upperValue() const
double lowerValue() const
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)
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.
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
void setColor(const QColor &color)
Sets the color for the symbol.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
@ RenderPoints
Points (e.g., for font sizes)
@ RenderMillimeters
Millimeters.
@ RenderMapUnits
Map units.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
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.
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
QList< QgsRendererRange > QgsRangeList