Use real symbol buttons in categorized and graduated renderer widgets,

instead of fake ones

Gives these buttons the full power of the usual QgsSymbolButton,
including copy/paste symbols, color/opacity changes, etc. Plus,
some nice additional interface consistency!
This commit is contained in:
Nyall Dawson 2019-08-01 15:22:10 +10:00
parent 66ea97d4e2
commit ba55fb3e0a
8 changed files with 121 additions and 124 deletions

View File

@ -26,6 +26,8 @@ class QgsCategorizedSymbolRendererWidget : QgsRendererWidget
virtual QgsFeatureRenderer *renderer();
virtual void setContext( const QgsSymbolWidgetContext &context );
int matchToSymbols( QgsStyle *style );
%Docstring
@ -95,8 +97,6 @@ from the XML file with a matching name.
void updateUiFromRenderer();
void updateCategorizedSymbolIcon();
void populateCategories();
int currentCategoryRow();

View File

@ -24,9 +24,10 @@ class QgsGraduatedSymbolRendererWidget : QgsRendererWidget
virtual QgsFeatureRenderer *renderer();
virtual void setContext( const QgsSymbolWidgetContext &context );
public slots:
void changeGraduatedSymbol();
void graduatedColumnChanged( const QString &field );
void classifyGraduated();
void reapplyColorRamp();
@ -71,8 +72,6 @@ Toggle the link between classes boundaries
void disconnectUpdateHandlers();
bool rowsOrdered();
void updateGraduatedSymbolIcon();
QList<int> selectedClasses();
%Docstring
Returns a list of indexes for the classes under selection

View File

@ -517,6 +517,8 @@ QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVecto
this->layout()->setContentsMargins( 0, 0, 0, 0 );
mExpressionWidget->setLayer( mLayer );
btnChangeCategorizedSymbol->setLayer( mLayer );
btnChangeCategorizedSymbol->registerExpressionContextGenerator( this );
// initiate color ramp button to random
btnColorRamp->setShowRandomColorRamp( true );
@ -533,6 +535,8 @@ QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVecto
}
mCategorizedSymbol.reset( QgsSymbol::defaultSymbol( mLayer->geometryType() ) );
btnChangeCategorizedSymbol->setSymbolType( mCategorizedSymbol->type() );
btnChangeCategorizedSymbol->setSymbol( mCategorizedSymbol->clone() );
mModel = new QgsCategorizedSymbolRendererModel( this );
mModel->setRenderer( mRenderer.get() );
@ -546,6 +550,7 @@ QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVecto
viewCategories->resizeColumnToContents( 2 );
viewCategories->setStyle( new QgsCategorizedSymbolRendererViewStyle( viewCategories ) );
connect( viewCategories->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsCategorizedSymbolRendererWidget::selectionChanged );
connect( mModel, &QgsCategorizedSymbolRendererModel::rowsMoved, this, &QgsCategorizedSymbolRendererWidget::rowsMoved );
connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsPanelWidget::widgetChanged );
@ -555,7 +560,8 @@ QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVecto
connect( viewCategories, &QAbstractItemView::doubleClicked, this, &QgsCategorizedSymbolRendererWidget::categoriesDoubleClicked );
connect( viewCategories, &QTreeView::customContextMenuRequested, this, &QgsCategorizedSymbolRendererWidget::showContextMenu );
connect( btnChangeCategorizedSymbol, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::changeCategorizedSymbol );
connect( btnChangeCategorizedSymbol, &QgsSymbolButton::changed, this, &QgsCategorizedSymbolRendererWidget::updateSymbolsFromButton );
connect( btnAddCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::addCategories );
connect( btnDeleteCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::deleteCategories );
connect( btnDeleteAllCategories, &QAbstractButton::clicked, this, &QgsCategorizedSymbolRendererWidget::deleteAllCategories );
@ -603,8 +609,6 @@ void QgsCategorizedSymbolRendererWidget::updateUiFromRenderer()
// yet been connected, so that the updates to color ramp, symbol, etc
// don't override existing customizations.
updateCategorizedSymbolIcon();
//mModel->setRenderer ( mRenderer ); // necessary?
// set column
@ -615,7 +619,7 @@ void QgsCategorizedSymbolRendererWidget::updateUiFromRenderer()
if ( mRenderer->sourceSymbol() )
{
mCategorizedSymbol.reset( mRenderer->sourceSymbol()->clone() );
updateCategorizedSymbolIcon();
whileBlocking( btnChangeCategorizedSymbol )->setSymbol( mCategorizedSymbol->clone() );
}
// if a color ramp attached to the renderer, enable the color ramp button
@ -630,6 +634,13 @@ QgsFeatureRenderer *QgsCategorizedSymbolRendererWidget::renderer()
return mRenderer.get();
}
void QgsCategorizedSymbolRendererWidget::setContext( const QgsSymbolWidgetContext &context )
{
QgsRendererWidget::setContext( context );
btnChangeCategorizedSymbol->setMapCanvas( context.mapCanvas() );
btnChangeCategorizedSymbol->setMessageBar( context.messageBar() );
}
void QgsCategorizedSymbolRendererWidget::changeSelectedSymbols()
{
QList<int> selectedCats = selectedCategories();
@ -669,7 +680,6 @@ void QgsCategorizedSymbolRendererWidget::changeCategorizedSymbol()
dlg->setContext( mContext );
connect( dlg, &QgsPanelWidget::widgetChanged, this, &QgsCategorizedSymbolRendererWidget::updateSymbolsFromWidget );
connect( dlg, &QgsPanelWidget::panelAccepted, this, &QgsCategorizedSymbolRendererWidget::cleanUpSymbolSelector );
connect( dlg, &QgsPanelWidget::panelAccepted, this, &QgsCategorizedSymbolRendererWidget::updateCategorizedSymbolIcon );
openPanel( dlg );
}
else
@ -682,19 +692,10 @@ void QgsCategorizedSymbolRendererWidget::changeCategorizedSymbol()
}
mCategorizedSymbol = std::move( newSymbol );
updateCategorizedSymbolIcon();
applyChangeToSymbol();
}
}
void QgsCategorizedSymbolRendererWidget::updateCategorizedSymbolIcon()
{
if ( !mCategorizedSymbol )
return;
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mCategorizedSymbol.get(), btnChangeCategorizedSymbol->iconSize() );
btnChangeCategorizedSymbol->setIcon( icon );
}
void QgsCategorizedSymbolRendererWidget::populateCategories()
{
@ -1123,6 +1124,13 @@ void QgsCategorizedSymbolRendererWidget::updateSymbolsFromWidget()
applyChangeToSymbol();
}
void QgsCategorizedSymbolRendererWidget::updateSymbolsFromButton()
{
mCategorizedSymbol.reset( btnChangeCategorizedSymbol->symbol()->clone() );
applyChangeToSymbol();
}
void QgsCategorizedSymbolRendererWidget::applyChangeToSymbol()
{
// When there is a selection, change the selected symbols only
@ -1146,7 +1154,6 @@ void QgsCategorizedSymbolRendererWidget::applyChangeToSymbol()
}
mRenderer->updateCategorySymbol( idx, newCatSymbol );
}
emit widgetChanged();
}
}
else
@ -1154,6 +1161,7 @@ void QgsCategorizedSymbolRendererWidget::applyChangeToSymbol()
mRenderer->updateSymbols( mCategorizedSymbol.get() );
}
mModel->updateSymbology();
emit widgetChanged();
}
@ -1330,3 +1338,17 @@ void QgsCategorizedSymbolRendererWidget::showContextMenu( QPoint )
mContextMenu->exec( QCursor::pos() );
}
void QgsCategorizedSymbolRendererWidget::selectionChanged( const QItemSelection &, const QItemSelection & )
{
QList<int> selectedCats = selectedCategories();
if ( !selectedCats.isEmpty() )
{
whileBlocking( btnChangeCategorizedSymbol )->setSymbol( mRenderer->categories().at( selectedCats.at( 0 ) ).symbol()->clone() );
}
else
{
whileBlocking( btnChangeCategorizedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
}
btnChangeCategorizedSymbol->setDialogTitle( selectedCats.size() == 1 ? mRenderer->categories().at( selectedCats.at( 0 ) ).label() : tr( "Symbol Settings" ) );
}

View File

@ -99,6 +99,7 @@ class GUI_EXPORT QgsCategorizedSymbolRendererWidget : public QgsRendererWidget,
~QgsCategorizedSymbolRendererWidget() override;
QgsFeatureRenderer *renderer() override;
void setContext( const QgsSymbolWidgetContext &context ) override;
/**
* Replaces category symbols with the symbols from a style that have a matching
@ -156,6 +157,7 @@ class GUI_EXPORT QgsCategorizedSymbolRendererWidget : public QgsRendererWidget,
void cleanUpSymbolSelector( QgsPanelWidget *container );
void updateSymbolsFromWidget();
void updateSymbolsFromButton();
void dataDefinedSizeLegend();
/**
@ -174,12 +176,12 @@ class GUI_EXPORT QgsCategorizedSymbolRendererWidget : public QgsRendererWidget,
void showContextMenu( QPoint p );
void selectionChanged( const QItemSelection &selected, const QItemSelection &deselected );
protected:
void updateUiFromRenderer();
void updateCategorizedSymbolIcon();
// Called by virtual refreshSymbolView()
void populateCategories();

View File

@ -468,6 +468,9 @@ QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLay
mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric | QgsFieldProxyModel::Date );
mExpressionWidget->setLayer( mLayer );
btnChangeGraduatedSymbol->setLayer( mLayer );
btnChangeGraduatedSymbol->registerExpressionContextGenerator( this );
mSizeUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
@ -493,6 +496,8 @@ QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLay
viewGraduated->setStyle( new QgsGraduatedSymbolRendererViewStyle( viewGraduated ) );
mGraduatedSymbol.reset( QgsSymbol::defaultSymbol( mLayer->geometryType() ) );
btnChangeGraduatedSymbol->setSymbolType( mGraduatedSymbol->type() );
btnChangeGraduatedSymbol->setSymbol( mGraduatedSymbol->clone() );
methodComboBox->blockSignals( true );
methodComboBox->addItem( QStringLiteral( "Color" ) );
@ -516,7 +521,7 @@ QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLay
connect( viewGraduated, &QTreeView::customContextMenuRequested, this, &QgsGraduatedSymbolRendererWidget::contextMenuViewCategories );
connect( btnGraduatedClassify, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
connect( btnChangeGraduatedSymbol, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
connect( btnChangeGraduatedSymbol, &QgsSymbolButton::changed, this, &QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol );
connect( btnGraduatedDelete, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::deleteClasses );
connect( btnDeleteAllClasses, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::deleteAllClasses );
connect( btnGraduatedAdd, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::addClass );
@ -557,7 +562,6 @@ void QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed()
if ( !mGraduatedSymbol ) return;
mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() );
mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
updateGraduatedSymbolIcon();
mRenderer->updateSymbols( mGraduatedSymbol.get() );
refreshSymbolView();
}
@ -572,6 +576,13 @@ QgsFeatureRenderer *QgsGraduatedSymbolRendererWidget::renderer()
return mRenderer.get();
}
void QgsGraduatedSymbolRendererWidget::setContext( const QgsSymbolWidgetContext &context )
{
QgsRendererWidget::setContext( context );
btnChangeGraduatedSymbol->setMapCanvas( context.mapCanvas() );
btnChangeGraduatedSymbol->setMessageBar( context.messageBar() );
}
// Connect/disconnect event handlers which trigger updating renderer
void QgsGraduatedSymbolRendererWidget::connectUpdateHandlers()
{
@ -617,7 +628,6 @@ void QgsGraduatedSymbolRendererWidget::disconnectUpdateHandlers()
void QgsGraduatedSymbolRendererWidget::updateUiFromRenderer( bool updateCount )
{
disconnectUpdateHandlers();
updateGraduatedSymbolIcon();
spinSymmetryPointForOtherMethods->setShowClearButton( false );
// update UI from the graduated renderer (update combo boxes, view)
@ -701,12 +711,14 @@ void QgsGraduatedSymbolRendererWidget::updateUiFromRenderer( bool updateCount )
if ( mRenderer->sourceSymbol() )
{
mGraduatedSymbol.reset( mRenderer->sourceSymbol()->clone() );
updateGraduatedSymbolIcon();
whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
}
mModel->setRenderer( mRenderer.get() );
viewGraduated->setModel( mModel );
connect( viewGraduated->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsGraduatedSymbolRendererWidget::selectionChanged );
if ( mGraduatedSymbol )
{
mSizeUnitWidget->blockSignals( true );
@ -1029,43 +1041,6 @@ void QgsGraduatedSymbolRendererWidget::reapplySizes()
refreshSymbolView();
}
void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
{
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
std::unique_ptr< QgsSymbol > newSymbol( mGraduatedSymbol->clone() );
if ( panel && panel->dockMode() )
{
QgsSymbolSelectorWidget *dlg = new QgsSymbolSelectorWidget( newSymbol.release(), mStyle, mLayer, panel );
dlg->setContext( mContext );
connect( dlg, &QgsPanelWidget::widgetChanged, this, &QgsGraduatedSymbolRendererWidget::updateSymbolsFromWidget );
connect( dlg, &QgsPanelWidget::panelAccepted, this, &QgsGraduatedSymbolRendererWidget::cleanUpSymbolSelector );
connect( dlg, &QgsPanelWidget::panelAccepted, this, &QgsGraduatedSymbolRendererWidget::updateGraduatedSymbolIcon );
panel->openPanel( dlg );
}
else
{
QgsSymbolSelectorDialog dlg( newSymbol.get(), mStyle, mLayer, panel );
if ( !dlg.exec() || !newSymbol )
{
return;
}
mGraduatedSymbol = std::move( newSymbol );
updateGraduatedSymbolIcon();
applyChangeToSymbol();
}
}
void QgsGraduatedSymbolRendererWidget::updateGraduatedSymbolIcon()
{
if ( !mGraduatedSymbol )
return;
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mGraduatedSymbol.get(), btnChangeGraduatedSymbol->iconSize() );
btnChangeGraduatedSymbol->setIcon( icon );
}
#if 0
int QgsRendererPropertiesDialog::currentRangeRow()
{
@ -1151,6 +1126,7 @@ void QgsGraduatedSymbolRendererWidget::changeRangeSymbol( int rangeIdx )
}
mGraduatedSymbol = std::move( newSymbol );
whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mGraduatedSymbol->clone() );
applyChangeToSymbol();
}
}
@ -1388,6 +1364,20 @@ void QgsGraduatedSymbolRendererWidget::keyPressEvent( QKeyEvent *event )
}
}
void QgsGraduatedSymbolRendererWidget::selectionChanged( const QItemSelection &, const QItemSelection & )
{
const QgsRangeList ranges = selectedRanges();
if ( !ranges.isEmpty() )
{
whileBlocking( btnChangeGraduatedSymbol )->setSymbol( ranges.at( 0 ).symbol()->clone() );
}
else if ( mRenderer->sourceSymbol() )
{
whileBlocking( btnChangeGraduatedSymbol )->setSymbol( mRenderer->sourceSymbol()->clone() );
}
btnChangeGraduatedSymbol->setDialogTitle( ranges.size() == 1 ? ranges.at( 0 ).label() : tr( "Symbol Settings" ) );
}
void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
{
QgsMarkerSymbol *s = static_cast<QgsMarkerSymbol *>( mGraduatedSymbol.get() ); // this should be only enabled for marker symbols
@ -1403,6 +1393,12 @@ void QgsGraduatedSymbolRendererWidget::dataDefinedSizeLegend()
}
}
void QgsGraduatedSymbolRendererWidget::changeGraduatedSymbol()
{
mGraduatedSymbol.reset( btnChangeGraduatedSymbol->symbol()->clone() );
applyChangeToSymbol();
}
void QgsGraduatedSymbolRendererWidget::pasteSymbolToSelection()
{
std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );

View File

@ -94,9 +94,9 @@ class GUI_EXPORT QgsGraduatedSymbolRendererWidget : public QgsRendererWidget, pr
~QgsGraduatedSymbolRendererWidget() override;
QgsFeatureRenderer *renderer() override;
void setContext( const QgsSymbolWidgetContext &context ) override;
public slots:
void changeGraduatedSymbol();
void graduatedColumnChanged( const QString &field );
void classifyGraduated();
void reapplyColorRamp();
@ -129,6 +129,8 @@ class GUI_EXPORT QgsGraduatedSymbolRendererWidget : public QgsRendererWidget, pr
void updateSymbolsFromWidget();
void toggleMethodWidgets( int idx );
void dataDefinedSizeLegend();
void changeGraduatedSymbol();
void selectionChanged( const QItemSelection &selected, const QItemSelection &deselected );
protected slots:
@ -140,8 +142,6 @@ class GUI_EXPORT QgsGraduatedSymbolRendererWidget : public QgsRendererWidget, pr
void disconnectUpdateHandlers();
bool rowsOrdered();
void updateGraduatedSymbolIcon();
//! Returns a list of indexes for the classes under selection
QList<int> selectedClasses();
QgsRangeList selectedRanges();

View File

@ -44,19 +44,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="btnChangeCategorizedSymbol">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Change…</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
@ -190,6 +177,19 @@
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QgsSymbolButton" name="btnChangeCategorizedSymbol">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Change…</string>
</property>
</widget>
</item>
</layout>
<zorder>viewCategories</zorder>
<zorder>btnChangeCategorizedSymbol</zorder>
@ -211,6 +211,11 @@
<header>qgscolorrampbutton.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsSymbolButton</class>
<extends>QToolButton</extends>
<header>qgssymbolbutton.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mExpressionWidget</tabstop>
@ -225,38 +230,6 @@
</tabstops>
<resources>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -47,19 +47,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="btnChangeGraduatedSymbol">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Change…</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
@ -498,6 +485,19 @@ Negative rounds to powers of 10</string>
</widget>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsSymbolButton" name="btnChangeGraduatedSymbol">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Change…</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@ -524,6 +524,11 @@ Negative rounds to powers of 10</string>
<header>qgscolorrampbutton.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsSymbolButton</class>
<extends>QToolButton</extends>
<header>qgssymbolbutton.h</header>
</customwidget>
<customwidget>
<class>QgsGraduatedHistogramWidget</class>
<extends>QWidget</extends>