All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
QueryDialog.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/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 
40 // Qt
41 #include <QGridLayout>
42 #include <QMessageBox>
43 
44 // STL
45 #include <cassert>
46 #include <memory>
47 
49 
50 te::qt::widgets::QueryDialog::QueryDialog(QWidget* parent, Qt::WindowFlags f)
51  : QDialog(parent, f),
52  m_ui(new Ui::QueryDialogForm)
53 {
54  m_ui->setupUi(this);
55 
56  // Build form
57  QGridLayout* layout = new QGridLayout(m_ui->m_widget);
59  layout->addWidget(m_whereClauseWidget.get());
60  layout->setContentsMargins(0, 0, 0, 0);
61 
62  // Color Picker
64  m_colorPicker->setFixedSize(70, 24);
65  m_colorPicker->setColor(QColor(255, 255, 0, 128));
66 
67  // Adjusting...
68  QGridLayout* colorPickerLayout = new QGridLayout(m_ui->m_colorPickerFrame);
69  colorPickerLayout->setContentsMargins(0, 0, 0, 0);
70  colorPickerLayout->addWidget(m_colorPicker);
71 
72  // Signals¨& slots
73  connect(m_ui->m_inputLayerComboBox, SIGNAL(activated(QString)), this, SLOT(onInputLayerActivated(QString)));
74  connect(m_ui->m_applyPushButton, SIGNAL(clicked()), this, SLOT(onApplyPushButtonClicked()));
75 
76  //
77  m_ui->m_helpPushButton->setPageReference("widgets/query/query_dialog.html");
78 }
79 
81 {
82 }
83 
85 {
86  return m_whereClauseWidget.get();
87 }
88 
89 void te::qt::widgets::QueryDialog::setLayerList(std::list<te::map::AbstractLayerPtr>& layerList)
90 {
91  m_whereClauseWidget->setLayerList(layerList);
92 
93  m_ui->m_inputLayerComboBox->clear();
94 
95  std::list<te::map::AbstractLayerPtr>::iterator it = layerList.begin();
96 
97  while(it != layerList.end())
98  {
100 
101  std::auto_ptr<te::da::DataSetType> dsType = l->getSchema();
102 
103  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(l.get());
104 
105  if(dsLayer && dsType->hasGeom())
106  m_ui->m_inputLayerComboBox->addItem(l->getTitle().c_str(), QVariant::fromValue(l));
107 
108  ++it;
109  }
110 
111  if(m_ui->m_inputLayerComboBox->count() > 0)
112  {
113  QString s = m_ui->m_inputLayerComboBox->currentText();
114 
115  onInputLayerActivated(s);
116  }
117 }
118 
120 {
121  for(int i = 0; i < m_ui->m_inputLayerComboBox->count(); ++i)
122  {
123  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(i, Qt::UserRole);
125 
126  if(layer == l)
127  {
128  m_ui->m_inputLayerComboBox->setCurrentIndex(i);
129  break;
130  }
131  }
132 
133  if(m_ui->m_inputLayerComboBox->count() > 0)
134  {
135  QString s = m_ui->m_inputLayerComboBox->currentText();
136 
137  onInputLayerActivated(s);
138  }
139 }
140 
141 std::string te::qt::widgets::QueryDialog::setAliasName(std::string value)
142 {
143  if(value.empty() == false)
144  {
145  std::string dataSetName = value;
146  std::string aliasName = value;
147 
148  int pos = dataSetName.find(".");
149  if(pos != std::string::npos)
150  {
151  aliasName = dataSetName.substr(pos + 1, dataSetName.size() - 1);
152  }
153 
154  return aliasName;
155  }
156  return "";
157 }
158 
160 {
161  return m_whereClauseWidget->getWhere();
162 }
163 
165 {
166  //setCurrentLayer(layer);
167 }
168 
170 {
171  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(layer.get());
172 
173  if(dsLayer)
174  m_ui->m_inputLayerComboBox->addItem(layer->getTitle().c_str(), QVariant::fromValue(layer));
175 
176  int curIdx = m_ui->m_inputLayerComboBox->currentIndex();
177 
178  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(curIdx, Qt::UserRole);
180 
181  if(l == layer)
182  {
183  QString s = m_ui->m_inputLayerComboBox->currentText();
184 
185  onInputLayerActivated(s);
186  }
187 }
188 
190 {
191  int curIdx = m_ui->m_inputLayerComboBox->currentIndex();
192 
193  for(int i = 0; i < m_ui->m_inputLayerComboBox->count(); ++i)
194  {
195  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(i, Qt::UserRole);
197 
198  if(l == layer)
199  {
200  m_ui->m_inputLayerComboBox->removeItem(i);
201 
202  if(i == curIdx)
203  {
204  if(m_ui->m_inputLayerComboBox->count() != 0)
205  {
206  m_ui->m_inputLayerComboBox->setCurrentIndex(0);
207 
208  QString s = m_ui->m_inputLayerComboBox->currentText();
209 
210  onInputLayerActivated(s);
211  }
212  else
213  {
214  m_whereClauseWidget->resetInterface();
215  }
216  }
217  }
218  }
219 }
220 
222 {
223  m_whereClauseWidget->resetInterface();
224 
225  // Gets the input layer
226  int idxLayer = m_ui->m_inputLayerComboBox->currentIndex();
227 
228  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(idxLayer, Qt::UserRole);
229 
230  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
231 
232  te::map::DataSetLayer* dsLayer = dynamic_cast<te::map::DataSetLayer*>(layer.get());
233 
234  // Sets the DataSource
235  std::string dataSourceName = dsLayer->getDataSourceId();
236 
237  te::da::DataSourcePtr dsPtr = te::da::GetDataSource(dataSourceName);
238 
239  if(!dsPtr->isOpened())
240  dsPtr->open();
241 
242  m_whereClauseWidget->setDataSource(dsPtr);
243 
244  // Gets the capabilities
245  std::vector<std::string> vecOperators;
246  std::vector<std::string> vecSpatialOperators;
247  std::vector<std::string> vecConnectors;
248 
249  te::da::DataSourceCapabilities dsCap = dsPtr->getCapabilities();
251 
252  std::set<std::string>::iterator it;
253 
254  it = queryCap.getArithmeticOperators().begin();
255  while(it != queryCap.getArithmeticOperators().end())
256  {
257  vecOperators.push_back(*it);
258  ++it;
259  }
260 
261  it = queryCap.getComparsionOperators().begin();
262  while(it != queryCap.getComparsionOperators().end())
263  {
264  vecOperators.push_back(*it);
265  ++it;
266  }
267 
268  m_whereClauseWidget->setOperatorsList(vecOperators);
269 
270  it = queryCap.getSpatialTopologicOperators().begin();
271  while(it != queryCap.getSpatialTopologicOperators().end())
272  {
273  vecSpatialOperators.push_back(*it);
274  ++it;
275  }
276 
277  // For while! TODO: Revision!!!
278  if(vecSpatialOperators.size() == 1 && vecSpatialOperators[0] == te::da::FunctionNames::sm_ST_EnvelopeIntersects)
279  {
280  vecSpatialOperators.clear();
281  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Intersects);
282  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Disjoint);
283  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Touches);
284  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Overlaps);
285  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Crosses);
286  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Within);
287  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Contains);
288  vecSpatialOperators.push_back(te::da::FunctionNames::sm_ST_Equals);
289  }
290 
291  m_whereClauseWidget->setSpatialOperatorsList(vecSpatialOperators);
292 
293  it = queryCap.getLogicalOperators().begin();
294  while(it != queryCap.getLogicalOperators().end())
295  {
296  vecConnectors.push_back(*it);
297  ++it;
298  }
299 
300  m_whereClauseWidget->setConnectorsList(vecConnectors);
301 
302  // Gets data set information
303  std::auto_ptr<te::da::DataSetType> dsType = dsLayer->getSchema();
304 
305  std::string dsName = dsType->getName();
306  std::string aliasName = setAliasName(dsName);
307 
308  std::vector<std::pair<std::string, std::string> > list;
309  list.push_back(std::pair<std::string, std::string>(dsName, aliasName));
310 
311  m_whereClauseWidget->setFromItems(list);
312 
313  // Get properties
314  std::vector<std::string> inputProperties;
315  std::vector<std::string> geomProperties;
316 
317  for(size_t i = 0; i < dsType->size(); ++i)
318  {
319  std::string propName = dsType->getProperty(i)->getName();
320 
321  if(dsType->getProperty(i)->getType() == te::dt::GEOMETRY_TYPE)
322  geomProperties.push_back(propName);
323  else
324  inputProperties.push_back(propName);
325  }
326 
327  m_whereClauseWidget->setAttributeList(inputProperties);
328  m_whereClauseWidget->setGeomAttributeList(geomProperties, dsLayer->getSRID());
329 }
330 
332 {
333  // Gets the defined restriction
334  te::da::Where* wh = getWhere();
335  if(wh == 0 || wh->getExp() == 0)
336  {
337  QMessageBox::information(this, tr("Query"), tr("Add a restriction expression first."));
338  return;
339  }
340 
341  // Gets the selected layer
342  int index = m_ui->m_inputLayerComboBox->currentIndex();
343 
344  QVariant varLayer = m_ui->m_inputLayerComboBox->itemData(index, Qt::UserRole);
345 
346  te::map::AbstractLayerPtr layer = varLayer.value<te::map::AbstractLayerPtr>();
347 
348  assert(layer.get());
349 
350  // Let's execute the query
351  try
352  {
353  setCursor(Qt::WaitCursor);
354 
355  // The filter expression
356  te::da::Expression* e = wh->getExp()->clone();
357 
358  // Gets the layer schema
359  std::auto_ptr<const te::map::LayerSchema> schema(layer->getSchema());
360 
361  // Gets the dataset
362  std::auto_ptr<te::da::DataSet> dataset = layer->getData(e);
363  assert(dataset.get());
364 
365  if(m_ui->m_newSelRadioButton->isChecked())
366  {
367  // Generates the oids
368  dataset->moveBeforeFirst();
369  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataset.get(), schema.get());
370 
371  layer->clearSelected();
372  layer->select(oids);
373 
374  emit layerSelectedObjectsChanged(layer);
375  }
376  else if(m_ui->m_addSelRadioButton->isChecked())
377  {
378  // Generates the oids
379  dataset->moveBeforeFirst();
380  te::da::ObjectIdSet* oids = te::da::GenerateOIDSet(dataset.get(), schema.get());
381 
382  layer->select(oids);
383 
384  emit layerSelectedObjectsChanged(layer);
385  }
386 
387  emit highlightLayerObjects(layer, dataset.get(), m_colorPicker->getColor());
388 
389  setCursor(Qt::ArrowCursor);
390 
391  //QMessageBox::information(this, tr("Query"), tr("Query executed with successfully."));
392  }
393  catch(std::exception& e)
394  {
395  setCursor(Qt::ArrowCursor);
396  QMessageBox::information(this, tr("Query"), e.what());
397  }
398 }
399 
400 
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:259
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:70
static const std::string sm_ST_Overlaps
Definition: FunctionNames.h:76
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
static const std::string sm_ST_Touches
Definition: FunctionNames.h:74
static const std::string sm_ST_Intersects
Definition: FunctionNames.h:84
QueryDialog(QWidget *parent=0, Qt::WindowFlags f=0)
Definition: QueryDialog.cpp:50
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.
static const std::string sm_ST_Contains
Definition: FunctionNames.h:79
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:78
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:53
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:86
Expression * getExp() const
Definition: Where.cpp:60
TEDATAACCESSEXPORT ObjectIdSet * GenerateOIDSet(DataSet *dataset, const DataSetType *type)
Definition: Utils.cpp:363
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:71
void onInputLayerActivated(QString value)
static const std::string sm_ST_Within
Definition: FunctionNames.h:75
te::qt::widgets::WhereClauseWidget * getWidget()
Definition: QueryDialog.cpp:84
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:89
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr