QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) : QgsRendererV2Widget( layer, style ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( !renderer || renderer->type() != "graduatedSymbol" ) { // we're not going to use it - so let's delete the renderer delete renderer; mRenderer = new QgsGraduatedSymbolRendererV2( "", QgsRangeList() ); } else { mRenderer = static_cast<QgsGraduatedSymbolRendererV2*>( renderer ); } // setup user interface setupUi( this ); populateColumns(); cboGraduatedColorRamp->populate( mStyle ); QStandardItemModel* mg = new QStandardItemModel( this ); QStringList labels; labels << tr( "Range" ) << tr( "Label" ); mg->setHorizontalHeaderLabels( labels ); viewGraduated->setModel( mg ); mGraduatedSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() ); connect( cboGraduatedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( graduatedColumnChanged() ) ); connect( viewGraduated, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( rangesDoubleClicked( const QModelIndex & ) ) ); connect( viewGraduated, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( rangesClicked( const QModelIndex & ) ) ); connect( mg, SIGNAL( itemChanged( QStandardItem * ) ), this, SLOT( changeCurrentValue( QStandardItem * ) ) ); connect( btnGraduatedClassify, SIGNAL( clicked() ), this, SLOT( classifyGraduated() ) ); connect( btnChangeGraduatedSymbol, SIGNAL( clicked() ), this, SLOT( changeGraduatedSymbol() ) ); connect( btnGraduatedDelete, SIGNAL( clicked() ), this, SLOT( deleteCurrentClass() ) ); connect( btnGraduatedAdd, SIGNAL( clicked() ), this, SLOT( addClass() ) ); // initialize from previously set renderer updateUiFromRenderer(); // menus for data-defined rotation/size QMenu* advMenu = new QMenu; mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(), mRenderer->rotationField(), mRenderer->sizeScaleField() ); connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) ); connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) ); btnAdvanced->setMenu( advMenu ); }
QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) : QgsRendererV2Widget( layer, style ) , mRenderer( 0 ) , mModel( 0 ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( renderer ) { mRenderer = QgsCategorizedSymbolRendererV2::convertFromRenderer( renderer ); } if ( !mRenderer ) { mRenderer = new QgsCategorizedSymbolRendererV2( "", QgsCategoryList() ); } QString attrName = mRenderer->classAttribute(); mOldClassificationAttribute = attrName; // setup user interface setupUi( this ); mExpressionWidget->setLayer( mLayer ); cboCategorizedColorRamp->populate( mStyle ); int randomIndex = cboCategorizedColorRamp->findText( tr( "Random colors" ) ); if ( randomIndex != -1 ) { cboCategorizedColorRamp->setCurrentIndex( randomIndex ); } // set project default color ramp QString defaultColorRamp = QgsProject::instance()->readEntry( "DefaultStyles", "/ColorRamp", "" ); if ( defaultColorRamp != "" ) { int index = cboCategorizedColorRamp->findText( defaultColorRamp, Qt::MatchCaseSensitive ); if ( index >= 0 ) cboCategorizedColorRamp->setCurrentIndex( index ); } mCategorizedSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() ); mModel = new QgsCategorizedSymbolRendererV2Model( this ); mModel->setRenderer( mRenderer ); // update GUI from renderer updateUiFromRenderer(); viewCategories->setModel( mModel ); viewCategories->resizeColumnToContents( 0 ); viewCategories->resizeColumnToContents( 1 ); viewCategories->resizeColumnToContents( 2 ); viewCategories->setStyle( new QgsCategorizedSymbolRendererV2ViewStyle( viewCategories->style() ) ); connect( mModel, SIGNAL( rowsMoved() ), this, SLOT( rowsMoved() ) ); connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( categoryColumnChanged( QString ) ) ); connect( viewCategories, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( categoriesDoubleClicked( const QModelIndex & ) ) ); connect( viewCategories, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) ); connect( btnChangeCategorizedSymbol, SIGNAL( clicked() ), this, SLOT( changeCategorizedSymbol() ) ); connect( btnAddCategories, SIGNAL( clicked() ), this, SLOT( addCategories() ) ); connect( btnDeleteCategories, SIGNAL( clicked() ), this, SLOT( deleteCategories() ) ); connect( btnDeleteAllCategories, SIGNAL( clicked() ), this, SLOT( deleteAllCategories() ) ); connect( btnAddCategory, SIGNAL( clicked() ), this, SLOT( addCategory() ) ); connect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ), this, SLOT( applyColorRamp() ) ); connect( cboCategorizedColorRamp, SIGNAL( currentIndexChanged( int ) ), this, SLOT( applyColorRamp() ) ); // menus for data-defined rotation/size QMenu* advMenu = new QMenu; advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) ); mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer, mRenderer->rotationField(), mRenderer->sizeScaleField(), mRenderer->scaleMethod() ); connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) ); connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) ); connect( mDataDefinedMenus, SIGNAL( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ), this, SLOT( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ) ); btnAdvanced->setMenu( advMenu ); }
QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) : QgsRendererV2Widget( layer, style ) , mRenderer( nullptr ) , mModel( nullptr ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( renderer ) { mRenderer = QgsGraduatedSymbolRendererV2::convertFromRenderer( renderer ); } if ( !mRenderer ) { mRenderer = new QgsGraduatedSymbolRendererV2( "", QgsRangeList() ); } // setup user interface setupUi( this ); mModel = new QgsGraduatedSymbolRendererV2Model( this ); mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric | QgsFieldProxyModel::Date ); mExpressionWidget->setLayer( mLayer ); mSizeUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels ); cboGraduatedColorRamp->populate( mStyle ); spinPrecision->setMinimum( QgsRendererRangeV2LabelFormat::MinPrecision ); spinPrecision->setMaximum( QgsRendererRangeV2LabelFormat::MaxPrecision ); // set project default color ramp QString defaultColorRamp = QgsProject::instance()->readEntry( "DefaultStyles", "/ColorRamp", "" ); if ( defaultColorRamp != "" ) { int index = cboGraduatedColorRamp->findText( defaultColorRamp, Qt::MatchCaseSensitive ); if ( index >= 0 ) cboGraduatedColorRamp->setCurrentIndex( index ); } viewGraduated->setStyle( new QgsGraduatedSymbolRendererV2ViewStyle( viewGraduated->style() ) ); mGraduatedSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() ); methodComboBox->blockSignals( true ); methodComboBox->addItem( "Color" ); if ( mGraduatedSymbol->type() == QgsSymbolV2::Marker ) { methodComboBox->addItem( "Size" ); minSizeSpinBox->setValue( 1 ); maxSizeSpinBox->setValue( 8 ); } else if ( mGraduatedSymbol->type() == QgsSymbolV2::Line ) { methodComboBox->addItem( "Size" ); minSizeSpinBox->setValue( .1 ); maxSizeSpinBox->setValue( 2 ); } methodComboBox->blockSignals( false ); connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( graduatedColumnChanged( QString ) ) ); connect( viewGraduated, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( rangesDoubleClicked( const QModelIndex & ) ) ); connect( viewGraduated, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( rangesClicked( const QModelIndex & ) ) ); connect( viewGraduated, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) ); connect( btnGraduatedClassify, SIGNAL( clicked() ), this, SLOT( classifyGraduated() ) ); connect( btnChangeGraduatedSymbol, SIGNAL( clicked() ), this, SLOT( changeGraduatedSymbol() ) ); connect( btnGraduatedDelete, SIGNAL( clicked() ), this, SLOT( deleteClasses() ) ); connect( btnDeleteAllClasses, SIGNAL( clicked() ), this, SLOT( deleteAllClasses() ) ); connect( btnGraduatedAdd, SIGNAL( clicked() ), this, SLOT( addClass() ) ); connect( cbxLinkBoundaries, SIGNAL( toggled( bool ) ), this, SLOT( toggleBoundariesLink( bool ) ) ); connect( mSizeUnitWidget, SIGNAL( changed() ), this, SLOT( on_mSizeUnitWidget_changed() ) ); connectUpdateHandlers(); // initialize from previously set renderer updateUiFromRenderer(); // menus for data-defined rotation/size QMenu* advMenu = new QMenu; advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) ); btnAdvanced->setMenu( advMenu ); mHistogramWidget->setLayer( mLayer ); mHistogramWidget->setRenderer( mRenderer ); connect( mHistogramWidget, SIGNAL( rangesModified( bool ) ), this, SLOT( refreshRanges( bool ) ) ); connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), mHistogramWidget, SLOT( setSourceFieldExp( QString ) ) ); mExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, this ); }
QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) : QgsRendererV2Widget( layer, style ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( !renderer || renderer->type() != "categorizedSymbol" ) { // we're not going to use it - so let's delete the renderer delete renderer; mRenderer = new QgsCategorizedSymbolRendererV2( "", QgsCategoryList() ); } else { mRenderer = static_cast<QgsCategorizedSymbolRendererV2*>( renderer ); } QString attrName = mRenderer->classAttribute(); mOldClassificationAttribute = attrName; // setup user interface setupUi( this ); populateColumns(); cboCategorizedColorRamp->populate( mStyle ); QStandardItemModel* m = new QStandardItemModel( this ); QStringList labels; labels << tr( "Symbol" ) << tr( "Value" ) << tr( "Label" ); m->setHorizontalHeaderLabels( labels ); viewCategories->setModel( m ); mCategorizedSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() ); connect( cboCategorizedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( categoryColumnChanged() ) ); connect( viewCategories, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( categoriesDoubleClicked( const QModelIndex & ) ) ); connect( viewCategories, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) ); connect( btnChangeCategorizedSymbol, SIGNAL( clicked() ), this, SLOT( changeCategorizedSymbol() ) ); connect( btnAddCategories, SIGNAL( clicked() ), this, SLOT( addCategories() ) ); connect( btnDeleteCategory, SIGNAL( clicked() ), this, SLOT( deleteCategory() ) ); connect( btnDeleteAllCategories, SIGNAL( clicked() ), this, SLOT( deleteAllCategories() ) ); connect( btnAddCategory, SIGNAL( clicked() ), this, SLOT( addCategory() ) ); connect( m, SIGNAL( itemChanged( QStandardItem * ) ), this, SLOT( changeCurrentValue( QStandardItem * ) ) ); // update GUI from renderer updateUiFromRenderer(); // menus for data-defined rotation/size QMenu* advMenu = new QMenu; advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) ); mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(), mRenderer->rotationField(), mRenderer->sizeScaleField() ); connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) ); connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) ); btnAdvanced->setMenu( advMenu ); }
QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) : QgsRendererV2Widget( layer, style ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( !renderer || renderer->type() != "graduatedSymbol" ) { // we're not going to use it - so let's delete the renderer delete renderer; mRenderer = new QgsGraduatedSymbolRendererV2( "", QgsRangeList() ); } else { mRenderer = static_cast<QgsGraduatedSymbolRendererV2*>( renderer ); } // setup user interface setupUi( this ); populateColumns(); cboGraduatedColorRamp->populate( mStyle ); // set project default color ramp QString defaultColorRamp = QgsProject::instance()->readEntry( "DefaultStyles", "/ColorRamp", "" ); if ( defaultColorRamp != "" ) { int index = cboGraduatedColorRamp->findText( defaultColorRamp, Qt::MatchCaseSensitive ); if ( index >= 0 ) cboGraduatedColorRamp->setCurrentIndex( index ); } QStandardItemModel* mg = new QStandardItemModel( this ); QStringList labels; labels << tr( "Range" ) << tr( "Label" ); mg->setHorizontalHeaderLabels( labels ); viewGraduated->setModel( mg ); mGraduatedSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() ); connect( cboGraduatedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( graduatedColumnChanged() ) ); connect( viewGraduated, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( rangesDoubleClicked( const QModelIndex & ) ) ); connect( viewGraduated, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( rangesClicked( const QModelIndex & ) ) ); connect( viewGraduated, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) ); connect( mg, SIGNAL( itemChanged( QStandardItem * ) ), this, SLOT( changeCurrentValue( QStandardItem * ) ) ); connect( btnGraduatedClassify, SIGNAL( clicked() ), this, SLOT( classifyGraduated() ) ); connect( btnChangeGraduatedSymbol, SIGNAL( clicked() ), this, SLOT( changeGraduatedSymbol() ) ); connect( btnGraduatedDelete, SIGNAL( clicked() ), this, SLOT( deleteCurrentClass() ) ); connect( btnGraduatedAdd, SIGNAL( clicked() ), this, SLOT( addClass() ) ); // initialize from previously set renderer updateUiFromRenderer(); connect( spinGraduatedClasses, SIGNAL( valueChanged( int ) ) , this, SLOT( classifyGraduated() ) ); connect( cboGraduatedMode, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( classifyGraduated() ) ); connect( cboGraduatedColorRamp, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( reapplyColorRamp() ) ); // menus for data-defined rotation/size QMenu* advMenu = new QMenu; advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) ); mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(), mRenderer->rotationField(), mRenderer->sizeScaleField(), mRenderer->scaleMethod() ); connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) ); connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) ); connect( mDataDefinedMenus, SIGNAL( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ), this, SLOT( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ) ); btnAdvanced->setMenu( advMenu ); }
QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer ) : QgsRendererWidget( layer, style ) , mRenderer( nullptr ) , mModel( nullptr ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( renderer ) { mRenderer = QgsCategorizedSymbolRenderer::convertFromRenderer( renderer ); } if ( !mRenderer ) { mRenderer = new QgsCategorizedSymbolRenderer( QLatin1String( "" ), QgsCategoryList() ); } QString attrName = mRenderer->classAttribute(); mOldClassificationAttribute = attrName; // setup user interface setupUi( this ); this->layout()->setContentsMargins( 0, 0, 0, 0 ); mExpressionWidget->setLayer( mLayer ); // initiate color ramp button to random btnColorRamp->setShowRandomColorRamp( true ); // set project default color ramp QString defaultColorRamp = QgsProject::instance()->readEntry( QStringLiteral( "DefaultStyles" ), QStringLiteral( "/ColorRamp" ), QLatin1String( "" ) ); if ( defaultColorRamp != QLatin1String( "" ) ) { btnColorRamp->setColorRampFromName( defaultColorRamp ); } else { btnColorRamp->setRandomColorRamp(); } mCategorizedSymbol = QgsSymbol::defaultSymbol( mLayer->geometryType() ); mModel = new QgsCategorizedSymbolRendererModel( this ); mModel->setRenderer( mRenderer ); // update GUI from renderer updateUiFromRenderer(); viewCategories->setModel( mModel ); viewCategories->resizeColumnToContents( 0 ); viewCategories->resizeColumnToContents( 1 ); viewCategories->resizeColumnToContents( 2 ); viewCategories->setStyle( new QgsCategorizedSymbolRendererViewStyle( viewCategories->style() ) ); connect( mModel, &QgsCategorizedSymbolRendererModel::rowsMoved, this, &QgsCategorizedSymbolRendererWidget::rowsMoved ); connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsPanelWidget::widgetChanged ); connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) >( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsCategorizedSymbolRendererWidget::categoryColumnChanged ); connect( viewCategories, &QAbstractItemView::doubleClicked, this, &QgsCategorizedSymbolRendererWidget::categoriesDoubleClicked ); connect( viewCategories, &QTreeView::customContextMenuRequested, this, &QgsCategorizedSymbolRendererWidget::contextMenuViewCategories ); connect( btnChangeCategorizedSymbol, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::changeCategorizedSymbol ); connect( btnAddCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::addCategories ); connect( btnDeleteCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::deleteCategories ); connect( btnDeleteAllCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::deleteAllCategories ); connect( btnAddCategory, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::addCategory ); connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsCategorizedSymbolRendererWidget::applyColorRamp ); // menus for data-defined rotation/size QMenu *advMenu = new QMenu; advMenu->addAction( tr( "Match to saved symbols" ), this, SLOT( matchToSymbolsFromLibrary() ) ); advMenu->addAction( tr( "Match to symbols from file..." ), this, SLOT( matchToSymbolsFromXml() ) ); advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) ); btnAdvanced->setMenu( advMenu ); mExpressionWidget->registerExpressionContextGenerator( this ); }
QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer ) : QgsRendererWidget( layer, style ) , mContextMenu( new QMenu( this ) ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( renderer ) { mRenderer.reset( QgsCategorizedSymbolRenderer::convertFromRenderer( renderer ) ); } if ( !mRenderer ) { mRenderer = qgis::make_unique< QgsCategorizedSymbolRenderer >( QString(), QgsCategoryList() ); } QString attrName = mRenderer->classAttribute(); mOldClassificationAttribute = attrName; // setup user interface setupUi( this ); this->layout()->setContentsMargins( 0, 0, 0, 0 ); mExpressionWidget->setLayer( mLayer ); // initiate color ramp button to random btnColorRamp->setShowRandomColorRamp( true ); // set project default color ramp QString defaultColorRamp = QgsProject::instance()->readEntry( QStringLiteral( "DefaultStyles" ), QStringLiteral( "/ColorRamp" ), QString() ); if ( !defaultColorRamp.isEmpty() ) { btnColorRamp->setColorRampFromName( defaultColorRamp ); } else { btnColorRamp->setRandomColorRamp(); } mCategorizedSymbol.reset( QgsSymbol::defaultSymbol( mLayer->geometryType() ) ); mModel = new QgsCategorizedSymbolRendererModel( this ); mModel->setRenderer( mRenderer.get() ); // update GUI from renderer updateUiFromRenderer(); viewCategories->setModel( mModel ); viewCategories->resizeColumnToContents( 0 ); viewCategories->resizeColumnToContents( 1 ); viewCategories->resizeColumnToContents( 2 ); viewCategories->setStyle( new QgsCategorizedSymbolRendererViewStyle( viewCategories ) ); connect( mModel, &QgsCategorizedSymbolRendererModel::rowsMoved, this, &QgsCategorizedSymbolRendererWidget::rowsMoved ); connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsPanelWidget::widgetChanged ); connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) >( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsCategorizedSymbolRendererWidget::categoryColumnChanged ); connect( viewCategories, &QAbstractItemView::doubleClicked, this, &QgsCategorizedSymbolRendererWidget::categoriesDoubleClicked ); connect( viewCategories, &QTreeView::customContextMenuRequested, this, &QgsCategorizedSymbolRendererWidget::showContextMenu ); connect( btnChangeCategorizedSymbol, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::changeCategorizedSymbol ); connect( btnAddCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::addCategories ); connect( btnDeleteCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::deleteCategories ); connect( btnDeleteAllCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::deleteAllCategories ); connect( btnAddCategory, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::addCategory ); connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsCategorizedSymbolRendererWidget::applyColorRamp ); // menus for data-defined rotation/size QMenu *advMenu = new QMenu; advMenu->addAction( tr( "Match to Saved Symbols" ), this, SLOT( matchToSymbolsFromLibrary() ) ); advMenu->addAction( tr( "Match to Symbols from File…" ), this, SLOT( matchToSymbolsFromXml() ) ); advMenu->addAction( tr( "Symbol Levels…" ), this, SLOT( showSymbolLevels() ) ); if ( mCategorizedSymbol->type() == QgsSymbol::Marker ) { QAction *actionDdsLegend = advMenu->addAction( tr( "Data-defined Size Legend…" ) ); // only from Qt 5.6 there is convenience addAction() with new style connection connect( actionDdsLegend, &QAction::triggered, this, &QgsCategorizedSymbolRendererWidget::dataDefinedSizeLegend ); } btnAdvanced->setMenu( advMenu ); mExpressionWidget->registerExpressionContextGenerator( this ); mMergeCategoriesAction = new QAction( tr( "Merge Categories" ), this ); connect( mMergeCategoriesAction, &QAction::triggered, this, &QgsCategorizedSymbolRendererWidget::mergeSelectedCategories ); mUnmergeCategoriesAction = new QAction( tr( "Unmerge Categories" ), this ); connect( mUnmergeCategoriesAction, &QAction::triggered, this, &QgsCategorizedSymbolRendererWidget::unmergeSelectedCategories ); }
void QgsGraduatedSymbolRendererV2Widget::classifyGraduated() { QString attrName = mExpressionWidget->currentField(); int nclasses = spinGraduatedClasses->value(); QSharedPointer<QgsVectorColorRampV2> ramp( cboGraduatedColorRamp->currentColorRamp() ); if ( !ramp ) { if ( cboGraduatedColorRamp->count() == 0 ) QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) ); else QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) ); return; } QgsGraduatedSymbolRendererV2::Mode mode; if ( cboGraduatedMode->currentIndex() == 0 ) mode = QgsGraduatedSymbolRendererV2::EqualInterval; else if ( cboGraduatedMode->currentIndex() == 2 ) mode = QgsGraduatedSymbolRendererV2::Jenks; else if ( cboGraduatedMode->currentIndex() == 3 ) mode = QgsGraduatedSymbolRendererV2::StdDev; else if ( cboGraduatedMode->currentIndex() == 4 ) mode = QgsGraduatedSymbolRendererV2::Pretty; else // default should be quantile for now mode = QgsGraduatedSymbolRendererV2::Quantile; // Jenks is n^2 complexity, warn for big dataset (more than 50k records) // and give the user the chance to cancel if ( QgsGraduatedSymbolRendererV2::Jenks == mode && mLayer->featureCount() > 50000 ) { if ( QMessageBox::Cancel == QMessageBox::question( this, tr( "Warning" ), 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 ) ) return; } // create and set new renderer mRenderer->setClassAttribute( attrName ); mRenderer->setMode( mode ); if ( methodComboBox->currentIndex() == 0 ) { QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp(); if ( !ramp ) { if ( cboGraduatedColorRamp->count() == 0 ) QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) ); else QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) ); return; } mRenderer->setSourceColorRamp( ramp ); } else { mRenderer->setSourceColorRamp( nullptr ); } QApplication::setOverrideCursor( Qt::WaitCursor ); mRenderer->updateClasses( mLayer, mode, nclasses ); if ( methodComboBox->currentIndex() == 1 ) mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() ); mRenderer->calculateLabelPrecision(); QApplication::restoreOverrideCursor(); // PrettyBreaks and StdDev calculation don't generate exact // number of classes - leave user interface unchanged for these updateUiFromRenderer( false ); }
QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVectorLayer* layer, QgsStyle* style, QgsFeatureRenderer* renderer ) : QgsRendererWidget( layer, style ) , mRenderer( nullptr ) , mModel( nullptr ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( renderer ) { mRenderer = QgsCategorizedSymbolRenderer::convertFromRenderer( renderer ); } if ( !mRenderer ) { mRenderer = new QgsCategorizedSymbolRenderer( QLatin1String( "" ), QgsCategoryList() ); } QString attrName = mRenderer->classAttribute(); mOldClassificationAttribute = attrName; // setup user interface setupUi( this ); mExpressionWidget->setLayer( mLayer ); cboCategorizedColorRamp->populate( mStyle ); int randomIndex = cboCategorizedColorRamp->findText( tr( "Random colors" ) ); if ( randomIndex != -1 ) { cboCategorizedColorRamp->setCurrentIndex( randomIndex ); mButtonEditRamp->setEnabled( false ); } // set project default color ramp QString defaultColorRamp = QgsProject::instance()->readEntry( QStringLiteral( "DefaultStyles" ), QStringLiteral( "/ColorRamp" ), QLatin1String( "" ) ); if ( defaultColorRamp != QLatin1String( "" ) ) { int index = cboCategorizedColorRamp->findText( defaultColorRamp, Qt::MatchCaseSensitive ); if ( index >= 0 ) cboCategorizedColorRamp->setCurrentIndex( index ); } mCategorizedSymbol = QgsSymbol::defaultSymbol( mLayer->geometryType() ); mModel = new QgsCategorizedSymbolRendererModel( this ); mModel->setRenderer( mRenderer ); // update GUI from renderer updateUiFromRenderer(); viewCategories->setModel( mModel ); viewCategories->resizeColumnToContents( 0 ); viewCategories->resizeColumnToContents( 1 ); viewCategories->resizeColumnToContents( 2 ); viewCategories->setStyle( new QgsCategorizedSymbolRendererViewStyle( viewCategories->style() ) ); connect( mModel, SIGNAL( rowsMoved() ), this, SLOT( rowsMoved() ) ); connect( mModel, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SIGNAL( widgetChanged() ) ); connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( categoryColumnChanged( QString ) ) ); connect( viewCategories, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( categoriesDoubleClicked( const QModelIndex & ) ) ); connect( viewCategories, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) ); connect( btnChangeCategorizedSymbol, SIGNAL( clicked() ), this, SLOT( changeCategorizedSymbol() ) ); connect( btnAddCategories, SIGNAL( clicked() ), this, SLOT( addCategories() ) ); connect( btnDeleteCategories, SIGNAL( clicked() ), this, SLOT( deleteCategories() ) ); connect( btnDeleteAllCategories, SIGNAL( clicked() ), this, SLOT( deleteAllCategories() ) ); connect( btnAddCategory, SIGNAL( clicked() ), this, SLOT( addCategory() ) ); connect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ), this, SLOT( applyColorRamp() ) ); connect( cboCategorizedColorRamp, SIGNAL( currentIndexChanged( int ) ), this, SLOT( applyColorRamp() ) ); connect( cboCategorizedColorRamp, SIGNAL( sourceRampEdited() ), this, SLOT( applyColorRamp() ) ); connect( mButtonEditRamp, SIGNAL( clicked() ), cboCategorizedColorRamp, SLOT( editSourceRamp() ) ); // menus for data-defined rotation/size QMenu* advMenu = new QMenu; advMenu->addAction( tr( "Match to saved symbols" ), this, SLOT( matchToSymbolsFromLibrary() ) ); advMenu->addAction( tr( "Match to symbols from file..." ), this, SLOT( matchToSymbolsFromXml() ) ); advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) ); btnAdvanced->setMenu( advMenu ); mExpressionWidget->registerExpressionContextGenerator( this ); }
void QgsGraduatedSymbolRendererWidget::classifyGraduated() { QString attrName = mExpressionWidget->currentField(); int nclasses = spinGraduatedClasses->value(); std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() ); if ( !ramp ) { QMessageBox::critical( this, tr( "Apply Classification" ), tr( "No color ramp defined." ) ); return; } QgsGraduatedSymbolRenderer::Mode mode; bool useSymmetricMode = false; bool astride = false; int attrNum = mLayer->fields().lookupField( attrName ); double minimum = mLayer->minimumValue( attrNum ).toDouble(); double maximum = mLayer->maximumValue( attrNum ).toDouble(); spinSymmetryPointForOtherMethods->setMinimum( minimum ); spinSymmetryPointForOtherMethods->setMaximum( maximum ); spinSymmetryPointForOtherMethods->setDecimals( spinPrecision->value() ); double symmetryPoint = spinSymmetryPointForOtherMethods->value(); const QgsGraduatedSymbolRenderer::Mode cboMode = static_cast< QgsGraduatedSymbolRenderer::Mode >( cboGraduatedMode->currentData().toInt() ); switch ( cboMode ) { case QgsGraduatedSymbolRenderer::EqualInterval: { mode = QgsGraduatedSymbolRenderer::EqualInterval; // knowing that spinSymmetryPointForOtherMethods->value() is automatically put at minimum when out of min-max // using "(maximum-minimum)/100)" to avoid direct comparison of doubles if ( spinSymmetryPointForOtherMethods->value() < ( minimum + ( maximum - minimum ) / 100. ) || spinSymmetryPointForOtherMethods->value() > ( maximum - ( maximum - minimum ) / 100. ) ) spinSymmetryPointForOtherMethods->setValue( minimum + ( maximum - minimum ) / 2. ); if ( mGroupBoxSymmetric->isChecked() ) { useSymmetricMode = true; symmetryPoint = spinSymmetryPointForOtherMethods->value(); astride = cbxAstride->isChecked(); } break; } case QgsGraduatedSymbolRenderer::Jenks: { mode = QgsGraduatedSymbolRenderer::Jenks; break; } case QgsGraduatedSymbolRenderer::StdDev: { mode = QgsGraduatedSymbolRenderer::StdDev; // knowing that spinSymmetryPointForOtherMethods->value() is automatically put at minimum when out of min-max // using "(maximum-minimum)/100)" to avoid direct comparison of doubles if ( spinSymmetryPointForOtherMethods->value() < ( minimum + ( maximum - minimum ) / 100. ) || spinSymmetryPointForOtherMethods->value() > ( maximum - ( maximum - minimum ) / 100. ) ) spinSymmetryPointForOtherMethods->setValue( minimum + ( maximum - minimum ) / 2. ); if ( mGroupBoxSymmetric->isChecked() ) { useSymmetricMode = true; symmetryPoint = spinSymmetryPointForOtherMethods->value(); astride = cbxAstride->isChecked(); } break; } case QgsGraduatedSymbolRenderer::Pretty: { mode = QgsGraduatedSymbolRenderer::Pretty; if ( mGroupBoxSymmetric->isChecked() ) { useSymmetricMode = true; astride = cbxAstride->isChecked(); symmetryPoint = cboSymmetryPointForPretty->currentText().toDouble(); //selected number } break; } case QgsGraduatedSymbolRenderer::Quantile: case QgsGraduatedSymbolRenderer::Custom: { // default should be quantile for now mode = QgsGraduatedSymbolRenderer::Quantile; // Quantile break; } } // Jenks is n^2 complexity, warn for big dataset (more than 50k records) // and give the user the chance to cancel if ( QgsGraduatedSymbolRenderer::Jenks == mode && mLayer->featureCount() > 50000 ) { 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 ) ) return; } // create and set new renderer mRenderer->setClassAttribute( attrName ); mRenderer->setMode( mode ); mRenderer->setUseSymmetricMode( useSymmetricMode ); mRenderer->setSymmetryPoint( symmetryPoint ); mRenderer->setAstride( astride ); if ( methodComboBox->currentIndex() == 0 ) { if ( !ramp ) { QMessageBox::critical( this, tr( "Apply Classification" ), tr( "No color ramp defined." ) ); return; } mRenderer->setSourceColorRamp( ramp.release() ); } else { mRenderer->setSourceColorRamp( nullptr ); } QApplication::setOverrideCursor( Qt::WaitCursor ); mRenderer->updateClasses( mLayer, mode, nclasses, useSymmetricMode, symmetryPoint, astride ); if ( methodComboBox->currentIndex() == 1 ) mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() ); mRenderer->calculateLabelPrecision(); QApplication::restoreOverrideCursor(); // PrettyBreaks and StdDev calculation don't generate exact // number of classes - leave user interface unchanged for these updateUiFromRenderer( false ); }
QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer ) : QgsRendererWidget( layer, style ) { // try to recognize the previous renderer // (null renderer means "no previous renderer") if ( renderer ) { mRenderer.reset( QgsGraduatedSymbolRenderer::convertFromRenderer( renderer ) ); } if ( !mRenderer ) { mRenderer = qgis::make_unique< QgsGraduatedSymbolRenderer >( QString(), QgsRangeList() ); } // setup user interface setupUi( this ); cboGraduatedMode->addItem( tr( "Equal Interval" ), QgsGraduatedSymbolRenderer::EqualInterval ); cboGraduatedMode->addItem( tr( "Quantile (Equal Count)" ), QgsGraduatedSymbolRenderer::Quantile ); cboGraduatedMode->addItem( tr( "Natural Breaks (Jenks)" ), QgsGraduatedSymbolRenderer::Jenks ); cboGraduatedMode->addItem( tr( "Standard Deviation" ), QgsGraduatedSymbolRenderer::StdDev ); cboGraduatedMode->addItem( tr( "Pretty Breaks" ), QgsGraduatedSymbolRenderer::Pretty ); connect( methodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged ); this->layout()->setContentsMargins( 0, 0, 0, 0 ); mModel = new QgsGraduatedSymbolRendererModel( this ); mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric | QgsFieldProxyModel::Date ); mExpressionWidget->setLayer( mLayer ); mSizeUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches ); spinPrecision->setMinimum( QgsRendererRangeLabelFormat::MIN_PRECISION ); spinPrecision->setMaximum( QgsRendererRangeLabelFormat::MAX_PRECISION ); btnColorRamp->setShowRandomColorRamp( true ); // set project default color ramp QString defaultColorRamp = QgsProject::instance()->readEntry( QStringLiteral( "DefaultStyles" ), QStringLiteral( "/ColorRamp" ), QString() ); if ( !defaultColorRamp.isEmpty() ) { btnColorRamp->setColorRampFromName( defaultColorRamp ); } else { QgsColorRamp *ramp = new QgsGradientColorRamp( QColor( 255, 255, 255 ), QColor( 255, 0, 0 ) ); btnColorRamp->setColorRamp( ramp ); delete ramp; } viewGraduated->setStyle( new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) ); mGraduatedSymbol.reset( QgsSymbol::defaultSymbol( mLayer->geometryType() ) ); methodComboBox->blockSignals( true ); methodComboBox->addItem( QStringLiteral( "Color" ) ); if ( mGraduatedSymbol->type() == QgsSymbol::Marker ) { methodComboBox->addItem( QStringLiteral( "Size" ) ); minSizeSpinBox->setValue( 1 ); maxSizeSpinBox->setValue( 8 ); } else if ( mGraduatedSymbol->type() == QgsSymbol::Line ) { methodComboBox->addItem( QStringLiteral( "Size" ) ); minSizeSpinBox->setValue( .1 ); maxSizeSpinBox->setValue( 2 ); } methodComboBox->blockSignals( false ); connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) >( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsGraduatedSymbolRendererWidget::graduatedColumnChanged ); connect( viewGraduated, &QAbstractItemView::doubleClicked, this, &QgsGraduatedSymbolRendererWidget::rangesDoubleClicked ); connect( viewGraduated, &QAbstractItemView::clicked, this, &QgsGraduatedSymbolRendererWidget::rangesClicked ); connect( viewGraduated, &QTreeView::customContextMenuRequested, this, &QgsGraduatedSymbolRendererWidget::contextMenuViewCategories ); connect( btnGraduatedClassify, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated ); connect( btnChangeGraduatedSymbol, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol ); connect( btnGraduatedDelete, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::deleteClasses ); connect( btnDeleteAllClasses, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::deleteAllClasses ); connect( btnGraduatedAdd, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::addClass ); connect( cbxLinkBoundaries, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::toggleBoundariesLink ); connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed ); connectUpdateHandlers(); // initialize from previously set renderer updateUiFromRenderer(); // default to collapsed symmetric group for ui simplicity mGroupBoxSymmetric->setCollapsed( true ); // // menus for data-defined rotation/size QMenu *advMenu = new QMenu( this ); advMenu->addAction( tr( "Symbol Levels…" ), this, SLOT( showSymbolLevels() ) ); if ( mGraduatedSymbol->type() == QgsSymbol::Marker ) { QAction *actionDdsLegend = advMenu->addAction( tr( "Data-defined Size Legend…" ) ); // only from Qt 5.6 there is convenience addAction() with new style connection connect( actionDdsLegend, &QAction::triggered, this, &QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend ); } btnAdvanced->setMenu( advMenu ); mHistogramWidget->setLayer( mLayer ); mHistogramWidget->setRenderer( mRenderer.get() ); connect( mHistogramWidget, &QgsGraduatedHistogramWidget::rangesModified, this, &QgsGraduatedSymbolRendererWidget::refreshRanges ); connect( mExpressionWidget, static_cast < void ( QgsFieldExpressionWidget::* )( const QString & ) >( &QgsFieldExpressionWidget::fieldChanged ), mHistogramWidget, &QgsHistogramWidget::setSourceFieldExp ); mExpressionWidget->registerExpressionContextGenerator( this ); }