All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
WhereClauseWidget.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/widgets/query/WhereClauseWidget.cpp
22 
23  \brief This file has the WhereClauseWidget class.
24 */
25 
26 // TerraLib
27 #include "../../../common/STLUtils.h"
28 #include "../../../dataaccess/dataset/DataSet.h"
29 #include "../../../dataaccess/dataset/DataSetType.h"
30 #include "../../../dataaccess/dataset/ObjectIdSet.h"
31 #include "../../../dataaccess/datasource/DataSourceCatalog.h"
32 #include "../../../dataaccess/query/BinaryFunction.h"
33 #include "../../../dataaccess/query/DataSetName.h"
34 #include "../../../dataaccess/query/Distinct.h"
35 #include "../../../dataaccess/query/Field.h"
36 #include "../../../dataaccess/query/Fields.h"
37 #include "../../../dataaccess/query/From.h"
38 #include "../../../dataaccess/query/LiteralDouble.h"
39 #include "../../../dataaccess/query/LiteralGeom.h"
40 #include "../../../dataaccess/query/LiteralInt16.h"
41 #include "../../../dataaccess/query/LiteralInt32.h"
42 #include "../../../dataaccess/query/LiteralString.h"
43 #include "../../../dataaccess/query/OrderByItem.h"
44 #include "../../../dataaccess/query/PropertyName.h"
45 #include "../../../dataaccess/query/Select.h"
46 #include "../../../dataaccess/query/SQLVisitor.h"
47 #include "../../../dataaccess/utils/Utils.h"
48 #include "../../../geometry/Geometry.h"
49 #include "../../../geometry/GeometryCollection.h"
50 #include "../../../geometry/GeometryProperty.h"
51 #include "ui_WhereClauseWidgetForm.h"
52 #include "WhereClauseWidget.h"
53 
54 // Qt
55 #include <QIcon>
56 #include <QMessageBox>
57 #include <QToolButton>
58 
60 
61 
62 te::qt::widgets::WhereClauseWidget::WhereClauseWidget(QWidget* parent, Qt::WindowFlags f)
63  : QWidget(parent, f),
64  m_ui(new Ui::WhereClauseWidgetForm)
65 {
66  m_ui->setupUi(this);
67 
68  m_ds.reset();
69 
70  // set icons
71  m_ui->m_addWhereClausePushButton->setIcon(QIcon::fromTheme("list-add"));
72  m_ui->m_clearAllPushButton->setIcon(QIcon::fromTheme("edit-clear"));
73 
74  //connects
75  connect(m_ui->m_addWhereClausePushButton, SIGNAL(clicked()), this, SLOT(onAddWhereClausePushButtonClicked()));
76  connect(m_ui->m_clearAllPushButton, SIGNAL(clicked()), this, SLOT(onClearAllPushButtonClicked()));
77  connect(m_ui->m_valueValueRadioButton, SIGNAL(clicked()), this, SLOT(onValuePropertyRadioButtonClicked()));
78  connect(m_ui->m_restrictValueComboBox, SIGNAL(activated(QString)), this, SLOT(onRestrictValueComboBoxActivated(QString)));
79 
80  m_count = 0;
81  m_srid = 0;
82 }
83 
85 {
86  clear();
87 }
88 
89 Ui::WhereClauseWidgetForm* te::qt::widgets::WhereClauseWidget::getForm() const
90 {
91  return m_ui.get();
92 }
93 
95 {
96  int row = m_ui->m_whereClauseTableWidget->rowCount();
97 
98  if(row == 0)
99  return 0;
100 
101  te::da::Expression* leftSide = 0;
102  std::string lastConnectorName = "";
103 
104  for(int i = 0; i < row; ++i)
105  {
106  //create binary function
107  std::string propName = "";
108  QTableWidgetItem* itemPropName = m_ui->m_whereClauseTableWidget->item(i, 1);
109  if(itemPropName)
110  propName = itemPropName->text().toStdString();
111  else
112  {
113  QWidget* w = m_ui->m_whereClauseTableWidget->cellWidget(i, 1);
114  QComboBox* cmbBox = dynamic_cast<QComboBox*>(w);
115  if(cmbBox)
116  propName = cmbBox->currentText().toStdString();
117  }
118 
119  std::string funcName = "";
120  QTableWidgetItem* itemFuncName = m_ui->m_whereClauseTableWidget->item(i, 2);
121  if(itemFuncName)
122  funcName = itemFuncName->text().toStdString();
123  else
124  {
125  QWidget* w = m_ui->m_whereClauseTableWidget->cellWidget(i, 2);
126  QComboBox* cmbBox = dynamic_cast<QComboBox*>(w);
127  if(cmbBox)
128  funcName = cmbBox->currentText().toStdString();
129  }
130 
131  int expIdx = -1;
132  QTableWidgetItem* itemValue = m_ui->m_whereClauseTableWidget->item(i, 3);
133  if(itemValue)
134  {
135  expIdx = itemValue->data(Qt::UserRole).toInt();
136  }
137  else
138  {
139  QWidget* w = m_ui->m_whereClauseTableWidget->cellWidget(i, 3);
140  QComboBox* cmbBox = dynamic_cast<QComboBox*>(w);
141  if(cmbBox)
142  expIdx = m_comboMap[cmbBox].first;
143  else
144  return 0;
145  }
146 
147 
148  te::da::Expression* exp1 = new te::da::PropertyName(propName);
149  te::da::Expression* exp2 = m_mapExp[expIdx]->m_expression->clone();
150 
151  te::da::BinaryFunction* func = new te::da::BinaryFunction(funcName, exp1, exp2);
152 
153  //check left side expression
154  if(leftSide != 0 && lastConnectorName.empty() == false)
155  {
156  te::da::BinaryFunction* connectFunc = new te::da::BinaryFunction(lastConnectorName, leftSide, func);
157  leftSide = connectFunc;
158  }
159  else
160  {
161  leftSide = func;
162  }
163 
164  //check connector
165  QTableWidgetItem* itemConnectorName = m_ui->m_whereClauseTableWidget->item(i, 4);
166  if(itemConnectorName)
167  {
168  if(itemPropName->text().isEmpty() == false)
169  lastConnectorName = itemConnectorName->text().toStdString();
170  else
171  lastConnectorName = "";
172  }
173  else
174  {
175  QWidget* w = m_ui->m_whereClauseTableWidget->cellWidget(i, 4);
176  QComboBox* cmbBox = dynamic_cast<QComboBox*>(w);
177  if(cmbBox)
178  lastConnectorName = cmbBox->currentText().toStdString();
179  }
180  }
181 
182  te::da::Where* w = new te::da::Where(leftSide);
183 
184  return w;
185 }
186 
188 {
189  std::string sql = "";
190 
191  te::da::Where* w = getWhere();
192 
193  if(w)
194  {
195  te::da::SQLVisitor visitor(*m_ds->getDialect(), sql);
196  te::da::Expression* exp = w->getExp();
197 
198  try
199  {
200  exp->accept(visitor);
201  }
202  catch(...)
203  {
204  delete w;
205  return "";
206  }
207  }
208 
209  delete w;
210 
211  return sql;
212 }
213 
215 {
216  m_ds = ds;
217 }
218 
219 void te::qt::widgets::WhereClauseWidget::setLayerList(std::list<te::map::AbstractLayerPtr>& layerList)
220 {
221  m_ui->m_layerComboBox->clear();
222 
223  std::list<te::map::AbstractLayerPtr>::iterator it = layerList.begin();
224 
225  while(it != layerList.end())
226  {
228 
229  std::auto_ptr<te::da::DataSetType> dsType = l->getSchema();
230 
231  if(dsType.get())
232  {
233  if(dsType->hasGeom())
234  m_ui->m_layerComboBox->addItem(l->getTitle().c_str(), QVariant::fromValue(l));
235  }
236  ++it;
237  }
238 }
239 
240 void te::qt::widgets::WhereClauseWidget::setFromItems(std::vector<std::pair<std::string, std::string> > vec)
241 {
242  m_fromItems = vec;
243 }
244 
245 void te::qt::widgets::WhereClauseWidget::setAttributeList(const std::vector<std::string>& vec)
246 {
247  m_ui->m_restrictValueComboBox->clear();
248  m_ui->m_valuePropertyComboBox->clear();
249 
250  for(size_t t = 0; t <vec.size(); ++t)
251  {
252  m_ui->m_restrictValueComboBox->addItem(vec[t].c_str());
253  m_ui->m_valuePropertyComboBox->addItem(vec[t].c_str());
254  }
255 }
256 
257 void te::qt::widgets::WhereClauseWidget::setGeomAttributeList(const std::vector<std::string>& vec, int srid)
258 {
259  m_srid = srid;
260 
261  m_ui->m_geomAttrComboBox->clear();
262 
263  for(size_t t = 0; t <vec.size(); ++t)
264  {
265  m_ui->m_geomAttrComboBox->addItem(vec[t].c_str());
266  }
267 }
268 
269 void te::qt::widgets::WhereClauseWidget::setOperatorsList(const std::vector<std::string>& vec)
270 {
271  m_ui->m_OperatorComboBox->clear();
272 
273  for(size_t t = 0; t <vec.size(); ++t)
274  {
275  m_ui->m_OperatorComboBox->addItem(vec[t].c_str());
276  }
277 }
278 
279 void te::qt::widgets::WhereClauseWidget::setSpatialOperatorsList(const std::vector<std::string>& vec)
280 {
281  m_ui->m_SpatialOperatorComboBox->clear();
282 
283  for(size_t t = 0; t <vec.size(); ++t)
284  {
285  m_ui->m_SpatialOperatorComboBox->addItem(vec[t].c_str());
286  }
287 }
288 
289 void te::qt::widgets::WhereClauseWidget::setConnectorsList(const std::vector<std::string>& vec)
290 {
291  m_connectorsList.clear();
292 
293  m_connectorsList.append("");
294 
295  for(size_t t = 0; t <vec.size(); ++t)
296  {
297  m_connectorsList.append(vec[t].c_str());
298  }
299 }
300 
302 {
303  te::common::FreeContents(m_mapExp);
304 
305  m_mapExp.clear();
306 
307  m_comboMap.clear();
308 
309  m_ui->m_whereClauseTableWidget->setRowCount(0);
310 
311  m_count = 0;
312 }
313 
315 {
316  clear();
317 
318  m_ds.reset();
319  m_srid = 0;
320 
321  m_ui->m_restrictValueComboBox->clear();
322  m_ui->m_valuePropertyComboBox->clear();
323  m_ui->m_valueValueComboBox->clear();
324  m_ui->m_geomAttrComboBox->clear();
325  m_ui->m_OperatorComboBox->clear();
326  m_ui->m_SpatialOperatorComboBox->clear();
327  m_ui->m_sqlTextEdit->clear();
328  m_ui->m_tabWidget->setCurrentIndex(0);
329 }
330 
332 {
333  std::string restrictValue = "";
334  std::string operatorStr = "";
335  std::string valueStr = "";
336 
337  if(m_ui->m_criteriaTabWidget->currentIndex() == 0) // criteria by attribute restriction
338  {
339  int expId = ++m_count;
340 
341  if(m_ui->m_restrictValueComboBox->currentText().isEmpty())
342  {
343  QMessageBox::warning(this, tr("Query Builder"), tr("Restrict value not defined."));
344  return;
345  }
346 
347  if(m_ui->m_valuePropertyRadioButton->isChecked() == false &&
348  m_ui->m_valueValueRadioButton->isChecked() == false)
349  {
350  if(m_ui->m_valueValueComboBox->currentText().isEmpty())
351  {
352  QMessageBox::warning(this, tr("Query Builder"), tr("Value not defined."));
353  return;
354  }
355  }
356 
357  if(m_ui->m_valueValueRadioButton->isChecked())
358  {
359  if(m_ui->m_valueValueComboBox->currentText().isEmpty())
360  {
361  QMessageBox::warning(this, tr("Query Builder"), tr("Value not defined."));
362  return;
363  }
364  }
365 
366  restrictValue = m_ui->m_restrictValueComboBox->currentText().toStdString();
367 
368  if(m_ui->m_OperatorComboBox->currentText().isEmpty())
369  {
370  QMessageBox::warning(this, tr("Query Builder"), tr("Operator not defined."));
371  return;
372  }
373  operatorStr = m_ui->m_OperatorComboBox->currentText().toStdString();
374 
376  ep->m_isAttributeCriteria = true;
377  ep->m_property = restrictValue;
378  ep->m_operator = operatorStr;
379 
380  if(m_ui->m_valuePropertyRadioButton->isChecked())
381  {
382  valueStr = m_ui->m_valuePropertyComboBox->currentText().toStdString();
383 
384  te::da::Expression* exp = new te::da::PropertyName(valueStr);
385 
386  ep->m_isPropertyValue = true;
387  ep->m_value = valueStr;
388  ep->m_expression = exp;
389 
390  m_mapExp.insert(std::map<int, ExpressionProperty*>::value_type(expId, ep));
391  }
392  else if(m_ui->m_valueValueRadioButton->isChecked())
393  {
394  valueStr = m_ui->m_valueValueComboBox->currentText().toStdString();
395 
396  te::da::Expression* exp = getExpression(m_ui->m_valueValueComboBox->currentText(), restrictValue);
397 
398  ep->m_isValueValue = true;
399  ep->m_value = valueStr;
400  ep->m_expression = exp;
401 
402  m_mapExp.insert(std::map<int, ExpressionProperty*>::value_type(expId, ep));
403  }
404 
405  std::string connector = tr("and").toStdString();
406 
407  //new entry
408  int newrow = m_ui->m_whereClauseTableWidget->rowCount();
409 
410  m_ui->m_whereClauseTableWidget->insertRow(newrow);
411 
412  //remove button
413  QToolButton* removeBtn = new QToolButton(m_ui->m_whereClauseTableWidget);
414  removeBtn->setIcon(QIcon::fromTheme("list-remove"));
415  connect(removeBtn, SIGNAL(clicked()), this, SLOT(onRemoveWhereClausePushButtonClicked()));
416  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 0, removeBtn);
417 
418  //property combo
419  QComboBox* cmbProperty = new QComboBox(m_ui->m_whereClauseTableWidget);
420  connect(cmbProperty, SIGNAL(activated(QString)), this, SLOT(onComboBoxActivated(QString)));
421  std::pair<int, int> pairProperty(expId, 1);
422  m_comboMap.insert(std::map< QComboBox*, std::pair<int, int> >::value_type(cmbProperty, pairProperty));
423  copyCombo(m_ui->m_restrictValueComboBox, cmbProperty, restrictValue);
424  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 1, cmbProperty);
425 
426  //operator combo
427  QComboBox* cmbOperator = new QComboBox(m_ui->m_whereClauseTableWidget);
428  connect(cmbOperator, SIGNAL(activated(QString)), this, SLOT(onComboBoxActivated(QString)));
429  std::pair<int, int> pairOperator(expId, 2);
430  m_comboMap.insert(std::map< QComboBox*, std::pair<int, int> >::value_type(cmbOperator, pairOperator));
431  copyCombo(m_ui->m_OperatorComboBox, cmbOperator, operatorStr);
432  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 2, cmbOperator);
433 
434  //value combo
435  QComboBox* cmbValue = new QComboBox(m_ui->m_whereClauseTableWidget);
436  connect(cmbValue, SIGNAL(activated(QString)), this, SLOT(onComboBoxActivated(QString)));
437  connect(cmbValue, SIGNAL(editTextChanged(QString)), this, SLOT(onComboBoxActivated(QString)));
438  std::pair<int, int> pairValue(expId, 3);
439  m_comboMap.insert(std::map< QComboBox*, std::pair<int, int> >::value_type(cmbValue, pairValue));
440  if(m_ui->m_valuePropertyRadioButton->isChecked())
441  copyCombo(m_ui->m_valuePropertyComboBox, cmbValue, valueStr);
442  else
443  {
444  cmbValue->setEditable(true);
445  copyCombo(m_ui->m_valueValueComboBox, cmbValue, valueStr);
446  }
447  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 3, cmbValue);
448  ep->m_valuesComboBox = cmbValue;
449 
450  //connector information
451  QComboBox* connectorCmbBox = new QComboBox(m_ui->m_whereClauseTableWidget);
452  connect(connectorCmbBox, SIGNAL(activated(QString)), this, SLOT(onComboBoxActivated(QString)));
453  std::pair<int, int> pairConnector(expId, 4);
454  m_comboMap.insert(std::map< QComboBox*, std::pair<int, int> >::value_type(connectorCmbBox, pairConnector));
455  connectorCmbBox->addItems(m_connectorsList);
456  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 4, connectorCmbBox);
457 
458  for(int i = 0; i < connectorCmbBox->count(); ++i)
459  {
460  if(connectorCmbBox->itemText(i).toStdString() == connector)
461  {
462  connectorCmbBox->setCurrentIndex(i);
463  break;
464  }
465  }
466  }
467  else // criteria by spatial restriction
468  {
469  if(m_ui->m_SpatialOperatorComboBox->currentText().isEmpty())
470  {
471  QMessageBox::warning(this, tr("Query Builder"), tr("Operator not defined."));
472  return;
473  }
474  operatorStr = m_ui->m_SpatialOperatorComboBox->currentText().toStdString();
475 
476  restrictValue = m_ui->m_geomAttrComboBox->currentText().toStdString();
477 
478  //get layer
479  int layerIdx = m_ui->m_layerComboBox->currentIndex();
480  QVariant varLayer = m_ui->m_layerComboBox->itemData(layerIdx, Qt::UserRole);
481  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
482 
483  std::auto_ptr<const te::map::LayerSchema> schema(layer->getSchema());
484 
486 
487  if(!prop)
488  {
489  QMessageBox::warning(this, tr("Query Builder"), tr("Selected layer has no geometry property."));
490  return;
491  }
492 
493  std::auto_ptr<te::da::DataSet> ds;
494 
495  if(m_ui->m_selectedObjCheckBox->isChecked())
496  {
497  const te::da::ObjectIdSet* selecteds = layer->getSelected();
498 
499  if(!selecteds || selecteds->size() == 0)
500  {
501  QMessageBox::warning(this, tr("Query Builder"), tr("Selected layer has no selected geometries."));
502  return;
503  }
504 
505  ds = layer->getData(selecteds);
506  }
507  else
508  {
509  ds = layer->getData();
510  }
511 
512  ds->moveBeforeFirst();
513 
514  size_t dsSize = ds->size();
515  size_t count = 0;
516 
517  //get all geometries
518  while(ds->moveNext())
519  {
520 
521  int expId = ++m_count;
522 
523  te::gm::Geometry* geom = ds->getGeometry(prop->getName()).release();
524 
525  geom->setSRID(layer->getSRID());
526 
527  //convert
528  if(layer->getSRID() != m_srid)
529  {
530  geom->transform(m_srid);
531  }
532 
533  //valueStr = geom->toString();
534  valueStr = tr("Geometry Value").toStdString();
535 
536  //create expression
537  te::da::LiteralGeom* lGeom = new te::da::LiteralGeom(geom);
538 
540  ep->m_isSpatialCriteria = true;
541  ep->m_property = restrictValue;
542  ep->m_operator = operatorStr;
543  ep->m_value = valueStr;
544  ep->m_expression = lGeom;
545 
546  m_mapExp.insert(std::map<int, ExpressionProperty*>::value_type(expId, ep));
547 
548  //set connector
549  std::string connector = "";
550 
551  if(count < dsSize - 1)
552  connector = tr("or").toStdString();
553 
554  ++count;
555 
556  //new entry
557  int newrow = m_ui->m_whereClauseTableWidget->rowCount();
558 
559  m_ui->m_whereClauseTableWidget->insertRow(newrow);
560 
561  //remove button
562  QToolButton* removeBtn = new QToolButton(m_ui->m_whereClauseTableWidget);
563  removeBtn->setIcon(QIcon::fromTheme("list-remove"));
564  connect(removeBtn, SIGNAL(clicked()), this, SLOT(onRemoveWhereClausePushButtonClicked()));
565  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 0, removeBtn);
566 
567  //property combo
568  QComboBox* cmbProperty = new QComboBox(m_ui->m_whereClauseTableWidget);
569  connect(cmbProperty, SIGNAL(activated(QString)), this, SLOT(onComboBoxActivated(QString)));
570  std::pair<int, int> pairProperty(expId, 1);
571  m_comboMap.insert(std::map< QComboBox*, std::pair<int, int> >::value_type(cmbProperty, pairProperty));
572  copyCombo(m_ui->m_geomAttrComboBox, cmbProperty, restrictValue);
573  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 1, cmbProperty);
574 
575  //operator combo
576  QComboBox* cmbOperator = new QComboBox(m_ui->m_whereClauseTableWidget);
577  connect(cmbOperator, SIGNAL(activated(QString)), this, SLOT(onComboBoxActivated(QString)));
578  std::pair<int, int> pairOperator(expId, 2);
579  m_comboMap.insert(std::map< QComboBox*, std::pair<int, int> >::value_type(cmbOperator, pairOperator));
580  copyCombo(m_ui->m_SpatialOperatorComboBox, cmbOperator, operatorStr);
581  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 2, cmbOperator);
582 
583  //value combo
584  QTableWidgetItem* itemValue = new QTableWidgetItem(valueStr.c_str());
585  itemValue->setData(Qt::UserRole, QVariant(expId));
586  m_ui->m_whereClauseTableWidget->setItem(newrow, 3, itemValue);
587 
588  //connector information
589  QComboBox* connectorCmbBox = new QComboBox(m_ui->m_whereClauseTableWidget);
590  connect(connectorCmbBox, SIGNAL(activated(QString)), this, SLOT(onComboBoxActivated(QString)));
591  std::pair<int, int> pairConnector(expId, 4);
592  m_comboMap.insert(std::map< QComboBox*, std::pair<int, int> >::value_type(connectorCmbBox, pairConnector));
593  connectorCmbBox->addItems(m_connectorsList);
594  m_ui->m_whereClauseTableWidget->setCellWidget(newrow, 4, connectorCmbBox);
595 
596  for(int i = 0; i < connectorCmbBox->count(); ++i)
597  {
598  if(connectorCmbBox->itemText(i).toStdString() == connector)
599  {
600  connectorCmbBox->setCurrentIndex(i);
601  break;
602  }
603  }
604  }
605  }
606 
607  m_ui->m_whereClauseTableWidget->resizeColumnsToContents();
608 
609  //get string sql
610  std::string sql = getWhereString();
611 
612  m_ui->m_sqlTextEdit->setText(sql.c_str());
613 }
614 
616 {
617  QToolButton* button = dynamic_cast<QToolButton*>(sender());
618  if(button)
619  {
620  int row = -1;
621 
622  for(int i = 0; i < m_ui->m_whereClauseTableWidget->rowCount(); ++i)
623  {
624  QWidget* w = m_ui->m_whereClauseTableWidget->cellWidget(i, 0);
625  QToolButton* btn = dynamic_cast<QToolButton*>(w);
626  if(button == w)
627  {
628  row = i;
629  break;
630  }
631  }
632 
633  if(row >= 0)
634  m_ui->m_whereClauseTableWidget->removeRow(row);
635 
636  m_ui->m_whereClauseTableWidget->resizeColumnsToContents();
637  }
638 
639  //get string sql
640  std::string sql = getWhereString();
641 
642  m_ui->m_sqlTextEdit->setText(sql.c_str());
643 }
644 
646 {
647  std::string propertyName = m_ui->m_restrictValueComboBox->currentText().toStdString();
648 
649  m_ui->m_valueValueComboBox->clear();
650  m_ui->m_valueValueComboBox->addItems(getPropertyValues(propertyName));
651 }
652 
654 {
655  m_ui->m_whereClauseTableWidget->setRowCount(0);
656  m_ui->m_whereClauseTableWidget->resizeColumnsToContents();
657 }
658 
660 {
661  if(value.isEmpty() || !m_ui->m_valueValueRadioButton->isChecked())
662  return;
663 
664  onValuePropertyRadioButtonClicked();
665 }
666 
668 {
669  QComboBox* cmbBox = dynamic_cast<QComboBox*>(sender());
670  if(!cmbBox)
671  return;
672 
673  int expId = m_comboMap[cmbBox].first;
674  int column = m_comboMap[cmbBox].second;
675 
676  ExpressionProperty* ep = m_mapExp[expId];
677 
678  if(!ep)
679  return;
680 
681  if(ep->m_isAttributeCriteria)
682  {
683  //update expression property
684  if(column == 1) //property
685  {
686  ep->m_property = value.toStdString();
687 
688  if(ep->m_isValueValue)
689  {
690  ep->m_valuesComboBox->clear();
691  ep->m_valuesComboBox->addItems(getPropertyValues(ep->m_property));
692  ep->m_value = ep->m_valuesComboBox->currentText().toStdString();
693  }
694  }
695  else if(column == 2) //operator
696  {
697  ep->m_operator = value.toStdString();
698  }
699  else if(column == 3) //value
700  {
701  ep->m_value = value.toStdString();
702  }
703 
704  //re-create expression
705  te::da::Expression* exp = 0;
706 
707  if(ep->m_isValueValue)
708  {
709  exp = getExpression(ep->m_value.c_str(), ep->m_property);
710  }
711 
712  if(ep->m_isPropertyValue)
713  {
714  exp = new te::da::PropertyName(ep->m_property);
715  }
716 
717  delete ep->m_expression;
718 
719  ep->m_expression = exp;
720  }
721 
722  //get string sql
723  std::string sql = getWhereString();
724 
725  m_ui->m_sqlTextEdit->setText(sql.c_str());
726 }
727 
728 te::da::Expression* te::qt::widgets::WhereClauseWidget::getExpression(const QString& value, const std::string& propName)
729 {
730  std::string dataSetName;
731  std::string dataSetAliasName;
732  std::string propertyName = propName;
733 
734  std::size_t pos = propName.find(".");
735  if(pos != std::string::npos)
736  {
737  dataSetAliasName = propName.substr(0, pos);
738  propertyName = propName.substr(pos + 1, propName.size() - 1);
739  }
740 
741  //get the dataset name
742  if(m_fromItems.size() == 1)
743  {
744  dataSetName = m_fromItems[0].first;
745  }
746  else
747  {
748  for(size_t t = 0; t < m_fromItems.size(); ++t)
749  {
750  if(m_fromItems[t].second == dataSetAliasName)
751  {
752  dataSetName = m_fromItems[t].first;
753  break;
754  }
755  }
756  }
757 
758  if(dataSetName.empty())
759  return 0;
760 
761  //get the dataset property type
762  std::auto_ptr<te::da::DataSetType> dsType = m_ds->getDataSetType(dataSetName);
763 
764  if(dsType.get())
765  {
766  te::dt::Property* prop = dsType->getProperty(propertyName);
767 
768  te::da::Literal* l = 0;
769 
770  if(prop)
771  {
772  if(prop->getType() == te::dt::DOUBLE_TYPE)
773  {
774  l = new te::da::LiteralDouble(value.toDouble());
775  }
776  else if(prop->getType() == te::dt::INT16_TYPE)
777  {
778  l = new te::da::LiteralInt16(value.toInt());
779  }
780  else if(prop->getType() == te::dt::INT32_TYPE)
781  {
782  l = new te::da::LiteralInt32(value.toInt());
783  }
784  else if(prop->getType() == te::dt::STRING_TYPE)
785  {
786  l = new te::da::LiteralString(value.toStdString());
787  }
788  }
789 
790  return l;
791  }
792 
793  return 0;
794 }
795 
796 void te::qt::widgets::WhereClauseWidget::copyCombo(QComboBox* input, QComboBox* output, std::string curValue)
797 {
798  int idx = 0;
799 
800  for(int i = 0; i < input->count(); ++i)
801  {
802  output->addItem(input->itemText(i));
803 
804  if(!curValue.empty() && input->itemText(i).toStdString() == curValue)
805  idx = i;
806  }
807 
808  output->setCurrentIndex(idx);
809 }
810 
811 QStringList te::qt::widgets::WhereClauseWidget::getPropertyValues(std::string propertyName)
812 {
813  QStringList list;
814 
815  if(m_ds.get() == 0)
816  return list;
817 
818  te::da::Fields* fields = new te::da::Fields;
819  te::da::Field* f = new te::da::Field(new te::da::PropertyName(propertyName));
820  fields->push_back(f);
821 
822  te::da::PropertyName* name = new te::da::PropertyName(propertyName);
823 
824  te::da::From* from = new te::da::From;
825 
826  for(size_t t = 0; t < m_fromItems.size(); ++t)
827  {
828  te::da::FromItem* fi = new te::da::DataSetName(m_fromItems[t].first, m_fromItems[t].second);
829 
830  from->push_back(fi);
831  }
832 
833  te::da::Select* select = new te::da::Select();
834 
835  select->setFields(fields);
836  select->setFrom(from);
837 
838  std::auto_ptr<te::da::DataSet> dataset;
839 
840  try
841  {
842  dataset = m_ds->query(*select);
843  }
844  catch(const std::exception& e)
845  {
846  std::string msg = "An exception has occurred: ";
847  msg += e.what();
848 
849  QMessageBox::warning(0, "Query Error: ", msg.c_str());
850 
851  return list;
852  }
853  catch(...)
854  {
855  std::string msg = "An unexpected exception has occurred!";
856 
857  QMessageBox::warning(0, "Query Error: ", msg.c_str());
858 
859  return list;
860  }
861 
862  std::size_t pos = propertyName.find(".");
863  if(pos != std::string::npos)
864  {
865  std::string dataSetAliasName = propertyName.substr(0, pos);
866  propertyName = propertyName.substr(pos + 1, propertyName.size() - 1);
867  }
868 
869  std::set<std::string> valuesStr;
870  std::set<double> valuesDouble;
871  std::set<int> valuesInt;
872 
873  std::size_t propertyPos;
874  for(std::size_t t = 0; t < dataset->getNumProperties(); ++t)
875  {
876  if(dataset->getPropertyName(t) == propertyName)
877  {
878  propertyPos = t;
879  break;
880  }
881  }
882 
883  int propertyType = dataset->getPropertyDataType(propertyPos);
884 
885  if(dataset.get())
886  {
887  while(dataset->moveNext())
888  {
889  if(!dataset->isNull(propertyName))
890  {
891  if(propertyType == te::dt::INT32_TYPE)
892  {
893  int value = dataset->getInt32(propertyName);
894 
895  std::set<int>::iterator it = valuesInt.find(value);
896 
897  if(it == valuesInt.end())
898  valuesInt.insert(value);
899  }
900  else if(propertyType == te::dt::DOUBLE_TYPE || propertyType == te::dt::FLOAT_TYPE)
901  {
902  double value = dataset->getDouble(propertyName);
903 
904  std::set<double>::iterator it = valuesDouble.find(value);
905 
906  if(it == valuesDouble.end())
907  valuesDouble.insert(value);
908  }
909  else
910  {
911  std::string value = dataset->getAsString(propertyName);
912 
913  std::set<std::string>::iterator it = valuesStr.find(value);
914 
915  if(it == valuesStr.end())
916  valuesStr.insert(value);
917  }
918  }
919  }
920  }
921 
922  if(propertyType == te::dt::INT32_TYPE)
923  {
924  std::set<int>::iterator it = valuesInt.begin();
925 
926  while(it != valuesInt.end())
927  {
928  list.append(QString::number(*it));
929 
930  ++it;
931  }
932  }
933  else if(propertyType == te::dt::DOUBLE_TYPE || propertyType == te::dt::FLOAT_TYPE)
934  {
935  std::set<double>::iterator it = valuesDouble.begin();
936 
937  while(it != valuesDouble.end())
938  {
939  list.append(QString::number(*it, 'f', 5));
940 
941  ++it;
942  }
943  }
944  else
945  {
946  std::set<std::string>::iterator it = valuesStr.begin();
947 
948  while(it != valuesStr.end())
949  {
950  list.append((*it).c_str());
951 
952  ++it;
953  }
954  }
955 
956  return list;
957 }
void setDataSource(const te::da::DataSourcePtr &ds)
Geometric property.
std::auto_ptr< Ui::WhereClauseWidgetForm > m_ui
An abstract class that models a source of data in a query.
Definition: FromItem.h:50
The Field class can be used to model an expression that takes part of the output items of a SELECT...
Definition: Field.h:50
A class that models the name of a dataset used in a From clause.
Definition: DataSetName.h:43
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
A class that models the name of any property of an object.
Definition: PropertyName.h:50
void copyCombo(QComboBox *input, QComboBox *output, std::string curValue="")
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr)
void onRestrictValueComboBoxActivated(QString value)
void setGeomAttributeList(const std::vector< std::string > &vec, int srid)
virtual void transform(int srid)=0
It converts the coordinate values of the geometry to the new spatial reference system.
WhereClauseWidget(QWidget *parent=0, Qt::WindowFlags f=0)
void setOperatorsList(const std::vector< std::string > &vec)
It models a property definition.
Definition: Property.h:59
This is an abstract class that models a query expression.
Definition: Expression.h:47
void setFromItems(std::vector< std::pair< std::string, std::string > > vec)
This class models a literal value.
Definition: Literal.h:53
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:53
std::size_t size() const
It returns the object id set size.
This file has the DataSetWidget class.
boost::ptr_vector< Field > Fields
Fields is just a boost::ptr_vector of Field pointers.
Definition: Fields.h:37
A class that can be used to model a filter expression that can be applied to a query.
Definition: Where.h:47
Expression * getExp() const
Definition: Where.cpp:60
te::da::Expression * getExpression(const QString &value, const std::string &propName)
A class that models a literal for double values.
Definition: LiteralDouble.h:43
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
int getType() const
It returns the property data type.
Definition: Property.h:143
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
void setConnectorsList(const std::vector< std::string > &vec)
void setSpatialOperatorsList(const std::vector< std::string > &vec)
void setAttributeList(const std::vector< std::string > &vec)
QStringList getPropertyValues(std::string propertyName)
A visitor for building an SQL statement from a given Query hierarchy.
Definition: SQLVisitor.h:58
virtual Expression * clone() const =0
It creates a new copy of this expression.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:508
Ui::WhereClauseWidgetForm * getForm() const
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
A base class for binary functions.
void setFields(Fields *f)
It sets the list of output expressions used to form the result set.
Definition: Select.cpp:927
virtual void setSRID(int srid)=0
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
A class that models a literal for Geometry values.
Definition: LiteralGeom.h:46
void setFrom(From *f)
It sets the list of source information.
Definition: Select.cpp:937
void setLayerList(std::list< te::map::AbstractLayerPtr > &layerList)
This class models a string Literal value.
Definition: LiteralString.h:46