From ab9c0e9a525ecca0c3b527fe9b3b7e8e37f8bb71 Mon Sep 17 00:00:00 2001 From: mhugent Date: Mon, 1 Feb 2010 09:01:41 +0000 Subject: [PATCH] Applied patch #2341 (loading and saving of WMS and PostGIS connections) from alexbruy git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12855 c8812cc2-4d05-0410-92ff-de0c093fc19c --- src/app/CMakeLists.txt | 4 + src/app/postgres/qgspgsourceselect.cpp | 14 + src/app/postgres/qgspgsourceselect.h | 4 + src/app/qgsmanageconnectionsdialog.cpp | 413 +++++++++++++++++++++++ src/app/qgsmanageconnectionsdialog.h | 66 ++++ src/app/qgswmssourceselect.cpp | 18 +- src/app/qgswmssourceselect.h | 4 + src/ui/qgsmanageconnectionsdialogbase.ui | 98 ++++++ src/ui/qgspgsourceselectbase.ui | 28 +- src/ui/qgswmssourceselectbase.ui | 85 +++-- 10 files changed, 696 insertions(+), 38 deletions(-) create mode 100644 src/app/qgsmanageconnectionsdialog.cpp create mode 100644 src/app/qgsmanageconnectionsdialog.h create mode 100644 src/ui/qgsmanageconnectionsdialogbase.ui diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 2a7f3a3654e8..459ca8591714 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -72,6 +72,8 @@ SET(QGIS_APP_SRCS qgsvectorlayerproperties.cpp qgsquerybuilder.cpp + qgsmanageconnectionsdialog.cpp + composer/qgsattributeselectiondialog.cpp composer/qgscomposer.cpp composer/qgscomposerarrowwidget.cpp @@ -138,6 +140,8 @@ SET (QGIS_APP_MOC_HDRS qgsidentifyresults.h qgslabeldialog.h + qgsmanageconnectionsdialog.h + qgsmaptoolidentify.h qgsmaptoolsplitfeatures.h qgsmaptoolvertexedit.h diff --git a/src/app/postgres/qgspgsourceselect.cpp b/src/app/postgres/qgspgsourceselect.cpp index a4deb3e0c35a..8594f0aca995 100644 --- a/src/app/postgres/qgspgsourceselect.cpp +++ b/src/app/postgres/qgspgsourceselect.cpp @@ -24,6 +24,7 @@ email : sherman at mrcc.com #include "qgsapplication.h" #include "qgscontexthelp.h" #include "qgspgnewconnection.h" +#include "qgsmanageconnectionsdialog.h" #include "qgsquerybuilder.h" #include "qgsdatasourceuri.h" #include "qgsvectorlayer.h" @@ -126,6 +127,19 @@ void QgsPgSourceSelect::on_btnDelete_clicked() populateConnectionList(); } +void QgsPgSourceSelect::on_btnSave_clicked() +{ + QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Save, QgsManageConnectionsDialog::PostGIS ); + dlg.exec(); +} + +void QgsPgSourceSelect::on_btnLoad_clicked() +{ + QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Load, QgsManageConnectionsDialog::PostGIS ); + dlg.exec(); + populateConnectionList(); +} + // Slot for editing a connection void QgsPgSourceSelect::on_btnEdit_clicked() { diff --git a/src/app/postgres/qgspgsourceselect.h b/src/app/postgres/qgspgsourceselect.h index 032313851199..ac18e91cf431 100644 --- a/src/app/postgres/qgspgsourceselect.h +++ b/src/app/postgres/qgspgsourceselect.h @@ -131,6 +131,10 @@ class QgsPgSourceSelect : public QDialog, private Ui::QgsPgSourceSelectBase void on_btnBuildQuery_clicked(); //! Deletes the selected connection void on_btnDelete_clicked(); + //! Saves the selected connections to the file + void on_btnSave_clicked(); + //! Loads the selected connections from the file + void on_btnLoad_clicked(); void on_mSearchOptionsButton_clicked(); void on_mSearchTableEdit_textChanged( const QString & text ); void on_mSearchColumnComboBox_currentIndexChanged( const QString & text ); diff --git a/src/app/qgsmanageconnectionsdialog.cpp b/src/app/qgsmanageconnectionsdialog.cpp new file mode 100644 index 000000000000..fdf92910d74f --- /dev/null +++ b/src/app/qgsmanageconnectionsdialog.cpp @@ -0,0 +1,413 @@ +/*************************************************************************** + qgsmanageconnectionsdialog.cpp + --------------------- + begin : Dec 2009 + copyright : (C) 2009 by Alexander Bruy + email : alexander dot bruy at gmail dot com + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* $Id$ */ + +#include +#include +#include +#include +#include + +#include "qgsmanageconnectionsdialog.h" + +QgsManageConnectionsDialog::QgsManageConnectionsDialog( QWidget *parent, Mode mode, Type type ) : QDialog( parent ), mDialogMode( mode ), mConnectionType( type ) +{ + setupUi( this ); + + if ( mDialogMode == Load ) + { + label->setText( tr( "Load from file" ) ); + buttonBox->button( QDialogButtonBox::Ok )->setText( tr( "Load" ) ); + } + else + { + buttonBox->button( QDialogButtonBox::Ok )->setText( tr( "Save" ) ); + populateConnections(); + } + + buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); +} + +void QgsManageConnectionsDialog::on_btnBrowse_clicked() +{ + QString fileName; + if ( mDialogMode == Save ) + { + fileName = QFileDialog::getSaveFileName( this, tr( "Save connections" ), ".", tr( "XML files (*.xml *.XML)" ) ); + } + else + { + fileName = QFileDialog::getOpenFileName( this, tr( "Load connections" ), ".", tr( "XML files (*.xml *XML)" ) ); + } + + if ( fileName.isEmpty() ) + { + return; + } + + // ensure the user never ommited the extension from the file name + if ( !fileName.toLower().endsWith( ".xml" ) ) + { + fileName += ".xml"; + } + + mFileName = fileName; + leFileName->setText( mFileName ); + //buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true ); + + if ( mDialogMode == Load ) + { + populateConnections(); + } + + buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true ); +} + +void QgsManageConnectionsDialog::on_buttonBox_accepted() +{ + QList selection = listConnections->selectedItems(); + if ( selection.isEmpty() ) + { + return; + } + QStringList items; + for ( int i = 0; i < selection.size(); ++i ) + { + items.append( selection.at( i )->text() ); + } + + if ( mDialogMode == Save ) + { + QDomDocument doc; + if ( mConnectionType == WMS ) + { + doc = saveWMSConnections( items ); + } + else + { + doc = savePgConnections( items ); + } + + QFile file( mFileName ); + if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) + { + QMessageBox::warning( this, tr( "Saving connections" ), + tr( "Cannot write file %1:\n%2." ) + .arg( mFileName ) + .arg( file.errorString() ) ); + return; + } + + QTextStream out( &file ); + doc.save( out, 4 ); + } + else // load connections + { + QFile file( mFileName ); + if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + QMessageBox::warning( this, tr( "Loading connections" ), + tr( "Cannot read file %1:\n%2." ) + .arg( mFileName ) + .arg( file.errorString() ) ); + return; + } + + QDomDocument doc; + QString errorStr; + int errorLine; + int errorColumn; + + if ( !doc.setContent( &file, true, &errorStr, &errorLine, &errorColumn ) ) + { + QMessageBox::warning( this, tr( "Loading connections" ), + tr( "Parse error at line %1, column %2:\n%3" ) + .arg( errorLine ) + .arg( errorColumn ) + .arg( errorStr ) ); + return; + } + + if ( mConnectionType == WMS ) + { + loadWMSConnections( doc, items ); + } + else + { + loadPgConnections( doc, items ); + } + } + + mFileName = ""; + leFileName->clear(); + listConnections->clear(); + buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); +} + +void QgsManageConnectionsDialog::populateConnections() +{ + // Save mode. Populate connections list from settings + if ( mDialogMode == 0 ) + { + QSettings settings; + if ( mConnectionType == 0 ) + { + settings.beginGroup( "/Qgis/connections-wms" ); + } + else + { + settings.beginGroup( "/PostgreSQL/connections" ); + } + QStringList keys = settings.childGroups(); + QStringList::Iterator it = keys.begin(); + while ( it != keys.end() ) + { + QListWidgetItem *item = new QListWidgetItem(); + item->setText( *it ); + listConnections->addItem( item ); + ++it; + } + settings.endGroup(); + } + // Load mode. Populate connections list from file + else + { + QFile file( mFileName ); + if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + QMessageBox::warning( this, tr( "Loading connections" ), + tr( "Cannot read file %1:\n%2." ) + .arg( mFileName ) + .arg( file.errorString() ) ); + return; + } + + QDomDocument doc; + QString errorStr; + int errorLine; + int errorColumn; + + if ( !doc.setContent( &file, true, &errorStr, &errorLine, &errorColumn ) ) + { + QMessageBox::warning( this, tr( "Loading connections" ), + tr( "Parse error at line %1, column %2:\n%3" ) + .arg( errorLine ) + .arg( errorColumn ) + .arg( errorStr ) ); + return; + } + + QDomElement root = doc.documentElement(); + if ( mConnectionType == 0 ) + { + if ( root.tagName() != "qgsWMSConnections" ) + { + QMessageBox::information( this, tr( "Loading connections" ), + tr( "The file is not an WMS connections exchange file." ) ); + mFileName = ""; + leFileName->clear(); + listConnections->clear(); + return; + } + } + else + { + if ( root.tagName() != "qgsPgConnections" ) + { + QMessageBox::information( this, tr( "Loading connections" ), + tr( "The file is not an PostGIS connections exchange file." ) ); + mFileName = ""; + leFileName->clear(); + listConnections->clear(); + return; + } + } + + QDomElement child = root.firstChildElement(); + while ( !child.isNull() ) + { + QListWidgetItem *item = new QListWidgetItem(); + item->setText( child.attribute( "name" ) ); + listConnections->addItem( item ); + child = child.nextSiblingElement(); + } + } +} + +QDomDocument QgsManageConnectionsDialog::saveWMSConnections( const QStringList &connections ) +{ + QDomDocument doc( "connections" ); + QDomElement root = doc.createElement( "qgsWMSConnections" ); + root.setAttribute( "version", "1.0" ); + doc.appendChild( root ); + + QSettings settings; + QString path; + for ( int i = 0; i < connections.count(); ++i ) + { + path = "/Qgis/connections-wms/"; + QDomElement el = doc.createElement( "wms" ); + el.setAttribute( "name", connections[ i ] ); + el.setAttribute( "url", settings.value( path + connections[ i ] + "/url", "" ).toString() ); + + path = "/Qgis/WMS/"; + el.setAttribute( "username", settings.value( path + connections[ i ] + "/username", "" ).toString() ); + el.setAttribute( "password", settings.value( path + connections[ i ] + "/password", "" ).toString() ); + root.appendChild( el ); + } + + return doc; +} + +QDomDocument QgsManageConnectionsDialog::savePgConnections( const QStringList &connections ) +{ + QDomDocument doc( "connections" ); + QDomElement root = doc.createElement( "qgsPgConnections" ); + root.setAttribute( "version", "1.0" ); + doc.appendChild( root ); + + QSettings settings; + QString path; + for ( int i = 0; i < connections.count(); ++i ) + { + path = "/PostgreSQL/connections/" + connections[ i ]; + QDomElement el = doc.createElement( "postgis" ); + el.setAttribute( "name", connections[ i ] ); + el.setAttribute( "host", settings.value( path + "/host", "" ).toString() ); + el.setAttribute( "port", settings.value( path + "/port", "" ).toString() ); + el.setAttribute( "db", settings.value( path + "/database", "" ).toString() ); + el.setAttribute( "username", settings.value( path + "/username", "" ).toString() ); + el.setAttribute( "password", settings.value( path + "/password", "" ).toString() ); + el.setAttribute( "sslmode", settings.value( path + "/sslmode", "1" ).toString() ); + root.appendChild( el ); + } + + return doc; +} + +void QgsManageConnectionsDialog::loadWMSConnections( const QDomDocument &doc, const QStringList &items ) +{ + QDomElement root = doc.documentElement(); + if ( root.tagName() != "qgsWMSConnections" ) + { + QMessageBox::information( this, tr( "Loading connections" ), + tr( "The file is not an WMS connections exchange file." ) ); + return; + } + + QString connectionName; + QSettings settings; + settings.beginGroup( "/Qgis/connections-wms" ); + QStringList keys = settings.childGroups(); + settings.endGroup(); + QDomElement child = root.firstChildElement(); + while ( !child.isNull() ) + { + connectionName = child.attribute( "name" ); + if ( !items.contains( connectionName ) ) + { + child = child.nextSiblingElement(); + continue; + } + + // check for duplicates + if ( keys.contains( connectionName ) ) + { + int res = QMessageBox::warning( this, tr( "Loading connections" ), + tr( "Connection with name %1 already exists. Overwrite?" ) + .arg( connectionName ), + QMessageBox::Yes | QMessageBox::No ); + if ( res != QMessageBox::Yes ) + { + child = child.nextSiblingElement(); + continue; + } + } + + // no dups detected or overwrite is allowed + settings.beginGroup( "/Qgis/connections-wms" ); + settings.setValue( QString( "/" + connectionName + "/url" ) , child.attribute( "url" ) ); + settings.endGroup(); + + if ( !child.attribute( "username" ).isEmpty() ) + { + settings.beginGroup( "/Qgis/WMS/" + connectionName ); + settings.setValue( "/username", child.attribute( "username" ) ); + settings.setValue( "/password", child.attribute( "password" ) ); + settings.endGroup(); + } + child = child.nextSiblingElement(); + } +} + +void QgsManageConnectionsDialog::loadPgConnections( const QDomDocument &doc, const QStringList &items ) +{ + QDomElement root = doc.documentElement(); + if ( root.tagName() != "qgsPgConnections" ) + { + QMessageBox::information( this, tr( "Loading connections" ), + tr( "The file is not an PostGIS connections exchange file." ) ); + return; + } + + QString connectionName; + QSettings settings; + settings.beginGroup( "/PostgreSQL/connections" ); + QStringList keys = settings.childGroups(); + settings.endGroup(); + QDomElement child = root.firstChildElement(); + while ( !child.isNull() ) + { + connectionName = child.attribute( "name" ); + if ( !items.contains( connectionName ) ) + { + child = child.nextSiblingElement(); + continue; + } + + // check for duplicates + if ( keys.contains( connectionName ) ) + { + int res = QMessageBox::warning( this, tr( "Loading conections" ), + tr( "Connection with name %1 already exists. Overwrite?" ) + .arg( connectionName ), + QMessageBox::Yes | QMessageBox::No ); + if ( res != QMessageBox::Yes ) + { + child = child.nextSiblingElement(); + continue; + } + } + + //no dups detected or overwrite is allowed + settings.beginGroup( "/PostgreSQL/connections/" + connectionName ); + settings.setValue( "/host", child.attribute( "host" ) ); + settings.setValue( "/port", child.attribute( "port" ) ); + settings.setValue( "/database", child.attribute( "db" ) ); + settings.setValue( "/sslmode", child.attribute( "sslmode" ) ); + if ( !child.attribute( "username" ).isEmpty() ) + { + settings.setValue( "/username", child.attribute( "username" ) ); + settings.setValue( "/password", child.attribute( "password" ) ); + settings.setValue( "/save", "true" ); + } + settings.endGroup(); + + child = child.nextSiblingElement(); + } +} + diff --git a/src/app/qgsmanageconnectionsdialog.h b/src/app/qgsmanageconnectionsdialog.h new file mode 100644 index 000000000000..6cecb90fde9c --- /dev/null +++ b/src/app/qgsmanageconnectionsdialog.h @@ -0,0 +1,66 @@ +/*************************************************************************** + qgsmanageconnectionsdialog.h + --------------------- + begin : Dec 2009 + copyright : (C) 2009 by Alexander Bruy + email : alexander dot bruy at gmail dot com + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* $Id$ */ + +#ifndef QGSMANAGECONNECTIONSDIALOG_H +#define QGSMANAGECONNECTIONSDIALOG_H + +#include +#include +#include "ui_qgsmanageconnectionsdialogbase.h" + +class QgsManageConnectionsDialog : public QDialog, private Ui::QgsManageConnectionsDialogBase +{ + Q_OBJECT + + public: + enum Mode + { + Save, + Load + }; + + enum Type + { + WMS, + PostGIS + }; + + // constructor + // mode argument must be 0 for saving and 1 for loading + // type argument must be 0 for WMS and 1 for PostGIS + QgsManageConnectionsDialog( QWidget *parent = NULL, Mode mode = Save, Type type = WMS ); + + public slots: + void on_btnBrowse_clicked(); + void on_buttonBox_accepted(); + + void populateConnections(); + + private: + QDomDocument saveWMSConnections( const QStringList &connections ); + QDomDocument savePgConnections( const QStringList & connections ); + void loadWMSConnections( const QDomDocument &doc, const QStringList &items ); + void loadPgConnections( const QDomDocument &doc, const QStringList &items ); + + QString mFileName; + Mode mDialogMode; + Type mConnectionType; +}; + +#endif // QGSMANAGECONNECTIONSDIALOG_H + diff --git a/src/app/qgswmssourceselect.cpp b/src/app/qgswmssourceselect.cpp index 9d38a71c6210..25957640d971 100644 --- a/src/app/qgswmssourceselect.cpp +++ b/src/app/qgswmssourceselect.cpp @@ -27,6 +27,7 @@ #include "qgsgenericprojectionselector.h" #include "qgshttptransaction.h" #include "qgslogger.h" +#include "qgsmanageconnectionsdialog.h" #include "qgsmessageviewer.h" #include "qgsnewhttpconnection.h" #include "qgsnumericsortlistviewitem.h" @@ -35,7 +36,6 @@ #include "qgswmssourceselect.h" #include - #include #include #include @@ -203,11 +203,25 @@ void QgsWMSSourceSelect::on_btnDelete_clicked() if ( result == QMessageBox::Ok ) { settings.remove( key ); + settings.remove( "/Qgis/WMS/" + cmbConnections->currentText() ); cmbConnections->removeItem( cmbConnections->currentIndex() ); // populateConnectionList(); setConnectionListPosition(); } } +void QgsWMSSourceSelect::on_btnSave_clicked() +{ + QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Save, QgsManageConnectionsDialog::WMS ); + dlg.exec(); +} + +void QgsWMSSourceSelect::on_btnLoad_clicked() +{ + QgsManageConnectionsDialog dlg( this, QgsManageConnectionsDialog::Load, QgsManageConnectionsDialog::WMS ); + dlg.exec(); + populateConnectionList(); +} + QgsNumericSortTreeWidgetItem *QgsWMSSourceSelect::createItem( int id, const QStringList &names, QMap &items, int &layerAndStyleCount, const QMap &layerParents, const QMap &layerParentNames ) @@ -821,7 +835,7 @@ bool QgsWMSSourceSelect::retrieveSearchResults( const QString& searchTerm, QByte } // Get username/password from settings for protected WMS - QString mySearchUrl = settings.value("/qgis/WMSSearchUrl", "http://geopole.org/wms/search?search=%1&type=rss").toString(); + QString mySearchUrl = settings.value( "/qgis/WMSSearchUrl", "http://geopole.org/wms/search?search=%1&type=rss" ).toString(); QUrl url( mySearchUrl.arg( searchTerm ) ); QgsDebugMsg( url.toString() ); QgsHttpTransaction http( url.toEncoded(), diff --git a/src/app/qgswmssourceselect.h b/src/app/qgswmssourceselect.h index 8e72d5fa36b0..f13377f77d48 100644 --- a/src/app/qgswmssourceselect.h +++ b/src/app/qgswmssourceselect.h @@ -98,6 +98,10 @@ class QgsWMSSourceSelect : public QDialog, private Ui::QgsWMSSourceSelectBase void on_btnEdit_clicked(); //! Deletes the selected connection void on_btnDelete_clicked(); + //! Saves conncetions to the file + void on_btnSave_clicked(); + //! Loads connections from the file + void on_btnLoad_clicked(); /*! Connects to the database using the stored connection parameters. * Once connected, available layers are displayed. diff --git a/src/ui/qgsmanageconnectionsdialogbase.ui b/src/ui/qgsmanageconnectionsdialogbase.ui new file mode 100644 index 000000000000..04d06e1faa84 --- /dev/null +++ b/src/ui/qgsmanageconnectionsdialogbase.ui @@ -0,0 +1,98 @@ + + + QgsManageConnectionsDialogBase + + + + 0 + 0 + 400 + 300 + + + + Manage connections + + + + + + + + Save to file + + + + + + + + + + Browse + + + + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::ExtendedSelection + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + QgsManageConnectionsDialogBase + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + QgsManageConnectionsDialogBase + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/qgspgsourceselectbase.ui b/src/ui/qgspgsourceselectbase.ui index aed2d8cf30df..826a8e72e815 100644 --- a/src/ui/qgspgsourceselectbase.ui +++ b/src/ui/qgspgsourceselectbase.ui @@ -7,7 +7,7 @@ 0 0 406 - 470 + 500 @@ -37,28 +37,28 @@ 6 - + Delete - + Edit - + New - + Connect @@ -71,6 +71,24 @@ + + + + + + Save connections + + + + + + + Load connections + + + + + diff --git a/src/ui/qgswmssourceselectbase.ui b/src/ui/qgswmssourceselectbase.ui index 90cddec7ae69..6f459795fc9c 100644 --- a/src/ui/qgswmssourceselectbase.ui +++ b/src/ui/qgswmssourceselectbase.ui @@ -6,8 +6,8 @@ 0 0 - 555 - 508 + 439 + 539 @@ -15,8 +15,7 @@ - - + ../../../../.designer/backup../../../../.designer/backup true @@ -24,8 +23,8 @@ true - - + + 0 @@ -34,11 +33,11 @@ Servers - - + + - + false @@ -48,14 +47,14 @@ - + &New - + false @@ -65,7 +64,7 @@ - + false @@ -75,23 +74,20 @@ - - + + Qt::Horizontal - - QSizePolicy::Expanding - - 16 - 31 + 8 + 20 - + Adds a few example WMS servers @@ -104,7 +100,7 @@ - + @@ -140,6 +136,33 @@ + + + + Save + + + + + + + Load + + + + + + + Qt::Horizontal + + + + 292 + 20 + + + + @@ -250,7 +273,7 @@ - + @@ -269,7 +292,7 @@ - + Options @@ -311,7 +334,14 @@ - + + + + QDialogButtonBox::Close|QDialogButtonBox::Help + + + + @@ -327,13 +357,6 @@ - - - - QDialogButtonBox::Close|QDialogButtonBox::Help - - -