Skip to content

Commit

Permalink
Port mesh layer adding to new api/dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 12, 2021
1 parent d44f310 commit 41d2206
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 118 deletions.
167 changes: 71 additions & 96 deletions src/app/qgisapp.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5658,24 +5658,21 @@ QgsMeshLayer *QgisApp::addMeshLayerPrivate( const QString &url, const QString &b
QgsCanvasRefreshBlocker refreshBlocker; QgsCanvasRefreshBlocker refreshBlocker;
QgsSettings settings; QgsSettings settings;


QString base( baseName ); // query sublayers
QList< QgsProviderSublayerDetails > sublayers = QgsProviderRegistry::instance()->providerMetadata( providerKey ) ?
QgsProviderRegistry::instance()->providerMetadata( providerKey )->querySublayers( url )
: QgsProviderRegistry::instance()->querySublayers( url );


if ( settings.value( QStringLiteral( "qgis/formatLayerName" ), false ).toBool() ) // filter out non-mesh sublayers
sublayers.erase( std::remove_if( sublayers.begin(), sublayers.end(), []( const QgsProviderSublayerDetails & sublayer )
{ {
base = QgsMapLayer::formatLayerName( base ); return sublayer.type() != QgsMapLayerType::MeshLayer;
} } ), sublayers.end() );


QgsDebugMsgLevel( "completeBaseName: " + base, 2 ); QgsMeshLayer *result = nullptr;
QgsProviderSublayerDetails::LayerOptions options( QgsProject::instance()->transformContext() );


// create the layer if ( sublayers.empty() )
QgsMeshLayer::LayerOptions options;
std::unique_ptr<QgsMeshLayer> layer( new QgsMeshLayer( url, base, providerKey, options ) );

QDateTime referenceTime = QgsProject::instance()->timeSettings()->temporalRange().begin();
if ( !referenceTime.isValid() ) // If project reference time is invalid, use current date
referenceTime = QDateTime( QDate::currentDate(), QTime( 0, 0, 0 ), Qt::UTC );

if ( ! layer || ( !layer->isValid() && layer->subLayers().isEmpty() ) )
{ {
if ( guiWarning ) if ( guiWarning )
{ {
Expand All @@ -5686,45 +5683,79 @@ QgsMeshLayer *QgisApp::addMeshLayerPrivate( const QString &url, const QString &b
// since the layer is bad, stomp on it // since the layer is bad, stomp on it
return nullptr; return nullptr;
} }

else if ( sublayers.size() > 1 )
if ( !layer->isValid() && layer->subLayers().count() > 0 ) //sublayers to load
{ {
QList< QgsMapLayer * > subLayers = askUserForMDALSublayers( layer.get() ); // ask user for sublayers

QgsProviderSublayersDialog dlg( url, sublayers, this );
if ( subLayers.isEmpty() ) if ( dlg.exec() )
layer.reset( nullptr );
else
{ {
for ( QgsMapLayer *newLayer : std::as_const( subLayers ) ) const QList< QgsProviderSublayerDetails > selectedLayers = dlg.selectedLayers();
if ( !selectedLayers.isEmpty() )
{ {
askUserForDatumTransform( newLayer->crs(), QgsProject::instance()->crs(), newLayer ); const QString groupName = dlg.groupName();
QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( newLayer ); QgsLayerTreeGroup *group = nullptr;
if ( ! qobject_cast< QgsMeshLayerTemporalProperties * >( meshLayer->temporalProperties() )->referenceTime().isValid() ) if ( !groupName.isEmpty() )
qobject_cast< QgsMeshLayerTemporalProperties * >( meshLayer->temporalProperties() )->setReferenceTime( referenceTime, meshLayer->dataProvider()->temporalCapabilities() ); {
bool ok; group = QgsProject::instance()->layerTreeRoot()->insertGroup( 0, groupName );
newLayer->loadDefaultStyle( ok ); }
newLayer->loadDefaultMetadata( ok );
}


layer.reset( qobject_cast< QgsMeshLayer * >( subLayers.at( 0 ) ) ); for ( const QgsProviderSublayerDetails &sublayer : std::as_const( selectedLayers ) )
} {
std::unique_ptr<QgsMeshLayer> layer( qobject_cast< QgsMeshLayer * >( sublayer.toLayer( options ) ) );
QgsMeshLayer *ml = layer.get();
if ( !result )
result = ml;

if ( group )
{
QgsProject::instance()->addMapLayer( layer.release(), false );
group->addLayer( ml );
}
else
{
QgsProject::instance()->addMapLayer( layer.release() );
}


postProcessAddedMeshLayer( ml );
}
}
}
} }
else else
{ {
if ( ! qobject_cast< QgsMeshLayerTemporalProperties * >( layer->temporalProperties() )->referenceTime().isValid() ) // create the layer
qobject_cast< QgsMeshLayerTemporalProperties * >( layer->temporalProperties() )->setReferenceTime( referenceTime, layer->dataProvider()->temporalCapabilities() ); std::unique_ptr<QgsMeshLayer> layer( qobject_cast< QgsMeshLayer * >( sublayers.at( 0 ).toLayer( options ) ) );
QgsProject::instance()->addMapLayer( layer.get() ); result = layer.get();
askUserForDatumTransform( layer->crs(), QgsProject::instance()->crs(), layer.get() );


bool ok; QString base( baseName );
layer->loadDefaultStyle( ok ); if ( settings.value( QStringLiteral( "qgis/formatLayerName" ), false ).toBool() )
layer->loadDefaultMetadata( ok ); {
base = QgsMapLayer::formatLayerName( base );
}
layer->setName( base );

QgsProject::instance()->addMapLayer( layer.release() );
postProcessAddedMeshLayer( result );
} }


activateDeactivateLayerRelatedActions( activeLayer() ); activateDeactivateLayerRelatedActions( activeLayer() );
return result;
}


return layer.release(); void QgisApp::postProcessAddedMeshLayer( QgsMeshLayer *layer )
{
QDateTime referenceTime = QgsProject::instance()->timeSettings()->temporalRange().begin();
if ( !referenceTime.isValid() ) // If project reference time is invalid, use current date
referenceTime = QDateTime( QDate::currentDate(), QTime( 0, 0, 0 ), Qt::UTC );

if ( ! qobject_cast< QgsMeshLayerTemporalProperties * >( layer->temporalProperties() )->referenceTime().isValid() )
qobject_cast< QgsMeshLayerTemporalProperties * >( layer->temporalProperties() )->setReferenceTime( referenceTime, layer->dataProvider()->temporalCapabilities() );

askUserForDatumTransform( layer->crs(), QgsProject::instance()->crs(), layer );

bool ok = false;
layer->loadDefaultStyle( ok );
layer->loadDefaultMetadata( ok );
} }


QgsVectorTileLayer *QgisApp::addVectorTileLayer( const QString &url, const QString &baseName ) QgsVectorTileLayer *QgisApp::addVectorTileLayer( const QString &url, const QString &baseName )
Expand Down Expand Up @@ -6272,62 +6303,6 @@ QList<QgsMapLayer *> QgisApp::askUserForOGRSublayers( QgsVectorLayer *&parentLay
return result; return result;
} }


QList<QgsMapLayer *> QgisApp::askUserForMDALSublayers( QgsMeshLayer *layer )
{
QList< QgsMapLayer * > result;
if ( !layer )
return result;

QStringList sublayers = layer->subLayers();
if ( sublayers.empty() )
return result;

QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Mdal, QStringLiteral( "mdal" ), this );
chooseSublayersDialog.setShowAddToGroupCheckbox( true );

QgsSublayersDialog::LayerDefinitionList layersDefList;
int id = 1;
for ( const QString &layerUri : sublayers )
{
QgsSublayersDialog::LayerDefinition definition;
QString name = layerUri;
definition.layerName = layerUri;
definition.layerId = id++;
layersDefList.append( definition );
}

chooseSublayersDialog.populateLayerTable( layersDefList );
if ( chooseSublayersDialog.exec() )
{
QgsSublayersDialog::LayerDefinitionList selection = chooseSublayersDialog.selection();
for ( auto definition : selection )
{
int id = definition.layerId;
QString name = definition.layerName;
QString path = layer->source();
name = name.mid( name.indexOf( path ) + path.length() + 2 );
result.append( new QgsMeshLayer( sublayers.at( id - 1 ), name, QStringLiteral( "mdal" ) ) );
}

if ( !selection.isEmpty() )
{
if ( chooseSublayersDialog.addToGroupCheckbox() )
{
QgsLayerTreeGroup *group = QgsProject::instance()->layerTreeRoot()->insertGroup( 0, layer->name() );
for ( QgsMapLayer *layerAdded : result )
{
QgsProject::instance()->addMapLayer( layerAdded, false );
group->addLayer( layerAdded );
}
}
else
QgsProject::instance()->addMapLayers( result );
}
}

return result;
}

void QgisApp::addDatabaseLayers( QStringList const &layerPathList, QString const &providerKey ) void QgisApp::addDatabaseLayers( QStringList const &layerPathList, QString const &providerKey )
{ {
QList<QgsMapLayer *> myList; QList<QgsMapLayer *> myList;
Expand Down
8 changes: 2 additions & 6 deletions src/app/qgisapp.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2111,16 +2111,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
const QString &providerKey, bool guiWarning, const QString &providerKey, bool guiWarning,
bool guiUpdate ); bool guiUpdate );


/**
* This method will open a dialog so the user can select MDAL mesh sublayers to load,
* and then returns a list of these layers. Layers are added to the project in the method.
*/
QList< QgsMapLayer * > askUserForMDALSublayers( QgsMeshLayer *layer );

//! Open a mesh layer - this is the generic function which takes all parameters //! Open a mesh layer - this is the generic function which takes all parameters
QgsMeshLayer *addMeshLayerPrivate( const QString &uri, const QString &baseName, QgsMeshLayer *addMeshLayerPrivate( const QString &uri, const QString &baseName,
const QString &providerKey, bool guiWarning = true ); const QString &providerKey, bool guiWarning = true );


void postProcessAddedMeshLayer( QgsMeshLayer *layer );

//! Open a vector tile layer - this is the generic function which takes all parameters //! Open a vector tile layer - this is the generic function which takes all parameters
QgsVectorTileLayer *addVectorTileLayerPrivate( const QString &uri, const QString &baseName, bool guiWarning = true ); QgsVectorTileLayer *addVectorTileLayerPrivate( const QString &uri, const QString &baseName, bool guiWarning = true );


Expand Down
46 changes: 30 additions & 16 deletions src/app/qgsprovidersublayersdialog.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ QgsProviderSublayersDialog::QgsProviderSublayersDialog( const QString &uri, cons
QgsGui::enableAutoGeometryRestore( this ); QgsGui::enableAutoGeometryRestore( this );


const QFileInfo fileInfo( uri ); const QFileInfo fileInfo( uri );
const QString filePath = fileInfo.isFile() && fileInfo.exists() ? uri : QString(); mFilePath = fileInfo.isFile() && fileInfo.exists() ? uri : QString();
const QString fileName = !filePath.isEmpty() ? fileInfo.fileName() : QString(); mFileName = !mFilePath.isEmpty() ? fileInfo.fileName() : QString();


setWindowTitle( fileName.isEmpty() ? tr( "Select Items to Add" ) : QStringLiteral( "%1 | %2" ).arg( tr( "Select Items to Add" ), fileName ) ); setWindowTitle( mFileName.isEmpty() ? tr( "Select Items to Add" ) : QStringLiteral( "%1 | %2" ).arg( tr( "Select Items to Add" ), mFileName ) );


mLblFilePath->setText( QStringLiteral( "<a href=\"%1\">%2</a>" ) mLblFilePath->setText( QStringLiteral( "<a href=\"%1\">%2</a>" )
.arg( QUrl::fromLocalFile( filePath ).toString(), QDir::toNativeSeparators( QFileInfo( filePath ).canonicalFilePath() ) ) ); .arg( QUrl::fromLocalFile( mFilePath ).toString(), QDir::toNativeSeparators( QFileInfo( mFilePath ).canonicalFilePath() ) ) );
mLblFilePath->setVisible( ! fileName.isEmpty() ); mLblFilePath->setVisible( !mFileName.isEmpty() );
mLblFilePath->setWordWrap( true ); mLblFilePath->setWordWrap( true );
mLblFilePath->setTextInteractionFlags( Qt::TextBrowserInteraction ); mLblFilePath->setTextInteractionFlags( Qt::TextBrowserInteraction );
connect( mLblFilePath, &QLabel::linkActivated, this, [ = ]( const QString & link ) connect( mLblFilePath, &QLabel::linkActivated, this, [ = ]( const QString & link )
Expand Down Expand Up @@ -158,17 +158,7 @@ QgsProviderSublayersDialog::QgsProviderSublayersDialog( const QString &uri, cons
connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject ); connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
connect( mButtonBox, &QDialogButtonBox::accepted, this, [ = ] connect( mButtonBox, &QDialogButtonBox::accepted, this, [ = ]
{ {
const QModelIndexList selection = mLayersTree->selectionModel()->selectedRows(); emit layersAdded( selectedLayers() );
QList< QgsProviderSublayerDetails > selectedSublayers;
for ( const QModelIndex &index : selection )
{
const QModelIndex sourceIndex = mProxyModel->mapToSource( index );
if ( !mModel->data( sourceIndex, static_cast< int >( QgsProviderSublayerModel::Role::IsNonLayerItem ) ).toBool() )
{
selectedSublayers << mModel->indexToSublayer( sourceIndex );
}
}
emit layersAdded( selectedSublayers );
accept(); accept();
} ); } );
mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
Expand All @@ -182,6 +172,30 @@ QgsProviderSublayersDialog::~QgsProviderSublayersDialog()
mTask->cancel(); mTask->cancel();
} }


QList<QgsProviderSublayerDetails> QgsProviderSublayersDialog::selectedLayers() const
{
const QModelIndexList selection = mLayersTree->selectionModel()->selectedRows();
QList< QgsProviderSublayerDetails > selectedSublayers;
for ( const QModelIndex &index : selection )
{
const QModelIndex sourceIndex = mProxyModel->mapToSource( index );
if ( !mModel->data( sourceIndex, static_cast< int >( QgsProviderSublayerModel::Role::IsNonLayerItem ) ).toBool() )
{
selectedSublayers << mModel->indexToSublayer( sourceIndex );
}
}
return selectedSublayers;
}

QString QgsProviderSublayersDialog::groupName() const
{
if ( !mCbxAddToGroup->isChecked() )
return QString();

const QFileInfo fi( mFilePath );
return fi.completeBaseName();
}

void QgsProviderSublayersDialog::treeSelectionChanged( const QItemSelection &, const QItemSelection & ) void QgsProviderSublayersDialog::treeSelectionChanged( const QItemSelection &, const QItemSelection & )
{ {
mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !mLayersTree->selectionModel()->selectedRows().empty() ); mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !mLayersTree->selectionModel()->selectedRows().empty() );
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgsprovidersublayersdialog.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class QgsProviderSublayersDialog : public QDialog, private Ui::QgsProviderSublay


~QgsProviderSublayersDialog() override; ~QgsProviderSublayersDialog() override;


QList< QgsProviderSublayerDetails > selectedLayers() const;
QString groupName() const;

signals: signals:


/** /**
Expand All @@ -69,6 +72,8 @@ class QgsProviderSublayersDialog : public QDialog, private Ui::QgsProviderSublay
QgsProviderSublayerModel *mModel = nullptr; QgsProviderSublayerModel *mModel = nullptr;
QgsProviderSublayerProxyModel *mProxyModel = nullptr; QgsProviderSublayerProxyModel *mProxyModel = nullptr;
QPointer< QgsProviderSublayerTask > mTask; QPointer< QgsProviderSublayerTask > mTask;
QString mFilePath;
QString mFileName;


}; };


Expand Down

0 comments on commit 41d2206

Please sign in to comment.