All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PostGISConnectorDialog.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2011-2012 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/qt/plugins/datasource/pgis/PostGISConnectorDialog.cpp
22 
23  \brief A dialog window for showing the PostGIS connector widget.
24 */
25 
26 // TerraLib
27 #include "../../../../common/Translator.h"
28 #include "../../../../dataaccess/datasource/DataSource.h"
29 #include "../../../../dataaccess/datasource/DataSourceFactory.h"
30 #include "../../../../dataaccess/datasource/DataSourceManager.h"
31 #include "../../../../dataaccess/datasource/DataSourceInfo.h"
32 #include "../../../widgets/Exception.h"
33 #include "PostGISConnectorDialog.h"
34 #include "ui_PostGISConnectorDialogForm.h"
35 
36 // Boost
37 #include <boost/algorithm/string/case_conv.hpp>
38 #include <boost/uuid/random_generator.hpp>
39 #include <boost/uuid/uuid_io.hpp>
40 #include <boost/lexical_cast.hpp>
41 
42 // Qt
43 #include <QMessageBox>
44 
46  : QDialog(parent, f),
47  m_ui(new Ui::PostGISConnectorDialogForm)
48 {
49 // add controls
50  m_ui->setupUi(this);
51 
52 // init controls
53  m_ui->m_advancedConnectionOptionsGroupBox->hide();
54 
55 // connect signal and slots
56  connect(m_ui->m_openPushButton, SIGNAL(pressed()), this, SLOT(openPushButtonPressed()));
57  connect(m_ui->m_testPushButton, SIGNAL(pressed()), this, SLOT(testPushButtonPressed()));
58  connect(m_ui->m_userNameLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordLineEditEditingFinished()));
59  connect(m_ui->m_passwordLineEdit, SIGNAL(editingFinished()), this, SLOT(passwordLineEditEditingFinished()));
60  connect(m_ui->m_advancedConnectionOptionsCheckBox, SIGNAL(toggled(bool)), this, SLOT(advancedConnectionOptionsCheckBoxToggled(bool)));
61 
62  m_ui->m_portLineEdit->setValidator(new QIntValidator(0, 9999, this));
63 
64  m_ui->m_helpPushButton->setNameSpace("dpi.inpe.br.plugins");
65  m_ui->m_helpPushButton->setPageReference("plugins/pgis/pgis.html");
66 }
67 
69 {
70 }
71 
73 {
74  return m_datasource;
75 }
76 
78 {
79  return m_driver;
80 }
81 
83 {
84  m_datasource = ds;
85 
86  if(m_datasource.get() != 0)
87  {
88  setConnectionInfo(m_datasource->getConnInfo());
89 
90  m_ui->m_datasourceTitleLineEdit->setText(QString::fromStdString(m_datasource->getTitle()));
91 
92  m_ui->m_datasourceDescriptionTextEdit->setText(QString::fromStdString(m_datasource->getDescription()));
93  }
94 }
95 
97 {
98  try
99  {
100  // Check if driver is loaded
101  if(te::da::DataSourceFactory::find("POSTGIS") == 0)
102  throw te::qt::widgets::Exception(TE_TR("Sorry! No data access driver loaded for PostgreSQL + PostGIS data sources!"));
103 
104  // Get the data source connection info based on form data
105  std::map<std::string, std::string> dsInfo;
106 
107  getConnectionInfo(dsInfo);
108 
109  // Perform connection
110  std::auto_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("POSTGIS");
111  ds->setConnectionInfo(dsInfo);
112  ds->open();
113  m_driver.reset(ds.release());
114 
115  if(m_driver.get() == 0)
116  throw te::qt::widgets::Exception(TE_TR("Could not open PostgreSQL + PostGIS data source due to an unknown error!"));
117 
118  QString title = m_ui->m_datasourceTitleLineEdit->text().trimmed();
119 
120  if(title.isEmpty())
121  title = m_ui->m_hostNameLineEdit->text().trimmed() + QString::fromStdString("@") + m_ui->m_databaseComboBox->currentText().trimmed() + QString::fromStdString("@") + m_ui->m_userNameLineEdit->text().trimmed();
122 
123  if(m_datasource.get() == 0)
124  {
125  // Create a new data source based on the form data
126  m_datasource.reset(new te::da::DataSourceInfo);
127 
128  m_datasource->setConnInfo(dsInfo);
129 
130  boost::uuids::basic_random_generator<boost::mt19937> gen;
131  boost::uuids::uuid u = gen();
132  std::string dsId = boost::uuids::to_string(u);
133 
134  m_datasource->setId(dsId);
135  m_driver->setId(dsId);
136  m_datasource->setTitle(title.toStdString());
137  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().toStdString());
138  m_datasource->setAccessDriver("POSTGIS");
139  m_datasource->setType("POSTGIS");
140  }
141  else
142  {
143  m_driver->setId(m_datasource->getId());
144  m_datasource->setConnInfo(dsInfo);
145  m_datasource->setTitle(title.toStdString());
146  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().toStdString());
147  }
148  }
149  catch(const std::exception& e)
150  {
151  QMessageBox::warning(this,
152  tr("TerraLib Qt Components"),
153  tr(e.what()));
154  return;
155  }
156  catch(...)
157  {
158  QMessageBox::warning(this,
159  tr("TerraLib Qt Components"),
160  tr("Unknown error while opening PostgreSQL database!"));
161  return;
162  }
163 
164  accept();
165 }
166 
168 {
169  try
170  {
171  // Check if driver is loaded
172  if(te::da::DataSourceFactory::find("POSTGIS") == 0)
173  throw te::qt::widgets::Exception(TE_TR("Sorry! No data access driver loaded for PostgreSQL + PostGIS data sources!"));
174 
175  // Get the data source connection info based on form data
176  std::map<std::string, std::string> dsInfo;
177 
178  getConnectionInfo(dsInfo);
179 
180  // Perform connection
181  std::auto_ptr<te::da::DataSource> ds(te::da::DataSourceFactory::make("POSTGIS"));
182 
183  if(ds.get() == 0)
184  throw te::qt::widgets::Exception(TE_TR("Could not open PostgreSQL + PostGIS database!"));
185 
186  ds->setConnectionInfo(dsInfo);
187  ds->open();
188 
189  QMessageBox::information(this,
190  tr("TerraLib Qt Components"),
191  tr("Data source is ok!"));
192 
193  ds->close();
194  }
195  catch(const std::exception& e)
196  {
197  QMessageBox::warning(this,
198  tr("TerraLib Qt Components"),
199  tr(e.what()));
200  }
201  catch(...)
202  {
203  QMessageBox::warning(this,
204  tr("TerraLib Qt Components"),
205  tr("Unknown error while testing PostgreSQL + PostGIS data source!"));
206  }
207 }
208 
209 void te::qt::plugins::pgis::PostGISConnectorDialog::getConnectionInfo(std::map<std::string, std::string>& connInfo) const
210 {
211 // clear input
212  connInfo.clear();
213 
214 // get host
215  QString qstr = m_ui->m_hostNameLineEdit->text().trimmed();
216 
217  if(!qstr.isEmpty())
218  connInfo["PG_HOST"] = qstr.toStdString();
219 
220 // get port
221  qstr = m_ui->m_portLineEdit->text().trimmed();
222 
223  if(!qstr.isEmpty())
224  connInfo["PG_PORT"] = qstr.toStdString();
225 
226 // get dbname
227  qstr = m_ui->m_databaseComboBox->currentText().trimmed();
228 
229  if(!qstr.isEmpty())
230  connInfo["PG_DB_NAME"] = qstr.toStdString();
231 
232 // get client encoding
233  qstr = m_ui->m_clientEncodingComboBox->currentText().trimmed();
234 
235  if(!qstr.isEmpty())
236  connInfo["PG_CLIENT_ENCODING"] = qstr.toStdString();
237 
238 // get user
239  qstr = m_ui->m_userNameLineEdit->text().trimmed();
240 
241  if(!qstr.isEmpty())
242  connInfo["PG_USER"] = qstr.toStdString();
243 
244 // get password
245  qstr = m_ui->m_passwordLineEdit->text().trimmed();
246 
247  if(!qstr.isEmpty())
248  connInfo["PG_PASSWORD"] = qstr.toStdString();
249 
250 // get table info
251  qstr = m_ui->m_tablesToHideLineEdit->text().trimmed();
252 
253  if(!qstr.isEmpty())
254  connInfo["PG_HIDE_TABLES"] = qstr.toStdString();
255 
256  connInfo["PG_HIDE_SPATIAL_METADATA_TABLES"] = m_ui->m_hideMetadataTablesCheckBox->isChecked() ? "TRUE" : "FALSE";
257 
258  connInfo["PG_HIDE_RASTER_TABLES"] = m_ui->m_hideRasterTablesCheckBox->isChecked() ? "TRUE" : "FALSE";
259 
260 // get connect_timeout
261  qstr = m_ui->m_connectTimeoutSpinBox->text().trimmed();
262 
263  if(!qstr.isEmpty())
264  connInfo["PG_CONNECT_TIMEOUT"] = qstr.toStdString();
265 
266 // get MinPoolSize
267  qstr = m_ui->m_minPoolSizeSpinBox->text().trimmed();
268 
269  if(!qstr.isEmpty())
270  connInfo["PG_MIN_POOL_SIZE"] = qstr.toStdString();
271 
272 // get MaxPoolSize
273  qstr = m_ui->m_maxPoolSizeSpinBox->text().trimmed();
274 
275  if(!qstr.isEmpty())
276  connInfo["PG_MAX_POOL_SIZE"] = qstr.toStdString();
277 
278 // get options
279  qstr = m_ui->m_optionsLineEdit->text().trimmed();
280 
281  if(!qstr.isEmpty())
282  connInfo["PG_OPTIONS"] = qstr.toStdString();
283 }
284 
285 void te::qt::plugins::pgis::PostGISConnectorDialog::setConnectionInfo(const std::map<std::string, std::string>& connInfo)
286 {
287  std::map<std::string, std::string>::const_iterator it = connInfo.find("PG_HOST");
288  std::map<std::string, std::string>::const_iterator itend = connInfo.end();
289 
290  if(it != itend)
291  m_ui->m_hostNameLineEdit->setText(QString::fromStdString(it->second));
292 
293  it = connInfo.find("PG_HOST_ADDR");
294 
295  if(it != itend)
296  m_ui->m_hostNameLineEdit->setText(QString::fromStdString(it->second));
297 
298  it = connInfo.find("PG_PORT");
299 
300  if(it != itend)
301  m_ui->m_portLineEdit->setText(QString::fromStdString(it->second));
302 
303  it = connInfo.find("PG_DB_NAME");
304 
305  if(it != itend)
306  {
307  int pos = m_ui->m_databaseComboBox->findText(QString::fromStdString(it->second));
308 
309  if(pos != -1)
310  m_ui->m_databaseComboBox->setCurrentIndex(pos);
311  else
312  {
313  m_ui->m_databaseComboBox->addItem(QString::fromStdString(it->second));
314  m_ui->m_databaseComboBox->setCurrentIndex(0);
315  }
316  }
317 
318  it = connInfo.find("PG_CLIENT_ENCODING");
319 
320  if(it != itend)
321  {
322  int pos = m_ui->m_clientEncodingComboBox->findText(QString::fromStdString(it->second));
323 
324  if(pos != -1)
325  m_ui->m_clientEncodingComboBox->setCurrentIndex(pos);
326  else
327  {
328  m_ui->m_clientEncodingComboBox->addItem(QString::fromStdString(it->second));
329  m_ui->m_clientEncodingComboBox->setCurrentIndex(0);
330  }
331  }
332 
333  it = connInfo.find("PG_USER");
334 
335  if(it != itend)
336  m_ui->m_userNameLineEdit->setText(QString::fromStdString(it->second));
337 
338  it = connInfo.find("PG_PASSWORD");
339 
340  if(it != itend)
341  m_ui->m_passwordLineEdit->setText(QString::fromStdString(it->second));
342 
343  it = connInfo.find("PG_CONNECT_TIMEOUT");
344 
345  if(it != itend)
346  m_ui->m_connectTimeoutSpinBox->setValue(boost::lexical_cast<int>(it->second.c_str()));
347 
348  it = connInfo.find("PG_MIN_POOL_SIZE");
349 
350  if(it != itend)
351  m_ui->m_minPoolSizeSpinBox->setValue(boost::lexical_cast<int>(it->second.c_str()));
352 
353  it = connInfo.find("PG_MAX_POOL_SIZE");
354 
355  if(it != itend)
356  m_ui->m_maxPoolSizeSpinBox->setValue(boost::lexical_cast<int>(it->second.c_str()));
357 
358  it = connInfo.find("PG_OPTIONS");
359 
360  if(it != itend)
361  m_ui->m_optionsLineEdit->setText(QString::fromStdString(it->second));
362 
363  it = connInfo.find("PG_HIDE_SPATIAL_METADATA_TABLES");
364 
365  m_ui->m_hideMetadataTablesCheckBox->setChecked((it != itend) && (boost::to_upper_copy(it->second) == "TRUE"));
366 
367  it = connInfo.find("PG_HIDE_RASTER_TABLES");
368 
369  m_ui->m_hideRasterTablesCheckBox->setChecked((it != itend) && (boost::to_upper_copy(it->second) == "TRUE"));
370 
371  it = connInfo.find("PG_HIDE_TABLES");
372 
373  if(it != itend)
374  m_ui->m_tablesToHideLineEdit->setText(QString::fromStdString(it->second));
375 }
376 
378 {
379  m_ui->m_advancedConnectionOptionsGroupBox->setVisible(t);
380 }
381 
383 {
384  if(m_ui->m_userNameLineEdit->text() != "" || m_ui->m_passwordLineEdit->text() != "")
385  {
386  try{
387  std::map<std::string, std::string> dsInfo;
388  getConnectionInfo(dsInfo);
389 
390  // Get DataSources
391  std::vector<std::string> dbNames = te::da::DataSource::getDataSourceNames("POSTGIS", dsInfo);
392  if(!dbNames.empty())
393  {
394  m_ui->m_databaseComboBox->clear();
395  for(std::size_t i = 0; i < dbNames.size(); i++)
396  m_ui->m_databaseComboBox->addItem(dbNames[i].c_str());
397  }
398 
399  // Get Encodings
400  m_ui->m_clientEncodingComboBox->clear();
401  m_ui->m_clientEncodingComboBox->addItem("");
402  std::vector<te::common::CharEncoding> encodings = te::da::DataSource::getEncodings("POSTGIS", dsInfo);
403  if(!encodings.empty())
404  {
405  for(std::size_t i = 0; i < encodings.size(); i++)
406  m_ui->m_clientEncodingComboBox->addItem(te::common::CharEncodingConv::getCharEncodingName(encodings[i]).c_str());
407 
408  int idx;
409 #ifdef WIN32
410  idx = m_ui->m_clientEncodingComboBox->findText("CP1252");
411 #else
412  idx = m_ui->m_clientEncodingComboBox->findText("UTF-8");
413 #endif
414  m_ui->m_clientEncodingComboBox->setCurrentIndex(idx);
415  }
416  }
417  catch(...)
418  {}
419  }
420 }
static bool find(const std::string &dsType)
void set(const te::da::DataSourceInfoPtr &ds)
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
void setConnectionInfo(const std::map< std::string, std::string > &connInfo)
const te::da::DataSourcePtr & getDriver() const
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:345
void getConnectionInfo(std::map< std::string, std::string > &connInfo) const
static std::auto_ptr< DataSource > make(const std::string &dsType)
static std::vector< te::common::CharEncoding > getEncodings(const std::string &dsType, const std::map< std::string, std::string > &info)
It gets the encoding names of the data source.
Definition: DataSource.cpp:552
const te::da::DataSourceInfoPtr & getDataSource() const
static std::vector< std::string > getDataSourceNames(const std::string &dsType, const std::map< std::string, std::string > &info)
It returns the data source names available in the driver.
Definition: DataSource.cpp:542
PostGISConnectorDialog(QWidget *parent=0, Qt::WindowFlags f=0)
A class that represents a data source component.
A dialog window for showing the PostGIS connector widget.
static std::string getCharEncodingName(const CharEncoding &code)
It returns the name of the given charset.
std::auto_ptr< Ui::PostGISConnectorDialogForm > m_ui
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr