Skip to content

Commit

Permalink
Add the filename to the "Select Layers to Add.."
Browse files Browse the repository at this point in the history
  • Loading branch information
suricactus authored and nyalldawson committed May 17, 2020
1 parent 6c5cb2e commit 8ff229e
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 95 deletions.
25 changes: 23 additions & 2 deletions python/gui/auto_generated/qgssublayersdialog.sip.in
Expand Up @@ -16,6 +16,18 @@ class QgsSublayersDialog : QDialog
%End
public:

enum PromptMode
{

PromptAlways,

PromptIfNeeded,

PromptNever,

PromptLoadAll
};

enum ProviderType
{
Ogr,
Expand All @@ -35,12 +47,20 @@ class QgsSublayersDialog : QDialog

typedef QList<QgsSublayersDialog::LayerDefinition> LayerDefinitionList;


QgsSublayersDialog( ProviderType providerType,
const QString &name,
QWidget *parent /TransferThis/ = 0,
Qt::WindowFlags fl = 0 );
Qt::WindowFlags fl = 0,
const QString &providerSource = QString() );
%Docstring
Constructor for QgsSublayersDialog
Construct a new QgsSublayersDialog object - a dialog to select which sub layers to be imported from a file (e.g. from geopackage or zipfile)

@param providerType provider type
@param name provider type name
@param parent parent widget of the dialog
@param fl window flags
@param providerSource full file name
%End

~QgsSublayersDialog();
Expand Down Expand Up @@ -93,6 +113,7 @@ Returns column with count or -1

protected:


};

/************************************************************************
Expand Down
27 changes: 12 additions & 15 deletions src/app/qgisapp.cpp
Expand Up @@ -5603,7 +5603,7 @@ bool QgisApp::askUserForZipItemLayers( const QString &path )
QVector<QgsDataItem *> childItems;
QgsZipItem *zipItem = nullptr;
QgsSettings settings;
int promptLayers = settings.value( QStringLiteral( "qgis/promptForRasterSublayers" ), 1 ).toInt();
QgsSublayersDialog::PromptMode promptLayers = settings.enumValue( QStringLiteral( "qgis/promptForSublayers" ), QgsSublayersDialog::PromptAlways );

QgsDebugMsg( "askUserForZipItemLayers( " + path + ')' );

Expand All @@ -5628,20 +5628,20 @@ bool QgisApp::askUserForZipItemLayers( const QString &path )
}

// if promptLayers=Load all, load all layers without prompting
if ( promptLayers == 3 )
if ( promptLayers == QgsSublayersDialog::PromptLoadAll )
{
childItems = zipItem->children();
}
// exit if promptLayers=Never
else if ( promptLayers == 2 )
else if ( promptLayers == QgsSublayersDialog::PromptNever )
{
delete zipItem;
return false;
}
else
{
// We initialize a selection dialog and display it.
QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Vsifile, QStringLiteral( "vsi" ), this );
QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Vsifile, QStringLiteral( "vsi" ), this, nullptr, path );
QgsSublayersDialog::LayerDefinitionList layers;

for ( int i = 0; i < zipItem->children().size(); i++ )
Expand Down Expand Up @@ -5725,14 +5725,14 @@ QList< QgsMapLayer * > QgisApp::askUserForGDALSublayers( QgsRasterLayer *layer )

// if promptLayers=Load all, load all sublayers without prompting
QgsSettings settings;
if ( settings.value( QStringLiteral( "qgis/promptForRasterSublayers" ), 1 ).toInt() == 3 )
if ( settings.enumValue( QStringLiteral( "qgis/promptForSublayers" ), QgsSublayersDialog::PromptAlways ) == QgsSublayersDialog::PromptLoadAll )
{
result.append( loadGDALSublayers( layer->source(), sublayers ) );
return result;
}

// We initialize a selection dialog and display it.
QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Gdal, QStringLiteral( "gdal" ), this );
QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Gdal, QStringLiteral( "gdal" ), this, nullptr, layer->dataProvider()->dataSourceUri() );
chooseSublayersDialog.setShowAddToGroupCheckbox( true );

QgsSublayersDialog::LayerDefinitionList layers;
Expand Down Expand Up @@ -5849,13 +5849,11 @@ bool QgisApp::shouldAskUserForGDALSublayers( QgsRasterLayer *layer )
return false;

QgsSettings settings;
int promptLayers = settings.value( QStringLiteral( "qgis/promptForRasterSublayers" ), 1 ).toInt();
// 0 = Always -> always ask (if there are existing sublayers)
// 1 = If needed -> ask if layer has no bands, but has sublayers
// 2 = Never -> never prompt, will not load anything
// 3 = Load all -> never prompt, but load all sublayers
QgsSublayersDialog::PromptMode promptLayers = settings.enumValue( QStringLiteral( "qgis/promptForSublayers" ), QgsSublayersDialog::PromptAlways );

return promptLayers == 0 || promptLayers == 3 || ( promptLayers == 1 && layer->bandCount() == 0 );
return promptLayers == QgsSublayersDialog::PromptAlways ||
promptLayers == QgsSublayersDialog::PromptLoadAll ||
( promptLayers == QgsSublayersDialog::PromptIfNeeded && layer->bandCount() == 0 );
}

// This method will load with GDAL the layers in parameter.
Expand Down Expand Up @@ -5955,7 +5953,7 @@ QList<QgsMapLayer *> QgisApp::askUserForOGRSublayers( QgsVectorLayer *layer )
// Check if the current layer uri contains the

// We initialize a selection dialog and display it.
QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Ogr, QStringLiteral( "ogr" ), this );
QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Ogr, QStringLiteral( "ogr" ), this, nullptr, layer->dataProvider()->dataSourceUri() );
chooseSublayersDialog.setShowAddToGroupCheckbox( true );
chooseSublayersDialog.populateLayerTable( list );

Expand Down Expand Up @@ -5992,10 +5990,9 @@ QList<QgsMapLayer *> QgisApp::askUserForOGRSublayers( QgsVectorLayer *layer )
}

QgsDebugMsg( "Creating new vector layer using " + composedURI );
QString name = fileName + " " + def.layerName;
QgsVectorLayer::LayerOptions options { QgsProject::instance()->transformContext() };
options.loadDefaultStyle = false;
QgsVectorLayer *layer = new QgsVectorLayer( composedURI, name, QStringLiteral( "ogr" ), options );
QgsVectorLayer *layer = new QgsVectorLayer( composedURI, def.layerName, QStringLiteral( "ogr" ), options );
if ( layer && layer->isValid() )
{
result << layer;
Expand Down
21 changes: 9 additions & 12 deletions src/app/qgsoptions.cpp
Expand Up @@ -58,6 +58,7 @@
#include "qgswelcomepage.h"
#include "qgsnewsfeedparser.h"
#include "qgsbearingnumericformat.h"
#include "qgssublayersdialog.h"

#ifdef HAVE_OPENCL
#include "qgsopenclutils.h"
Expand Down Expand Up @@ -419,17 +420,12 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
spinBoxAttrTableRowCache->setValue( mSettings->value( QStringLiteral( "/qgis/attributeTableRowCache" ), 10000 ).toInt() );
spinBoxAttrTableRowCache->setSpecialValueText( tr( "All" ) );

// set the prompt for raster sublayers
// 0 = Always -> always ask (if there are existing sublayers)
// 1 = If needed -> ask if layer has no bands, but has sublayers
// 2 = Never -> never prompt, will not load anything
// 3 = Load all -> never prompt, but load all sublayers
cmbPromptRasterSublayers->clear();
cmbPromptRasterSublayers->addItem( tr( "Always" ) );
cmbPromptRasterSublayers->addItem( tr( "If needed" ) ); //this means, prompt if there are sublayers but no band in the main dataset
cmbPromptRasterSublayers->addItem( tr( "Never" ) );
cmbPromptRasterSublayers->addItem( tr( "Load all" ) );
cmbPromptRasterSublayers->setCurrentIndex( mSettings->value( QStringLiteral( "/qgis/promptForRasterSublayers" ), 0 ).toInt() );
cmbPromptSublayers->clear();
cmbPromptSublayers->addItem( tr( "Always" ), QgsSublayersDialog::PromptAlways );
cmbPromptSublayers->addItem( tr( "If needed" ), QgsSublayersDialog::PromptIfNeeded ); //this means, prompt if there are sublayers but no band in the main dataset
cmbPromptSublayers->addItem( tr( "Never" ), QgsSublayersDialog::PromptNever );
cmbPromptSublayers->addItem( tr( "Load all" ), QgsSublayersDialog::PromptLoadAll ); // check if this is true
cmbPromptSublayers->setCurrentIndex( cmbPromptSublayers->findData( mSettings->enumValue( QStringLiteral( "/qgis/promptForSublayers" ), QgsSublayersDialog::PromptAlways ) ) );

// Scan for valid items in the browser dock
cmbScanItemsInBrowser->clear();
Expand Down Expand Up @@ -1494,7 +1490,8 @@ void QgsOptions::saveOptions()
mSettings->setEnumValue( QStringLiteral( "/qgis/attributeTableBehavior" ), ( QgsAttributeTableFilterModel::FilterMode )cmbAttrTableBehavior->currentData().toInt() );
mSettings->setValue( QStringLiteral( "/qgis/attributeTableView" ), mAttrTableViewComboBox->currentData() );
mSettings->setValue( QStringLiteral( "/qgis/attributeTableRowCache" ), spinBoxAttrTableRowCache->value() );
mSettings->setValue( QStringLiteral( "/qgis/promptForRasterSublayers" ), cmbPromptRasterSublayers->currentIndex() );
mSettings->setEnumValue( QStringLiteral( "/qgis/promptForSublayers" ), ( QgsSublayersDialog::PromptMode )cmbPromptSublayers->currentData().toInt() );

mSettings->setValue( QStringLiteral( "/qgis/scanItemsInBrowser2" ),
cmbScanItemsInBrowser->currentData().toString() );
mSettings->setValue( QStringLiteral( "/qgis/scanZipInBrowser2" ),
Expand Down
73 changes: 46 additions & 27 deletions src/gui/qgssublayersdialog.cpp
Expand Up @@ -17,6 +17,7 @@
#include "qgslogger.h"
#include "qgssettings.h"
#include "qgsgui.h"
#include "qgsproviderregistry.h"

#include <QTableWidgetItem>
#include <QPushButton>
Expand All @@ -42,50 +43,62 @@ class SubLayerItem : public QTreeWidgetItem
};
//! @endcond

QgsSublayersDialog::QgsSublayersDialog( ProviderType providerType, const QString &name,
QWidget *parent, Qt::WindowFlags fl )
QgsSublayersDialog::QgsSublayersDialog( ProviderType providerType,
const QString &name,
QWidget *parent,
Qt::WindowFlags fl,
const QString &providerSource )
: QDialog( parent, fl )
, mName( name )
{
setupUi( this );
QgsGui::enableAutoGeometryRestore( this );

QString title;
switch ( providerType )
{
case QgsSublayersDialog::Ogr :
setWindowTitle( tr( "Select Vector Layers to Add…" ) );
title = tr( "Select Vector Layers to Add…" );
layersTable->setHeaderLabels( QStringList() << tr( "Layer ID" ) << tr( "Layer name" )
<< tr( "Number of features" ) << tr( "Geometry type" ) << tr( "Description" ) );
mShowCount = true;
mShowType = true;
mShowDescription = true;
break;
case QgsSublayersDialog::Gdal:
setWindowTitle( tr( "Select Raster Layers to Add…" ) );
title = tr( "Select Raster Layers to Add…" );
layersTable->setHeaderLabels( QStringList() << tr( "Layer ID" ) << tr( "Layer name" ) );
break;
case QgsSublayersDialog::Mdal:
setWindowTitle( tr( "Select Mesh Layers to Add…" ) );
title = tr( "Select Mesh Layers to Add…" );
layersTable->setHeaderLabels( QStringList() << tr( "Layer ID" ) << tr( "Mesh name" ) );
break;
default:
setWindowTitle( tr( "Select Layers to Add…" ) );
title = tr( "Select Layers to Add…" );
layersTable->setHeaderLabels( QStringList() << tr( "Layer ID" ) << tr( "Layer name" )
<< tr( "Type" ) );
mShowType = true;
break;
}

QString fileFullPath = providerType == QgsSublayersDialog::Vsifile
? providerSource
: QgsProviderRegistry::instance()->decodeUri( name, providerSource )
.value( QStringLiteral( "path" ) )
.toString();
QString filename = QFileInfo( fileFullPath ).fileName();

setWindowTitle( filename.isEmpty() ? title : QStringLiteral( "%1 | %2" ).arg( title, filename ) );
txtFilePath->setText( QDir::toNativeSeparators( QFileInfo( fileFullPath ).canonicalFilePath() ) );

if ( filename.isEmpty() )
txtFilePath->setVisible( false );

// add a "Select All" button - would be nicer with an icon
QPushButton *button = new QPushButton( tr( "Select All" ) );
buttonBox->addButton( button, QDialogButtonBox::ActionRole );
connect( button, &QAbstractButton::pressed, layersTable, &QTreeView::selectAll );
// connect( pbnSelectNone, SIGNAL( pressed() ), SLOT( layersTable->selectNone() ) );
connect( btnSelectAll, &QAbstractButton::pressed, layersTable, &QTreeView::selectAll );
connect( btnDeselectAll, &QAbstractButton::pressed, this, &QgsSublayersDialog::btnDeselectAll_pressed );
connect( layersTable->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsSublayersDialog::layersTable_selectionChanged );

// Checkbox about adding sublayers to a group
mCheckboxAddToGroup = new QCheckBox( tr( "Add layers to a group" ), this );
buttonBox->addButton( mCheckboxAddToGroup, QDialogButtonBox::ActionRole );
mCheckboxAddToGroup->setVisible( false );
mCbxAddToGroup->setVisible( false );
}

QgsSublayersDialog::~QgsSublayersDialog()
Expand Down Expand Up @@ -172,27 +185,23 @@ void QgsSublayersDialog::populateLayerTable( const QgsSublayersDialog::LayerDefi
int QgsSublayersDialog::exec()
{
QgsSettings settings;
QString promptLayers = settings.value( QStringLiteral( "qgis/promptForSublayers" ), 1 ).toString();
PromptMode promptLayers = settings.enumValue( QStringLiteral( "qgis/promptForSublayers" ), PromptAlways );

// make sure three are sublayers to choose
if ( layersTable->topLevelItemCount() == 0 )
return QDialog::Rejected;

layersTable->selectAll();

// check promptForSublayers settings - perhaps this should be in QgsDataSource instead?
if ( promptLayers == QLatin1String( "no" ) )
if ( promptLayers == PromptNever )
return QDialog::Rejected;
else if ( promptLayers == QLatin1String( "all" ) )
{
layersTable->selectAll();
else if ( promptLayers == PromptLoadAll )
return QDialog::Accepted;
}

// if there is only 1 sublayer (probably the main layer), just select that one and return
if ( layersTable->topLevelItemCount() == 1 )
{
layersTable->selectAll();
return QDialog::Accepted;
}

layersTable->sortByColumn( 1, Qt::AscendingOrder );
layersTable->setSortingEnabled( true );
Expand All @@ -210,16 +219,26 @@ int QgsSublayersDialog::exec()
// Checkbox about adding sublayers to a group
if ( mShowAddToGroupCheckbox )
{
mCheckboxAddToGroup->setVisible( true );
mCbxAddToGroup->setVisible( true );
bool addToGroup = settings.value( QStringLiteral( "/qgis/openSublayersInGroup" ), false ).toBool();
mCheckboxAddToGroup->setChecked( addToGroup );
mCbxAddToGroup->setChecked( addToGroup );
}

int ret = QDialog::exec();
if ( overrideCursor )
QApplication::setOverrideCursor( cursor );

if ( mShowAddToGroupCheckbox )
settings.setValue( QStringLiteral( "/qgis/openSublayersInGroup" ), mCheckboxAddToGroup->isChecked() );
settings.setValue( QStringLiteral( "/qgis/openSublayersInGroup" ), mCbxAddToGroup->isChecked() );
return ret;
}

void QgsSublayersDialog::layersTable_selectionChanged( const QItemSelection &, const QItemSelection & )
{
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( layersTable->selectedItems().length() > 0 );
}

void QgsSublayersDialog::btnDeselectAll_pressed()
{
layersTable->selectionModel()->clear();
}

0 comments on commit 8ff229e

Please sign in to comment.