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 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 ( mContext.mapCanvas() )
428 expContext << generator->createExpressionContextScope();
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 );
494 spinGraduatedClasses->setShowClearButton(
false );
496 btnColorRamp->setShowRandomColorRamp(
true );
499 QString defaultColorRamp =
QgsProject::instance()->
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ), QString() );
500 if ( !defaultColorRamp.isEmpty() )
502 btnColorRamp->setColorRampFromName( defaultColorRamp );
507 btnColorRamp->setColorRamp( ramp );
512 viewGraduated->setStyle(
new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
515 if ( mGraduatedSymbol )
517 btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
518 btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
520 methodComboBox->blockSignals(
true );
521 methodComboBox->addItem( tr(
"Color" ), ColorMode );
522 switch ( mGraduatedSymbol->type() )
526 methodComboBox->addItem( tr(
"Size" ), SizeMode );
527 minSizeSpinBox->setValue( 1 );
528 maxSizeSpinBox->setValue( 8 );
533 methodComboBox->addItem( tr(
"Size" ), SizeMode );
534 minSizeSpinBox->setValue( .1 );
535 maxSizeSpinBox->setValue( 2 );
541 methodComboBox->hide();
548 methodComboBox->blockSignals(
false );
557 connect( btnChangeGraduatedSymbol, &
QgsSymbolButton::changed,
this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
564 connect( cboGraduatedMode, qgis::overload<int>::of( &QComboBox::currentIndexChanged ),
this, &QgsGraduatedSymbolRendererWidget::updateMethodParameters );
572 mGroupBoxSymmetric->setCollapsed(
true );
575 QMenu *advMenu =
new QMenu(
this );
577 advMenu->addAction( tr(
"Symbol Levels…" ),
this, SLOT(
showSymbolLevels() ) );
580 QAction *actionDdsLegend = advMenu->addAction( tr(
"Data-defined Size Legend…" ) );
582 connect( actionDdsLegend, &QAction::triggered,
this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend );
585 btnAdvanced->setMenu( advMenu );
587 mHistogramWidget->setLayer(
mLayer );
588 mHistogramWidget->setRenderer( mRenderer.get() );
592 mExpressionWidget->registerExpressionContextGenerator(
this );
595 void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
597 if ( !mGraduatedSymbol )
599 mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
600 mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
601 mRenderer->updateSymbols( mGraduatedSymbol.get() );
608 mParameterWidgetWrappers.clear();
613 return mRenderer.get();
619 btnChangeGraduatedSymbol->setMapCanvas( context.
mapCanvas() );
620 btnChangeGraduatedSymbol->setMessageBar( context.
messageBar() );
641 connect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
643 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
667 disconnect( cboSymmetryPoint->lineEdit(), &QLineEdit::editingFinished,
this, &QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished );
669 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
677 disconnectUpdateHandlers();
684 int precision = spinPrecision->value() + 2;
685 while ( cboSymmetryPoint->count() )
686 cboSymmetryPoint->removeItem( 0 );
687 for (
int i = 0; i < ranges.count() - 1; i++ )
688 cboSymmetryPoint->addItem( QString::number( ranges.at( i ).upperValue(),
'f',
precision ), ranges.at( i ).upperValue() );
692 int idx = cboGraduatedMode->findData( method->
id() );
694 cboGraduatedMode->setCurrentIndex( idx );
700 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QString::number( method->
symmetryPoint(),
'f', method->
labelPrecision() + 2 ) );
707 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
711 ppww->setParameterValue( value, context );
716 int nclasses = ranges.count();
717 if ( nclasses && updateCount )
719 spinGraduatedClasses->setValue( ranges.count() );
723 QString attrName = mRenderer->classAttribute();
724 mExpressionWidget->setField( attrName );
725 mHistogramWidget->setSourceFieldExp( attrName );
728 if ( mRenderer->sourceSymbol() )
730 mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
731 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
734 mModel->setRenderer( mRenderer.get() );
735 viewGraduated->setModel( mModel );
737 connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
739 if ( mGraduatedSymbol )
741 mSizeUnitWidget->blockSignals(
true );
742 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
743 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
744 mSizeUnitWidget->blockSignals(
false );
748 methodComboBox->blockSignals(
true );
749 switch ( mRenderer->graduatedMethod() )
753 methodComboBox->setCurrentIndex( methodComboBox->findData( ColorMode ) );
754 if ( mRenderer->sourceColorRamp() )
756 btnColorRamp->setColorRamp( mRenderer->sourceColorRamp() );
762 methodComboBox->setCurrentIndex( methodComboBox->findData( SizeMode ) );
763 if ( !mRenderer->ranges().isEmpty() )
765 minSizeSpinBox->setValue( mRenderer->minSymbolSize() );
766 maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() );
771 toggleMethodWidgets(
static_cast< MethodMode
>( methodComboBox->currentData().toInt() ) );
772 methodComboBox->blockSignals(
false );
774 viewGraduated->resizeColumnToContents( 0 );
775 viewGraduated->resizeColumnToContents( 1 );
776 viewGraduated->resizeColumnToContents( 2 );
778 mHistogramWidget->refresh();
780 connectUpdateHandlers();
781 emit widgetChanged();
786 mRenderer->setClassAttribute( field );
789 void QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged(
int )
791 const MethodMode newMethod =
static_cast< MethodMode
>( methodComboBox->currentData().toInt() );
792 toggleMethodWidgets( newMethod );
802 QMessageBox::critical(
this, tr(
"Select Method" ), tr(
"No color ramp defined." ) );
805 mRenderer->setSourceColorRamp( ramp );
812 lblColorRamp->setVisible(
false );
813 btnColorRamp->setVisible(
false );
814 lblSize->setVisible(
true );
815 minSizeSpinBox->setVisible(
true );
816 lblSize->setVisible(
true );
817 maxSizeSpinBox->setVisible(
true );
818 mSizeUnitWidget->setVisible(
true );
827 void QgsGraduatedSymbolRendererWidget::updateMethodParameters()
829 clearParameterWidgets();
831 const QString methodId = cboGraduatedMode->currentData().toString();
843 QVariant value = method->
parameterValues().value( def->name(), def->defaultValue() );
848 mParameterWidgetWrappers.push_back( std::unique_ptr<QgsAbstractProcessingParameterWidgetWrapper>( ppww ) );
852 void QgsGraduatedSymbolRendererWidget::toggleMethodWidgets( MethodMode mode )
858 lblColorRamp->setVisible(
true );
859 btnColorRamp->setVisible(
true );
860 lblSize->setVisible(
false );
861 minSizeSpinBox->setVisible(
false );
862 lblSizeTo->setVisible(
false );
863 maxSizeSpinBox->setVisible(
false );
864 mSizeUnitWidget->setVisible(
false );
870 lblColorRamp->setVisible(
false );
871 btnColorRamp->setVisible(
false );
872 lblSize->setVisible(
true );
873 minSizeSpinBox->setVisible(
true );
874 lblSizeTo->setVisible(
true );
875 maxSizeSpinBox->setVisible(
true );
876 mSizeUnitWidget->setVisible(
true );
882 void QgsGraduatedSymbolRendererWidget::clearParameterWidgets()
884 while ( mParametersLayout->rowCount() )
886 QFormLayout::TakeRowResult row = mParametersLayout->takeRow( 0 );
887 for ( QLayoutItem *item : QList<QLayoutItem *>( {row.labelItem, row.fieldItem} ) )
890 if ( item->widget() )
891 item->widget()->deleteLater();
895 mParameterWidgetWrappers.clear();
903 mModel->updateSymbology();
905 disconnectUpdateHandlers();
906 spinGraduatedClasses->setValue( mRenderer->ranges().count() );
907 connectUpdateHandlers();
909 emit widgetChanged();
912 void QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector(
QgsPanelWidget *container )
921 void QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget()
926 applyChangeToSymbol();
931 mSizeUnitWidget->blockSignals(
true );
932 mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() );
933 mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() );
934 mSizeUnitWidget->blockSignals(
false );
936 QItemSelectionModel *m = viewGraduated->selectionModel();
937 QModelIndexList selectedIndexes = m->selectedRows( 1 );
938 if ( !selectedIndexes.isEmpty() )
940 const auto constSelectedIndexes = selectedIndexes;
941 for (
const QModelIndex &idx : constSelectedIndexes )
945 int rangeIdx = idx.row();
947 if ( selectedIndexes.count() > 1 )
950 newRangeSymbol->
setColor( mRenderer->ranges().at( rangeIdx ).symbol()->color() );
952 mRenderer->updateRangeSymbol( rangeIdx, newRangeSymbol );
958 mRenderer->updateSymbols( mGraduatedSymbol.get() );
962 emit widgetChanged();
965 void QgsGraduatedSymbolRendererWidget::symmetryPointEditingFinished( )
967 const QString text = cboSymmetryPoint->lineEdit()->text();
968 int index = cboSymmetryPoint->findText( text );
971 cboSymmetryPoint->setCurrentIndex( index );
975 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), text );
985 QString attrName = mExpressionWidget->currentField();
986 int nclasses = spinGraduatedClasses->value();
988 const QString methodId = cboGraduatedMode->currentData().toString();
992 int attrNum = mLayer->fields().lookupField( attrName );
993 double minimum = mLayer->minimumValue( attrNum ).toDouble();
994 double maximum = mLayer->maximumValue( attrNum ).toDouble();
995 mSymmetryPointValidator->setBottom( minimum );
996 mSymmetryPointValidator->setTop( maximum );
997 mSymmetryPointValidator->setDecimals( spinPrecision->value() );
1004 double currentValue = cboSymmetryPoint->currentText().toDouble();
1005 if ( currentValue < ( minimum + ( maximum - minimum ) / 100. ) || currentValue > ( maximum - ( maximum - minimum ) / 100. ) )
1006 cboSymmetryPoint->setItemText( cboSymmetryPoint->currentIndex(), QString::number( minimum + ( maximum - minimum ) / 2.,
'f', method->
labelPrecision() + 2 ) );
1009 if ( mGroupBoxSymmetric->isChecked() )
1011 double symmetryPoint = cboSymmetryPoint->currentText().toDouble();
1012 bool astride = cbxAstride->isChecked();
1016 QVariantMap parameterValues;
1017 for (
const auto &ppww : qgis::as_const( mParameterWidgetWrappers ) )
1022 mRenderer->setClassificationMethod( method );
1025 mRenderer->setClassAttribute( attrName );
1029 if ( method->
codeComplexity() > 1 && mLayer->featureCount() > 50000 )
1031 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 ) )
1037 if ( methodComboBox->currentData() == ColorMode )
1039 std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
1042 QMessageBox::critical(
this, tr(
"Apply Classification" ), tr(
"No color ramp defined." ) );
1045 mRenderer->setSourceColorRamp( ramp.release() );
1049 mRenderer->setSourceColorRamp(
nullptr );
1052 mRenderer->updateClasses( mLayer, nclasses );
1054 if ( methodComboBox->currentData() == SizeMode )
1055 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1057 mRenderer->calculateLabelPrecision();
1060 updateUiFromRenderer(
false );
1065 std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
1069 mRenderer->updateColorRamp( ramp.release() );
1070 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1071 refreshSymbolView();
1076 mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
1077 mRenderer->updateSymbols( mGraduatedSymbol.get() );
1078 refreshSymbolView();
1082 int QgsRendererPropertiesDialog::currentRangeRow()
1084 QModelIndex idx = viewGraduated->selectionModel()->currentIndex();
1085 if ( !idx.isValid() )
1094 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1096 const auto constSelectedRows = selectedRows;
1097 for (
const QModelIndex &r : constSelectedRows )
1101 rows.append( r.row() );
1110 QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1111 QModelIndexList::const_iterator sIt = selectedRows.constBegin();
1113 for ( ; sIt != selectedRows.constEnd(); ++sIt )
1115 selectedRanges.append( mModel->rendererRange( *sIt ) );
1117 return selectedRanges;
1122 if ( idx.isValid() && idx.column() == 0 )
1123 changeRangeSymbol( idx.row() );
1124 if ( idx.isValid() && idx.column() == 1 )
1125 changeRange( idx.row() );
1130 if ( !idx.isValid() )
1133 mRowSelected = idx.row();
1143 std::unique_ptr< QgsSymbol > newSymbol( range.
symbol()->
clone() );
1160 if ( !dlg.exec() || !newSymbol )
1165 mGraduatedSymbol = std::move( newSymbol );
1166 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
1167 applyChangeToSymbol();
1178 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1179 if ( decimalPlaces < 0 ) decimalPlaces = 0;
1183 if ( dialog.exec() == QDialog::Accepted )
1192 mRenderer->updateRangeUpperValue( rangeIdx, upperValue );
1193 mRenderer->updateRangeLowerValue( rangeIdx, lowerValue );
1196 if ( cbxLinkBoundaries->isChecked() )
1200 mRenderer->updateRangeUpperValue( rangeIdx - 1, lowerValue );
1203 if ( rangeIdx < mRenderer->ranges().size() - 1 )
1205 mRenderer->updateRangeLowerValue( rangeIdx + 1, upperValue );
1209 mHistogramWidget->refresh();
1210 emit widgetChanged();
1215 mModel->addClass( mGraduatedSymbol.get() );
1216 mHistogramWidget->refresh();
1217 emit widgetChanged();
1223 QList<int> classIndexes = selectedClasses();
1224 mModel->deleteRows( classIndexes );
1225 mHistogramWidget->refresh();
1226 emit widgetChanged();
1231 mModel->removeAllRows();
1232 mHistogramWidget->refresh();
1233 emit widgetChanged();
1239 bool ordered =
true;
1240 for (
int i = 1; i < ranges.size(); ++i )
1242 if ( ranges[i] < ranges[i - 1] )
1257 if ( ! rowsOrdered() )
1259 int result = QMessageBox::warning(
1261 tr(
"Link Class Boundaries" ),
1262 tr(
"Rows will be reordered before linking boundaries. Continue?" ),
1263 QMessageBox::Ok | QMessageBox::Cancel );
1264 if ( result != QMessageBox::Ok )
1266 cbxLinkBoundaries->setChecked(
false );
1269 mRenderer->sortByValue();
1273 for (
int i = 1; i < mRenderer->ranges().size(); ++i )
1275 mRenderer->updateRangeLowerValue( i, mRenderer->ranges()[i - 1].upperValue() );
1277 refreshSymbolView();
1283 if ( item->column() == 2 )
1285 QString label = item->text();
1286 int idx = item->row();
1287 mRenderer->updateRangeLabel( idx, label );
1293 mRenderer->classificationMethod()->setLabelFormat( txtLegendFormat->text() );
1294 mRenderer->classificationMethod()->setLabelPrecision( spinPrecision->value() );
1295 mRenderer->classificationMethod()->setLabelTrimTrailingZeroes( cbxTrimTrailingZeroes->isChecked() );
1296 mRenderer->updateRangeLabels();
1297 mModel->updateLabels();
1303 QList<QgsSymbol *> selectedSymbols;
1305 QItemSelectionModel *m = viewGraduated->selectionModel();
1306 QModelIndexList selectedIndexes = m->selectedRows( 1 );
1307 if ( !selectedIndexes.isEmpty() )
1310 QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
1311 for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
1313 QStringList list = m->model()->data( *indexIt ).toString().split(
' ' );
1314 if ( list.size() < 3 )
1327 QgsSymbol *s = findSymbolForRange( lowerBound, upperBound, ranges );
1330 selectedSymbols.append( s );
1334 return selectedSymbols;
1339 int decimalPlaces = mRenderer->classificationMethod()->labelPrecision() + 2;
1340 if ( decimalPlaces < 0 )
1342 double precision = 1.0 / std::pow( 10, decimalPlaces );
1344 for ( QgsRangeList::const_iterator it = ranges.begin(); it != ranges.end(); ++it )
1348 return it->symbol();
1358 mModel->updateSymbology();
1360 mHistogramWidget->refresh();
1361 emit widgetChanged();
1366 showSymbolLevelsDialog( mRenderer.get() );
1371 viewGraduated->selectionModel()->clear();
1372 if ( ! rowsOrdered() )
1374 cbxLinkBoundaries->setChecked(
false );
1376 emit widgetChanged();
1381 emit widgetChanged();
1391 if ( event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier )
1393 mCopyBuffer.clear();
1394 mCopyBuffer = selectedRanges();
1396 else if ( event->key() == Qt::Key_V && event->modifiers() == Qt::ControlModifier )
1398 QgsRangeList::const_iterator rIt = mCopyBuffer.constBegin();
1399 for ( ; rIt != mCopyBuffer.constEnd(); ++rIt )
1401 mModel->addClass( *rIt );
1403 emit widgetChanged();
1407 void QgsGraduatedSymbolRendererWidget::selectionChanged(
const QItemSelection &,
const QItemSelection & )
1410 if ( !ranges.isEmpty() )
1412 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
1414 else if ( mRenderer->sourceSymbol() )
1416 whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
1418 btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr(
"Symbol Settings" ) );
1421 void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
1424 QgsDataDefinedSizeLegendWidget *panel = createDataDefinedSizeLegendWidget( s, mRenderer->dataDefinedSizeLegend() );
1429 mRenderer->setDataDefinedSizeLegend( panel->dataDefinedSizeLegend() );
1430 emit widgetChanged();
1436 void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
1438 mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
1439 applyChangeToSymbol();
1448 const QModelIndexList selectedRows = viewGraduated->selectionModel()->selectedRows();
1449 for (
const QModelIndex &index : selectedRows )
1451 if ( !index.isValid() )
1454 const int row = index.row();
1455 if ( !mRenderer || mRenderer->ranges().size() <= row )
1458 if ( mRenderer->ranges().at( row ).symbol()->type() != tempSymbol->type() )
1461 std::unique_ptr< QgsSymbol > newCatSymbol( tempSymbol->clone() );
1462 if ( selectedRows.count() > 1 )
1465 newCatSymbol->setColor( mRenderer->ranges().at( row ).symbol()->color() );
1468 mRenderer->updateRangeSymbol( row, newCatSymbol.release() );
1470 emit widgetChanged();