improve bad layer handling: make all datasource editable (fixes #7039)

This commit is contained in:
Juergen E. Fischer 2014-06-17 23:45:30 +02:00
parent d308ee5201
commit 1532048430
3 changed files with 104 additions and 151 deletions

View File

@ -70,21 +70,20 @@ QgsHandleBadLayers::QgsHandleBadLayers( const QList<QDomNode> &layers, const QDo
mBrowseButton->setDisabled( true ); mBrowseButton->setDisabled( true );
connect( mLayerList, SIGNAL( itemSelectionChanged() ), this, SLOT( selectionChanged() ) ); connect( mLayerList, SIGNAL( itemSelectionChanged() ), this, SLOT( selectionChanged() ) );
connect( mLayerList, SIGNAL( itemChanged( QTableWidgetItem * ) ), this, SLOT( itemChanged( QTableWidgetItem * ) ) );
connect( mLayerList, SIGNAL( cellDoubleClicked( int, int ) ), this, SLOT( cellDoubleClicked( int, int ) ) );
connect( mBrowseButton, SIGNAL( clicked() ), this, SLOT( browseClicked() ) ); connect( mBrowseButton, SIGNAL( clicked() ), this, SLOT( browseClicked() ) );
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );
mLayerList->clear(); mLayerList->clear();
mLayerList->setSortingEnabled( true ); mLayerList->setSortingEnabled( true );
mLayerList->setSelectionBehavior( QAbstractItemView::SelectRows ); mLayerList->setSelectionBehavior( QAbstractItemView::SelectRows );
mLayerList->setColumnCount( 5 ); mLayerList->setColumnCount( 4 );
mLayerList->setHorizontalHeaderLabels( QStringList() mLayerList->setHorizontalHeaderLabels( QStringList()
<< tr( "Layer name" ) << tr( "Layer name" )
<< tr( "Type" ) << tr( "Type" )
<< tr( "Provider" ) << tr( "Provider" )
<< tr( "New file" ) << tr( "Datasource" )
<< tr( "New datasource" )
); );
int j = 0; int j = 0;
@ -95,42 +94,12 @@ QgsHandleBadLayers::QgsHandleBadLayers( const QList<QDomNode> &layers, const QDo
QString name = node.namedItem( "layername" ).toElement().text(); QString name = node.namedItem( "layername" ).toElement().text();
QString type = node.toElement().attribute( "type" ); QString type = node.toElement().attribute( "type" );
QString datasource = node.namedItem( "datasource" ).toElement().text(); QString datasource = node.namedItem( "datasource" ).toElement().text();
QString provider; QString provider = type == "vector" ? node.namedItem( "provider" ).toElement().text() : tr( "none" );
QString filename = datasource; QgsDebugMsg( QString( "name=%1 type=%2 provider=%3 datasource='%4'" )
if ( type == "vector" )
{
provider = node.namedItem( "provider" ).toElement().text();
if ( provider == "spatialite" )
{
QgsDataSourceURI uri( datasource );
filename = uri.database();
}
else if ( provider == "ogr" )
{
QStringList theURIParts = datasource.split( "|" );
filename = theURIParts[0];
}
else if ( provider == "delimitedtext" )
{
filename = QUrl::fromEncoded( datasource.toAscii() ).toLocalFile();
}
else if ( provider == "postgres" || provider == "sqlanywhere" )
{
continue;
}
}
else
{
provider = tr( "none" );
}
QgsDebugMsg( QString( "name=%1 type=%2 provider=%3 filename=%4 datasource='%5'" )
.arg( name ) .arg( name )
.arg( type ) .arg( type )
.arg( provider ) .arg( provider )
.arg( filename )
.arg( datasource ) ); .arg( datasource ) );
mLayerList->setRowCount( j + 1 ); mLayerList->setRowCount( j + 1 );
@ -150,42 +119,19 @@ QgsHandleBadLayers::QgsHandleBadLayers( const QList<QDomNode> &layers, const QDo
item->setFlags( item->flags() & ~Qt::ItemIsEditable ); item->setFlags( item->flags() & ~Qt::ItemIsEditable );
mLayerList->setItem( j, 2, item ); mLayerList->setItem( j, 2, item );
item = new QTableWidgetItem( filename );
mLayerList->setItem( j, 3, item );
item = new QTableWidgetItem( datasource ); item = new QTableWidgetItem( datasource );
item->setFlags( item->flags() & ~Qt::ItemIsEditable ); mLayerList->setItem( j, 3, item );
mLayerList->setItem( j, 4, item );
j++; j++;
} }
mLayerList->resizeColumnsToContents(); // mLayerList->resizeColumnsToContents();
} }
QgsHandleBadLayers::~QgsHandleBadLayers() QgsHandleBadLayers::~QgsHandleBadLayers()
{ {
} }
void QgsHandleBadLayers::itemChanged( QTableWidgetItem *item )
{
if ( item->column() != 3 )
return;
QFileInfo fi( item->text() );
item->setForeground( fi.exists() ? QBrush( Qt::green ) : QBrush( Qt::red ) );
}
void QgsHandleBadLayers::cellDoubleClicked( int row, int column )
{
Q_UNUSED( row );
if ( column != 3 || !mBrowseButton->isEnabled() )
return;
mBrowseButton->click();
}
void QgsHandleBadLayers::selectionChanged() void QgsHandleBadLayers::selectionChanged()
{ {
QgsDebugMsg( "entered." ); QgsDebugMsg( "entered." );
@ -203,94 +149,47 @@ void QgsHandleBadLayers::selectionChanged()
mBrowseButton->setEnabled( mRows.size() > 0 ); mBrowseButton->setEnabled( mRows.size() > 0 );
} }
void QgsHandleBadLayers::browseClicked() QString QgsHandleBadLayers::filename( int row )
{ {
QgsDebugMsg( "entered." ); QString type = mLayerList->item( row, 1 )->text();
QString provider = mLayerList->item( row, 2 )->text();
QString datasource = mLayerList->item( row, 3 )->text();
if ( mRows.size() == 1 ) if ( type == "vector" )
{ {
QString memoryQualifier; if ( provider == "spatialite" )
QString fileFilter;
int idx = mLayerList->item( mRows[0], 0 )->data( Qt::UserRole ).toInt();
QTableWidgetItem *fileItem = mLayerList->item( mRows[0], 3 );
if ( mLayers[ idx ].toElement().attribute( "type" ) == "vector" )
{ {
memoryQualifier = "lastVectorFileFilter"; QgsDataSourceURI uri( datasource );
fileFilter = mVectorFileFilter; return uri.database();
}
else if ( provider == "ogr" )
{
QStringList theURIParts = datasource.split( "|" );
return theURIParts[0];
}
else if ( provider == "delimitedtext" )
{
return QUrl::fromEncoded( datasource.toAscii() ).toLocalFile();
}
} }
else else
{ {
memoryQualifier = "lastRasterFileFilter"; return datasource;
fileFilter = mRasterFileFilter;
} }
QStringList selectedFiles; return QString::null;
QString enc; }
QString title = tr( "Select file to replace '%1'" ).arg( fileItem->text() );
QgisGui::openFilesRememberingFilter( memoryQualifier, fileFilter, selectedFiles, enc, title ); void QgsHandleBadLayers::setFilename( int row, QString filename )
if ( selectedFiles.size() != 1 )
{ {
QMessageBox::information( this, title, tr( "Please select exactly one file." ) );
return;
}
fileItem->setText( selectedFiles[0] );
}
else if ( mRows.size() > 1 )
{
QStringList selectedFiles;
QString enc;
QString title = tr( "Select new directory of selected files" );
QgisGui::openFilesRememberingFilter( "missingDirectory", tr( "All files (*)" ), selectedFiles, enc, title );
if ( selectedFiles.isEmpty() )
{
return;
}
QFileInfo path( selectedFiles[0] );
if ( !path.exists() )
{
return;
}
foreach ( int i, mRows )
{
QTableWidgetItem *fileItem = mLayerList->item( i, 3 );
QFileInfo fi( fileItem->text() );
fi.setFile( path.dir(), fi.fileName() );
if ( !fi.exists() )
continue;
fileItem->setText( fi.absoluteFilePath() );
}
}
}
void QgsHandleBadLayers::apply()
{
QgsDebugMsg( "entered." );
for ( int i = 0; i < mLayerList->rowCount(); i++ )
{
int idx = mLayerList->item( i, 0 )->data( Qt::UserRole ).toInt();
QDomNode &node = const_cast<QDomNode &>( mLayers[ idx ] );
QString type = mLayerList->item( i, 1 )->text();
QString provider = mLayerList->item( i, 2 )->text();
QTableWidgetItem *fileItem = mLayerList->item( i, 3 );
QString datasource = mLayerList->item( i, 4 )->text();
QString filename = fileItem->text();
if ( !QFileInfo( filename ).exists() ) if ( !QFileInfo( filename ).exists() )
{ return;
continue;
} QString type = mLayerList->item( row, 1 )->text();
QString provider = mLayerList->item( row, 2 )->text();
QTableWidgetItem *item = mLayerList->item( row, 3 );
QString datasource = item->text();
if ( type == "vector" ) if ( type == "vector" )
{ {
@ -319,6 +218,95 @@ void QgsHandleBadLayers::apply()
datasource = filename; datasource = filename;
} }
item->setText( datasource );
}
void QgsHandleBadLayers::browseClicked()
{
QgsDebugMsg( "entered." );
if ( mRows.size() == 1 )
{
int row = mRows[0];
QString type = mLayerList->item( row, 1 )->text();
QString memoryQualifier, fileFilter;
if ( type == "vector" )
{
memoryQualifier = "lastVectorFileFilter";
fileFilter = mVectorFileFilter;
}
else
{
memoryQualifier = "lastRasterFileFilter";
fileFilter = mRasterFileFilter;
}
QString fn = filename( row );
if ( fn.isNull() )
return;
QStringList selectedFiles;
QString enc;
QString title = tr( "Select file to replace '%1'" ).arg( fn );
QgisGui::openFilesRememberingFilter( memoryQualifier, fileFilter, selectedFiles, enc, title );
if ( selectedFiles.size() != 1 )
{
QMessageBox::information( this, title, tr( "Please select exactly one file." ) );
return;
}
setFilename( row, selectedFiles[0] );
}
else if ( mRows.size() > 1 )
{
QStringList selectedFiles;
QString enc;
QString title = tr( "Select new directory of selected files" );
QgisGui::openFilesRememberingFilter( "missingDirectory", tr( "All files (*)" ), selectedFiles, enc, title );
if ( selectedFiles.isEmpty() )
{
return;
}
QFileInfo path( selectedFiles[0] );
if ( !path.exists() )
{
return;
}
foreach ( int row, mRows )
{
QString type = mLayerList->item( row, 1 )->text();
QString fn = filename( row );
if ( fn.isEmpty() )
continue;
QFileInfo fi( fn );
fi.setFile( path.dir(), fi.fileName() );
if ( !fi.exists() )
continue;
setFilename( row, fi.absoluteFilePath() );
}
}
}
void QgsHandleBadLayers::apply()
{
QgsDebugMsg( "entered." );
for ( int i = 0; i < mLayerList->rowCount(); i++ )
{
int idx = mLayerList->item( i, 0 )->data( Qt::UserRole ).toInt();
QDomNode &node = const_cast<QDomNode &>( mLayers[ idx ] );
QString type = mLayerList->item( i, 1 )->text();
QString provider = mLayerList->item( i, 2 )->text();
QTableWidgetItem *item = mLayerList->item( i, 3 );
QString datasource = item->text();
node.namedItem( "datasource" ).toElement().firstChild().toText().setData( datasource ); node.namedItem( "datasource" ).toElement().firstChild().toText().setData( datasource );
if ( QgsProject::instance()->read( node ) ) if ( QgsProject::instance()->read( node ) )
{ {
@ -326,7 +314,7 @@ void QgsHandleBadLayers::apply()
} }
else else
{ {
fileItem->setForeground( QBrush( Qt::red ) ); item->setForeground( QBrush( Qt::red ) );
} }
} }
} }

View File

@ -54,8 +54,6 @@ class APP_EXPORT QgsHandleBadLayers
void apply(); void apply();
void accept(); void accept();
void rejected(); void rejected();
void itemChanged( QTableWidgetItem * );
void cellDoubleClicked( int row, int column );
private: private:
QPushButton *mBrowseButton; QPushButton *mBrowseButton;
@ -63,6 +61,9 @@ class APP_EXPORT QgsHandleBadLayers
QList<int> mRows; QList<int> mRows;
QString mVectorFileFilter; QString mVectorFileFilter;
QString mRasterFileFilter; QString mRasterFileFilter;
QString filename( int row );
void setFilename( int row, QString filename );
}; };
#endif #endif

View File

@ -15,43 +15,7 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QTableWidget" name="mLayerList"> <widget class="QTableWidget" name="mLayerList"/>
<column>
<property name="text">
<string>Layer name</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Provider</string>
</property>
</column>
<column>
<property name="text">
<string>Original filename</string>
</property>
</column>
<column>
<property name="text">
<string>New filename</string>
</property>
</column>
<column>
<property name="text">
<string>Original datasource</string>
</property>
</column>
<column>
<property name="text">
<string>New datasource</string>
</property>
</column>
</widget>
</item> </item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">