Sort multiple layers (via drag and drop) being added into a project

to insure maximum features visibility.

Because adding a pair of polygon and point layers should never
result in polygons covering the points.

The sorting logic is from top to bottom:
- vector: point
- vector: line
- vector: polygon
- point cloud
- mesh
- vector tile
- raster
This commit is contained in:
Mathieu Pellerin 2022-09-27 13:35:20 +07:00
parent 672e577623
commit 43d9facca8
4 changed files with 181 additions and 81 deletions

View File

@ -36,6 +36,7 @@
#include "qgslayertreenode.h"
#include "qgslayertree.h"
#include "qgslayertreeview.h"
#include "qgslayertreemodel.h"
#include "qgsgui.h"
#include "qgsmbtiles.h"
#include "qgsmessagelog.h"
@ -136,6 +137,87 @@ void QgsAppLayerHandling::postProcessAddedLayer( QgsMapLayer *layer )
}
}
void QgsAppLayerHandling::addSortedLayersToLegend( QList<QgsMapLayer *> &layers )
{
if ( layers.size() > 1 )
{
std::sort( layers.begin(), layers.end(), []( QgsMapLayer * a, QgsMapLayer * b )
{
const static QMap<QgsMapLayerType, int> layerTypeOrdering =
{
{ QgsMapLayerType::AnnotationLayer, -1 },
{ QgsMapLayerType::VectorLayer, 0 },
{ QgsMapLayerType::PointCloudLayer, 1 },
{ QgsMapLayerType::MeshLayer, 2 },
{ QgsMapLayerType::VectorTileLayer, 3 },
{ QgsMapLayerType::RasterLayer, 4 },
{ QgsMapLayerType::GroupLayer, 5 },
{ QgsMapLayerType::PluginLayer, 6 },
};
if ( a->type() == QgsMapLayerType::VectorLayer && b->type() == QgsMapLayerType::VectorLayer )
{
QgsVectorLayer *av = qobject_cast<QgsVectorLayer *>( a );
QgsVectorLayer *bv = qobject_cast<QgsVectorLayer *>( b );
if ( av->geometryType() == QgsWkbTypes::PointGeometry && bv->geometryType() != QgsWkbTypes::PointGeometry )
{
return false;
}
else if ( av->geometryType() == QgsWkbTypes::LineGeometry && bv->geometryType() == QgsWkbTypes::PolygonGeometry )
{
return false;
}
else
{
return true;
}
}
return layerTypeOrdering.value( a->type() ) > layerTypeOrdering.value( b->type() );
} );
}
QgsLayerTreeGroup *parent = nullptr;
QgsLayerTreeNode *currentNode { QgisApp::instance()->layerTreeView()->currentNode() };
int index = 0;
if ( currentNode && currentNode->parent() )
{
if ( QgsLayerTree::isGroup( currentNode ) )
{
parent = qobject_cast<QgsLayerTreeGroup *>( currentNode );
}
else if ( QgsLayerTree::isLayer( currentNode ) )
{
const QList<QgsLayerTreeNode *> currentNodeSiblings { currentNode->parent()->children() };
int nodeIdx = 0;
for ( const QgsLayerTreeNode *child : std::as_const( currentNodeSiblings ) )
{
nodeIdx++;
if ( child == currentNode )
{
index = nodeIdx;
break;
}
}
parent = qobject_cast<QgsLayerTreeGroup *>( currentNode->parent() );
}
else
{
parent = qobject_cast<QgsLayerTreeGroup *>( QgsProject::instance()->layerTreeRoot() );
}
}
else
{
parent = qobject_cast<QgsLayerTreeGroup *>( QgsProject::instance()->layerTreeRoot() );
}
for ( QgsMapLayer *layer : layers )
{
parent->insertLayer( index, layer );
}
QgisApp::instance()->layerTreeView()->setCurrentLayer( layers.at( 0 ) );
}
void QgsAppLayerHandling::postProcessAddedLayers( const QList<QgsMapLayer *> &layers )
{
for ( QgsMapLayer *layer : layers )
@ -370,7 +452,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::addOgrVectorLayers( const QStringLis
return addedLayers;
}
QgsPointCloudLayer *QgsAppLayerHandling::addPointCloudLayer( const QString &uri, const QString &baseName, const QString &provider, bool showWarningOnInvalid )
QgsPointCloudLayer *QgsAppLayerHandling::addPointCloudLayer( const QString &uri, const QString &baseName, const QString &provider, bool showWarningOnInvalid, bool addToLegend )
{
QgsCanvasRefreshBlocker refreshBlocker;
QgsSettings settings;
@ -402,13 +484,13 @@ QgsPointCloudLayer *QgsAppLayerHandling::addPointCloudLayer( const QString &uri,
QgsAppLayerHandling::postProcessAddedLayer( layer.get() );
QgsProject::instance()->addMapLayer( layer.get() );
QgsProject::instance()->addMapLayer( layer.get(), addToLegend );
QgisApp::instance()->activateDeactivateLayerRelatedActions( QgisApp::instance()->activeLayer() );
return layer.release();
}
QgsPluginLayer *QgsAppLayerHandling::addPluginLayer( const QString &uri, const QString &baseName, const QString &provider )
QgsPluginLayer *QgsAppLayerHandling::addPluginLayer( const QString &uri, const QString &baseName, const QString &provider, bool addToLegend )
{
QgsPluginLayer *layer = QgsApplication::pluginLayerRegistry()->createLayer( provider, uri );
if ( !layer )
@ -416,12 +498,12 @@ QgsPluginLayer *QgsAppLayerHandling::addPluginLayer( const QString &uri, const Q
layer->setName( baseName );
QgsProject::instance()->addMapLayer( layer );
QgsProject::instance()->addMapLayer( layer, addToLegend );
return layer;
}
QgsVectorTileLayer *QgsAppLayerHandling::addVectorTileLayer( const QString &uri, const QString &baseName, bool showWarningOnInvalid )
QgsVectorTileLayer *QgsAppLayerHandling::addVectorTileLayer( const QString &uri, const QString &baseName, bool showWarningOnInvalid, bool addToLegend )
{
QgsCanvasRefreshBlocker refreshBlocker;
QgsSettings settings;
@ -453,7 +535,7 @@ QgsVectorTileLayer *QgsAppLayerHandling::addVectorTileLayer( const QString &uri,
QgsAppLayerHandling::postProcessAddedLayer( layer.get() );
QgsProject::instance()->addMapLayer( layer.get() );
QgsProject::instance()->addMapLayer( layer.get(), addToLegend );
QgisApp::instance()->activateDeactivateLayerRelatedActions( QgisApp::instance()->activeLayer() );
return layer.release();
@ -577,10 +659,10 @@ QgsAppLayerHandling::SublayerHandling QgsAppLayerHandling::shouldAskUserForSubla
return SublayerHandling::AskUser;
}
QList<QgsMapLayer *> QgsAppLayerHandling::addSublayers( const QList<QgsProviderSublayerDetails> &layers, const QString &baseName, const QString &groupName )
QList<QgsMapLayer *> QgsAppLayerHandling::addSublayers( const QList<QgsProviderSublayerDetails> &layers, const QString &baseName, const QString &groupName, bool addToLegend )
{
QgsLayerTreeGroup *group = nullptr;
if ( !groupName.isEmpty() )
if ( !groupName.isEmpty() && addToLegend )
{
int index { 0 };
QgsLayerTreeNode *currentNode { QgisApp::instance()->layerTreeView()->currentNode() };
@ -659,14 +741,17 @@ QList<QgsMapLayer *> QgsAppLayerHandling::addSublayers( const QList<QgsProviderS
// filename in the layer's name, because the group is already titled with the filename.
// But otherwise, we DO include the file name so that users can differentiate the source
// when multiple layers are loaded from a GPX file or similar (refs https://github.com/qgis/QGIS/issues/37551)
if ( group )
if ( !groupName.isEmpty() )
{
if ( !layerName.isEmpty() )
layer->setName( layerName );
else if ( !baseName.isEmpty() )
layer->setName( baseName );
QgsProject::instance()->addMapLayer( layer.release(), false );
group->addLayer( ml );
QgsProject::instance()->addMapLayer( layer.release(), addToLegend );
if ( group )
{
group->addLayer( ml );
}
}
else
{
@ -676,7 +761,7 @@ QList<QgsMapLayer *> QgsAppLayerHandling::addSublayers( const QList<QgsProviderS
layer->setName( layerName );
else if ( !baseName.isEmpty() )
layer->setName( baseName );
QgsProject::instance()->addMapLayer( layer.release() );
QgsProject::instance()->addMapLayer( layer.release(), addToLegend );
}
// Some of the logic relating to matching a new project's CRS to the first layer added CRS is deferred to happen when the event loop
@ -718,7 +803,7 @@ QList<QgsMapLayer *> QgsAppLayerHandling::addSublayers( const QList<QgsProviderS
return result;
}
QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName, bool &ok, bool allowInteractive, bool suppressBulkLayerPostProcessing )
QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName, bool &ok, bool allowInteractive, bool suppressBulkLayerPostProcessing, bool addToLegend )
{
QList< QgsMapLayer * > openedLayers;
auto postProcessAddedLayers = [suppressBulkLayerPostProcessing, &openedLayers]
@ -749,7 +834,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
case QgsMapLayerType::PointCloudLayer:
{
if ( QgsPointCloudLayer *layer = addPointCloudLayer( fileName, fileInfo.completeBaseName(), candidateProviders.at( 0 ).metadata()->key(), true ) )
if ( QgsPointCloudLayer *layer = addPointCloudLayer( fileName, fileInfo.completeBaseName(), candidateProviders.at( 0 ).metadata()->key(), true, addToLegend ) )
{
ok = true;
openedLayers << layer;
@ -800,7 +885,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
if ( vtLayer->isValid() )
{
openedLayers << vtLayer.get();
QgsProject::instance()->addMapLayer( vtLayer.release() );
QgsProject::instance()->addMapLayer( vtLayer.release(), addToLegend );
postProcessAddedLayers();
ok = true;
return openedLayers;
@ -812,7 +897,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
QUrlQuery uq;
uq.addQueryItem( QStringLiteral( "type" ), QStringLiteral( "mbtiles" ) );
uq.addQueryItem( QStringLiteral( "url" ), QUrl::fromLocalFile( fileName ).toString() );
if ( QgsRasterLayer *rasterLayer = addRasterLayer( uq.toString(), fileInfo.completeBaseName(), QStringLiteral( "wms" ) ) )
if ( QgsRasterLayer *rasterLayer = addRasterLayer( uq.toString(), fileInfo.completeBaseName(), QStringLiteral( "wms" ), addToLegend ) )
{
openedLayers << rasterLayer;
postProcessAddedLayers();
@ -834,7 +919,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
{
openedLayers << vtLayer.get();
QgsAppLayerHandling::postProcessAddedLayer( vtLayer.get() );
QgsProject::instance()->addMapLayer( vtLayer.release() );
QgsProject::instance()->addMapLayer( vtLayer.release(), addToLegend );
postProcessAddedLayers();
ok = true;
return openedLayers;
@ -925,7 +1010,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
base = QgsMapLayer::formatLayerName( base );
}
openedLayers.append( addSublayers( sublayers, base, groupName ) );
openedLayers.append( addSublayers( sublayers, base, groupName, addToLegend ) );
QgisApp::instance()->activateDeactivateLayerRelatedActions( QgisApp::instance()->activeLayer() );
}
else if ( !nonLayerItems.empty() )
@ -978,19 +1063,19 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
return openedLayers;
}
QgsVectorLayer *QgsAppLayerHandling::addVectorLayer( const QString &uri, const QString &baseName, const QString &provider )
QgsVectorLayer *QgsAppLayerHandling::addVectorLayer( const QString &uri, const QString &baseName, const QString &provider, bool addToLegend )
{
return addLayerPrivate< QgsVectorLayer >( QgsMapLayerType::VectorLayer, uri, baseName, !provider.isEmpty() ? provider : QLatin1String( "ogr" ), true );
return addLayerPrivate< QgsVectorLayer >( QgsMapLayerType::VectorLayer, uri, baseName, !provider.isEmpty() ? provider : QLatin1String( "ogr" ), true, addToLegend );
}
QgsRasterLayer *QgsAppLayerHandling::addRasterLayer( const QString &uri, const QString &baseName, const QString &provider )
QgsRasterLayer *QgsAppLayerHandling::addRasterLayer( const QString &uri, const QString &baseName, const QString &provider, bool addToLegend )
{
return addLayerPrivate< QgsRasterLayer >( QgsMapLayerType::RasterLayer, uri, baseName, !provider.isEmpty() ? provider : QLatin1String( "gdal" ), true );
return addLayerPrivate< QgsRasterLayer >( QgsMapLayerType::RasterLayer, uri, baseName, !provider.isEmpty() ? provider : QLatin1String( "gdal" ), true, addToLegend );
}
QgsMeshLayer *QgsAppLayerHandling::addMeshLayer( const QString &uri, const QString &baseName, const QString &provider )
QgsMeshLayer *QgsAppLayerHandling::addMeshLayer( const QString &uri, const QString &baseName, const QString &provider, bool addToLegend )
{
return addLayerPrivate< QgsMeshLayer >( QgsMapLayerType::MeshLayer, uri, baseName, provider, true );
return addLayerPrivate< QgsMeshLayer >( QgsMapLayerType::MeshLayer, uri, baseName, provider, true, addToLegend );
}
QList<QgsMapLayer *> QgsAppLayerHandling::addGdalRasterLayers( const QStringList &uris, bool &ok, bool showWarningOnInvalid )
@ -1088,16 +1173,14 @@ QList<QgsMapLayer *> QgsAppLayerHandling::addGdalRasterLayers( const QStringList
return res;
}
void QgsAppLayerHandling::addMapLayer( QgsMapLayer *mapLayer )
void QgsAppLayerHandling::addMapLayer( QgsMapLayer *mapLayer, bool addToLegend )
{
QgsCanvasRefreshBlocker refreshBlocker;
if ( mapLayer->isValid() )
{
// Register this layer with the layers registry
QList<QgsMapLayer *> myList;
myList << mapLayer;
QgsProject::instance()->addMapLayers( myList );
QgsProject::instance()->addMapLayer( mapLayer, addToLegend );
QgisApp::instance()->askUserForDatumTransform( mapLayer->crs(), QgsProject::instance()->crs(), mapLayer );
}
@ -1247,7 +1330,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::addDatabaseLayers( const QStringList
}
template<typename T>
T *QgsAppLayerHandling::addLayerPrivate( QgsMapLayerType type, const QString &uri, const QString &name, const QString &providerKey, bool guiWarnings )
T *QgsAppLayerHandling::addLayerPrivate( QgsMapLayerType type, const QString &uri, const QString &name, const QString &providerKey, bool guiWarnings, bool addToLegend )
{
QgsSettings settings;
@ -1317,14 +1400,14 @@ T *QgsAppLayerHandling::addLayerPrivate( QgsMapLayerType type, const QString &ur
const QList< QgsProviderSublayerDetails > selectedLayers = dlg.selectedLayers();
if ( !selectedLayers.isEmpty() )
{
result = qobject_cast< T * >( addSublayers( selectedLayers, baseName, dlg.groupName() ).value( 0 ) );
result = qobject_cast< T * >( addSublayers( selectedLayers, baseName, dlg.groupName(), addToLegend ).value( 0 ) );
}
}
break;
}
case SublayerHandling::LoadAll:
{
result = qobject_cast< T * >( addSublayers( sublayers, baseName, QString() ).value( 0 ) );
result = qobject_cast< T * >( addSublayers( sublayers, baseName, QString(), addToLegend ).value( 0 ) );
break;
}
case SublayerHandling::AbortLoading:
@ -1333,7 +1416,7 @@ T *QgsAppLayerHandling::addLayerPrivate( QgsMapLayerType type, const QString &ur
}
else
{
result = qobject_cast< T * >( addSublayers( sublayers, name, QString() ).value( 0 ) );
result = qobject_cast< T * >( addSublayers( sublayers, name, QString(), addToLegend ).value( 0 ) );
if ( result )
{
@ -1359,7 +1442,7 @@ T *QgsAppLayerHandling::addLayerPrivate( QgsMapLayerType type, const QString &ur
base = QgsMapLayer::formatLayerName( base );
}
result->setName( base );
QgsProject::instance()->addMapLayer( result );
QgsProject::instance()->addMapLayer( result, addToLegend );
QgisApp::instance()->askUserForDatumTransform( result->crs(), QgsProject::instance()->crs(), result );
QgsAppLayerHandling::postProcessAddedLayer( result );

View File

@ -56,7 +56,7 @@ class APP_EXPORT QgsAppLayerHandling
* \note This may trigger a dialog asking users to select from available sublayers in the datasource,
* depending on the contents of the datasource and the user's current QGIS settings.
*/
static QgsVectorLayer *addVectorLayer( const QString &uri, const QString &baseName, const QString &provider = QLatin1String( "ogr" ) );
static QgsVectorLayer *addVectorLayer( const QString &uri, const QString &baseName, const QString &provider = QLatin1String( "ogr" ), bool addToLegend = true );
/**
* Adds a list of vector layers from a list of layer \a uris supported by the OGR provider.
@ -77,7 +77,7 @@ class APP_EXPORT QgsAppLayerHandling
* \note This may trigger a dialog asking users to select from available sublayers in the datasource,
* depending on the contents of the datasource and the user's current QGIS settings.
*/
static QgsRasterLayer *addRasterLayer( QString const &uri, const QString &baseName, const QString &provider = QLatin1String( "gdal" ) );
static QgsRasterLayer *addRasterLayer( QString const &uri, const QString &baseName, const QString &provider = QLatin1String( "gdal" ), bool addToLegend = true );
/**
* Adds a list of raster layers from a list of layer \a uris supported by the GDAL provider.
@ -98,7 +98,7 @@ class APP_EXPORT QgsAppLayerHandling
* \note This may trigger a dialog asking users to select from available sublayers in the datasource,
* depending on the contents of the datasource and the user's current QGIS settings.
*/
static QgsMeshLayer *addMeshLayer( const QString &uri, const QString &baseName, const QString &provider );
static QgsMeshLayer *addMeshLayer( const QString &uri, const QString &baseName, const QString &provider, bool addToLegend = true );
/**
* Adds a point cloud layer from a given \a uri and \a provider.
@ -111,14 +111,15 @@ class APP_EXPORT QgsAppLayerHandling
static QgsPointCloudLayer *addPointCloudLayer( const QString &uri,
const QString &baseName,
const QString &provider,
bool showWarningOnInvalid = true );
bool showWarningOnInvalid = true,
bool addToLegend = true );
/**
* Adds a plugin layer from a given \a uri and \a provider.
*
* The \a baseName parameter will be used as the layer name (and shown in the map legend).
*/
static QgsPluginLayer *addPluginLayer( const QString &uri, const QString &baseName, const QString &providerKey );
static QgsPluginLayer *addPluginLayer( const QString &uri, const QString &baseName, const QString &providerKey, bool addToLegend = true );
/**
* Adds a vector tile layer from a given \a uri.
@ -128,7 +129,7 @@ class APP_EXPORT QgsAppLayerHandling
* If \a showWarningOnInvalid layers is TRUE then a user facing warning will be raised
* if the \a uri does not result in a valid vector tile layer.
*/
static QgsVectorTileLayer *addVectorTileLayer( const QString &uri, const QString &baseName, bool showWarningOnInvalid = true );
static QgsVectorTileLayer *addVectorTileLayer( const QString &uri, const QString &baseName, bool showWarningOnInvalid = true, bool addToLegend = true );
/**
* Post processes an entire group of added \a layers.
@ -139,6 +140,8 @@ class APP_EXPORT QgsAppLayerHandling
*/
static void postProcessAddedLayers( const QList< QgsMapLayer * > &layers );
static void addSortedLayersToLegend( QList< QgsMapLayer * > &layers );
/**
* Open a map layer from a file.
*
@ -147,10 +150,10 @@ class APP_EXPORT QgsAppLayerHandling
*
* \returns a list of added map layers if the file is successfully opened
*/
static QList< QgsMapLayer * > openLayer( const QString &fileName, bool &ok, bool allowInteractive = false, bool suppressBulkLayerPostProcessing = false );
static QList< QgsMapLayer * > openLayer( const QString &fileName, bool &ok, bool allowInteractive = false, bool suppressBulkLayerPostProcessing = false, bool addToLegend = true );
//! Add a 'pre-made' map layer to the project
static void addMapLayer( QgsMapLayer *mapLayer );
static void addMapLayer( QgsMapLayer *mapLayer, bool addToLegend = true );
static void openLayerDefinition( const QString &filename );
@ -216,7 +219,7 @@ class APP_EXPORT QgsAppLayerHandling
private:
template<typename T> static T *addLayerPrivate( QgsMapLayerType type, const QString &uri, const QString &baseName, const QString &providerKey, bool guiWarnings = true );
template<typename T> static T *addLayerPrivate( QgsMapLayerType type, const QString &uri, const QString &baseName, const QString &providerKey, bool guiWarnings = true, bool addToLegend = true );
/**
* Post processes a single added \a layer, applying any default behavior which should
@ -236,7 +239,7 @@ class APP_EXPORT QgsAppLayerHandling
static SublayerHandling shouldAskUserForSublayers( const QList< QgsProviderSublayerDetails > &layers, bool hasNonLayerItems = false );
static QList< QgsMapLayer * > addSublayers( const QList< QgsProviderSublayerDetails> &layers, const QString &baseName, const QString &groupName );
static QList< QgsMapLayer * > addSublayers( const QList< QgsProviderSublayerDetails> &layers, const QString &baseName, const QString &groupName, bool addToLegend = true );
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAppLayerHandling::DependencyFlags );

View File

@ -2103,6 +2103,7 @@ void QgisApp::dropEvent( QDropEvent *event )
lst = QgsMimeDataUtils::decodeUriList( event->mimeData() );
}
qDebug() << files;
connect( timer, &QTimer::timeout, this, [this, timer, files, lst]
{
QgsCanvasRefreshBlocker refreshBlocker;
@ -2130,13 +2131,13 @@ void QgisApp::dropEvent( QDropEvent *event )
if ( !handled )
{
addedLayers.append( openFile( file, QString(), true ) );
addedLayers.append( openFile( file, QString(), true, false ) );
}
}
if ( !lst.isEmpty() )
{
addedLayers.append( handleDropUriList( lst, true ) );
addedLayers.append( handleDropUriList( lst, true, false ) );
}
// Manually run autoSelectAddedLayer()
@ -2144,7 +2145,11 @@ void QgisApp::dropEvent( QDropEvent *event )
autoSelectAddedLayer( addedLayers );
if ( !addedLayers.isEmpty() )
{
qDebug() << addedLayers.size();
QgsAppLayerHandling::addSortedLayersToLegend( addedLayers );
QgsAppLayerHandling::postProcessAddedLayers( addedLayers );
}
timer->deleteLater();
} );
@ -2219,7 +2224,7 @@ QVector<QPointer<QgsLayoutCustomDropHandler> > QgisApp::customLayoutDropHandlers
return mCustomLayoutDropHandlers;
}
QList< QgsMapLayer * > QgisApp::handleDropUriList( const QgsMimeDataUtils::UriList &lst, bool suppressBulkLayerPostProcessing )
QList< QgsMapLayer * > QgisApp::handleDropUriList( const QgsMimeDataUtils::UriList &lst, bool suppressBulkLayerPostProcessing, bool addToLegend )
{
// avoid unnecessary work when adding lots of layers at once - defer emitting the active layer changed signal until we've
// added all layers, and only emit the signal once for the final layer added
@ -2257,31 +2262,31 @@ QList< QgsMapLayer * > QgisApp::handleDropUriList( const QgsMimeDataUtils::UriLi
if ( u.layerType == QLatin1String( "collection" ) )
{
bool ok = false;
const QList< QgsMapLayer * > collectionLayers = QgsAppLayerHandling::openLayer( uri, ok, true, true );
const QList< QgsMapLayer * > collectionLayers = QgsAppLayerHandling::openLayer( uri, ok, true, true, addToLegend );
if ( ok )
addedLayers.append( collectionLayers );
}
else if ( u.layerType == QLatin1String( "vector" ) )
{
QgsMapLayer *layer = QgsAppLayerHandling::addVectorLayer( uri, u.name, u.providerKey );
QgsMapLayer *layer = QgsAppLayerHandling::addVectorLayer( uri, u.name, u.providerKey, addToLegend );
if ( layer )
addedLayers << layer;
}
else if ( u.layerType == QLatin1String( "raster" ) )
{
QgsMapLayer *layer = QgsAppLayerHandling::addRasterLayer( uri, u.name, u.providerKey );
QgsMapLayer *layer = QgsAppLayerHandling::addRasterLayer( uri, u.name, u.providerKey, addToLegend );
if ( layer )
addedLayers << layer;
}
else if ( u.layerType == QLatin1String( "mesh" ) )
{
QgsMapLayer *layer = QgsAppLayerHandling::addMeshLayer( uri, u.name, u.providerKey );
QgsMapLayer *layer = QgsAppLayerHandling::addMeshLayer( uri, u.name, u.providerKey, addToLegend );
if ( layer )
addedLayers << layer;
}
else if ( u.layerType == QLatin1String( "pointcloud" ) )
{
QgsMapLayer *layer = QgsAppLayerHandling::addPointCloudLayer( uri, u.name, u.providerKey );
QgsMapLayer *layer = QgsAppLayerHandling::addPointCloudLayer( uri, u.name, u.providerKey, addToLegend );
if ( layer )
addedLayers << layer;
}
@ -2317,7 +2322,7 @@ QList< QgsMapLayer * > QgisApp::handleDropUriList( const QgsMimeDataUtils::UriLi
if ( subLayers.empty() )
{
QgsAppLayerHandling::addMapLayer( layer );
QgsAppLayerHandling::addMapLayer( layer, addToLegend );
addedLayers << layer;
}
else
@ -2325,55 +2330,64 @@ QList< QgsMapLayer * > QgisApp::handleDropUriList( const QgsMimeDataUtils::UriLi
// if there's any sublayers, we add them all to a group to keep things together
const QString groupName = layer->name();
QgsLayerTreeGroup *group = nullptr;
int index { 0 };
QgsLayerTreeNode *currentNode { mLayerTreeView->currentNode() };
if ( currentNode && currentNode->parent() )
if ( addToLegend )
{
if ( QgsLayerTree::isGroup( currentNode ) )
int index { 0 };
QgsLayerTreeNode *currentNode { mLayerTreeView->currentNode() };
if ( currentNode && currentNode->parent() )
{
group = qobject_cast<QgsLayerTreeGroup *>( currentNode )->insertGroup( 0, groupName );
}
else if ( QgsLayerTree::isLayer( currentNode ) )
{
const QList<QgsLayerTreeNode *> currentNodeSiblings { currentNode->parent()->children() };
int nodeIdx { 0 };
for ( const QgsLayerTreeNode *child : std::as_const( currentNodeSiblings ) )
if ( QgsLayerTree::isGroup( currentNode ) )
{
nodeIdx++;
if ( child == currentNode )
{
index = nodeIdx;
break;
}
group = qobject_cast<QgsLayerTreeGroup *>( currentNode )->insertGroup( 0, groupName );
}
else if ( QgsLayerTree::isLayer( currentNode ) )
{
const QList<QgsLayerTreeNode *> currentNodeSiblings { currentNode->parent()->children() };
int nodeIdx { 0 };
for ( const QgsLayerTreeNode *child : std::as_const( currentNodeSiblings ) )
{
nodeIdx++;
if ( child == currentNode )
{
index = nodeIdx;
break;
}
}
group = qobject_cast<QgsLayerTreeGroup *>( currentNode->parent() )->insertGroup( index, groupName );
}
else
{
group = QgsProject::instance()->layerTreeRoot()->insertGroup( 0, groupName );
}
group = qobject_cast<QgsLayerTreeGroup *>( currentNode->parent() )->insertGroup( index, groupName );
}
else
{
group = QgsProject::instance()->layerTreeRoot()->insertGroup( 0, groupName );
}
}
else
{
group = QgsProject::instance()->layerTreeRoot()->insertGroup( 0, groupName );
}
// sublayers get added first, because we want them to render on top of the vector tile layer (for now, maybe in future we can add support
// for rendering them amongst the vector tile layers(!) or for rendering them below the vector tile layer)
for ( QgsMapLayer *subLayer : std::as_const( subLayers ) )
{
QgsProject::instance()->addMapLayer( subLayer, false );
group->addLayer( subLayer );
if ( group )
{
group->addLayer( subLayer );
}
addedLayers << subLayer;
}
QgsProject::instance()->addMapLayer( layer, false );
group->addLayer( layer );
if ( group )
{
group->addLayer( layer );
}
addedLayers << layer;
}
}
else if ( u.layerType == QLatin1String( "plugin" ) )
{
QgsMapLayer *layer = QgsAppLayerHandling::addPluginLayer( uri, u.name, u.providerKey );
QgsMapLayer *layer = QgsAppLayerHandling::addPluginLayer( uri, u.name, u.providerKey, addToLegend );
if ( layer )
addedLayers << layer;
}
@ -6721,7 +6735,7 @@ void QgisApp::openProject( const QString &fileName )
}
// Open a file specified by a commandline argument, Drop or FileOpen event.
QList< QgsMapLayer * > QgisApp::openFile( const QString &fileName, const QString &fileTypeHint, bool suppressBulkLayerPostProcessing )
QList< QgsMapLayer * > QgisApp::openFile( const QString &fileName, const QString &fileTypeHint, bool suppressBulkLayerPostProcessing, bool addToLegend )
{
QList< QgsMapLayer * > res;
@ -6748,7 +6762,7 @@ QList< QgsMapLayer * > QgisApp::openFile( const QString &fileName, const QString
{
QgsDebugMsgLevel( "Adding " + fileName + " to the map canvas", 2 );
bool ok = false;
res = QgsAppLayerHandling::openLayer( fileName, ok, true, suppressBulkLayerPostProcessing );
res = QgsAppLayerHandling::openLayer( fileName, ok, true, suppressBulkLayerPostProcessing, addToLegend );
}
return res;

View File

@ -905,14 +905,14 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
*
* Returns a list of layers loaded as a result of opening the URIs.
*/
QList< QgsMapLayer * > handleDropUriList( const QgsMimeDataUtils::UriList &lst, bool suppressBulkLayerPostProcessing = false );
QList< QgsMapLayer * > handleDropUriList( const QgsMimeDataUtils::UriList &lst, bool suppressBulkLayerPostProcessing = false, bool addToLegend = true );
/**
* Convenience function to open either a project or a layer file.
*
* Returns a list of layers loaded as a result of opening the file.
*/
QList< QgsMapLayer * > openFile( const QString &fileName, const QString &fileTypeHint = QString(), bool suppressBulkLayerPostProcessing = false );
QList< QgsMapLayer * > openFile( const QString &fileName, const QString &fileTypeHint = QString(), bool suppressBulkLayerPostProcessing = false, bool addToLegend = true );
void layerTreeViewDoubleClicked( const QModelIndex &index );
//! Make sure the insertion point for new layers is up-to-date with the current item in layer tree view
void updateNewLayerInsertionPoint();