All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DataSetTreeModel.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/dataset/explorer/DataSetTreeModel.cpp
22 
23  \brief A simple model for datasets belonging to a data source.
24 */
25 
26 // TerraLib
27 #include "../../datasource/explorer/DataSetGroupItem.h"
28 #include "DataSetTreeModel.h"
29 
30 // STL
31 #include <memory>
32 
33 // Qt
34 #include <QMessageBox>
35 #include <QWidget>
36 
38  : QAbstractItemModel(parent),
39  m_datasets(0),
40  m_checkable(false),
41  m_forceCatalogCache(false)
42 {
43  if(datasource.get() != 0)
44  m_datasets = new DataSetGroupItem(datasource, 0);
45 }
46 
48 {
49  delete m_datasets;
50 }
51 
52 bool te::qt::widgets::DataSetTreeModel::canFetchMore(const QModelIndex& parent) const
53 {
54  if(!parent.isValid())
55  return false;
56 
57  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(parent.internalPointer());
58 
59  if(item == 0)
60  return false;
61 
62  return item->canFetchMore();
63 }
64 
65 int te::qt::widgets::DataSetTreeModel::columnCount(const QModelIndex& /*parent*/) const
66 {
67  return 1;
68 }
69 
70 QVariant te::qt::widgets::DataSetTreeModel::data(const QModelIndex& index, int role) const
71 {
72  if(!index.isValid())
73  return QVariant();
74 
75  if(role == Qt::CheckStateRole && !m_checkable)
76  return QVariant();
77 
78  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(index.internalPointer());
79 
80  if(item == 0)
81  return QVariant();
82 
83  try
84  {
85  return item->data(index.column(), role);
86  }
87  catch(const std::exception& e)
88  {
89  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
90  tr("TerraLib Qt Components"),
91  tr(e.what()));
92  }
93  catch(...)
94  {
95  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
96  tr("TerraLib Qt Components"),
97  tr("Unknown error in dataset explorer model!"));
98  }
99 
100  return QVariant();
101 }
102 
103 void te::qt::widgets::DataSetTreeModel::fetchMore(const QModelIndex& parent)
104 {
105  if(!parent.isValid())
106  return;
107 
108  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(parent.internalPointer());
109 
110  if(item == 0)
111  return;
112 
113  try
114  {
115  item->fetchMore();
116  }
117  catch(const std::exception& e)
118  {
119  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
120  tr("TerraLib Qt Components"),
121  tr(e.what()));
122  }
123  catch(...)
124  {
125  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
126  tr("TerraLib Qt Components"),
127  tr("Unknown error in dataset explorer model!"));
128  }
129 }
130 
131 Qt::ItemFlags te::qt::widgets::DataSetTreeModel::flags(const QModelIndex& index) const
132 {
133  if(!index.isValid())
134  return QAbstractItemModel::flags(index);
135 
136  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(index.internalPointer());
137 
138  if(item == 0)
139  return QAbstractItemModel::flags(index);
140 
141  try
142  {
143  return QAbstractItemModel::flags(index) | item->flags();
144  }
145  catch(const std::exception& e)
146  {
147  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
148  tr("TerraLib Qt Components"),
149  tr(e.what()));
150  }
151  catch(...)
152  {
153  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
154  tr("TerraLib Qt Components"),
155  tr("Unknown error in dataset explorer model!"));
156  }
157 
158  return QAbstractItemModel::flags(index);
159 }
160 
161 bool te::qt::widgets::DataSetTreeModel::hasChildren(const QModelIndex& parent) const
162 {
163  if(!parent.isValid())
164  return true;
165 
166  try
167  {
168  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(parent.internalPointer());
169 
170  if(item == 0)
171  return false;
172 
173  return item->hasChildren();
174  }
175  catch(const std::exception& e)
176  {
177  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
178  tr("TerraLib Qt Components"),
179  tr(e.what()));
180  }
181  catch(...)
182  {
183  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
184  tr("TerraLib Qt Components"),
185  tr("Unknown error in dataset explorer model!"));
186  }
187 
188  return false;
189 }
190 
191 QModelIndex te::qt::widgets::DataSetTreeModel::index(int row, int column, const QModelIndex& parent) const
192 {
193  if(m_datasets == 0)
194  return QModelIndex();
195 
196  if(!parent.isValid()) // is it the top-level item? we have just one descendent from root!
197  {
198  if(row != 0)
199  return QModelIndex();
200 
201  return createIndex(row, column, m_datasets);
202  }
203 
204  AbstractDataSourceTreeItem* parentItem = static_cast<AbstractDataSourceTreeItem*>(parent.internalPointer());
205 
206  if(parentItem == 0 || parentItem->children().empty() || ( row >= parentItem->children().size())) // if there isn't a child, return an invalid index
207  return QModelIndex();
208 
209  AbstractDataSourceTreeItem* item = dynamic_cast<AbstractDataSourceTreeItem*>(parentItem->children().at(row));
210 
211  if(item == 0)
212  return QModelIndex();
213 
214  return createIndex(row, column, item);
215 }
216 
217 QModelIndex te::qt::widgets::DataSetTreeModel::parent(const QModelIndex& index) const
218 {
219  if(!index.isValid())
220  return QModelIndex();
221 
222  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(index.internalPointer());
223 
224  if(item == 0 || item->parent() == 0)
225  return QModelIndex();
226 
227  AbstractDataSourceTreeItem* parentItem = dynamic_cast<AbstractDataSourceTreeItem*>(item->parent());
228 
229  if(parentItem == 0)
230  return QModelIndex();
231 
232  AbstractDataSourceTreeItem* grandParentItem = dynamic_cast<AbstractDataSourceTreeItem*>(parentItem->parent());
233 
234  if(grandParentItem == 0)
235  {
236 // the parent is a top level item
237  return createIndex(0, index.column(), parentItem);
238  }
239  else
240  {
241 // the parent has a grandparent
242  const QObjectList& items = grandParentItem->children();
243 
244  int i = 0;
245 
246  for(QObjectList::const_iterator it = items.begin(); it != items.end(); ++it, ++i)
247  {
248  if((*it) == parentItem)
249  return createIndex(i, index.column(), parentItem);
250  }
251  }
252 
253  return QModelIndex();
254 }
255 
256 int te::qt::widgets::DataSetTreeModel::rowCount(const QModelIndex& parent) const
257 {
258  if(!parent.isValid()) // if parent index is not valid we assume we are asking for root item
259  return 1;
260 
261  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(parent.internalPointer());
262 
263  if(item == 0)
264  return 0;
265 
266  return item->children().count();
267 }
268 
269 bool te::qt::widgets::DataSetTreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
270 {
271  if(!index.isValid())
272  return false;
273 
274  if(role == Qt::CheckStateRole && !m_checkable)
275  return false;
276 
277  AbstractDataSourceTreeItem* item = static_cast<AbstractDataSourceTreeItem*>(index.internalPointer());
278 
279  if(item == 0)
280  return false;
281 
282  try
283  {
284  bool retval = item->setData(value, role);
285 
286  emit dataChanged(index, index);
287 
288  // Emit dataChanged signals for the descendants of this index (if any)
289  emitDataChangedForDescendants(index);
290 
291  // Emit dataChanged signals for the descendants of this index (if any)
292  emitDataChangedForAncestors(index);
293 
294  return retval;
295  }
296  catch(const std::exception& e)
297  {
298  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
299  tr("TerraLib Qt Components"),
300  tr(e.what()));
301  }
302  catch(...)
303  {
304  QMessageBox::warning(static_cast<QWidget*>(QObject::parent()),
305  tr("TerraLib Qt Components"),
306  tr("Unknown error in dataset explorer model!"));
307  }
308 
309  return false;
310 }
311 
313 {
314  m_checkable = checkable;
315 }
316 
318 {
319  return m_checkable;
320 }
321 
323 {
324  if(!parent.isValid())
325  return;
326 
327  int rows = rowCount(parent);
328 
329  for(int i = 0; i != rows; ++i)
330  {
331  QModelIndex idx = index(i, 0, parent);
332 
333  emit dataChanged(idx, idx);
334 
335  if(hasChildren(idx))
336  emitDataChangedForDescendants(idx);
337  }
338 }
339 
341 {
342  QModelIndex ancestorIndex = parent(index);
343  if(parent(index).isValid())
344  {
345  // Emit the dataChanged signal for the ascendants indexes
346  while(ancestorIndex.isValid())
347  {
348  emit dataChanged(ancestorIndex, ancestorIndex);
349  ancestorIndex = parent(ancestorIndex);
350  }
351  }
352 }
bool canFetchMore(const QModelIndex &parent) const
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
void fetchMore(const QModelIndex &parent)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
void emitDataChangedForAncestors(const QModelIndex &index)
It emits the dataChanged signal for the indexes that are ancestors of the given index.
A simple model for datasets belonging to a data source.
virtual bool setData(const QVariant &value, int role=Qt::EditRole)=0
int columnCount(const QModelIndex &parent=QModelIndex()) const
bool hasChildren(const QModelIndex &parent=QModelIndex()) const
QModelIndex parent(const QModelIndex &index) const
DataSetGroupItem * m_datasets
A container for the datasets of the input data source.
virtual Qt::ItemFlags flags() const =0
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Qt::ItemFlags flags(const QModelIndex &index) const
void setCheckable(const bool checkable)
void emitDataChangedForDescendants(const QModelIndex &parent)
It emits the dataChanged signal for the descendants indexes of the given index.
virtual QVariant data(int column, int role) const =0
int rowCount(const QModelIndex &parent=QModelIndex()) const
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
DataSetTreeModel(const te::da::DataSourceInfoPtr &datasource, QWidget *parent=0)