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