00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <QMessageBox>
00020 #include <QComboBox>
00021 #include <QFileDialog>
00022 #include <QProgressDialog>
00023 #include <QRegExp>
00024 #include <QFile>
00025 #include <QSettings>
00026 #include <QPixmap>
00027 #include <QHeaderView>
00028 #include <QTextCodec>
00029 #include <QList>
00030 #include <QTableWidgetItem>
00031 #include <QInputDialog>
00032
00033 #include <iostream>
00034
00035 #include "qgsencodingfiledialog.h"
00036
00037 #include "qgspgutil.h"
00038 #include "qgsspit.h"
00039 #include "qgsnewconnection.h"
00040 #include "qgsdatasourceuri.h"
00041 #include "qgsmessageviewer.h"
00042 #include "spiticon.xpm"
00043 #include "qgslogger.h"
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 QgsSpit::QgsSpit( QWidget *parent, Qt::WFlags fl ) : QDialog( parent, fl )
00061 {
00062 setupUi( this );
00063 QPixmap icon;
00064 icon = QPixmap( spitIcon );
00065 setWindowIcon( icon );
00066
00067
00068 tblShapefiles->setColumnCount( 5 );
00069 QStringList headerText;
00070 headerText << tr( "File Name" ) << tr( "Feature Class" ) << tr( "Features" )
00071 << tr( "DB Relation Name" ) << tr( "Schema" );
00072 tblShapefiles->setHorizontalHeaderLabels( headerText );
00073 tblShapefiles->verticalHeader()->hide();
00074 tblShapefiles->horizontalHeader()->setStretchLastSection( true );
00075
00076 populateConnectionList();
00077 defSrid = -1;
00078 defGeom = "the_geom";
00079 total_features = 0;
00080
00081 chkUseDefaultSrid->setChecked( true );
00082 chkUseDefaultGeom->setChecked( true );
00083 useDefaultSrid();
00084 useDefaultGeom();
00085
00086 txtPrimaryKeyName->setText( "gid" );
00087
00088 schema_list << "public";
00089 conn = NULL;
00090
00091
00092
00093
00094
00095
00096 ShapefileTableDelegate* delegate = new ShapefileTableDelegate( tblShapefiles, schema_list );
00097 tblShapefiles->setItemDelegate( delegate );
00098
00099
00100 tblShapefiles->resizeColumnsToContents();
00101 }
00102
00103 QgsSpit::~QgsSpit()
00104 {
00105 if ( conn )
00106 PQfinish( conn );
00107 }
00108
00109 void QgsSpit::populateConnectionList()
00110 {
00111 QSettings settings;
00112 settings.beginGroup( "/PostgreSQL/connections" );
00113 QStringList keys = settings.childGroups();
00114 QStringList::Iterator it = keys.begin();
00115 cmbConnections->clear();
00116 while ( it != keys.end() )
00117 {
00118 cmbConnections->addItem( *it );
00119 ++it;
00120 }
00121 settings.endGroup();
00122 }
00123
00124 void QgsSpit::newConnection()
00125 {
00126 QgsNewConnection *nc = new QgsNewConnection( this );
00127
00128 if ( nc->exec() )
00129 {
00130 populateConnectionList();
00131 }
00132 }
00133
00134 void QgsSpit::editConnection()
00135 {
00136 QgsNewConnection *nc = new QgsNewConnection( this, cmbConnections->currentText() );
00137
00138 if ( nc->exec() )
00139 {
00140 nc->saveConnection();
00141 }
00142 }
00143
00144 void QgsSpit::removeConnection()
00145 {
00146 QSettings settings;
00147 QString key = "/PostgreSQL/connections/" + cmbConnections->currentText();
00148 QString msg = tr( "Are you sure you want to remove the [" ) + cmbConnections->currentText() + tr( "] connection and all associated settings?" );
00149 QMessageBox::StandardButton result = QMessageBox::information( this, tr( "Confirm Delete" ), msg, QMessageBox::Ok | QMessageBox::Cancel );
00150 if ( result == QMessageBox::Ok )
00151 {
00152 settings.remove( key + "/host" );
00153 settings.remove( key + "/database" );
00154 settings.remove( key + "/port" );
00155 settings.remove( key + "/username" );
00156 settings.remove( key + "/password" );
00157 settings.remove( key + "/save" );
00158
00159 cmbConnections->removeItem( cmbConnections->currentIndex() );
00160 }
00161 }
00162
00163 void QgsSpit::addFile()
00164 {
00165 QString error1 = "";
00166 QString error2 = "";
00167 bool exist;
00168 bool is_error = false;
00169 QSettings settings;
00170
00171 QgsEncodingFileDialog dlg( this,
00172 tr( "Add Shapefiles" ),
00173 settings.value( "/Plugin-Spit/last_directory" ).toString(),
00174 tr( "Shapefiles (*.shp);;All files (*.*)" ),
00175 settings.value( "/Plugin-Spit/last_encoding" ).toString() );
00176 dlg.setFileMode( QFileDialog::ExistingFiles );
00177
00178 if ( dlg.exec() != QDialog::Accepted )
00179 return;
00180 QStringList files = dlg.selectedFiles();
00181
00182 if ( files.size() > 0 )
00183 {
00184
00185 QFileInfo fi( files[ 0 ] );
00186 settings.setValue( "/Plugin-Spit/last_directory", fi.absolutePath() );
00187 settings.setValue( "/Plugin-Spit/last_encoding", dlg.encoding() );
00188 }
00189
00190 for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it )
00191 {
00192 exist = false;
00193 is_error = false;
00194
00195
00196 QList<QTableWidgetItem*> items = tblShapefiles->findItems( *it,
00197 Qt::MatchExactly );
00198 if ( items.count() > 0 )
00199 {
00200 exist = true;
00201 }
00202
00203 if ( !exist )
00204 {
00205
00206 QString name = *it;
00207 if ( !QFile::exists( name.left( name.length() - 3 ) + "dbf" ) )
00208 {
00209 is_error = true;
00210 }
00211 else if ( !QFile::exists( name.left( name.length() - 3 ) + "shx" ) )
00212 {
00213 is_error = true;
00214 }
00215
00216 if ( !is_error )
00217 {
00218 QgsShapeFile * file = new QgsShapeFile( name, dlg.encoding() );
00219 if ( file->is_valid() )
00220 {
00221
00222
00223
00224
00225 QString featureClass = file->getFeatureClass();
00226 fileList.push_back( file );
00227
00228 QTableWidgetItem *fileNameItem = new QTableWidgetItem( name );
00229 QTableWidgetItem *featureClassItem = new QTableWidgetItem( featureClass );
00230 QTableWidgetItem *featureCountItem = new QTableWidgetItem( QString( "%1" ).arg( file->getFeatureCount() ) );
00231
00232 QString relName = file->getTable().replace( QRegExp( "\\s" ), "_" );
00233 QTableWidgetItem *dbRelationNameItem = new QTableWidgetItem( relName );
00234 QTableWidgetItem *dbSchemaNameItem = new QTableWidgetItem( cmbSchema->currentText() );
00235
00236
00237 fileNameItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
00238 featureCountItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
00239
00240 int row = tblShapefiles->rowCount();
00241 tblShapefiles->insertRow( row );
00242 tblShapefiles->setItem( row, ColFILENAME, fileNameItem );
00243 tblShapefiles->setItem( row, ColFEATURECLASS, featureClassItem );
00244 tblShapefiles->setItem( row, ColFEATURECOUNT, featureCountItem );
00245 tblShapefiles->setItem( row, ColDBRELATIONNAME, dbRelationNameItem );
00246 tblShapefiles->setItem( row, ColDBSCHEMA, dbSchemaNameItem );
00247
00248 total_features += file->getFeatureCount();
00249 }
00250 else
00251 {
00252 error1 += name + "\n";
00253 is_error = true;
00254 delete file;
00255 }
00256 }
00257 else
00258 {
00259 error2 += name + "\n";
00260 }
00261 }
00262 }
00263
00264 tblShapefiles->resizeColumnsToContents();
00265
00266 if ( error1 != "" || error2 != "" )
00267 {
00268 QString message = tr( "The following Shapefile(s) could not be loaded:\n\n" );
00269 if ( error1 != "" )
00270 {
00271 error1 += "----------------------------------------------------------------------------------------";
00272 error1 += "\n" + tr( "REASON: File cannot be opened" ) + "\n\n";
00273 }
00274 if ( error2 != "" )
00275 {
00276 error2 += "----------------------------------------------------------------------------------------";
00277 error2 += "\n" + tr( "REASON: One or both of the Shapefile files (*.dbf, *.shx) missing" ) + "\n\n";
00278 }
00279 QgsMessageViewer * e = new QgsMessageViewer( this );
00280 e->setMessageAsPlainText( message + error1 + error2 );
00281 e->exec();
00282 }
00283 }
00284
00285 void QgsSpit::removeFile()
00286 {
00287 std::vector <int> temp;
00288 for ( int n = 0; n < tblShapefiles->rowCount(); n++ )
00289 if ( tblShapefiles->isItemSelected( tblShapefiles->item( n, 0 ) ) )
00290 {
00291 for ( std::vector<QgsShapeFile *>::iterator vit = fileList.begin(); vit != fileList.end(); vit++ )
00292 {
00293 if (( *vit ) ->getName() == tblShapefiles->item( n, 0 )->text() )
00294 {
00295 total_features -= ( *vit ) ->getFeatureCount();
00296 fileList.erase( vit );
00297 temp.push_back( n );
00298 break;
00299 }
00300 }
00301 }
00302
00303 for ( int i = temp.size() - 1; i >= 0; --i )
00304 tblShapefiles->removeRow( temp[ i ] );
00305
00306 QList<QTableWidgetItem*> selected = tblShapefiles->selectedItems();
00307 for ( int i = 0; i < selected.count(); ++i )
00308 selected[i]->setSelected( false );
00309 }
00310
00311 void QgsSpit::removeAllFiles()
00312 {
00313 int i = tblShapefiles->rowCount() - 1;
00314 for ( ; i >= 0; --i )
00315 tblShapefiles->removeRow( i );
00316
00317 fileList.clear();
00318 total_features = 0;
00319 }
00320
00321 void QgsSpit::useDefaultSrid()
00322 {
00323 if ( chkUseDefaultSrid->isChecked() )
00324 {
00325 defaultSridValue = spinSrid->value();
00326 spinSrid->setValue( defSrid );
00327 spinSrid->setEnabled( false );
00328 }
00329 else
00330 {
00331 spinSrid->setEnabled( true );
00332 spinSrid->setValue( defaultSridValue );
00333 }
00334 }
00335
00336 void QgsSpit::useDefaultGeom()
00337 {
00338 if ( chkUseDefaultGeom->isChecked() )
00339 {
00340 defaultGeomValue = txtGeomName->text();
00341 txtGeomName->setText( defGeom );
00342 txtGeomName->setEnabled( false );
00343 }
00344 else
00345 {
00346 txtGeomName->setEnabled( true );
00347 txtGeomName->setText( defaultGeomValue );
00348 }
00349 }
00350
00351
00352 void QgsSpit::helpInfo()
00353 {
00354 QString message = tr( "General Interface Help:" ) + "\n\n";
00355 message += QString(
00356 tr( "PostgreSQL Connections:" ) + "\n" ) + QString(
00357 "----------------------------------------------------------------------------------------\n" ) + QString(
00358 tr( "[New ...] - create a new connection" ) + "\n" ) + QString(
00359 tr( "[Edit ...] - edit the currently selected connection" ) + "\n" ) + QString(
00360 tr( "[Remove] - remove the currently selected connection" ) + "\n" ) + QString(
00361 tr( "-you need to select a connection that works (connects properly) in order to import files" ) + "\n" ) + QString(
00362 tr( "-when changing connections Global Schema also changes accordingly" ) + "\n\n" ) + QString(
00363 tr( "Shapefile List:" ) + "\n" ) + QString(
00364 "----------------------------------------------------------------------------------------\n" ) + QString(
00365 tr( "[Add ...] - open a File dialog and browse to the desired file(s) to import" ) + "\n" ) + QString(
00366 tr( "[Remove] - remove the currently selected file(s) from the list" ) + "\n" ) + QString(
00367 tr( "[Remove All] - remove all the files in the list" ) + "\n" ) + QString(
00368 tr( "[SRID] - Reference ID for the shapefiles to be imported" ) + "\n" ) + QString(
00369 tr( "[Use Default (SRID)] - set SRID to -1" ) + "\n" ) + QString(
00370 tr( "[Geometry Column Name] - name of the geometry column in the database" ) + "\n" ) + QString(
00371 tr( "[Use Default (Geometry Column Name)] - set column name to \'the_geom\'" ) + "\n" ) + QString(
00372 tr( "[Glogal Schema] - set the schema for all files to be imported into" ) + "\n\n" ) + QString(
00373 "----------------------------------------------------------------------------------------\n" ) + QString(
00374 tr( "[Import] - import the current shapefiles in the list" ) + "\n" ) + QString(
00375 tr( "[Quit] - quit the program\n" ) ) + QString(
00376 tr( "[Help] - display this help dialog" ) + "\n\n" );
00377 QgsMessageViewer * e = new QgsMessageViewer( this );
00378 e->setMessageAsPlainText( message );
00379 e->exec();
00380 }
00381
00382 void QgsSpit::dbConnect()
00383 {
00384 if ( conn )
00385 {
00386 PQfinish( conn );
00387 conn = NULL;
00388 }
00389
00390 QSettings settings;
00391 QString connName = cmbConnections->currentText();
00392 if ( connName.isEmpty() )
00393 {
00394 QMessageBox::warning( this, tr( "Import Shapefiles" ), tr( "You need to specify a Connection first" ) );
00395 return;
00396 }
00397
00398 QString key = "/PostgreSQL/connections/" + connName;
00399 QString database = settings.value( key + "/database" ).toString();
00400 QString username = settings.value( key + "/username" ).toString();
00401 QString password = settings.value( key + "/password" ).toString();
00402
00403 bool makeConnection = true;
00404
00405 if ( password.isEmpty() )
00406 {
00407
00408 password = QInputDialog::getText( this, tr( "Password for " ) + username,
00409 tr( "Please enter your password:" ),
00410 QLineEdit::Password, QString::null, &makeConnection );
00411 }
00412
00413 if ( makeConnection )
00414 {
00415
00416 QgsDataSourceURI uri;
00417 uri.setConnection( settings.value( key + "/host" ).toString(),
00418 settings.value( key + "/port" ).toString(),
00419 database,
00420 settings.value( key + "/username" ).toString(),
00421 password );
00422
00423 conn = PQconnectdb( uri.connectionInfo().toUtf8() );
00424 }
00425
00426 if ( conn == NULL || PQstatus( conn ) != CONNECTION_OK )
00427 {
00428 QMessageBox::warning( this, tr( "Import Shapefiles" ), tr( "Connection failed - Check settings and try again" ) );
00429 if ( conn )
00430 {
00431 PQfinish( conn );
00432 conn = 0;
00433 }
00434 }
00435
00436 schema_list.clear();
00437 schema_list << "public";
00438
00439 if ( conn )
00440 {
00441 int errcode = PQsetClientEncoding( conn, QString( "UNICODE" ).toLocal8Bit() );
00442 if ( errcode == 0 )
00443 {
00444 QgsDebugMsg( "encoding successfully set" );
00445 }
00446 else if ( errcode == -1 )
00447 {
00448 QgsDebugMsg( "error in setting encoding" );
00449 }
00450 else
00451 {
00452 QgsDebugMsg( "undefined return value from encoding setting" );
00453 }
00454
00455
00456 QString sql1 = "SELECT postgis_lib_version()";
00457 QString sql2 = "SELECT postgis_version()";
00458
00459 PGresult* ver = PQexec( conn, sql1.toUtf8() );
00460 if ( PQresultStatus( ver ) != PGRES_TUPLES_OK )
00461 {
00462
00463
00464 PQclear( ver );
00465 ver = PQexec( conn, sql2.toUtf8() );
00466 if ( PQresultStatus( ver ) != PGRES_TUPLES_OK )
00467 {
00468 QMessageBox::warning( this, tr( "PostGIS not available" ),
00469 tr( "<p>The chosen database does not have PostGIS installed, "
00470 "but this is required for storage of spatial data.</p>" ) );
00471 }
00472 }
00473
00474 QString schemaSql = QString( "select nspname from pg_namespace,pg_user where nspowner=usesysid and usename=%1" )
00475 .arg( QgsPgUtil::quotedValue( username ) );
00476 PGresult *schemas = PQexec( conn, schemaSql.toUtf8() );
00477
00478 if ( PQresultStatus( schemas ) == PGRES_TUPLES_OK )
00479 {
00480 for ( int i = 0; i < PQntuples( schemas ); i++ )
00481 {
00482 if ( QString( PQgetvalue( schemas, i, 0 ) ) != "public" )
00483 schema_list << QString( PQgetvalue( schemas, i, 0 ) );
00484 }
00485 }
00486 PQclear( schemas );
00487 }
00488
00489
00490
00491
00492 ShapefileTableDelegate* delegate = new ShapefileTableDelegate( tblShapefiles, schema_list );
00493 tblShapefiles->setItemDelegate( delegate );
00494
00495 cmbSchema->clear();
00496 cmbSchema->insertItems( 0, schema_list );
00497 cmbSchema->setCurrentIndex( 0 );
00498 }
00499
00500 void QgsSpit::import()
00501 {
00502 QList<QTableWidgetItem*> selected = tblShapefiles->selectedItems();
00503 for ( int i = 0; i < selected.count(); ++i )
00504 selected[i]->setSelected( false );
00505
00506 QString connName = cmbConnections->currentText();
00507 QSettings settings;
00508 bool canceled = false;
00509
00510 QString query;
00511 if ( total_features == 0 )
00512 {
00513 QMessageBox::warning( this, tr( "Import Shapefiles" ),
00514 tr( "You need to add shapefiles to the list first" ) );
00515 }
00516 else if ( conn != NULL )
00517 {
00518 PGresult * res;
00519 QProgressDialog pro( tr( "Importing files" ), tr( "Cancel" ),
00520 0, total_features, this );
00521
00522 pro.setValue( 0 );
00523 pro.setLabelText( tr( "Progress" ) );
00524 pro.setAutoClose( true );
00525
00526 qApp->processEvents();
00527
00528 int count = fileList.size(), successes = 0;
00529
00530 for ( std::vector<QgsShapeFile*>::size_type i = 0; i < fileList.size() ; i++ )
00531 {
00532 QString error = tr( "Problem inserting features from file:" ) + "\n" +
00533 tblShapefiles->item( i, ColFILENAME )->text();
00534
00535
00536 if ( ! tblShapefiles->item( i, ColDBRELATIONNAME )->text()[ 0 ].isLetter() )
00537 {
00538 QMessageBox::warning( &pro, tr( "Import Shapefiles" ),
00539 error + "\n" + tr( "Invalid table name." ) );
00540 pro.setValue( pro.value()
00541 + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00542 continue;
00543 }
00544
00545
00546 if (( fileList[ i ] ->column_names ).size() == 0 )
00547 {
00548 QMessageBox::warning( &pro, tr( "Import Shapefiles" ),
00549 error + "\n" + tr( "No fields detected." ) );
00550 pro.setValue( pro.value() +
00551 tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00552 continue;
00553 }
00554
00555
00556 std::vector<QString> names_copy = fileList[ i ] ->column_names;
00557 names_copy.push_back( txtPrimaryKeyName->text() );
00558 names_copy.push_back( txtGeomName->text() );
00559
00560 QString dupl = "";
00561 std::sort( names_copy.begin(), names_copy.end() );
00562
00563 for ( std::vector<QString>::size_type k = 1; k < names_copy.size(); k++ )
00564 {
00565 QgsDebugMsg( QString( "Checking to see if %1 == %2" ).arg( names_copy[ k ] ).arg( names_copy[ k - 1 ] ) );
00566 if ( names_copy[ k ] == names_copy[ k - 1 ] )
00567 dupl += names_copy[ k ] + "\n";
00568 }
00569
00570
00571 if ( dupl != "" )
00572 {
00573 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error +
00574 "\n" + tr( "The following fields are duplicates:" ) + "\n" + dupl );
00575 pro.setValue( pro.value() + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00576 continue;
00577 }
00578
00579
00580 fileList[ i ] ->setTable( tblShapefiles->item( i, ColDBRELATIONNAME )->text() );
00581 pro.setLabelText( tr( "Importing files" ) + "\n"
00582 + tblShapefiles->item( i, ColFILENAME )->text() );
00583 bool rel_exists1 = false;
00584 bool rel_exists2 = false;
00585 query = QString( "SELECT f_table_name FROM geometry_columns WHERE f_table_name=%1 AND f_table_schema=%2" )
00586 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBRELATIONNAME )->text() ) )
00587 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBSCHEMA )->text() ) );
00588 res = PQexec( conn, query.toUtf8() );
00589 rel_exists1 = ( PQntuples( res ) > 0 );
00590
00591 if ( PQresultStatus( res ) != PGRES_TUPLES_OK )
00592 {
00593 QString err = PQresultErrorMessage( res );
00594 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00595 tr( "<p>Error while executing the SQL:</p><p>" ) +
00596 query + tr( "</p><p>The database said:" ) +
00597 err + "</p>" );
00598 pro.setValue( pro.value() + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00599 PQclear( res );
00600 continue;
00601 }
00602
00603 PQclear( res );
00604
00605 query = QString( "SELECT tablename FROM pg_tables WHERE tablename=%1 AND schemaname=%2" )
00606 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBRELATIONNAME )->text() ) )
00607 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBSCHEMA )->text() ) );
00608 res = PQexec( conn, query.toUtf8() );
00609
00610 rel_exists2 = ( PQntuples( res ) > 0 );
00611
00612 if ( PQresultStatus( res ) != PGRES_TUPLES_OK )
00613 {
00614 QString err = PQresultErrorMessage( res );
00615 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00616 tr( "<p>Error while executing the SQL:</p><p>" ) +
00617 query + tr( "</p><p>The database said:" ) +
00618 err + "</p>" );
00619
00620 pro.setValue( pro.value() + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00621 PQclear( res );
00622 continue;
00623 }
00624 else
00625 {
00626 PQclear( res );
00627 }
00628
00629
00630 query = "BEGIN";
00631 res = PQexec( conn, query.toUtf8() );
00632 if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
00633 {
00634 QString err = PQresultErrorMessage( res );
00635 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00636 tr( "<p>Error while executing the SQL:</p><p>" ) +
00637 query + tr( "</p><p>The database said:" ) +
00638 err + "</p>" );
00639 pro.setValue( pro.value() + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00640 PQclear( res );
00641 continue;
00642 }
00643 else
00644 {
00645 PQclear( res );
00646 }
00647
00648 query = "SET SEARCH_PATH TO ";
00649 if ( !tblShapefiles->item( i, ColDBSCHEMA )->text().isEmpty() &&
00650 tblShapefiles->item( i, ColDBSCHEMA )->text() != "public" )
00651 query += QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBSCHEMA )->text() ) + ",";
00652 query += QgsPgUtil::quotedValue( "public" );
00653 res = PQexec( conn, query.toUtf8() );
00654
00655 if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
00656 {
00657 QString err = PQresultErrorMessage( res );
00658 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00659 tr( "<p>Error while executing the SQL:</p><p>" ) +
00660 query + tr( "</p><p>The database said:" ) +
00661 err + "</p>" );
00662 pro.setValue( pro.value() + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00663 PQclear( res );
00664 continue;
00665 }
00666 else
00667 {
00668 PQclear( res );
00669 }
00670
00671 if ( rel_exists1 || rel_exists2 )
00672 {
00673 QMessageBox::StandardButton del_confirm = QMessageBox::warning( this,
00674 tr( "Import Shapefiles - Relation Exists" ),
00675 tr( "The Shapefile:" ) + "\n" + tblShapefiles->item( i, 0 )->text() + "\n" + tr( "will use [" ) +
00676 tblShapefiles->item( i, ColDBRELATIONNAME )->text() + tr( "] relation for its data," ) + "\n" + tr( "which already exists and possibly contains data." ) + "\n" +
00677 tr( "To avoid data loss change the \"DB Relation Name\"" ) + "\n" + tr( "for this Shapefile in the main dialog file list." ) + "\n\n" +
00678 tr( "Do you want to overwrite the [" ) + tblShapefiles->item( i, ColDBRELATIONNAME )->text() + tr( "] relation?" ),
00679 QMessageBox::Ok | QMessageBox::Cancel );
00680
00681 if ( del_confirm == QMessageBox::Ok )
00682 {
00683 if ( rel_exists2 )
00684 {
00685 query = QString( "DROP TABLE %1" )
00686 .arg( QgsPgUtil::quotedIdentifier( tblShapefiles->item( i, ColDBRELATIONNAME )->text() ) );
00687
00688 res = PQexec( conn, query.toUtf8() );
00689 if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
00690 {
00691 QString err = PQresultErrorMessage( res );
00692 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00693 tr( "<p>Error while executing the SQL:</p><p>" ) +
00694 query + tr( "</p><p>The database said:" ) +
00695 err + "</p>" );
00696 pro.setValue( pro.value() + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00697 PQclear( res );
00698 continue;
00699 }
00700 else
00701 {
00702 PQclear( res );
00703 }
00704 }
00705
00706 if ( rel_exists1 )
00707 {
00708 query = QString( "SELECT f_geometry_column FROM geometry_columns WHERE f_table_schema=%1 AND f_table_name=%2" )
00709 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBSCHEMA )->text() ) )
00710 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBRELATIONNAME )->text() ) );
00711
00712 QStringList columns;
00713 res = PQexec( conn, query.toUtf8() );
00714 if ( PQresultStatus( res ) != PGRES_TUPLES_OK )
00715 {
00716 for ( int i = 0; i < PQntuples( res ); i++ )
00717 columns.append( PQgetvalue( res, i, 0 ) );
00718 }
00719 PQclear( res );
00720
00721 for ( int i = 0; i < columns.size(); i++ )
00722 {
00723 query = QString( "SELECT DropGeometryColumn(%1,%2,%3)" )
00724 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBSCHEMA )->text() ) )
00725 .arg( QgsPgUtil::quotedValue( tblShapefiles->item( i, ColDBRELATIONNAME )->text() ) )
00726 .arg( QgsPgUtil::quotedValue( columns[i] ) );
00727
00728 res = PQexec( conn, query.toUtf8() );
00729 if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
00730 {
00731 QString err = PQresultErrorMessage( res );
00732 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00733 tr( "<p>Error while executing the SQL:</p><p>" ) +
00734 query + tr( "</p><p>The database said:" ) +
00735 err + "</p>" );
00736 pro.setValue( pro.value() + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00737 }
00738
00739 PQclear( res );
00740 }
00741 }
00742 }
00743 else
00744 {
00745 query = "ROLLBACK";
00746 res = PQexec( conn, query.toUtf8() );
00747 if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
00748 {
00749 QString err = PQresultErrorMessage( res );
00750 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00751 tr( "<p>Error while executing the SQL:</p><p>" ) +
00752 query + tr( "</p><p>The database said:" ) +
00753 err + "</p>" );
00754 }
00755 PQclear( res );
00756
00757 pro.setValue( pro.value() + tblShapefiles->item( i, 2 )->text().toInt() );
00758 continue;
00759 }
00760 }
00761
00762
00763 int temp_progress = pro.value();
00764 canceled = false;
00765
00766 QString key = "/PostgreSQL/connections/" + connName;
00767 QString dbname = settings.value( key + "/database" ).toString();
00768 QString schema = tblShapefiles->item( i, ColDBSCHEMA )->text();
00769 QString srid = QString( "%1" ).arg( spinSrid->value() );
00770 QString errorText;
00771
00772 bool layerInserted = fileList[i]->insertLayer( dbname, schema, txtPrimaryKeyName->text(), txtGeomName->text(), srid, conn, pro, canceled, errorText );
00773 if ( layerInserted && !canceled )
00774 {
00775 query = "COMMIT";
00776 res = PQexec( conn, query.toUtf8() );
00777 if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
00778 {
00779 QString err = PQresultErrorMessage( res );
00780 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00781 tr( "<p>Error while executing the SQL:</p><p>" ) +
00782 query + tr( "</p><p>The database said:" ) +
00783 err + "</p>" );
00784 PQclear( res );
00785 continue;
00786 }
00787
00788 PQclear( res );
00789
00790
00791 for ( int j = 0; j < tblShapefiles->rowCount(); j++ )
00792 {
00793 if ( tblShapefiles->item( j, ColFILENAME )->text() == QString( fileList[ i ] ->getName() ) )
00794 {
00795 tblShapefiles->selectRow( j );
00796 removeFile();
00797 i--;
00798 break;
00799 }
00800 }
00801
00802 successes++;
00803 }
00804 else if ( !canceled )
00805 {
00806 pro.setValue( temp_progress + tblShapefiles->item( i, ColFEATURECOUNT )->text().toInt() );
00807 QString errTxt = error + "\n" + errorText;
00808 QMessageBox::warning( this, tr( "Import Shapefiles" ), errTxt );
00809 query = "ROLLBACK";
00810 res = PQexec( conn, query.toUtf8() );
00811 if ( PQresultStatus( res ) != PGRES_COMMAND_OK )
00812 {
00813 QString err = PQresultErrorMessage( res );
00814 QMessageBox::warning( &pro, tr( "Import Shapefiles" ), error + "\n" +
00815 tr( "<p>Error while executing the SQL:</p><p>" ) +
00816 query + tr( "</p><p>The database said:" ) +
00817 err + "</p>" );
00818 }
00819
00820 PQclear( res );
00821 }
00822 else
00823 {
00824 break;
00825 }
00826 }
00827
00828 if ( successes == count )
00829 accept();
00830 else
00831 QMessageBox::information( &pro, tr( "Import Shapefiles" ), QString( tr( "%1 of %2 shapefiles could not be imported." ) ).arg( count - successes ).arg( count ) );
00832 }
00833 else
00834 {
00835 QMessageBox::warning( this, tr( "Import Shapefiles" ), tr( "You need to specify a Connection first" ) );
00836 }
00837 }
00838
00839 QWidget *ShapefileTableDelegate::createEditor( QWidget *parent,
00840 const QStyleOptionViewItem &,
00841 const QModelIndex & index ) const
00842 {
00843 switch ( index.column() )
00844 {
00845 case 4:
00846 {
00847 QComboBox* editor = new QComboBox( parent );
00848 editor->setSizeAdjustPolicy( QComboBox::AdjustToContents );
00849 editor->installEventFilter( const_cast<ShapefileTableDelegate*>( this ) );
00850 return editor;
00851 break;
00852 }
00853 case 1:
00854 case 3:
00855 {
00856 QLineEdit* editor = new QLineEdit( parent );
00857 editor->installEventFilter( const_cast<ShapefileTableDelegate*>( this ) );
00858 return editor;
00859 break;
00860 }
00861 }
00862 return NULL;
00863 }
00864
00865 void ShapefileTableDelegate::setEditorData( QWidget *editor,
00866 const QModelIndex &index ) const
00867 {
00868 switch ( index.column() )
00869 {
00870 case 4:
00871 {
00872
00873 QComboBox *comboBox = static_cast<QComboBox*>( editor );
00874 comboBox->insertItems( 0, mSchemaList );
00875
00876
00877 QString text = index.model()->data( index, Qt::DisplayRole ).toString();
00878 comboBox->setCurrentIndex( mSchemaList.indexOf( text ) );
00879 break;
00880 }
00881 case 1:
00882 case 3:
00883 {
00884 QString text = index.model()->data( index, Qt::DisplayRole ).toString();
00885 QLineEdit *lineEdit = static_cast<QLineEdit*>( editor );
00886 lineEdit->setText( text );
00887 break;
00888 }
00889 }
00890 }
00891
00892 void ShapefileTableDelegate::setModelData( QWidget *editor, QAbstractItemModel *model,
00893 const QModelIndex &index ) const
00894 {
00895 switch ( index.column() )
00896 {
00897 case 4:
00898 {
00899 QComboBox *comboBox = static_cast<QComboBox*>( editor );
00900 QString text = comboBox->currentText();
00901 model->setData( index, text );
00902 break;
00903 }
00904 case 1:
00905 case 3:
00906 {
00907 QLineEdit *lineEdit = static_cast<QLineEdit*>( editor );
00908 QString text = lineEdit->text();
00909
00910 model->setData( index, text );
00911 break;
00912 }
00913 }
00914 }
00915
00916 void ShapefileTableDelegate::updateEditorGeometry( QWidget *editor,
00917 const QStyleOptionViewItem &option, const QModelIndex & ) const
00918 {
00919 editor->setGeometry( option.rect );
00920 }