Index: src/app/postgres/qgspgsourceselect.h =================================================================== --- src/app/postgres/qgspgsourceselect.h (revision 12852) +++ src/app/postgres/qgspgsourceselect.h (working copy) @@ -131,6 +131,10 @@ 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 ); Index: src/app/postgres/qgspgsourceselect.cpp =================================================================== --- src/app/postgres/qgspgsourceselect.cpp (revision 12852) +++ src/app/postgres/qgspgsourceselect.cpp (working copy) @@ -24,6 +24,7 @@ #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 @@ populateConnectionList(); } +void QgsPgSourceSelect::on_btnSave_clicked() +{ + QgsManageConnectionsDialog dlg( this, 0, 1 ); + dlg.exec(); +} + +void QgsPgSourceSelect::on_btnLoad_clicked() +{ + QgsManageConnectionsDialog dlg( this, 1, 1 ); + dlg.exec(); + populateConnectionList(); +} + // Slot for editing a connection void QgsPgSourceSelect::on_btnEdit_clicked() { Index: src/app/qgsmanageconnectionsdialog.h =================================================================== --- src/app/qgsmanageconnectionsdialog.h (revision 0) +++ src/app/qgsmanageconnectionsdialog.h (revision 0) @@ -0,0 +1,54 @@ +/*************************************************************************** + 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: + // 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, int mode = 0, int type = 0 ); + + 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; + int mDialogMode; + int mConnectionType; +}; + +#endif // QGSMANAGECONNECTIONSDIALOG_H + Index: src/app/qgsmanageconnectionsdialog.cpp =================================================================== --- src/app/qgsmanageconnectionsdialog.cpp (revision 0) +++ src/app/qgsmanageconnectionsdialog.cpp (revision 0) @@ -0,0 +1,416 @@ +/*************************************************************************** + 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, int mode, int type ) + : QDialog( parent ) +{ + setupUi( this ); + mDialogMode = mode; + mConnectionType = type; + + if ( mDialogMode == 1 ) + { + 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 == 0 ) + { + 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 == 1 ) + { + 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 == 0 ) + { + QDomDocument doc; + if ( mConnectionType == 0 ) + { + 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 == 0 ) + { + 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(); + } +} + Index: src/app/qgswmssourceselect.h =================================================================== --- src/app/qgswmssourceselect.h (revision 12852) +++ src/app/qgswmssourceselect.h (working copy) @@ -98,6 +98,10 @@ 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. Index: src/app/qgswmssourceselect.cpp =================================================================== --- src/app/qgswmssourceselect.cpp (revision 12852) +++ src/app/qgswmssourceselect.cpp (working copy) @@ -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 @@ 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, 0, 0 ); + dlg.exec(); +} + +void QgsWMSSourceSelect::on_btnLoad_clicked() +{ + QgsManageConnectionsDialog dlg( this, 1, 0 ); + dlg.exec(); + populateConnectionList(); +} + QgsNumericSortTreeWidgetItem *QgsWMSSourceSelect::createItem( int id, const QStringList &names, QMap &items, int &layerAndStyleCount, const QMap &layerParents, const QMap &layerParentNames ) Index: src/app/CMakeLists.txt =================================================================== --- src/app/CMakeLists.txt (revision 12852) +++ src/app/CMakeLists.txt (working copy) @@ -72,6 +72,8 @@ qgsvectorlayerproperties.cpp qgsquerybuilder.cpp + qgsmanageconnectionsdialog.cpp + composer/qgsattributeselectiondialog.cpp composer/qgscomposer.cpp composer/qgscomposerarrowwidget.cpp @@ -138,6 +140,8 @@ qgsidentifyresults.h qgslabeldialog.h + qgsmanageconnectionsdialog.h + qgsmaptoolidentify.h qgsmaptoolsplitfeatures.h qgsmaptoolvertexedit.h Index: src/ui/qgswmssourceselectbase.ui =================================================================== --- src/ui/qgswmssourceselectbase.ui (revision 12852) +++ src/ui/qgswmssourceselectbase.ui (working copy) @@ -140,6 +140,20 @@ + + + + Load + + + + + + + Save + + + @@ -311,7 +325,7 @@ - + @@ -327,7 +341,7 @@ - + QDialogButtonBox::Close|QDialogButtonBox::Help Index: src/ui/qgspgsourceselectbase.ui =================================================================== --- src/ui/qgspgsourceselectbase.ui (revision 12852) +++ src/ui/qgspgsourceselectbase.ui (working copy) @@ -7,7 +7,7 @@ 0 0 406 - 470 + 500 @@ -37,28 +37,28 @@ 6 - + Delete - + Edit - + New - + Connect @@ -72,6 +72,24 @@ + + + + + Save + + + + + + + Load + + + + + + QAbstractItemView::ExtendedSelection Index: src/ui/qgsmanageconnectionsdialogbase.ui =================================================================== --- src/ui/qgsmanageconnectionsdialogbase.ui (revision 0) +++ src/ui/qgsmanageconnectionsdialogbase.ui (revision 0) @@ -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 + + + + +