Skip to content

Commit

Permalink
[needs-docs] Reorganisation of contextual menu for group and layer (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
slarosa authored and nirvn committed Mar 28, 2018
1 parent f75c0a8 commit a29c6a7
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 124 deletions.
9 changes: 5 additions & 4 deletions src/app/qgisapp.h
Expand Up @@ -831,6 +831,11 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! pastes group or layer from the clipboard to layer tree
void pasteLayer();

//! Set CRS of a layer
void setLayerCrs();
//! Assign layer CRS to project
void setProjectCrsFromLayer();

//! copies features to internal clipboard
void copyFeatures( QgsFeatureStore &featureStore );
void loadGDALSublayers( const QString &uri, const QStringList &list );
Expand Down Expand Up @@ -1040,10 +1045,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void setLayerScaleVisibility();
//! Zoom to nearest scale such that current layer is visible
void zoomToLayerScale();
//! Set CRS of a layer
void setLayerCrs();
//! Assign layer CRS to project
void setProjectCrsFromLayer();

/**
* Zooms so that the pixels of the raster layer occupies exactly one screen pixel.
Expand Down
253 changes: 139 additions & 114 deletions src/app/qgsapplayertreeviewmenuprovider.cpp
Expand Up @@ -75,21 +75,35 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
{
menu->addAction( actions->actionZoomToGroup( mCanvas, menu ) );

menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemoveLayer.svg" ) ), tr( "&Remove" ), QgisApp::instance(), SLOT( removeLayer() ) );

menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSetCRS.png" ) ),
tr( "&Set Group CRS" ), QgisApp::instance(), SLOT( legendGroupSetCrs() ) );
menu->addAction( tr( "Copy Group" ), QgisApp::instance(), SLOT( copyLayer() ) );
if ( QgisApp::instance()->clipboard()->hasFormat( QGSCLIPBOARD_MAPLAYER_MIME ) )
{
QAction *actionPasteLayerOrGroup = new QAction( tr( "Paste Layer/Group" ), menu );
connect( actionPasteLayerOrGroup, &QAction::triggered, QgisApp::instance(), &QgisApp::pasteLayer );
menu->addAction( actionPasteLayerOrGroup );
}

menu->addAction( actions->actionRenameGroupOrLayer( menu ) );

menu->addAction( tr( "&Set Group WMS data" ), QgisApp::instance(), SLOT( legendGroupSetWmsData() ) );
menu->addSeparator();
menu->addAction( actions->actionAddGroup( menu ) );
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemoveLayer.svg" ) ), tr( "&Remove…" ), QgisApp::instance(), SLOT( removeLayer() ) );
menu->addSeparator();

menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSetCRS.png" ) ),
tr( "&Set Group CRS…" ), QgisApp::instance(), SLOT( legendGroupSetCrs() ) );
menu->addAction( tr( "&Set Group WMS Data…" ), QgisApp::instance(), SLOT( legendGroupSetWmsData() ) );

menu->addSeparator();

menu->addAction( actions->actionMutuallyExclusiveGroup( menu ) );

menu->addAction( actions->actionCheckAndAllChildren( menu ) );

menu->addAction( actions->actionUncheckAndAllChildren( menu ) );

menu->addSeparator();

if ( mView->selectedNodes( true ).count() >= 2 )
menu->addAction( actions->actionGroupSelected( menu ) );

Expand All @@ -98,17 +112,13 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
menu->addAction( tr( "Paste Style" ), QgisApp::instance(), SLOT( applyStyleToGroup() ) );
}

menu->addAction( tr( "Copy Group" ), QgisApp::instance(), SLOT( copyLayer() ) );
if ( QgisApp::instance()->clipboard()->hasFormat( QGSCLIPBOARD_MAPLAYER_MIME ) )
{
QAction *actionPasteLayerOrGroup = new QAction( tr( "Paste Layer/Group" ), menu );
connect( actionPasteLayerOrGroup, &QAction::triggered, QgisApp::instance(), &QgisApp::pasteLayer );
menu->addAction( actionPasteLayerOrGroup );
}

menu->addAction( tr( "Save As Layer Definition File…" ), QgisApp::instance(), SLOT( saveAsLayerDefinition() ) );
menu->addSeparator();

menu->addAction( actions->actionAddGroup( menu ) );
QMenu *menuExportGroup = new QMenu( tr( "Export" ), menu );
QAction *actionSaveAsDefinitionGroup = new QAction( tr( "Save as Layer Definition File…" ), menuExportGroup );
connect( actionSaveAsDefinitionGroup, &QAction::triggered, QgisApp::instance(), &QgisApp::saveAsLayerDefinition );
menuExportGroup->addAction( actionSaveAsDefinitionGroup );
menu->addMenu( menuExportGroup );
}
else if ( QgsLayerTree::isLayer( node ) )
{
Expand All @@ -122,6 +132,15 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
menu->addAction( actions->actionShowInOverview( menu ) );
}

if ( vlayer )
menu->addAction( actions->actionShowFeatureCount( menu ) );

QAction *actionCopyLayer = new QAction( tr( "Copy Layer" ), menu );
connect( actionCopyLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::copyLayer );
menu->addAction( actionCopyLayer );

menu->addAction( actions->actionRenameGroupOrLayer( menu ) );

if ( rlayer )
{
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionZoomActual.svg" ) ), tr( "&Zoom to Native Resolution (100%)" ), QgisApp::instance(), SLOT( legendLayerZoomNative() ) );
Expand All @@ -130,100 +149,31 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
menu->addAction( tr( "&Stretch Using Current Extent" ), QgisApp::instance(), SLOT( legendLayerStretchUsingCurrentExtent() ) );
}

menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemoveLayer.svg" ) ), tr( "&Remove" ), QgisApp::instance(), SLOT( removeLayer() ) );

// duplicate layer
QAction *duplicateLayersAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDuplicateLayer.svg" ) ), tr( "&Duplicate" ), QgisApp::instance(), SLOT( duplicateLayers() ) );

if ( layer && layer->isSpatial() )
addCustomLayerActions( menu, layer );
if ( layer && layer->type() == QgsMapLayer::VectorLayer && static_cast<QgsVectorLayer *>( layer )->providerType() == QLatin1String( "virtual" ) )
{
// set layer scale visibility
menu->addAction( tr( "&Set Layer Scale Visibility" ), QgisApp::instance(), SLOT( setLayerScaleVisibility() ) );

if ( !layer->isInScaleRange( mCanvas->scale() ) )
menu->addAction( tr( "Zoom to &Visible Scale" ), QgisApp::instance(), SLOT( zoomToLayerScale() ) );

QAction *checkAll = actions->actionCheckAndAllParents( menu );
if ( checkAll )
menu->addAction( checkAll );

// set layer crs
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSetCRS.png" ) ), tr( "Set Layer CRS" ), QgisApp::instance(), SLOT( setLayerCrs() ) );

// assign layer crs to project
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionSetProjectCRS.png" ) ), tr( "Set &Project CRS from Layer" ), QgisApp::instance(), SLOT( setProjectCrsFromLayer() ) );
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddVirtualLayer.svg" ) ), tr( "Edit Virtual Layer…" ), QgisApp::instance(), SLOT( addVirtualLayer() ) );
}

// style-related actions
if ( layer && mView->selectedLayerNodes().count() == 1 )
{
QMenu *menuStyleManager = new QMenu( tr( "Styles" ), menu );
menu->addSeparator();

QgisApp *app = QgisApp::instance();
menuStyleManager->addAction( tr( "Copy Style" ), app, SLOT( copyStyle() ) );
if ( app->clipboard()->hasFormat( QGSCLIPBOARD_STYLE_MIME ) )
{
menuStyleManager->addAction( tr( "Paste Style" ), app, SLOT( pasteStyle() ) );
}
// duplicate layer
QAction *duplicateLayersAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDuplicateLayer.svg" ) ), tr( "&Duplicate" ), QgisApp::instance(), SLOT( duplicateLayers() ) );
menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemoveLayer.svg" ) ), tr( "&Remove…" ), QgisApp::instance(), SLOT( removeLayer() ) );

menuStyleManager->addSeparator();
QgsMapLayerStyleGuiUtils::instance()->addStyleManagerActions( menuStyleManager, layer );
menu->addSeparator();

if ( vlayer )
{
const QgsSingleSymbolRenderer *singleRenderer = dynamic_cast< const QgsSingleSymbolRenderer * >( vlayer->renderer() );
if ( !singleRenderer && vlayer->renderer() && vlayer->renderer()->embeddedRenderer() )
{
singleRenderer = dynamic_cast< const QgsSingleSymbolRenderer * >( vlayer->renderer()->embeddedRenderer() );
}
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, &QgsColorWidgetAction::colorChanged, this, &QgsAppLayerTreeViewMenuProvider::setVectorSymbolColor );
//store the layer id in action, so we can later retrieve the corresponding layer
colorAction->setProperty( "layerId", vlayer->id() );
menuStyleManager->addAction( colorAction );
if ( node->parent() != mView->layerTreeModel()->rootGroup() )
menu->addAction( actions->actionMakeTopLevel( menu ) );

//add recent colors action
QList<QgsRecentColorScheme *> recentSchemes;
QgsApplication::colorSchemeRegistry()->schemes( recentSchemes );
if ( !recentSchemes.isEmpty() )
{
QgsColorSwatchGridAction *recentColorAction = new QgsColorSwatchGridAction( recentSchemes.at( 0 ), menuStyleManager, QStringLiteral( "symbology" ), menuStyleManager );
recentColorAction->setProperty( "layerId", vlayer->id() );
recentColorAction->setDismissOnColorSelection( false );
menuStyleManager->addAction( recentColorAction );
connect( recentColorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsAppLayerTreeViewMenuProvider::setVectorSymbolColor );
}
QAction *checkAll = actions->actionCheckAndAllParents( menu );
if ( checkAll )
menu->addAction( checkAll );

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, &QAction::triggered, this, &QgsAppLayerTreeViewMenuProvider::editVectorSymbol );
menuStyleManager->addAction( editSymbolAction );
}
}

menu->addMenu( menuStyleManager );
}
else
{
if ( QgisApp::instance()->clipboard()->hasFormat( QGSCLIPBOARD_STYLE_MIME ) )
{
menu->addAction( tr( "Paste Style" ), QgisApp::instance(), SLOT( applyStyleToGroup() ) );
}
}
if ( mView->selectedNodes( true ).count() >= 2 )
menu->addAction( actions->actionGroupSelected( menu ) );

menu->addSeparator();
QAction *actionCopyLayer = new QAction( tr( "Copy Layer" ), menu );
connect( actionCopyLayer, &QAction::triggered, QgisApp::instance(), &QgisApp::copyLayer );
menu->addAction( actionCopyLayer );

if ( vlayer )
{
Expand Down Expand Up @@ -263,11 +213,35 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
QAction *action = menu->addAction( tr( "&Filter…" ), QgisApp::instance(), SLOT( layerSubsetString() ) );
action->setEnabled( !vlayer->isEditable() );
}
}

menu->addAction( actions->actionShowFeatureCount( menu ) );
menu->addSeparator();

menu->addSeparator();
if ( layer && layer->isSpatial() )
{
// set layer scale visibility
menu->addAction( tr( "&Set Layer Scale Visibility" ), QgisApp::instance(), SLOT( setLayerScaleVisibility() ) );

if ( !layer->isInScaleRange( mCanvas->scale() ) )
menu->addAction( tr( "Zoom to &Visible Scale" ), QgisApp::instance(), SLOT( zoomToLayerScale() ) );

QMenu *menuSetCRS = new QMenu( tr( "Set CRS" ), menu );
// set layer crs
QAction *actionSetLayerCrs = new QAction( tr( "Set Layer CRS…" ), menuSetCRS );
connect( actionSetLayerCrs, &QAction::triggered, QgisApp::instance(), &QgisApp::setLayerCrs );
menuSetCRS->addAction( actionSetLayerCrs );
// assign layer crs to project
QAction *actionSetProjectCrs = new QAction( tr( "Set &Project CRS from Layer" ), menuSetCRS );
connect( actionSetProjectCrs, &QAction::triggered, QgisApp::instance(), &QgisApp::setProjectCrsFromLayer );
menuSetCRS->addAction( actionSetProjectCrs );

menu->addMenu( menuSetCRS );
}

menu->addSeparator();

if ( vlayer )
{
// save as vector file
QMenu *menuExportVector = new QMenu( tr( "Export" ), menu );
QAction *actionSaveAs = new QAction( tr( "Save as…" ), menuExportVector );
Expand Down Expand Up @@ -297,34 +271,85 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
connect( actionSaveStyle, &QAction::triggered, QgisApp::instance(), [ = ] { QgisApp::instance()->saveStyleFile(); } );
menuExportRaster->addAction( actionSaveStyle );
menu->addMenu( menuExportRaster );

menu->addSeparator();
}
else if ( layer && layer->type() == QgsMapLayer::PluginLayer && mView->selectedLayerNodes().count() == 1 )
{
// disable duplication of plugin layers
duplicateLayersAction->setEnabled( false );
}

addCustomLayerActions( menu, layer );
menu->addSeparator();

if ( layer && QgsProject::instance()->layerIsEmbedded( layer->id() ).isEmpty() )
menu->addAction( tr( "&Properties" ), QgisApp::instance(), SLOT( layerProperties() ) );
// style-related actions
if ( layer && mView->selectedLayerNodes().count() == 1 )
{
menu->addSeparator();
QMenu *menuStyleManager = new QMenu( tr( "Styles" ), menu );

if ( node->parent() != mView->layerTreeModel()->rootGroup() )
menu->addAction( actions->actionMakeTopLevel( menu ) );
QgisApp *app = QgisApp::instance();
menuStyleManager->addAction( tr( "Copy Style" ), app, SLOT( copyStyle() ) );
if ( app->clipboard()->hasFormat( QGSCLIPBOARD_STYLE_MIME ) )
{
menuStyleManager->addAction( tr( "Paste Style" ), app, SLOT( pasteStyle() ) );
}

menu->addAction( actions->actionRenameGroupOrLayer( menu ) );
menuStyleManager->addSeparator();
QgsMapLayerStyleGuiUtils::instance()->addStyleManagerActions( menuStyleManager, layer );

if ( mView->selectedNodes( true ).count() >= 2 )
menu->addAction( actions->actionGroupSelected( menu ) );
if ( vlayer )
{
const QgsSingleSymbolRenderer *singleRenderer = dynamic_cast< const QgsSingleSymbolRenderer * >( vlayer->renderer() );
if ( !singleRenderer && vlayer->renderer() && vlayer->renderer()->embeddedRenderer() )
{
singleRenderer = dynamic_cast< const QgsSingleSymbolRenderer * >( vlayer->renderer()->embeddedRenderer() );
}
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, &QgsColorWidgetAction::colorChanged, this, &QgsAppLayerTreeViewMenuProvider::setVectorSymbolColor );
//store the layer id in action, so we can later retrieve the corresponding layer
colorAction->setProperty( "layerId", vlayer->id() );
menuStyleManager->addAction( colorAction );

if ( layer && layer->type() == QgsMapLayer::VectorLayer && static_cast<QgsVectorLayer *>( layer )->providerType() == QLatin1String( "virtual" ) )
//add recent colors action
QList<QgsRecentColorScheme *> recentSchemes;
QgsApplication::colorSchemeRegistry()->schemes( recentSchemes );
if ( !recentSchemes.isEmpty() )
{
QgsColorSwatchGridAction *recentColorAction = new QgsColorSwatchGridAction( recentSchemes.at( 0 ), menuStyleManager, QStringLiteral( "symbology" ), menuStyleManager );
recentColorAction->setProperty( "layerId", vlayer->id() );
recentColorAction->setDismissOnColorSelection( false );
menuStyleManager->addAction( recentColorAction );
connect( recentColorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsAppLayerTreeViewMenuProvider::setVectorSymbolColor );
}

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, &QAction::triggered, this, &QgsAppLayerTreeViewMenuProvider::editVectorSymbol );
menuStyleManager->addAction( editSymbolAction );
}
}

menu->addMenu( menuStyleManager );
}
else
{
menu->addAction( tr( "Edit Virtual Layer…" ), QgisApp::instance(), SLOT( addVirtualLayer() ) );
if ( QgisApp::instance()->clipboard()->hasFormat( QGSCLIPBOARD_STYLE_MIME ) )
{
menu->addAction( tr( "Paste Style" ), QgisApp::instance(), SLOT( applyStyleToGroup() ) );
}
}
}

if ( layer && QgsProject::instance()->layerIsEmbedded( layer->id() ).isEmpty() )
menu->addAction( tr( "&Properties…" ), QgisApp::instance(), SLOT( layerProperties() ) );
}
}
else if ( QgsLayerTreeModelLegendNode *node = mView->layerTreeModel()->index2legendNode( idx ) )
{
Expand Down

0 comments on commit a29c6a7

Please sign in to comment.