mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
- [API] add optional progress dialog to QgsVectorLayerImport
- postgres/mssql: fix primary key generation on import (fixes #6907) - fix crash on browser refresh after vector layer import
This commit is contained in:
parent
4cffd07086
commit
460f578d93
@ -9,6 +9,7 @@ class QgsVectorLayerImport
|
||||
%TypeHeaderCode
|
||||
#include <qgsvectorlayerimport.h>
|
||||
#include <qgsfield.h>
|
||||
class QProgressDialog;
|
||||
%End
|
||||
|
||||
public:
|
||||
@ -37,7 +38,8 @@ class QgsVectorLayerImport
|
||||
bool onlySelected = false,
|
||||
QString *errorMessage /Out/ = 0,
|
||||
bool skipAttributeCreation = false,
|
||||
QMap<QString, QVariant> *options = 0
|
||||
QMap<QString, QVariant> *options = 0,
|
||||
QProgressDialog *progress = 0
|
||||
);
|
||||
|
||||
/** create a empty layer and add fields to it */
|
||||
@ -47,7 +49,8 @@ class QgsVectorLayerImport
|
||||
QGis::WkbType geometryType,
|
||||
const QgsCoordinateReferenceSystem* crs,
|
||||
bool overwrite = false,
|
||||
const QMap<QString, QVariant> *options = 0
|
||||
const QMap<QString, QVariant> *options = 0,
|
||||
QProgressDialog *progress = 0
|
||||
);
|
||||
|
||||
/** checks whether there were any errors */
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "qgsvectorlayerimport.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
|
||||
#include <QProgressDialog>
|
||||
|
||||
#define FEATURE_BUFFER_SIZE 200
|
||||
|
||||
typedef QgsVectorLayerImport::ImportError createEmptyLayer_t(
|
||||
@ -45,8 +47,10 @@ QgsVectorLayerImport::QgsVectorLayerImport( const QString &uri,
|
||||
QGis::WkbType geometryType,
|
||||
const QgsCoordinateReferenceSystem* crs,
|
||||
bool overwrite,
|
||||
const QMap<QString, QVariant> *options )
|
||||
const QMap<QString, QVariant> *options,
|
||||
QProgressDialog *progress )
|
||||
: mErrorCount( 0 )
|
||||
, mProgress( progress )
|
||||
{
|
||||
mProvider = NULL;
|
||||
|
||||
@ -83,7 +87,7 @@ QgsVectorLayerImport::QgsVectorLayerImport( const QString &uri,
|
||||
QgsDebugMsg( "Created empty layer" );
|
||||
|
||||
QgsVectorDataProvider *vectorProvider = ( QgsVectorDataProvider* ) pReg->provider( providerKey, uri );
|
||||
if ( !vectorProvider || !vectorProvider->isValid() )
|
||||
if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 )
|
||||
{
|
||||
mError = ErrInvalidLayer;
|
||||
mErrorMessage = QObject::tr( "Loading of layer failed" );
|
||||
@ -181,7 +185,8 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
|
||||
bool onlySelected,
|
||||
QString *errorMessage,
|
||||
bool skipAttributeCreation,
|
||||
QMap<QString, QVariant> *options )
|
||||
QMap<QString, QVariant> *options,
|
||||
QProgressDialog *progress )
|
||||
{
|
||||
const QgsCoordinateReferenceSystem* outputCRS;
|
||||
QgsCoordinateTransform* ct = 0;
|
||||
@ -255,7 +260,7 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
|
||||
}
|
||||
|
||||
QgsVectorLayerImport * writer =
|
||||
new QgsVectorLayerImport( uri, providerKey, fields, wkbType, outputCRS, overwrite, options );
|
||||
new QgsVectorLayerImport( uri, providerKey, fields, wkbType, outputCRS, overwrite, options, progress );
|
||||
|
||||
// check whether file creation was successful
|
||||
ImportError err = writer->hasError();
|
||||
@ -298,9 +303,23 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
|
||||
*errorMessage = QObject::tr( "Feature write errors:" );
|
||||
}
|
||||
|
||||
if ( progress )
|
||||
{
|
||||
progress->setRange( 0, layer->featureCount() );
|
||||
}
|
||||
|
||||
// write all features
|
||||
while ( layer->nextFeature( fet ) )
|
||||
{
|
||||
if ( progress && progress->wasCanceled() )
|
||||
{
|
||||
if ( errorMessage )
|
||||
{
|
||||
*errorMessage += "\n" + QObject::tr( "Import was canceled at %1 of %2" ).arg( progress->value() ).arg( progress->maximum() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( writer->errorCount() > 1000 )
|
||||
{
|
||||
if ( errorMessage )
|
||||
@ -348,6 +367,11 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
|
||||
}
|
||||
}
|
||||
n++;
|
||||
|
||||
if ( progress )
|
||||
{
|
||||
progress->setValue( n );
|
||||
}
|
||||
}
|
||||
|
||||
// flush the buffer to be sure that all features are written
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
class QProgressDialog;
|
||||
|
||||
/** \ingroup core
|
||||
* A convenience class for writing vector files to disk.
|
||||
There are two possibilities how to use this class:
|
||||
@ -59,7 +61,8 @@ class CORE_EXPORT QgsVectorLayerImport
|
||||
bool onlySelected = false,
|
||||
QString *errorMessage = 0,
|
||||
bool skipAttributeCreation = false,
|
||||
QMap<QString, QVariant> *options = 0
|
||||
QMap<QString, QVariant> *options = 0,
|
||||
QProgressDialog *progress = 0
|
||||
);
|
||||
|
||||
/** create a empty layer and add fields to it */
|
||||
@ -69,7 +72,8 @@ class CORE_EXPORT QgsVectorLayerImport
|
||||
QGis::WkbType geometryType,
|
||||
const QgsCoordinateReferenceSystem* crs,
|
||||
bool overwrite = false,
|
||||
const QMap<QString, QVariant> *options = 0
|
||||
const QMap<QString, QVariant> *options = 0,
|
||||
QProgressDialog *progress = 0
|
||||
);
|
||||
|
||||
/** checks whether there were any errors */
|
||||
@ -102,6 +106,7 @@ class CORE_EXPORT QgsVectorLayerImport
|
||||
QMap<int, int> mOldToNewAttrIdx;
|
||||
|
||||
QgsFeatureList mFeatureBuffer;
|
||||
QProgressDialog *mProgress;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1686,7 +1686,7 @@ QgsVectorLayerImport::ImportError QgsMssqlProvider::createEmptyLayer(
|
||||
QString pk = primaryKey = "qgs_fid";
|
||||
for ( QgsFieldMap::const_iterator fldIt = fields.begin(); fldIt != fields.end(); ++fldIt )
|
||||
{
|
||||
if ( fldIt.value().name() == pk )
|
||||
if ( fldIt.value().name() == primaryKey )
|
||||
{
|
||||
// it already exists, try again with a new name
|
||||
primaryKey = QString( "%1_%2" ).arg( pk ).arg( index++ );
|
||||
|
@ -22,18 +22,51 @@
|
||||
#include "qgsapplication.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
|
||||
QGISEXTERN bool deleteLayer( const QString& uri, QString& errCause );
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
QgsPGConnectionItem::QgsPGConnectionItem( QgsDataItem* parent, QString name, QString path )
|
||||
: QgsDataCollectionItem( parent, name, path )
|
||||
, mColumnTypeThread( 0 )
|
||||
{
|
||||
mIcon = QgsApplication::getThemeIcon( "mIconConnect.png" );
|
||||
}
|
||||
|
||||
QgsPGConnectionItem::~QgsPGConnectionItem()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void QgsPGConnectionItem::stop()
|
||||
{
|
||||
if ( mColumnTypeThread )
|
||||
{
|
||||
mColumnTypeThread->stop();
|
||||
mColumnTypeThread->wait();
|
||||
delete mColumnTypeThread;
|
||||
mColumnTypeThread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsPGConnectionItem::refresh()
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
|
||||
stop();
|
||||
|
||||
foreach ( QgsDataItem *child, mChildren )
|
||||
{
|
||||
deleteChildItem( child );
|
||||
}
|
||||
|
||||
foreach ( QgsDataItem *item, createChildren() )
|
||||
{
|
||||
addChildItem( item, true );
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
|
||||
@ -42,6 +75,8 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
|
||||
QVector<QgsDataItem*> children;
|
||||
QgsDataSourceURI uri = QgsPostgresConn::connUri( mName );
|
||||
|
||||
mSchemaMap.clear();
|
||||
|
||||
mConn = QgsPostgresConn::connectDb( uri.connectionInfo(), true );
|
||||
if ( !mConn )
|
||||
return children;
|
||||
@ -62,7 +97,7 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
|
||||
return children;
|
||||
}
|
||||
|
||||
QgsGeomColumnTypeThread *columnTypeThread = 0;
|
||||
stop();
|
||||
|
||||
foreach ( QgsPostgresLayerProperty layerProperty, layerProperties )
|
||||
{
|
||||
@ -76,17 +111,17 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
|
||||
|
||||
if ( QgsPostgresConn::wkbTypeFromPostgis( layerProperty.type ) == QGis::WKBUnknown )
|
||||
{
|
||||
if ( !columnTypeThread )
|
||||
if ( !mColumnTypeThread )
|
||||
{
|
||||
QgsPostgresConn *conn = QgsPostgresConn::connectDb( uri.connectionInfo(), true /* readonly */ );
|
||||
if ( conn )
|
||||
{
|
||||
columnTypeThread = new QgsGeomColumnTypeThread( conn, true /* use estimated metadata */ );
|
||||
mColumnTypeThread = new QgsGeomColumnTypeThread( conn, true /* use estimated metadata */ );
|
||||
|
||||
connect( columnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
|
||||
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
|
||||
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
|
||||
connect( this, SIGNAL( addGeometryColumn( QgsPostgresLayerProperty ) ),
|
||||
columnTypeThread, SLOT( addGeometryColumn( QgsPostgresLayerProperty ) ) );
|
||||
mColumnTypeThread, SLOT( addGeometryColumn( QgsPostgresLayerProperty ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,8 +133,8 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
|
||||
schemaItem->addLayer( layerProperty );
|
||||
}
|
||||
|
||||
if ( columnTypeThread )
|
||||
columnTypeThread->start();
|
||||
if ( mColumnTypeThread )
|
||||
mColumnTypeThread->start();
|
||||
|
||||
return children;
|
||||
}
|
||||
@ -186,6 +221,11 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
|
||||
|
||||
qApp->setOverrideCursor( Qt::WaitCursor );
|
||||
|
||||
QProgressDialog *progress = new QProgressDialog( tr( "Copying features..." ), tr( "Abort" ), 0, 0, 0 );
|
||||
progress->setWindowTitle( tr( "Import layer" ) );
|
||||
progress->setWindowModality( Qt::WindowModal );
|
||||
progress->show();
|
||||
|
||||
QStringList importResults;
|
||||
bool hasError = false;
|
||||
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
|
||||
@ -207,7 +247,7 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
|
||||
QgsDebugMsg( "URI " + uri.uri() );
|
||||
QgsVectorLayerImport::ImportError err;
|
||||
QString importError;
|
||||
err = QgsVectorLayerImport::importLayer( srcLayer, uri.uri(), "postgres", &srcLayer->crs(), false, &importError );
|
||||
err = QgsVectorLayerImport::importLayer( srcLayer, uri.uri(), "postgres", &srcLayer->crs(), false, &importError, false, 0, progress );
|
||||
if ( err == QgsVectorLayerImport::NoError )
|
||||
importResults.append( tr( "%1: OK!" ).arg( u.name ) );
|
||||
else
|
||||
@ -225,6 +265,8 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
|
||||
delete srcLayer;
|
||||
}
|
||||
|
||||
delete progress;
|
||||
|
||||
qApp->restoreOverrideCursor();
|
||||
|
||||
if ( hasError )
|
||||
|
@ -61,6 +61,8 @@ class QgsPGConnectionItem : public QgsDataCollectionItem
|
||||
|
||||
QgsPostgresConn *connection() const { return mConn; }
|
||||
|
||||
void refresh();
|
||||
|
||||
signals:
|
||||
void addGeometryColumn( QgsPostgresLayerProperty );
|
||||
|
||||
@ -71,8 +73,10 @@ class QgsPGConnectionItem : public QgsDataCollectionItem
|
||||
void setLayerType( QgsPostgresLayerProperty layerProperty );
|
||||
|
||||
private:
|
||||
void stop();
|
||||
QgsPostgresConn *mConn;
|
||||
QMap<QString, QgsPGSchemaItem * > mSchemaMap;
|
||||
QgsGeomColumnTypeThread *mColumnTypeThread;
|
||||
};
|
||||
|
||||
class QgsPGSchemaItem : public QgsDataCollectionItem
|
||||
|
@ -3274,7 +3274,7 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
|
||||
QString pk = primaryKey = "id";
|
||||
for ( QgsFieldMap::const_iterator fldIt = fields.begin(); fldIt != fields.end(); ++fldIt )
|
||||
{
|
||||
if ( fldIt.value().name() == pk )
|
||||
if ( fldIt.value().name() == primaryKey )
|
||||
{
|
||||
// it already exists, try again with a new name
|
||||
primaryKey = QString( "%1_%2" ).arg( pk ).arg( index++ );
|
||||
|
Loading…
x
Reference in New Issue
Block a user