QueryDialog.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/QueryDialog.h
22 
23  \brief This file defines a class for a Query Dialog Dialog.
24 */
25 
26 // TerraLib
27 #include "../../../dataaccess/dataset/DataSet.h"
28 #include "../../../dataaccess/dataset/DataSetType.h"
29 #include "../../../dataaccess/dataset/ObjectIdSet.h"
30 #include "../../../dataaccess/datasource/DataSourceCapabilities.h"
31 #include "../../../dataaccess/query/FunctionNames.h"
32 #include "../../../dataaccess/query/QueryCapabilities.h"
33 #include "../../../dataaccess/utils/Utils.h"
34 #include "../../../maptools/DataSetLayer.h"
35 #include "../utils/ColorPickerToolButton.h"
36 #include "QueryDialog.h"
37 #include "WhereClauseWidget.h"
38 #include "ui_QueryDialogForm.h"
39 #include "ui_WhereClauseWidgetForm.h"
40 
41 // Qt
42 #include <QGridLayout>
43 #include <QMessageBox>
44 
45 // STL
46 #include <cassert>
47 #include <memory>
48 
50 
51 te::qt::widgets::QueryDialog::QueryDialog(QWidget* parent, Qt::WindowFlags f)
52  : QDialog(parent, f),
53  m_ui(new Ui::QueryDialogForm)
54 {
55  m_ui->setupUi(this);
56 
57  // Build form
58  QGridLayout* layout = new QGridLayout(m_ui->m_widget);
60  layout->addWidget(m_whereClauseWidget.get());
61  layout->setContentsMargins(0, 0, 0, 0);
62 
63  // Color Picker
65  m_colorPicker->setFixedSize(70, 24);
66  m_colorPicker->setColor(QColor(255, 255, 0, 128));
67 
68  // Adjusting...
69  QGridLayout* colorPickerLayout = new QGridLayout(m_ui->m_colorPickerFrame);
70  colorPickerLayout->setContentsMargins(0, 0, 0, 0);
71  colorPickerLayout->addWidget(m_colorPicker);
72 
73  // Signals¨& slots
74  connect(m_ui->m_inputLayerComboBox, SIGNAL(activated(QString)), this, SLOT(onInputLayerActivated(QString)));
75  connect(m_ui->m_applyPushButton, SIGNAL(clicked()), this, SLOT(onApplyPushButtonClicked()));
76 
77  //
78  m_ui->m_helpPushButton->setPageReference("widgets/query/query_dialog.html");
79 }
80 
82 {
83 }
84 
86 {
87  return m_whereClauseWidget.get();
88 }
89 
90 void te::qt::widgets::QueryDialog::setLayerList(std::list<te::map::AbstractLayerPtr>& layerList)
91 {
92  m_whereClauseWidget->setLayerList(layerList);
93 
94  m_ui->m_inputLayerComboBox->clear();
95 
96  std::list<te::map::AbstractLayerPtr>::iterator it = layerList.begin();
97 
98  while(it != layerList.end())
99  {
101 
102  std::auto_ptr<te::da::DataSetType> dsType = l->getSchema();
103 
104  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(l.get());
105 
106  if(dsLayer && dsType->hasGeom())
107  m_ui->m_inputLayerComboBox->addItem(l->getTitle().c_str(), QVariant::fromValue(l));
108 
109  ++it;
110  }
111 
112  if(m_ui->m_inputLayerComboBox->count() > 0)
113  {
114  QString s = m_ui->m_inputLayerComboBox->currentText();
115 
116  onInputLayerActivated(s);
117  }
118 }
119 
121 {
122  for(int i = 0; i < m_ui->m_inputLayerComboBox->count(); ++i)
123  {
124  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(i, Qt::UserRole);
126 
127  if(layer == l)
128  {
129  m_ui->m_inputLayerComboBox->setCurrentIndex(i);
130  break;
131  }
132  }
133 
134  if(m_ui->m_inputLayerComboBox->count() > 0)
135  {
136  QString s = m_ui->m_inputLayerComboBox->currentText();
137 
138  onInputLayerActivated(s);
139  }
140 }
141 
142 std::string te::qt::widgets::QueryDialog::setAliasName(std::string value)
143 {
144  if(value.empty() == false)
145  {
146  std::string dataSetName = value;
147  std::string aliasName = value;
148 
149  int pos = dataSetName.find(".");
150  if(pos != std::string::npos)
151  {
152  aliasName = dataSetName.substr(pos + 1, dataSetName.size() - 1);
153  }
154 
155  return aliasName;
156  }
157  return "";
158 }
159 
161 {
162  return m_whereClauseWidget->getWhere();
163 }
164 
166 {
167  //setCurrentLayer(layer);
168 }
169 
171 {
172  //add layer to input layer combo box
173  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(layer.get());
174 
175  if(dsLayer)
176  m_ui->m_inputLayerComboBox->addItem(layer->getTitle().c_str(), QVariant::fromValue(layer));
177 
178  int curIdx = m_ui->m_inputLayerComboBox->currentIndex();
179 
180  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(curIdx, Qt::UserRole);
182 
183  if(l == layer)
184  {
185  QString s = m_ui->m_inputLayerComboBox->currentText();
186 
187  onInputLayerActivated(s);
188  }
189 
190  //add layer to spatial layer combo box
191  if(dsLayer)
192  m_whereClauseWidget->getForm()->m_layerComboBox->addItem(layer->getTitle().c_str(), QVariant::fromValue(layer));
193 }
194 
196 {
197  //remove layer from input layer combo box
198  int curIdx = m_ui->m_inputLayerComboBox->currentIndex();
199 
200  for(int i = 0; i < m_ui->m_inputLayerComboBox->count(); ++i)
201  {
202  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(i, Qt::UserRole);
204 
205  if(l == layer)
206  {
207  m_ui->m_inputLayerComboBox->removeItem(i);
208 
209  if(i == curIdx)
210  {
211  if(m_ui->m_inputLayerComboBox->count() != 0)
212  {
213  m_ui->m_inputLayerComboBox->setCurrentIndex(0);
214 
215  QString s = m_ui->m_inputLayerComboBox->currentText();
216 
217  onInputLayerActivated(s);
218  }
219  else
220  {
221  m_whereClauseWidget->resetInterface();
222  }
223  }
224  }
225  }
226 
227  //remove layer from spatial layer combo box
228  curIdx = m_whereClauseWidget->getForm()->m_layerComboBox->currentIndex();
229 
230  for(int i = 0; i < m_whereClauseWidget->getForm()->m_layerComboBox->count(); ++i)
231  {
232  QVariant varLayer = m_whereClauseWidget->getForm()->m_layerComboBox->itemData(i, Qt::UserRole);
234 
235  if(l == layer)
236  {
237  m_whereClauseWidget->getForm()->m_layerComboBox->removeItem(i);
238  }
239  }
240 }
241 
243 {
244  m_whereClauseWidget->resetInterface();
245 
246  // Gets the input layer
247  int idxLayer = m_ui->m_inputLayerComboBox->currentIndex();
248 
249  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(idxLayer, Qt::UserRole);
250 
251  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
252 
253  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(layer.get());
254 
255  // Sets the DataSource
256  std::string dataSourceName = dsLayer->getDataSourceId();
257 
258  te::da::DataSourcePtr dsPtr = te::da::GetDataSource(dataSourceName);
259 
260  if(!dsPtr->isOpened())
261  dsPtr->open();
262 
263  m_whereClauseWidget->setDataSource(dsPtr);
264 
265  // Gets the capabilities
266  std::vector<std::string> vecOperators;
267  std::vector<std::string> vecSpatialOperators;
268  std::vector<std::string> vecConnectors;
269 
270  te::da::DataSourceCapabilities dsCap = dsPtr->getCapabilities();
272 
273  std::set<std::string>::iterator it;
274 
275  it = queryCap.getArithmeticOperators().begin();
276  while(it != queryCap.getArithmeticOperators().end())
277  {
278  vecOperators.push_back(*it);
279  ++it;
280  }
281 
282  it = queryCap.getComparsionOperators().begin();
283  while(it != queryCap.getComparsionOperators().end())
284  {
285  vecOperators.push_back(*it);
286  ++it;
287  }
288 
289  m_whereClauseWidget->setOperatorsList(vecOperators);
290 
291  it = queryCap.getSpatialTopologicOperators().begin();
292  while(it != queryCap.getSpatialTopologicOperators().end())
293  {
294  vecSpatialOperators.push_back(*it);
295  ++it;
296  }
297 
298  // For while! TODO: Revision!!!
299  if(vecSpatialOperators.size() == 1 && vecSpatialOperators[0] == te::da::FunctionNames::sm_ST_EnvelopeIntersects)
300  {
301  vecSpatialOperators.clear();
302  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Intersects);
303  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Disjoint);
304  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Touches);
305  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Overlaps);
306  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Crosses);
307  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Within);
308  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Contains);
309  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Equals);
310  }
311 
312  m_whereClauseWidget->setSpatialOperatorsList(vecSpatialOperators);
313 
314  it = queryCap.getLogicalOperators().begin();
315  while(it != queryCap.getLogicalOperators().end())
316  {
317  vecConnectors.push_back(*it);
318  ++it;
319  }
320 
321  m_whereClauseWidget->setConnectorsList(vecConnectors);
322 
323  // Gets data set information
324  std::auto_ptr<te::da::DataSetType> dsType = dsLayer->getSchema();
325 
326  std::string dsName = dsType->getName();
327  std::string aliasName = setAliasName(dsName);
328 
329  std::vector<std::pair<std::string, std::string> > list;
330  list.push_back(std::pair<std::string, std::string>(dsName, aliasName));
331 
332  m_whereClauseWidget->setFromItems(list);
333 
334  // Get properties
335  std::vector<std::string> inputProperties;
336  std::vector<std::string> geomProperties;
337 
338  for(size_t i = 0; i < dsType->size(); ++i)
339  {
340  std::string propName = dsType->getProperty(i)->getName();
341 
342  if(dsType->getProperty(i)->getType() == te::dt::GEOMETRY_TYPE)
343  geomProperties.push_back(propName);
344  else
345  inputProperties.push_back(propName);
346  }
347 
348  m_whereClauseWidget->setAttributeList(inputProperties);
349  m_whereClauseWidget->setGeomAttributeList(geomProperties, dsLayer->getSRID());
350 }
351 
353 {
354  // Gets the defined restriction
355  te::da::Where* wh = getWhere();
356  if(wh == 0 || wh->getExp() == 0)
357  {
358  QMessageBox::information(this, tr("Query"), tr("Add a restriction expression first."));
359  return;
360  }
361 
362  // Gets the selected layer
363  int index = m_ui->m_inputLayerComboBox->currentIndex();
364 
365  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(index, Qt::UserRole);
366 
367  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
368 
369  assert(layer.get());
370 
371  // Let's execute the query
372  try
373  {
374  setCursor(Qt::WaitCursor);
375 
376  // The filter expression
377  te::da::Expression* e = wh->getExp()->clone();
378 
379  // Gets the layer schema
380  std::auto_ptr<const te::map::LayerSchema> schema(layer->getSchema());
381 
382  // Gets the dataset
383  std::auto_ptr<te::da::DataSet> dataset = layer->getData(e);
384  assert(dataset.get());
385 
386  if(m_ui->m_newSelRadioButton->isChecked())
387  {
388  // Generates the oids
389  dataset->moveBeforeFirst();
390  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataset.get(), schema.get());
391 
392  oids->setExpression(wh->getExp()->clone(), false);
393 
394  layer->clearSelected();
395  layer->select(oids);
396 
397  emit layerSelectedObjectsChanged(layer);
398  }
399  else if(m_ui->m_addSelRadioButton->isChecked())
400  {
401  // Generates the oids
402  dataset->moveBeforeFirst();
403  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataset.get(), schema.get());
404 
405  oids->setExpression(wh->getExp()->clone(), false);
406 
407  layer->select(oids);
408 
409  emit layerSelectedObjectsChanged(layer);
410  }
411 
412  emit highlightLayerObjects(layer, dataset.get(), m_colorPicker->getColor());
413 
414  setCursor(Qt::ArrowCursor);
415 
416  //QMessageBox::information(this, tr("Query"), tr("Query executed with successfully."));
417  }
418  catch(std::exception& e)
419  {
420  setCursor(Qt::ArrowCursor);
421  QMessageBox::information(this, tr("Query"), e.what());
422  }
423 }
424 
425 
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
Definition: Utils.cpp:262
const std::set< std::string > & getComparsionOperators() const
std::auto_ptr< Ui::QueryDialogForm > m_ui
Definition: QueryDialog.h:136
static const std::string sm_ST_Equals
Definition: FunctionNames.h:84
static const std::string sm_ST_Overlaps
Definition: FunctionNames.h:90
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
static const std::string sm_ST_Touches
Definition: FunctionNames.h:93
static const std::string sm_ST_Intersects
Definition: FunctionNames.h:86
QueryDialog(QWidget *parent=0, Qt::WindowFlags f=0)
Definition: QueryDialog.cpp:51
virtual void layerAdded(te::map::AbstractLayerPtr layer)
This method is used to add a new layer.
void setCurrentLayer(te::map::AbstractLayerPtr layer)
This method is used to set current layer.
A class that represents the known capabilities of a specific data source, i.e. this class informs all...
const std::set< std::string > & getArithmeticOperators() const
virtual void layerRemoved(te::map::AbstractLayerPtr layer)
This method is used to remove a layer.
void setExpression(te::da::Expression *expression, bool isClauseIn)
It set the expression that can be used to retrieve the data set that contains the all indentified ele...
Definition: ObjectIdSet.cpp:89
static const std::string sm_ST_Contains
Definition: FunctionNames.h:74
const QueryCapabilities & getQueryCapabilities() const
Q_DECLARE_METATYPE(te::map::AbstractLayerPtr)
This is an abstract class that models a query expression.
Definition: Expression.h:47
const std::set< std::string > & getLogicalOperators() const
static const std::string sm_ST_Crosses
Definition: FunctionNames.h:76
Custom tool button used to pick a color.
A class that informs the query support of a given data source.
const std::string & getDataSourceId() const
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:55
This file has the DataSetWidget class.
te::da::Where * getWhere()
A class that can be used to model a filter expression that can be applied to a query.
Definition: Where.h:47
static const std::string sm_ST_EnvelopeIntersects
Definition: FunctionNames.h:83
Expression * getExp() const
Definition: Where.cpp:60
TEDATAACCESSEXPORT ObjectIdSet * GenerateOIDSet(DataSet *dataset, const DataSetType *type)
Definition: Utils.cpp:412
This class is used to define the WHERE object of select operation.
std::string setAliasName(std::string value)
This method is used to set the alias name.
const std::set< std::string > & getSpatialTopologicOperators() const
std::auto_ptr< te::qt::widgets::WhereClauseWidget > m_whereClauseWidget
Definition: QueryDialog.h:137
ColorPickerToolButton * m_colorPicker
Definition: QueryDialog.h:138
virtual void layerSelected(te::map::AbstractLayerPtr layer)
This method is used to set current layer.
This file defines a class for a Query Dialog Dialog.
static const std::string sm_ST_Disjoint
Definition: FunctionNames.h:78
void onInputLayerActivated(QString value)
static const std::string sm_ST_Within
Definition: FunctionNames.h:95
te::qt::widgets::WhereClauseWidget * getWidget()
Definition: QueryDialog.cpp:85
A layer with reference to a dataset.
Definition: DataSetLayer.h:47
virtual Expression * clone() const =0
It creates a new copy of this expression.
void setLayerList(std::list< te::map::AbstractLayerPtr > &layerList)
This method is used to set the list of layers.
Definition: QueryDialog.cpp:90
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr