18 #include <QMessageBox>
19 #include <QStandardItemModel>
20 #include <QStandardItem>
64 QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent ) : QAbstractItemModel( parent )
65 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
73 if ( !mRenderer->ranges().isEmpty() )
75 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
86 if ( !renderer->
ranges().isEmpty() )
88 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
99 void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
101 if ( !mRenderer )
return;
102 int idx = mRenderer->
ranges().size();
103 beginInsertRows( QModelIndex(), idx, idx );
104 mRenderer->addClass( symbol );
108 void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
114 int idx = mRenderer->ranges().size();
115 beginInsertRows( QModelIndex(), idx, idx );
116 mRenderer->addClass( range );
120 QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
122 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
127 return mRenderer->ranges().value( index.row() );
130 Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
132 if ( !index.isValid() )
134 return Qt::ItemIsDropEnabled;
137 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
139 if ( index.column() == 2 )
141 flags |= Qt::ItemIsEditable;
147 Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
149 return Qt::MoveAction;
152 QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
154 if ( !index.isValid() || !mRenderer )
return QVariant();
158 if ( role == Qt::CheckStateRole && index.column() == 0 )
160 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
162 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
164 switch ( index.column() )
168 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
169 if ( decimalPlaces < 0 ) decimalPlaces = 0;
170 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
173 return range.
label();
178 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
183 else if ( role == Qt::TextAlignmentRole )
185 return ( index.column() == 0 ) ?
static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter ) :
static_cast<Qt::Alignment::Int
>( Qt::AlignLeft );
187 else if ( role == Qt::EditRole )
189 switch ( index.column() )
193 return range.
label();
202 bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
204 if ( !index.isValid() )
207 if ( index.column() == 0 && role == Qt::CheckStateRole )
209 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
210 emit dataChanged( index, index );
214 if ( role != Qt::EditRole )
217 switch ( index.column() )
222 mRenderer->updateRangeLabel( index.row(), value.toString() );
228 emit dataChanged( index, index );
232 QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
234 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
237 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
238 return lst.value( section );
243 int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
245 if ( parent.isValid() || !mRenderer )
249 return mRenderer->ranges().size();
252 int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
258 QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
260 if ( hasIndex( row, column, parent ) )
262 return createIndex( row, column );
264 return QModelIndex();
267 QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
270 return QModelIndex();
273 QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
276 types << mMimeFormat;
280 QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
282 QMimeData *mimeData =
new QMimeData();
283 QByteArray encodedData;
285 QDataStream stream( &encodedData, QIODevice::WriteOnly );
288 const auto constIndexes = indexes;
289 for (
const QModelIndex &index : constIndexes )
291 if ( !index.isValid() || index.column() != 0 )
294 stream << index.row();
296 mimeData->setData( mMimeFormat, encodedData );
300 bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
304 if ( action != Qt::MoveAction )
return true;
306 if ( !data->hasFormat( mMimeFormat ) )
return false;
308 QByteArray encodedData = data->data( mMimeFormat );
309 QDataStream stream( &encodedData, QIODevice::ReadOnly );
312 while ( !stream.atEnd() )
319 int to = parent.row();
322 if ( to == -1 ) to = mRenderer->ranges().size();
323 for (
int i = rows.size() - 1; i >= 0; i-- )
325 QgsDebugMsg( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ) );
328 if ( rows[i] < t ) t--;
329 mRenderer->moveClass( rows[i], t );
331 for (
int j = 0; j < i; j++ )
333 if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
336 if ( rows[i] < to ) to--;
338 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
343 void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
345 for (
int i = rows.size() - 1; i >= 0; i-- )
347 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
348 mRenderer->deleteClass( rows[i] );
353 void QgsGraduatedSymbolRendererModel::removeAllRows()
355 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
356 mRenderer->deleteAllClasses();
360 void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
368 mRenderer->sortByValue( order );
370 else if ( column == 2 )
372 mRenderer->sortByLabel( order );
375 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
378 void QgsGraduatedSymbolRendererModel::updateSymbology()
380 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
383 void QgsGraduatedSymbolRendererModel::updateLabels()
385 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
389 QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
393 void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
395 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
397 QStyleOption opt( *option );
398 opt.rect.setLeft( 0 );
400 opt.rect.setHeight( 0 );
401 if ( widget ) opt.rect.setRight( widget->width() );
402 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
405 QProxyStyle::drawPrimitive( element, option, painter, widget );
414 return new QgsGraduatedSymbolRendererWidget( layer, style, renderer );
424 if (
auto *lMapCanvas = mContext.mapCanvas() )
430 expContext << generator->createExpressionContextScope();
438 if (
auto *lVectorLayer = vectorLayer() )
442 const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
462 mRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( QString(),
QgsRangeList() );
471 cboSymmetryPoint->setEditable(
true );
472 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
475 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
478 cboGraduatedMode->addItem( icon, it.key(), it.value() );
481 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
482 this->layout()->setContentsMargins( 0, 0, 0, 0 );
484 mModel =
new QgsGraduatedSymbolRendererModel(
this );
487 mExpressionWidget->setLayer(
mLayer );
489 btnChangeGraduatedSymbol->setLayer(
mLayer );
490 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
497 spinPrecision->setClearValue( 4 );
499 spinGraduatedClasses->setShowClearButton(
false );
501 btnColorRamp->setShowRandomColorRamp(
true );
504 std::unique_ptr< QgsColorRamp > colorRamp(
QgsProject::instance()->styleSettings()->defaultColorRamp() );
507 btnColorRamp->setColorRamp( colorRamp.get() );
512 btnColorRamp->setColorRamp( ramp );
517 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
520 if ( mGraduatedSymbol )
522 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
523 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
525 methodComboBox->blockSignals(
true );
526 methodComboBox->addItem( tr(
"Color" ), ColorMode );
527 switch ( mGraduatedSymbol->type() )
531 methodComboBox->addItem( tr(
"Size" ), SizeMode );
532 minSizeSpinBox->setValue( 1 );
533 maxSizeSpinBox->setValue( 8 );
538 methodComboBox->addItem( tr(
"Size" ), SizeMode );
539 minSizeSpinBox->setValue( .1 );
540 maxSizeSpinBox->setValue( 2 );
546 methodComboBox->hide();
553 methodComboBox->blockSignals(
false );
562 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
569 connect( cboGraduatedMode, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
577 mGroupBoxSymmetric->setCollapsed(
true );
580 QMenu *advMenu =
new QMenu(
this );
585 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
587 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
590 btnAdvanced->setMenu( advMenu );
592 mHistogramWidget->setLayer(
mLayer );
593 mHistogramWidget->setRenderer( mRenderer.get() );
597 mExpressionWidget->registerExpressionContextGenerator(
this );
600 void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
602 if ( !mGraduatedSymbol )
604 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
605 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
606 mRenderer->updateSymbols( mGraduatedSymbol.get() );
613 mParameterWidgetWrappers.clear();
618 return mRenderer.get();
624 btnChangeGraduatedSymbol->setMapCanvas( context.
mapCanvas() );
625 btnChangeGraduatedSymbol->setMessageBar( context.
messageBar() );
630 delete mActionLevels;
631 mActionLevels =
nullptr;
652 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
654 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
678 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
680 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
688 disconnectUpdateHandlers();
696 int precision = spinPrecision->value() + 2;
697 while ( cboSymmetryPoint->count() )
698 cboSymmetryPoint->removeItem( 0 );
699 for (
int i = 0; i < ranges.count() - 1; i++ )
700 cboSymmetryPoint->addItem( QLocale().toString( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
704 int idx = cboGraduatedMode->findData( method->
id() );
706 cboGraduatedMode->setCurrentIndex( idx );
712 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
719 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
723 ppww->setParameterValue( value, context );
728 int nclasses = ranges.count();
729 if ( nclasses && ( updateCount || ( method && ( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) ) ) )
731 spinGraduatedClasses->setValue( ranges.count() );
735 spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
739 spinGraduatedClasses->setEnabled(
true );
743 QString attrName = mRenderer->classAttribute();
744 mExpressionWidget->setField( attrName );
745 mHistogramWidget->setSourceFieldExp( attrName );
748 if ( mRenderer->sourceSymbol() )
750 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
751 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
754 mModel->setRenderer( mRenderer.get() );
755 viewGraduated->setModel( mModel );
757 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
759 if ( mGraduatedSymbol )
761 mSizeUnitWidget->blockSignals(
true );
762 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
763 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
764 mSizeUnitWidget->blockSignals(
false );
768 methodComboBox->blockSignals(
true );
769 switch ( mRenderer->graduatedMethod() )
771 case Qgis::GraduatedMethod::Color:
773 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
774 if ( mRenderer->sourceColorRamp() )
776 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
780 case Qgis::GraduatedMethod::Size:
782 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
783 if ( !mRenderer->ranges().isEmpty() )
785 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
786 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
791 toggleMethodWidgets(
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
792 methodComboBox->blockSignals(
false );
794 viewGraduated->resizeColumnToContents( 0 );
795 viewGraduated->resizeColumnToContents( 1 );
796 viewGraduated->resizeColumnToContents( 2 );
798 mHistogramWidget->refresh();
800 connectUpdateHandlers();
803 emit widgetChanged();
808 mRenderer->setClassAttribute(
field );
811 void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
813 const MethodMode newMethod =
static_cast< MethodMode
>( methodComboBox->currentData().toInt() );
814 toggleMethodWidgets( newMethod );
819 mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Color );
824 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
827 mRenderer->setSourceColorRamp( ramp );
834 lblColorRamp->setVisible(
false );
835 btnColorRamp->setVisible(
false );
836 lblSize->setVisible(
true );
837 minSizeSpinBox->setVisible(
true );
838 lblSize->setVisible(
true );
839 maxSizeSpinBox->setVisible(
true );
840 mSizeUnitWidget->setVisible(
true );
842 mRenderer->setGraduatedMethod( Qgis::GraduatedMethod::Size );
849 void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
851 clearParameterWidgets();
853 const QString methodId = cboGraduatedMode->currentData().toString();
865 QVariant value = method->
parameterValues().value( def->name(), def->defaultValueForGui() );
870 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
873 spinGraduatedClasses->setEnabled( !( method->
flags() & QgsClassificationMethod::MethodProperty::IgnoresClassCount ) );
876 void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
882 lblColorRamp->setVisible(
true );
883 btnColorRamp->setVisible(
true );
884 lblSize->setVisible(
false );
885 minSizeSpinBox->setVisible(
false );
886 lblSizeTo->setVisible(
false );
887 maxSizeSpinBox->setVisible(
false );
888 mSizeUnitWidget->setVisible(
false );
894 lblColorRamp->setVisible(
false );
895 btnColorRamp->setVisible(
false );
896 lblSize->setVisible(
true );
897 minSizeSpinBox->setVisible(
true );
898 lblSizeTo->setVisible(
true );
899 maxSizeSpinBox->setVisible(
true );
900 mSizeUnitWidget->setVisible(
true );
906 void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
908 while ( mParametersLayout->rowCount() )
910 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
911 for ( QLayoutItem *item : QList<QLayoutItem *>( {row.labelItem, row.fieldItem} ) )
914 if ( item->widget() )
915 item->widget()->deleteLater();
919 mParameterWidgetWrappers.clear();
927 mModel->updateSymbology();
929 disconnectUpdateHandlers();
930 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
931 connectUpdateHandlers();
933 emit widgetChanged();
943 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->
clone() );
946 mRenderer->setUsingSymbolLevels( enabled );
947 mModel->updateSymbology();
948 emit widgetChanged();
951 void QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
960 void QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget()
965 applyChangeToSymbol();
970 mSizeUnitWidget->blockSignals(
true );
971 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
972 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
973 mSizeUnitWidget->blockSignals(
false );
975 QItemSelectionModel *m = viewGraduated->selectionModel();
976 QModelIndexList selectedIndexes = m->selectedRows( 1 );
977 if ( !selectedIndexes.isEmpty() )
979 const auto constSelectedIndexes = selectedIndexes;
980 for (
const QModelIndex &idx : constSelectedIndexes )
984 int rangeIdx = idx.row();
986 if ( selectedIndexes.count() > 1 )
989 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
991 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
997 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1000 refreshSymbolView();
1001 emit widgetChanged();
1004 void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
1006 const QString text = cboSymmetryPoint->lineEdit()->text();
1007 int index = cboSymmetryPoint->findText( text );
1010 cboSymmetryPoint->setCurrentIndex( index );
1014 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
1015 classifyGraduated();
1022 if ( mBlockUpdates )
1026 QString attrName = mExpressionWidget->currentField();
1027 int nclasses = spinGraduatedClasses->value();
1029 const QString methodId = cboGraduatedMode->currentData().toString();
1033 int attrNum = mLayer->fields().lookupField( attrName );
1037 mLayer->minimumAndMaximumValue( attrNum, minVal, maxVal );
1039 double minimum = minVal.toDouble();
1040 double maximum = maxVal.toDouble();
1041 mSymmetryPointValidator->setBottom( minimum );
1042 mSymmetryPointValidator->setTop( maximum );
1043 mSymmetryPointValidator->setMaxDecimals( spinPrecision->value() );
1051 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1052 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QLocale().toString( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1055 if ( mGroupBoxSymmetric->isChecked() )
1058 bool astride = cbxAstride->isChecked();
1062 QVariantMap parameterValues;
1063 for (
const auto &ppww : std::as_const( mParameterWidgetWrappers ) )
1068 mRenderer->setClassificationMethod( method );
1071 mRenderer->setClassAttribute( attrName );
1075 if ( method->
codeComplexity() > 1 && mLayer->featureCount() > 50000 )
1077 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 ) )
1083 if ( methodComboBox->currentData() == ColorMode )
1085 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1088 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1091 mRenderer->setSourceColorRamp( ramp.release() );
1095 mRenderer->setSourceColorRamp(
nullptr );
1098 mRenderer->updateClasses( mLayer, nclasses );
1100 if ( methodComboBox->currentData() == SizeMode )
1101 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1103 mRenderer->calculateLabelPrecision();
1106 updateUiFromRenderer(
false );
1111 std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
1115 mRenderer->updateColorRamp( ramp.release() );
1116 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1117 refreshSymbolView();
1122 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1123 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1124 refreshSymbolView();
1128 int QgsRendererPropertiesDialog::currentRangeRow()
1130 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1131 if ( !idx.isValid() )
1140 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1142 const auto constSelectedRows = selectedRows;
1143 for (
const QModelIndex &r : constSelectedRows )
1147 rows.append( r.row() );
1156 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1157 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1159 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1161 selectedRanges.append( mModel->rendererRange( *sIt ) );
1163 return selectedRanges;
1168 if ( idx.isValid() && idx.column() == 0 )
1169 changeRangeSymbol( idx.row() );
1170 if ( idx.isValid() && idx.column() == 1 )
1171 changeRange( idx.row() );
1176 if ( !idx.isValid() )
1179 mRowSelected = idx.row();
1189 std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
1206 if ( !dlg.exec() || !newSymbol )
1211 mGraduatedSymbol = std::move( newSymbol );
1212 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1213 applyChangeToSymbol();
1224 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1225 if ( decimalPlaces < 0 ) decimalPlaces = 0;
1229 if ( dialog.exec() == QDialog::Accepted )
1235 if ( cbxLinkBoundaries->isChecked() )
1239 mRenderer->updateRangeUpperValue( rangeIdx - 1, dialog.
lowerValueDouble() );
1242 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1244 mRenderer->updateRangeLowerValue( rangeIdx + 1, dialog.
upperValueDouble() );
1248 mHistogramWidget->refresh();
1249 emit widgetChanged();
1254 mModel->addClass( mGraduatedSymbol.get() );
1255 mHistogramWidget->refresh();
1256 emit widgetChanged();
1262 QList<int> classIndexes = selectedClasses();
1263 mModel->deleteRows( classIndexes );
1264 mHistogramWidget->refresh();
1265 emit widgetChanged();
1270 mModel->removeAllRows();
1271 mHistogramWidget->refresh();
1272 emit widgetChanged();
1278 bool ordered =
true;
1279 for (
int i = 1; i < ranges.size(); ++i )
1281 if ( ranges[i] < ranges[i - 1] )
1296 if ( ! rowsOrdered() )
1298 int result = QMessageBox::warning(
1300 tr(
"Link Class Boundaries" ),
1301 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1302 QMessageBox::Ok | QMessageBox::Cancel );
1303 if ( result != QMessageBox::Ok )
1305 cbxLinkBoundaries->setChecked(
false );
1308 mRenderer->sortByValue();
1312 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1314 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1316 refreshSymbolView();
1322 if ( item->column() == 2 )
1324 QString label = item->text();
1325 int idx = item->row();
1326 mRenderer->updateRangeLabel( idx, label );
1332 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1333 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1334 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1335 mRenderer->updateRangeLabels();
1336 mModel->updateLabels();
1342 QList<QgsSymbol *> selectedSymbols;
1344 QItemSelectionModel *m = viewGraduated->selectionModel();
1345 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1346 if ( !selectedIndexes.isEmpty() )
1349 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1350 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1352 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1353 if ( list.size() < 3 )
1366 QgsSymbol *s = findSymbolForRange( lowerBound, upperBound, ranges );
1369 selectedSymbols.append( s );
1373 return selectedSymbols;
1378 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1379 if ( decimalPlaces < 0 )
1381 double precision = 1.0 / std::pow( 10, decimalPlaces );
1383 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1387 return it->symbol();
1397 mModel->updateSymbology();
1399 mHistogramWidget->refresh();
1400 emit widgetChanged();
1405 showSymbolLevelsDialog( mRenderer.get() );
1410 viewGraduated->selectionModel()->clear();
1411 if ( ! rowsOrdered() )
1413 cbxLinkBoundaries->setChecked(
false );
1415 emit widgetChanged();
1420 emit widgetChanged();
1430 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1432 mCopyBuffer.clear();
1433 mCopyBuffer = selectedRanges();
1435 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1437 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1438 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1440 mModel->addClass( *rIt );
1442 emit widgetChanged();
1446 void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1449 if ( !ranges.isEmpty() )
1451 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1453 else if ( mRenderer->sourceSymbol() )
1455 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1457 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1460 void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1463 QgsDataDefinedSizeLegendWidget *panel = createDataDefinedSizeLegendWidget( s, mRenderer->dataDefinedSizeLegend() );
1468 mRenderer->setDataDefinedSizeLegend( panel->dataDefinedSizeLegend() );
1469 emit widgetChanged();
1475 void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1477 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1478 applyChangeToSymbol();
1487 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1488 for (
const QModelIndex &index : selectedRows )
1490 if ( !index.isValid() )
1493 const int row = index.row();
1494 if ( !mRenderer || mRenderer->ranges().size() <= row )
1497 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1500 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1501 if ( selectedRows.count() > 1 )
1504 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1507 mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
1509 emit widgetChanged();