Skip to content

Commit

Permalink
[FEATURE] Add color wheel and edit symbol shortcuts to style menu
Browse files Browse the repository at this point in the history
...for vector layers with single symbol renderer. This completes
earlier work where symbols from categorized/graduated/rule based
renderers can be quickly changed through the legend item context
menu.
  • Loading branch information
nyalldawson committed Jan 7, 2016
1 parent b8bce97 commit 974cc35
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
73 changes: 73 additions & 0 deletions src/app/qgsapplayertreeviewmenuprovider.cpp
Expand Up @@ -22,6 +22,7 @@
#include "qgsvectorlayer.h"
#include "qgslayertreeregistrybridge.h"
#include "qgssymbolv2selectordialog.h"
#include "qgssinglesymbolrendererv2.h"

QgsAppLayerTreeViewMenuProvider::QgsAppLayerTreeViewMenuProvider( QgsLayerTreeView* view, QgsMapCanvas* canvas )
: mView( view )
Expand Down Expand Up @@ -126,6 +127,30 @@ QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()
menuStyleManager->addSeparator();
QgsMapLayerStyleGuiUtils::instance()->addStyleManagerActions( menuStyleManager, layer );

if ( vlayer )
{
QgsSingleSymbolRendererV2* singleRenderer = dynamic_cast< QgsSingleSymbolRendererV2* >( vlayer->rendererV2() );
if ( singleRenderer && singleRenderer->symbol() )
{
//single symbol renderer, so add set color/edit symbol actions
menuStyleManager->addSeparator();
QgsColorWheel* colorWheel = new QgsColorWheel( menuStyleManager );
colorWheel->setColor( singleRenderer->symbol()->color() );
QgsColorWidgetAction* colorAction = new QgsColorWidgetAction( colorWheel, menuStyleManager, menuStyleManager );
colorAction->setDismissOnColorSelection( false );
connect( colorAction, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setVectorSymbolColor( const QColor& ) ) );
//store the layer id in action, so we can later retrieve the corresponding layer
colorAction->setProperty( "layerId", vlayer->id() );
menuStyleManager->addAction( colorAction );
menuStyleManager->addSeparator();
QAction* editSymbolAction = new QAction( tr( "Edit Symbol..." ), menuStyleManager );
//store the layer id in action, so we can later retrieve the corresponding layer
editSymbolAction->setProperty( "layerId", vlayer->id() );
connect( editSymbolAction, SIGNAL( triggered() ), this, SLOT( editVectorSymbol() ) );
menuStyleManager->addAction( editSymbolAction );
}
}

menu->addMenu( menuStyleManager );
}
else
Expand Down Expand Up @@ -398,6 +423,54 @@ void QgsAppLayerTreeViewMenuProvider::addCustomLayerActions( QMenu* menu, QgsMap
}
}

void QgsAppLayerTreeViewMenuProvider::editVectorSymbol()
{
QAction* action = qobject_cast< QAction*>( sender() );
if ( !action )
return;

QString layerId = action->property( "layerId" ).toString();
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
if ( !layer )
return;

QgsSingleSymbolRendererV2* singleRenderer = dynamic_cast< QgsSingleSymbolRendererV2* >( layer->rendererV2() );
if ( !singleRenderer )
return;

QScopedPointer< QgsSymbolV2 > symbol( singleRenderer->symbol() ? singleRenderer->symbol()->clone() : nullptr );
QgsSymbolV2SelectorDialog dlg( symbol.data(), QgsStyleV2::defaultStyle(), layer, mView->window() );
dlg.setMapCanvas( mCanvas );
if ( dlg.exec() )
{
singleRenderer->setSymbol( symbol.take() );
layer->triggerRepaint();
mView->refreshLayerSymbology( layer->id() );
}
}

void QgsAppLayerTreeViewMenuProvider::setVectorSymbolColor( const QColor& color )
{
QAction* action = qobject_cast< QAction*>( sender() );
if ( !action )
return;

QString layerId = action->property( "layerId" ).toString();
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
if ( !layer )
return;

QgsSingleSymbolRendererV2* singleRenderer = dynamic_cast< QgsSingleSymbolRendererV2* >( layer->rendererV2() );
if ( !singleRenderer || !singleRenderer->symbol() )
return;

QgsSymbolV2* newSymbol = singleRenderer->symbol()->clone();
newSymbol->setColor( color );
singleRenderer->setSymbol( newSymbol );
layer->triggerRepaint();
mView->refreshLayerSymbology( layer->id() );
}

void QgsAppLayerTreeViewMenuProvider::editSymbolLegendNodeSymbol()
{
QAction* action = qobject_cast< QAction*>( sender() );
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgsapplayertreeviewmenuprovider.h
Expand Up @@ -47,6 +47,8 @@ class QgsAppLayerTreeViewMenuProvider : public QObject, public QgsLayerTreeViewM

private slots:

void editVectorSymbol();
void setVectorSymbolColor( const QColor &color );
void editSymbolLegendNodeSymbol();
void setSymbolLegendNodeColor( const QColor &color );
};
Expand Down

2 comments on commit 974cc35

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 974cc35 Jan 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nyalldawson ahhh, fantastic, thanks.

Is there a way to remove the gray lines above and below the wheel?
lines
(just to be clear, I'm not referring to the two menu separators, those are fine and nice looking)

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 974cc35 Jan 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nyalldawson , sorry, also meant to mention that a recent colors palette would be very useful too. It's quite common to have to set a few layers to the same color. That'd be a big time saver. As for other palettes (system colors, project colors), it'd probably be too much.

Please sign in to comment.