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) 2008 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, 99999, 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  // Perform connection
105  std::auto_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("POSTGIS");
106  ds->setConnectionInfo(getConnectionInfo(true));
107  ds->open();
108  m_driver.reset(ds.release());
109 
110  if(m_driver.get() == 0)
111  throw te::qt::widgets::Exception(TE_TR("Could not open PostgreSQL + PostGIS data source due to an unknown error!"));
112 
113  QString title = m_ui->m_datasourceTitleLineEdit->text().trimmed();
114 
115  if(title.isEmpty())
116  title = m_ui->m_hostNameLineEdit->text().trimmed() + QString::fromStdString("@") + m_ui->m_databaseComboBox->currentText().trimmed() + QString::fromStdString("@") + m_ui->m_userNameLineEdit->text().trimmed();
117 
118  if(m_datasource.get() == 0)
119  {
120  // Create a new data source based on the form data
121  m_datasource.reset(new te::da::DataSourceInfo);
122 
123  m_datasource->setConnInfo(getConnectionInfo(m_ui->m_savePasswordCheckBox->isChecked()));
124 
125  boost::uuids::basic_random_generator<boost::mt19937> gen;
126  boost::uuids::uuid u = gen();
127  std::string dsId = boost::uuids::to_string(u);
128 
129  m_datasource->setId(dsId);
130  m_driver->setId(dsId);
131  m_datasource->setTitle(title.toStdString());
132  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().toStdString());
133  m_datasource->setAccessDriver("POSTGIS");
134  m_datasource->setType("POSTGIS");
135  }
136  else
137  {
138  m_driver->setId(m_datasource->getId());
139  m_datasource->setConnInfo(getConnectionInfo(m_ui->m_savePasswordCheckBox->isChecked()));
140  m_datasource->setTitle(title.toStdString());
141  m_datasource->setDescription(m_ui->m_datasourceDescriptionTextEdit->toPlainText().toStdString());
142  }
143  }
144  catch(const std::exception& e)
145  {
146  QMessageBox::warning(this,
147  tr("TerraLib Qt Components"),
148  tr(e.what()));
149  return;
150  }
151  catch(...)
152  {
153  QMessageBox::warning(this,
154  tr("TerraLib Qt Components"),
155  tr("Unknown error while opening PostgreSQL database!"));
156  return;
157  }
158 
159  accept();
160 }
161 
163 {
164  try
165  {
166  // Check if driver is loaded
167  if(te::da::DataSourceFactory::find("POSTGIS") == 0)
168  throw te::qt::widgets::Exception(TE_TR("Sorry! No data access driver loaded for PostgreSQL + PostGIS data sources!"));
169 
170  // Perform connection
171  std::auto_ptr<te::da::DataSource> ds(te::da::DataSourceFactory::make("POSTGIS"));
172 
173  if(ds.get() == 0)
174  throw te::qt::widgets::Exception(TE_TR("Could not open PostgreSQL + PostGIS database!"));
175 
176  ds->setConnectionInfo(getConnectionInfo(true));
177  ds->open();
178 
179  QMessageBox::information(this,
180  tr("TerraLib Qt Components"),
181  tr("Data source is ok!"));
182 
183  ds->close();
184  }
185  catch(const std::exception& e)
186  {
187  QMessageBox::warning(this,
188  tr("TerraLib Qt Components"),
189  tr(e.what()));
190  }
191  catch(...)
192  {
193  QMessageBox::warning(this,
194  tr("TerraLib Qt Components"),
195  tr("Unknown error while testing PostgreSQL + PostGIS data source!"));
196  }
197 }
198 
199 std::map<std::string, std::string> te::qt::plugins::pgis::PostGISConnectorDialog::getConnectionInfo(bool getPrivateKeys) const
200 {
201  std::map<std::string, std::string> connInfo;
202 
203 // get host
204  QString qstr = m_ui->m_hostNameLineEdit->text().trimmed();
205 
206  if(!qstr.isEmpty())
207  connInfo["PG_HOST"] = qstr.toStdString();
208 
209 // get port
210  qstr = m_ui->m_portLineEdit->text().trimmed();
211 
212  if(!qstr.isEmpty())
213  connInfo["PG_PORT"] = qstr.toStdString();
214 
215 // get dbname
216  qstr = m_ui->m_databaseComboBox->currentText().trimmed();
217 
218  if(!qstr.isEmpty())
219  connInfo["PG_DB_NAME"] = qstr.toStdString();
220 
221 // get client encoding
222  qstr = m_ui->m_clientEncodingComboBox->currentText().trimmed();
223 
224  if(!qstr.isEmpty())
225  connInfo["PG_CLIENT_ENCODING"] = qstr.toStdString();
226 
227 // get user
228  qstr = m_ui->m_userNameLineEdit->text().trimmed();
229 
230  if(!qstr.isEmpty())
231  connInfo["PG_USER"] = qstr.toStdString();
232 
233  if(getPrivateKeys)
234  {
235  // get password
236  qstr = m_ui->m_passwordLineEdit->text().trimmed();
237 
238  if(!qstr.isEmpty())
239  connInfo["PG_PASSWORD"] = qstr.toStdString();
240  }
241 
242 // get table info
243  qstr = m_ui->m_tablesToHideLineEdit->text().trimmed();
244 
245  if(!qstr.isEmpty())
246  connInfo["PG_HIDE_TABLES"] = qstr.toStdString();
247 
248  connInfo["PG_HIDE_SPATIAL_METADATA_TABLES"] = m_ui->m_hideMetadataTablesCheckBox->isChecked() ? "TRUE" : "FALSE";
249 
250  connInfo["PG_HIDE_RASTER_TABLES"] = m_ui->m_hideRasterTablesCheckBox->isChecked() ? "TRUE" : "FALSE";
251 
252 // get connect_timeout
253  qstr = m_ui->m_connectTimeoutSpinBox->text().trimmed();
254 
255  if(!qstr.isEmpty())
256  connInfo["PG_CONNECT_TIMEOUT"] = qstr.toStdString();
257 
258 // get MinPoolSize
259  qstr = m_ui->m_minPoolSizeSpinBox->text().trimmed();
260 
261  if(!qstr.isEmpty())
262  connInfo["PG_MIN_POOL_SIZE"] = qstr.toStdString();
263 
264 // get MaxPoolSize
265  qstr = m_ui->m_maxPoolSizeSpinBox->text().trimmed();
266 
267  if(!qstr.isEmpty())
268  connInfo["PG_MAX_POOL_SIZE"] = qstr.toStdString();
269 
270 // get options
271  qstr = m_ui->m_optionsLineEdit->text().trimmed();
272 
273  if(!qstr.isEmpty())
274  connInfo["PG_OPTIONS"] = qstr.toStdString();
275 
276  return connInfo;
277 }
278 
279 void te::qt::plugins::pgis::PostGISConnectorDialog::setConnectionInfo(const std::map<std::string, std::string>& connInfo)
280 {
281  std::map<std::string, std::string>::const_iterator it = connInfo.find("PG_HOST");
282  std::map<std::string, std::string>::const_iterator itend = connInfo.end();
283 
284  if(it != itend)
285  m_ui->m_hostNameLineEdit->setText(QString::fromStdString(it->second));
286 
287  it = connInfo.find("PG_HOST_ADDR");
288 
289  if(it != itend)
290  m_ui->m_hostNameLineEdit->setText(QString::fromStdString(it->second));
291 
292  it = connInfo.find("PG_PORT");
293 
294  if(it != itend)
295  m_ui->m_portLineEdit->setText(QString::fromStdString(it->second));
296 
297  it = connInfo.find("PG_DB_NAME");
298 
299  if(it != itend)
300  {
301  int pos = m_ui->m_databaseComboBox->findText(QString::fromStdString(it->second));
302 
303  if(pos != -1)
304  m_ui->m_databaseComboBox->setCurrentIndex(pos);
305  else
306  {
307  m_ui->m_databaseComboBox->addItem(QString::fromStdString(it->second));
308  m_ui->m_databaseComboBox->setCurrentIndex(0);
309  }
310  }
311 
312  it = connInfo.find("PG_CLIENT_ENCODING");
313 
314  if(it != itend)
315  {
316  int pos = m_ui->m_clientEncodingComboBox->findText(QString::fromStdString(it->second));
317 
318  if(pos != -1)
319  m_ui->m_clientEncodingComboBox->setCurrentIndex(pos);
320  else
321  {
322  m_ui->m_clientEncodingComboBox->addItem(QString::fromStdString(it->second));
323  m_ui->m_clientEncodingComboBox->setCurrentIndex(0);
324  }
325  }
326 
327  it = connInfo.find("PG_USER");
328 
329  if(it != itend)
330  m_ui->m_userNameLineEdit->setText(QString::fromStdString(it->second));
331 
332  it = connInfo.find("PG_PASSWORD");
333 
334  if(it != itend)
335  m_ui->m_passwordLineEdit->setText(QString::fromStdString(it->second));
336 
337  it = connInfo.find("PG_CONNECT_TIMEOUT");
338 
339  if(it != itend)
340  m_ui->m_connectTimeoutSpinBox->setValue(boost::lexical_cast<int>(it->second.c_str()));
341 
342  it = connInfo.find("PG_MIN_POOL_SIZE");
343 
344  if(it != itend)
345  m_ui->m_minPoolSizeSpinBox->setValue(boost::lexical_cast<int>(it->second.c_str()));
346 
347  it = connInfo.find("PG_MAX_POOL_SIZE");
348 
349  if(it != itend)
350  m_ui->m_maxPoolSizeSpinBox->setValue(boost::lexical_cast<int>(it->second.c_str()));
351 
352  it = connInfo.find("PG_OPTIONS");
353 
354  if(it != itend)
355  m_ui->m_optionsLineEdit->setText(QString::fromStdString(it->second));
356 
357  it = connInfo.find("PG_HIDE_SPATIAL_METADATA_TABLES");
358 
359  m_ui->m_hideMetadataTablesCheckBox->setChecked((it != itend) && (boost::to_upper_copy(it->second) == "TRUE"));
360 
361  it = connInfo.find("PG_HIDE_RASTER_TABLES");
362 
363  m_ui->m_hideRasterTablesCheckBox->setChecked((it != itend) && (boost::to_upper_copy(it->second) == "TRUE"));
364 
365  it = connInfo.find("PG_HIDE_TABLES");
366 
367  if(it != itend)
368  m_ui->m_tablesToHideLineEdit->setText(QString::fromStdString(it->second));
369 }
370 
372 {
373  m_ui->m_advancedConnectionOptionsGroupBox->setVisible(t);
374 }
375 
377 {
378  if(m_ui->m_userNameLineEdit->text() != "" || m_ui->m_passwordLineEdit->text() != "")
379  {
380  try{
381  std::map<std::string, std::string> dsInfo = getConnectionInfo(true);
382 
383  //get current informations
384  std::string curDb = "";
385 
386  if(!m_ui->m_databaseComboBox->currentText().isEmpty())
387  curDb = m_ui->m_databaseComboBox->currentText().toStdString();
388 
389  std::string curCE = "";
390 
391  if(!m_ui->m_clientEncodingComboBox->currentText().isEmpty())
392  curCE = m_ui->m_clientEncodingComboBox->currentText().toStdString();
393 
394  m_ui->m_databaseComboBox->clear();
395  m_ui->m_clientEncodingComboBox->clear();
396 
397  // Get DataSources
398  std::vector<std::string> dbNames = te::da::DataSource::getDataSourceNames("POSTGIS", dsInfo);
399 
400  if(!dbNames.empty())
401  {
402  setDatabasesNames(dbNames);
403 
404  if(!curDb.empty())
405  {
406  int idx = m_ui->m_databaseComboBox->findText(curDb.c_str(), Qt::MatchExactly);
407 
408  if(idx != -1)
409  m_ui->m_databaseComboBox->setCurrentIndex(idx);
410  }
411  }
412 
413  // Get Encodings
414  m_ui->m_clientEncodingComboBox->addItem("");
415  std::vector<te::common::CharEncoding> encodings = te::da::DataSource::getEncodings("POSTGIS", dsInfo);
416  if(!encodings.empty())
417  {
418  for(std::size_t i = 0; i < encodings.size(); i++)
419  m_ui->m_clientEncodingComboBox->addItem(te::common::CharEncodingConv::getCharEncodingName(encodings[i]).c_str());
420 
421  int idx;
422 #ifdef WIN32
423  idx = m_ui->m_clientEncodingComboBox->findText("CP1252");
424 #else
425  idx = m_ui->m_clientEncodingComboBox->findText("UTF-8");
426 #endif
427  if(!curDb.empty())
428  {
429  idx = m_ui->m_clientEncodingComboBox->findText(curCE.c_str(), Qt::MatchExactly);
430 
431  if(idx != -1)
432  m_ui->m_clientEncodingComboBox->setCurrentIndex(idx);
433  }
434  else
435  {
436  m_ui->m_clientEncodingComboBox->setCurrentIndex(idx);
437  }
438  }
439  }
440  catch(...)
441  {}
442  }
443 }
444 
446 {
447  std::sort(names.begin(), names.end());
448 
449  for(std::size_t i = 0; i < names.size(); ++i)
450  {
451  m_ui->m_databaseComboBox->addItem(names[i].c_str());
452  }
453 }
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:347
std::map< std::string, std::string > getConnectionInfo(bool getPrivateKeys) 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.
void setDatabasesNames(std::vector< std::string > names)
std::auto_ptr< Ui::PostGISConnectorDialogForm > m_ui
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr