18 #include <QMessageBox>
19 #include <QStandardItemModel>
20 #include <QStandardItem>
62 QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent ) : QAbstractItemModel( parent )
63 , mMimeFormat( QStringLiteral(
"application/x-qgsgraduatedsymbolrendererv2model" ) )
71 if ( !mRenderer->ranges().isEmpty() )
73 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
84 if ( !renderer->
ranges().isEmpty() )
86 beginInsertRows( QModelIndex(), 0, renderer->
ranges().size() - 1 );
97 void QgsGraduatedSymbolRendererModel::addClass(
QgsSymbol *symbol )
99 if ( !mRenderer )
return;
100 int idx = mRenderer->
ranges().size();
101 beginInsertRows( QModelIndex(), idx, idx );
102 mRenderer->addClass( symbol );
106 void QgsGraduatedSymbolRendererModel::addClass(
const QgsRendererRange &range )
112 int idx = mRenderer->ranges().size();
113 beginInsertRows( QModelIndex(), idx, idx );
114 mRenderer->addClass( range );
118 QgsRendererRange QgsGraduatedSymbolRendererModel::rendererRange(
const QModelIndex &index )
120 if ( !index.isValid() || !mRenderer || mRenderer->ranges().size() <= index.row() )
125 return mRenderer->ranges().value( index.row() );
128 Qt::ItemFlags QgsGraduatedSymbolRendererModel::flags(
const QModelIndex &index )
const
130 if ( !index.isValid() )
132 return Qt::ItemIsDropEnabled;
135 Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
137 if ( index.column() == 2 )
139 flags |= Qt::ItemIsEditable;
145 Qt::DropActions QgsGraduatedSymbolRendererModel::supportedDropActions()
const
147 return Qt::MoveAction;
150 QVariant QgsGraduatedSymbolRendererModel::data(
const QModelIndex &index,
int role )
const
152 if ( !index.isValid() || !mRenderer )
return QVariant();
156 if ( role == Qt::CheckStateRole && index.column() == 0 )
158 return range.
renderState() ? Qt::Checked : Qt::Unchecked;
160 else if ( role == Qt::DisplayRole || role == Qt::ToolTipRole )
162 switch ( index.column() )
166 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
167 if ( decimalPlaces < 0 ) decimalPlaces = 0;
168 return QString( QLocale().toString( range.
lowerValue(),
'f', decimalPlaces ) +
" - " + QLocale().toString( range.
upperValue(),
'f', decimalPlaces ) );
171 return range.
label();
176 else if ( role == Qt::DecorationRole && index.column() == 0 && range.
symbol() )
181 else if ( role == Qt::TextAlignmentRole )
183 return ( index.column() == 0 ) ? Qt::AlignHCenter : Qt::AlignLeft;
185 else if ( role == Qt::EditRole )
187 switch ( index.column() )
191 return range.
label();
200 bool QgsGraduatedSymbolRendererModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
202 if ( !index.isValid() )
205 if ( index.column() == 0 && role == Qt::CheckStateRole )
207 mRenderer->updateRangeRenderState( index.row(), value == Qt::Checked );
208 emit dataChanged( index, index );
212 if ( role != Qt::EditRole )
215 switch ( index.column() )
220 mRenderer->updateRangeLabel( index.row(), value.toString() );
226 emit dataChanged( index, index );
230 QVariant QgsGraduatedSymbolRendererModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
232 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 3 )
235 lst << tr(
"Symbol" ) << tr(
"Values" ) << tr(
"Legend" );
236 return lst.value( section );
241 int QgsGraduatedSymbolRendererModel::rowCount(
const QModelIndex &parent )
const
243 if ( parent.isValid() || !mRenderer )
247 return mRenderer->ranges().size();
250 int QgsGraduatedSymbolRendererModel::columnCount(
const QModelIndex &index )
const
256 QModelIndex QgsGraduatedSymbolRendererModel::index(
int row,
int column,
const QModelIndex &parent )
const
258 if ( hasIndex( row, column, parent ) )
260 return createIndex( row, column );
262 return QModelIndex();
265 QModelIndex QgsGraduatedSymbolRendererModel::parent(
const QModelIndex &index )
const
268 return QModelIndex();
271 QStringList QgsGraduatedSymbolRendererModel::mimeTypes()
const
274 types << mMimeFormat;
278 QMimeData *QgsGraduatedSymbolRendererModel::mimeData(
const QModelIndexList &indexes )
const
280 QMimeData *mimeData =
new QMimeData();
281 QByteArray encodedData;
283 QDataStream stream( &encodedData, QIODevice::WriteOnly );
286 const auto constIndexes = indexes;
287 for (
const QModelIndex &index : constIndexes )
289 if ( !index.isValid() || index.column() != 0 )
292 stream << index.row();
294 mimeData->setData( mMimeFormat, encodedData );
298 bool QgsGraduatedSymbolRendererModel::dropMimeData(
const QMimeData *data, Qt::DropAction action,
int row,
int column,
const QModelIndex &parent )
302 if ( action != Qt::MoveAction )
return true;
304 if ( !data->hasFormat( mMimeFormat ) )
return false;
306 QByteArray encodedData = data->data( mMimeFormat );
307 QDataStream stream( &encodedData, QIODevice::ReadOnly );
310 while ( !stream.atEnd() )
317 int to = parent.row();
320 if ( to == -1 ) to = mRenderer->ranges().size();
321 for (
int i = rows.size() - 1; i >= 0; i-- )
323 QgsDebugMsg( QStringLiteral(
"move %1 to %2" ).arg( rows[i] ).arg( to ) );
326 if ( rows[i] < t ) t--;
327 mRenderer->moveClass( rows[i], t );
329 for (
int j = 0; j < i; j++ )
331 if ( to < rows[j] && rows[i] > rows[j] ) rows[j] += 1;
334 if ( rows[i] < to ) to--;
336 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
341 void QgsGraduatedSymbolRendererModel::deleteRows( QList<int> rows )
343 for (
int i = rows.size() - 1; i >= 0; i-- )
345 beginRemoveRows( QModelIndex(), rows[i], rows[i] );
346 mRenderer->deleteClass( rows[i] );
351 void QgsGraduatedSymbolRendererModel::removeAllRows()
353 beginRemoveRows( QModelIndex(), 0, mRenderer->ranges().size() - 1 );
354 mRenderer->deleteAllClasses();
358 void QgsGraduatedSymbolRendererModel::sort(
int column, Qt::SortOrder order )
366 mRenderer->sortByValue( order );
368 else if ( column == 2 )
370 mRenderer->sortByLabel( order );
373 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
376 void QgsGraduatedSymbolRendererModel::updateSymbology()
378 emit dataChanged( createIndex( 0, 0 ), createIndex( mRenderer->ranges().size(), 0 ) );
381 void QgsGraduatedSymbolRendererModel::updateLabels()
383 emit dataChanged( createIndex( 0, 2 ), createIndex( mRenderer->ranges().size(), 2 ) );
387 QgsGraduatedSymbolRendererViewStyle::QgsGraduatedSymbolRendererViewStyle( QWidget *parent )
391 void QgsGraduatedSymbolRendererViewStyle::drawPrimitive( PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget )
const
393 if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
395 QStyleOption opt( *option );
396 opt.rect.setLeft( 0 );
398 opt.rect.setHeight( 0 );
399 if ( widget ) opt.rect.setRight( widget->width() );
400 QProxyStyle::drawPrimitive( element, &opt, painter, widget );
403 QProxyStyle::drawPrimitive( element, option, painter, widget );
412 return new QgsGraduatedSymbolRendererWidget( layer, style, renderer );
422 if (
auto *lMapCanvas = mContext.mapCanvas() )
428 expContext << generator->createExpressionContextScope();
436 if (
auto *lVectorLayer = vectorLayer() )
440 const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
460 mRenderer = qgis::make_unique< QgsGraduatedSymbolRenderer >( QString(),
QgsRangeList() );
466 mSymmetryPointValidator =
new QDoubleValidator();
467 cboSymmetryPoint->setEditable(
true );
468 cboSymmetryPoint->setValidator( mSymmetryPointValidator );
471 for ( QMap<QString, QString>::const_iterator it = methods.constBegin(); it != methods.constEnd(); ++it )
474 cboGraduatedMode->addItem( icon, it.key(), it.value() );
477 connect( methodComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
478 this->layout()->setContentsMargins( 0, 0, 0, 0 );
480 mModel =
new QgsGraduatedSymbolRendererModel(
this );
483 mExpressionWidget->setLayer(
mLayer );
485 btnChangeGraduatedSymbol->setLayer(
mLayer );
486 btnChangeGraduatedSymbol->registerExpressionContextGenerator(
this );
493 spinPrecision->setClearValue( 4 );
495 spinGraduatedClasses->setShowClearButton(
false );
497 btnColorRamp->setShowRandomColorRamp(
true );
500 QString defaultColorRamp =
QgsProject::instance()->
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ), QString() );
501 if ( !defaultColorRamp.isEmpty() )
503 btnColorRamp->setColorRampFromName( defaultColorRamp );
508 btnColorRamp->setColorRamp( ramp );
513 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
516 if ( mGraduatedSymbol )
518 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
519 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
521 methodComboBox->blockSignals(
true );
522 methodComboBox->addItem( tr(
"Color" ), ColorMode );
523 switch ( mGraduatedSymbol->type() )
527 methodComboBox->addItem( tr(
"Size" ), SizeMode );
528 minSizeSpinBox->setValue( 1 );
529 maxSizeSpinBox->setValue( 8 );
534 methodComboBox->addItem( tr(
"Size" ), SizeMode );
535 minSizeSpinBox->setValue( .1 );
536 maxSizeSpinBox->setValue( 2 );
542 methodComboBox->hide();
549 methodComboBox->blockSignals(
false );
558 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
565 connect( cboGraduatedMode, qgis::overload<int>::of( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
573 mGroupBoxSymmetric->setCollapsed(
true );
576 QMenu *advMenu =
new QMenu(
this );
578 advMenu->addAction( tr(
"Symbol Levels…" ),
this, SLOT(
showSymbolLevels() ) );
581 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
583 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
586 btnAdvanced->setMenu( advMenu );
588 mHistogramWidget->setLayer(
mLayer );
589 mHistogramWidget->setRenderer( mRenderer.get() );
593 mExpressionWidget->registerExpressionContextGenerator(
this );
596 void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
598 if ( !mGraduatedSymbol )
600 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
601 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
602 mRenderer->updateSymbols( mGraduatedSymbol.get() );
609 mParameterWidgetWrappers.clear();
614 return mRenderer.get();
620 btnChangeGraduatedSymbol->setMapCanvas( context.
mapCanvas() );
621 btnChangeGraduatedSymbol->setMessageBar( context.
messageBar() );
642 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
644 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
668 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
670 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
678 disconnectUpdateHandlers();
685 int precision = spinPrecision->value() + 2;
686 while ( cboSymmetryPoint->count() )
687 cboSymmetryPoint->removeItem( 0 );
688 for (
int i = 0; i < ranges.count() - 1; i++ )
689 cboSymmetryPoint->addItem( QString::number( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
693 int idx = cboGraduatedMode->findData( method->
id() );
695 cboGraduatedMode->setCurrentIndex( idx );
701 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QString::number( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
708 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
712 ppww->setParameterValue( value, context );
717 int nclasses = ranges.count();
718 if ( nclasses && updateCount )
720 spinGraduatedClasses->setValue( ranges.count() );
724 QString attrName = mRenderer->classAttribute();
725 mExpressionWidget->setField( attrName );
726 mHistogramWidget->setSourceFieldExp( attrName );
729 if ( mRenderer->sourceSymbol() )
731 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
732 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
735 mModel->setRenderer( mRenderer.get() );
736 viewGraduated->setModel( mModel );
738 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
740 if ( mGraduatedSymbol )
742 mSizeUnitWidget->blockSignals(
true );
743 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
744 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
745 mSizeUnitWidget->blockSignals(
false );
749 methodComboBox->blockSignals(
true );
750 switch ( mRenderer->graduatedMethod() )
754 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
755 if ( mRenderer->sourceColorRamp() )
757 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
763 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
764 if ( !mRenderer->ranges().isEmpty() )
766 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
767 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
772 toggleMethodWidgets(
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
773 methodComboBox->blockSignals(
false );
775 viewGraduated->resizeColumnToContents( 0 );
776 viewGraduated->resizeColumnToContents( 1 );
777 viewGraduated->resizeColumnToContents( 2 );
779 mHistogramWidget->refresh();
781 connectUpdateHandlers();
782 emit widgetChanged();
787 mRenderer->setClassAttribute(
field );
790 void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
792 const MethodMode newMethod =
static_cast< MethodMode
>( methodComboBox->currentData().toInt() );
793 toggleMethodWidgets( newMethod );
803 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
806 mRenderer->setSourceColorRamp( ramp );
813 lblColorRamp->setVisible(
false );
814 btnColorRamp->setVisible(
false );
815 lblSize->setVisible(
true );
816 minSizeSpinBox->setVisible(
true );
817 lblSize->setVisible(
true );
818 maxSizeSpinBox->setVisible(
true );
819 mSizeUnitWidget->setVisible(
true );
828 void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
830 clearParameterWidgets();
832 const QString methodId = cboGraduatedMode->currentData().toString();
844 QVariant value = method->
parameterValues().value( def->name(), def->defaultValue() );
849 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
853 void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
859 lblColorRamp->setVisible(
true );
860 btnColorRamp->setVisible(
true );
861 lblSize->setVisible(
false );
862 minSizeSpinBox->setVisible(
false );
863 lblSizeTo->setVisible(
false );
864 maxSizeSpinBox->setVisible(
false );
865 mSizeUnitWidget->setVisible(
false );
871 lblColorRamp->setVisible(
false );
872 btnColorRamp->setVisible(
false );
873 lblSize->setVisible(
true );
874 minSizeSpinBox->setVisible(
true );
875 lblSizeTo->setVisible(
true );
876 maxSizeSpinBox->setVisible(
true );
877 mSizeUnitWidget->setVisible(
true );
883 void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
885 while ( mParametersLayout->rowCount() )
887 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
888 for ( QLayoutItem *item : QList<QLayoutItem *>( {row.labelItem, row.fieldItem} ) )
891 if ( item->widget() )
892 item->widget()->deleteLater();
896 mParameterWidgetWrappers.clear();
904 mModel->updateSymbology();
906 disconnectUpdateHandlers();
907 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
908 connectUpdateHandlers();
910 emit widgetChanged();
913 void QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
922 void QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget()
927 applyChangeToSymbol();
932 mSizeUnitWidget->blockSignals(
true );
933 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
934 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
935 mSizeUnitWidget->blockSignals(
false );
937 QItemSelectionModel *m = viewGraduated->selectionModel();
938 QModelIndexList selectedIndexes = m->selectedRows( 1 );
939 if ( !selectedIndexes.isEmpty() )
941 const auto constSelectedIndexes = selectedIndexes;
942 for (
const QModelIndex &idx : constSelectedIndexes )
946 int rangeIdx = idx.row();
948 if ( selectedIndexes.count() > 1 )
951 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
953 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
959 mRenderer->updateSymbols( mGraduatedSymbol.get() );
963 emit widgetChanged();
966 void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
968 const QString text = cboSymmetryPoint->lineEdit()->text();
969 int index = cboSymmetryPoint->findText( text );
972 cboSymmetryPoint->setCurrentIndex( index );
976 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
986 QString attrName = mExpressionWidget->currentField();
987 int nclasses = spinGraduatedClasses->value();
989 const QString methodId = cboGraduatedMode->currentData().toString();
993 int attrNum = mLayer->fields().lookupField( attrName );
994 double minimum = mLayer->minimumValue( attrNum ).toDouble();
995 double maximum = mLayer->maximumValue( attrNum ).toDouble();
996 mSymmetryPointValidator->setBottom( minimum );
997 mSymmetryPointValidator->setTop( maximum );
998 mSymmetryPointValidator->setDecimals( spinPrecision->value() );
1005 double currentValue = cboSymmetryPoint->currentText().toDouble();
1006 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1007 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QString::number( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1010 if ( mGroupBoxSymmetric->isChecked() )
1012 double symmetryPoint = cboSymmetryPoint->currentText().toDouble();
1013 bool astride = cbxAstride->isChecked();
1017 QVariantMap parameterValues;
1018 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
1023 mRenderer->setClassificationMethod( method );
1026 mRenderer->setClassAttribute( attrName );
1030 if ( method->
codeComplexity() > 1 && mLayer->featureCount() > 50000 )
1032 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 ) )
1038 if ( methodComboBox->currentData() == ColorMode )
1040 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1043 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1046 mRenderer->setSourceColorRamp( ramp.release() );
1050 mRenderer->setSourceColorRamp(
nullptr );
1053 mRenderer->updateClasses( mLayer, nclasses );
1055 if ( methodComboBox->currentData() == SizeMode )
1056 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1058 mRenderer->calculateLabelPrecision();
1061 updateUiFromRenderer(
false );
1066 std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
1070 mRenderer->updateColorRamp( ramp.release() );
1071 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1072 refreshSymbolView();
1077 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1078 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1079 refreshSymbolView();
1083 int QgsRendererPropertiesDialog::currentRangeRow()
1085 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1086 if ( !idx.isValid() )
1095 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1097 const auto constSelectedRows = selectedRows;
1098 for (
const QModelIndex &r : constSelectedRows )
1102 rows.append( r.row() );
1111 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1112 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1114 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1116 selectedRanges.append( mModel->rendererRange( *sIt ) );
1118 return selectedRanges;
1123 if ( idx.isValid() && idx.column() == 0 )
1124 changeRangeSymbol( idx.row() );
1125 if ( idx.isValid() && idx.column() == 1 )
1126 changeRange( idx.row() );
1131 if ( !idx.isValid() )
1134 mRowSelected = idx.row();
1144 std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
1161 if ( !dlg.exec() || !newSymbol )
1166 mGraduatedSymbol = std::move( newSymbol );
1167 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1168 applyChangeToSymbol();
1179 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1180 if ( decimalPlaces < 0 ) decimalPlaces = 0;
1184 if ( dialog.exec() == QDialog::Accepted )
1193 mRenderer->updateRangeUpperValue( rangeIdx, upperValue );
1194 mRenderer->updateRangeLowerValue( rangeIdx, lowerValue );
1197 if ( cbxLinkBoundaries->isChecked() )
1201 mRenderer->updateRangeUpperValue( rangeIdx - 1, lowerValue );
1204 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1206 mRenderer->updateRangeLowerValue( rangeIdx + 1, upperValue );
1210 mHistogramWidget->refresh();
1211 emit widgetChanged();
1216 mModel->addClass( mGraduatedSymbol.get() );
1217 mHistogramWidget->refresh();
1218 emit widgetChanged();
1224 QList<int> classIndexes = selectedClasses();
1225 mModel->deleteRows( classIndexes );
1226 mHistogramWidget->refresh();
1227 emit widgetChanged();
1232 mModel->removeAllRows();
1233 mHistogramWidget->refresh();
1234 emit widgetChanged();
1240 bool ordered =
true;
1241 for (
int i = 1; i < ranges.size(); ++i )
1243 if ( ranges[i] < ranges[i - 1] )
1258 if ( ! rowsOrdered() )
1260 int result = QMessageBox::warning(
1262 tr(
"Link Class Boundaries" ),
1263 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1264 QMessageBox::Ok | QMessageBox::Cancel );
1265 if ( result != QMessageBox::Ok )
1267 cbxLinkBoundaries->setChecked(
false );
1270 mRenderer->sortByValue();
1274 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1276 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1278 refreshSymbolView();
1284 if ( item->column() == 2 )
1286 QString label = item->text();
1287 int idx = item->row();
1288 mRenderer->updateRangeLabel( idx, label );
1294 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1295 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1296 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1297 mRenderer->updateRangeLabels();
1298 mModel->updateLabels();
1304 QList<QgsSymbol *> selectedSymbols;
1306 QItemSelectionModel *m = viewGraduated->selectionModel();
1307 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1308 if ( !selectedIndexes.isEmpty() )
1311 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1312 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1314 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1315 if ( list.size() < 3 )
1328 QgsSymbol *s = findSymbolForRange( lowerBound, upperBound, ranges );
1331 selectedSymbols.append( s );
1335 return selectedSymbols;
1340 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1341 if ( decimalPlaces < 0 )
1343 double precision = 1.0 / std::pow( 10, decimalPlaces );
1345 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1349 return it->symbol();
1359 mModel->updateSymbology();
1361 mHistogramWidget->refresh();
1362 emit widgetChanged();
1367 showSymbolLevelsDialog( mRenderer.get() );
1372 viewGraduated->selectionModel()->clear();
1373 if ( ! rowsOrdered() )
1375 cbxLinkBoundaries->setChecked(
false );
1377 emit widgetChanged();
1382 emit widgetChanged();
1392 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1394 mCopyBuffer.clear();
1395 mCopyBuffer = selectedRanges();
1397 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1399 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1400 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1402 mModel->addClass( *rIt );
1404 emit widgetChanged();
1408 void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1411 if ( !ranges.isEmpty() )
1413 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1415 else if ( mRenderer->sourceSymbol() )
1417 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1419 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1422 void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1425 QgsDataDefinedSizeLegendWidget *panel = createDataDefinedSizeLegendWidget( s, mRenderer->dataDefinedSizeLegend() );
1430 mRenderer->setDataDefinedSizeLegend( panel->dataDefinedSizeLegend() );
1431 emit widgetChanged();
1437 void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1439 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1440 applyChangeToSymbol();
1449 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1450 for (
const QModelIndex &index : selectedRows )
1452 if ( !index.isValid() )
1455 const int row = index.row();
1456 if ( !mRenderer || mRenderer->ranges().size() <= row )
1459 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1462 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1463 if ( selectedRows.count() > 1 )
1466 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1469 mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
1471 emit widgetChanged();