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