27 #include "../../../../common/STLUtils.h"
28 #include "../../../../common/Translator.h"
29 #include "../../../../maptools/AbstractLayer.h"
30 #include "../../Exception.h"
37 #include <QtGui/QMessageBox>
38 #include <QtCore/QMimeData>
39 #include <QtCore/QStringList>
42 : QAbstractItemModel(parent),
45 setSupportedDragActions(Qt::MoveAction | Qt::CopyAction);
49 : QAbstractItemModel(parent),
52 setSupportedDragActions(Qt::MoveAction | Qt::CopyAction);
70 for(std::list<te::map::AbstractLayerPtr>::const_iterator it = layers.begin(); it != layers.end(); ++it)
75 m_items.push_back(litem);
77 m_layers.push_back(*it);
96 return !m_items.empty();
105 if(!parent.isValid())
111 throw Exception(
TR_QT_WIDGETS(
"Invalid data associated to the layer model!"));
123 if(!parent.isValid())
124 return static_cast<int>(m_items.size());
131 return item->children().count();
137 return QModelIndex();
139 if(!parent.isValid())
141 if(static_cast<std::size_t>(row) >= m_items.size())
142 return QModelIndex();
147 return createIndex(row, column, item);
153 throw Exception(
TR_QT_WIDGETS(
"Invalid data associated to the layer model!"));
155 if(row >= parentItem->children().count())
156 return QModelIndex();
161 throw Exception(
TR_QT_WIDGETS(
"The layer item is not an AbstractTreeItem!"));
163 return createIndex(row, column, item);
169 return QModelIndex();
173 if(item == 0 || item->parent() == 0)
174 return QModelIndex();
179 throw Exception(
TR_QT_WIDGETS(
"The layer item is not an AbstractTreeItem!"));
183 if(grandParentItem == 0)
186 for(std::size_t i = 0; i != m_items.size(); ++i)
188 if(m_items[i] == parentItem)
189 return createIndex(static_cast<int>(i), index.column(), parentItem);
195 const QObjectList& items = grandParentItem->children();
199 for(QObjectList::const_iterator it = items.begin(); it != items.end(); ++it, ++i)
201 if((*it) == parentItem)
202 return createIndex(i, index.column(), parentItem);
206 throw Exception(
TR_QT_WIDGETS(
"Could not determine the layer index in the model!"));
212 return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
217 throw Exception(
TR_QT_WIDGETS(
"Invalid data associated to the layer model!"));
219 return QAbstractItemModel::flags(index) | item->
flags();
227 if(role == Qt::CheckStateRole && !m_checkable)
235 return item->
data(index.column(), role);
243 if(role == Qt::CheckStateRole && !m_checkable)
253 retVal = item->
setData(index.column(), value, role);
255 emit dataChanged(index, index);
258 emitDataChangedForDescendants(index);
261 emitDataChangedForAncestors(index);
268 if(!parent.isValid())
269 return !m_items.empty();
274 throw Exception(
TR_QT_WIDGETS(
"Invalid data associated to the layer model!"));
283 mimes <<
"application/x-terralib;value=\"DraggedItems\"";
290 return Qt::MoveAction | Qt::CopyAction;
298 std::vector<AbstractTreeItem*>* draggedItems =
new std::vector<AbstractTreeItem*>;
300 for(
int i = 0; i < indexes.count(); ++i)
301 draggedItems->push_back(static_cast<AbstractTreeItem*>(indexes.at(i).internalPointer()));
304 s.setNum((qulonglong)draggedItems);
306 QByteArray encodedData(s.toStdString().c_str());
308 QMimeData* mimeData =
new QMimeData();
310 mimeData->setData(
"application/x-terralib;value=\"DraggedItems\"", encodedData);
316 Qt::DropAction action,
318 const QModelIndex& parent)
320 if(data == 0 || column > 0 || action != Qt::MoveAction)
323 if(action == Qt::IgnoreAction)
326 if(!data->hasFormat(
"application/x-terralib;value=\"DraggedItems\""))
330 QString sitem = data->data(
"application/x-terralib;value=\"DraggedItems\"");
335 qulonglong dataValue = sitem.toULongLong();
338 std::vector<AbstractTreeItem*>* draggedItems =
reinterpret_cast<std::vector<AbstractTreeItem*>*
>(dataValue);
339 int count = draggedItems->size();
341 m_insertingLayers.clear();
342 for(
int i = 0; i < count; ++i)
343 m_insertingLayers.push_back(draggedItems->operator[](i)->getLayer());
346 QModelIndex dropIndex = parent;
354 QModelIndex dropParentIndex = dropIndex.parent();
359 dropParentLayer = dropParentItem->
getLayer();
363 QModelIndex insertingItemParentIndex;
365 removeLayerFromParentChildrenList(m_insertingLayers);
371 if(row < 0 && dropItem && dropLayer.get() &&
372 dropLayer->getType() ==
"FOLDERLAYER" &&
376 insertingItemParentIndex = dropIndex;
379 for(
int i = 0; i < count; ++i)
380 dropLayer->insert(i, m_insertingLayers[i]);
387 QModelIndex dropParentIndex = dropIndex.parent();
392 if(dropParentIndex == QModelIndex())
395 if(dropIndex.row() == -1)
396 insertingRow = m_items.size();
398 insertingRow = dropIndex.row();
401 if(insertingRow >= (
int)m_layers.size())
403 for(
int i = 0; i < count; ++i)
404 m_layers.push_back(m_insertingLayers[i]);
408 for(
int i = 0; i < count; ++i)
409 m_layers.insert(m_layers.begin() + insertingRow + i, m_insertingLayers[i]);
415 insertingRow = dropIndex.row();
416 insertingItemParentIndex = dropParentIndex;
419 int k = insertingRow;
420 for(
int i = 0; i < count; ++i, ++k)
421 dropParentLayer->insert(k, m_insertingLayers[i]);
429 insertingRow = m_layers.size();
432 for(
int i = 0; i < count; ++i)
433 m_layers.insert(m_layers.begin() + insertingRow + i, m_insertingLayers[i]);
437 bool ret = insertRows(insertingRow, count, insertingItemParentIndex);
445 emit layerOrderChanged();
454 beginInsertRows(parent, row, row + count - 1);
458 if(row == m_items.size())
460 for(
int i = 0; i < count; ++i)
463 m_items.push_back(newItem);
469 for(
int i = row; i < row + count; ++i, ++k)
472 m_items.insert(m_items.begin() + i, newItem);
479 int numChildren = parentItem->children().count();
480 QList<QObject*> savedItemsList = parentItem->children();
482 for(
int i = 0; i < numChildren; ++i)
483 savedItemsList.at(i)->setParent(0);
487 for(
int i = row; i < row + count; ++i, ++k)
490 savedItemsList.insert(i, newItem);
494 for(
int i = 0; i < savedItemsList.count(); ++i)
495 savedItemsList.at(i)->setParent(parentItem);
501 m_insertingLayers[0]->updateVisibilityOfAncestors();
502 emitDataChangedForAncestors(parent);
511 beginRemoveRows(parent, row, row + count - 1);
513 if(!parent.isValid())
515 for(
int i = row; i < row + count; ++i)
518 m_items.erase(m_items.begin() + row, m_items.begin() + row + count);
529 const QList<QObject*>& childrenList = parentItem->children();
530 int numChildren = childrenList.count();
532 std::vector<QObject*> items;
533 for(
int i = row; i < row + count; ++i)
535 QObject* item = childrenList.at(i);
536 items.push_back(item);
539 for(std::size_t i = 0; i < items.size(); ++i)
543 emitDataChangedForAncestors(parent);
546 parentLayer->updateVisibility();
549 parentLayer->updateVisibilityOfAncestors();
561 m_checkable = checkable;
572 return QModelIndex();
575 QModelIndex parentIndex;
582 for(std::size_t i = 0; i < m_items.size(); ++i)
584 if(m_items[i] == item)
592 itemRow = parentItem->children().indexOf(item);
594 return createIndex(itemRow, 0, item);
607 for(std::size_t i = 0; i < m_layers.size(); ++i)
609 if(m_layers[i] == layer)
616 std::vector<std::size_t> rows;
617 QModelIndex topLayerIndex;
623 rows.push_back(auxLayer->getIndex());
624 auxLayer = parentLayer;
631 for(std::size_t i = 0; i < m_layers.size(); ++i)
633 if(m_layers[i] == topLayer)
635 topItem = m_items[i];
636 topLayerIndex = index(i, 0, QModelIndex());
641 QModelIndex inLayerIndex = topLayerIndex;
643 std::vector<std::size_t>::reverse_iterator it;
644 for(it = rows.rbegin(); it != rows.rend(); ++it)
645 inLayerIndex = index(*it, 0, inLayerIndex);
654 QModelIndex parentIndex;
658 row = m_layers.size();
659 m_layers.push_back(layer);
663 row = parentItem->children().size();
664 parentIndex = getIndex(parentItem);
667 m_insertingLayers.clear();
668 m_insertingLayers.push_back(layer);
670 insertRows(row, 1, parentIndex);
675 QModelIndex itemIndex = getIndex(item);
677 int itemRow = itemIndex.row();
678 QModelIndex parentIndex = parent(itemIndex);
688 for(std::size_t i = 0; i < m_items.size(); ++i)
690 if(m_items[i] == item)
692 m_layers.erase(m_layers.begin() + i);
699 return removeRows(itemRow, 1, parentIndex);
704 for(std::size_t i = 0; i < layers.size(); ++i)
712 for(std::size_t j = 0; j < m_layers.size(); ++j)
714 if(m_layers[j] == layer)
715 m_layers.erase(m_layers.begin() + j);
719 parentLayer->
remove(layer->getIndex());
725 if(!parent.isValid())
728 int rows = rowCount(parent);
730 for(
int i = 0; i != rows; ++i)
732 QModelIndex idx = index(i, 0, parent);
734 emit dataChanged(idx, idx);
737 emitDataChangedForDescendants(idx);
743 QModelIndex ancestorIndex = parent(index);
744 if(parent(index).isValid())
747 while(ancestorIndex.isValid())
749 emit dataChanged(ancestorIndex, ancestorIndex);
750 ancestorIndex = parent(ancestorIndex);
Qt::DropActions supportedDropActions() const
It returns the drop actions supported by this model.
virtual te::map::AbstractLayerPtr getLayer() const =0
void set(const std::list< te::map::AbstractLayerPtr > &layers)
It resets the model and associates the new top level items to the given top level layers...
te::qt::widgets::AbstractTreeItem * getLayerItem(const te::map::AbstractLayerPtr &layer)
It gets the layer item that is associated to the given layer.
virtual bool setData(int column, const QVariant &value, int role=Qt::EditRole)=0
This is the base class for layers.
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...
virtual void fetchMore()=0
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
It returns the index of the item in the model specified by the given row, column and parent index...
virtual QVariant data(int column, int role) const =0
void add(const te::map::AbstractLayerPtr &layer, AbstractTreeItem *parentItem=0)
It adds a item layer to the list of item layers of the parent layer item. If the parent layer is not ...
const std::vector< te::map::AbstractLayerPtr > & getTopLayers() const
It gets the top level layers of the model.
void setCheckable(const bool checkable)
It sets the model items as checkable or not.
bool remove(AbstractTreeItem *item)
It removes a item from the model.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
It handles the data supplied by a drag and drop operation that ended with the given action...
A class for building layer items.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
It sets the role data for the item at index to value.
static AbstractTreeItem * make(const te::map::AbstractLayerPtr &layer, QObject *parent)
const std::vector< te::qt::widgets::AbstractTreeItem * > & getTopLayerItems() const
It gets the top level layer items of the model.
void removeLayerFromParentChildrenList(std::vector< te::map::AbstractLayerPtr > &layers)
It removes the given layers from the list of children of their parents.
bool hasChildren(const QModelIndex &parent=QModelIndex()) const
It checks if the given index has children.
virtual Qt::ItemFlags flags() const =0
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex())
It inserts a determined number of rows given by the "count" parameter, starting with the given row un...
QModelIndex parent(const QModelIndex &index) const
It returns the item parent of the given index, or QModelIndex(), if it has no parent.
TreeItemPtr remove(std::size_t i)
It removes the i-th child.
Qt::ItemFlags flags(const QModelIndex &index) const
It returns the item flags for the given index.
int columnCount(const QModelIndex &parent=QModelIndex()) const
It returns the number of columns for the children of the given parent.
virtual bool canFetchMore() const =0
QMimeData * mimeData(const QModelIndexList &indexes) const
It returns an object that contains serialized items of data corresponding to the list of indexes spec...
The class that represents an item in a LayerTreeModel.
The class that represents a folder layer item in a LayerTreeModel.
void fetchMore(const QModelIndex &parent)
It fetches any available data for the items with the parent specified by the parent index...
#define TR_QT_WIDGETS(message)
It marks a string in order to get translated. This is a special mark used in the TerraLib Qt Widgets ...
void emitDataChangedForAncestors(const QModelIndex &index)
It emits the dataChanged signal for the indexes that are ancestors of the given index.
This class defines the model used in the Qt Model/View architecture for the tree of layers...
LayerTreeModel(QObject *parent=0)
It constructs a layer tree model with the given parent.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
It returns the data stored under the given role for the item referred to by the index.
QModelIndex getIndex(AbstractTreeItem *item)
It gets the index that is associated to the given item.
boost::intrusive_ptr< AbstractLayer > AbstractLayerPtr
bool isCheckable() const
It verifies if the model items are checkable or not.
bool canFetchMore(const QModelIndex &parent) const
It fetches more data for the given parent.
QStringList mimeTypes() const
It returns a list of MIME types that can be used to describe a list of model indexes.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex())
It removes a determined number of rows given by the "count" parameter, starting with the given row un...
int rowCount(const QModelIndex &parent=QModelIndex()) const
It returns the number of rows of the given parent.
virtual bool hasChildren() const =0
void emitDataChangedForDescendants(const QModelIndex &parent)
It emits the dataChanged signal for the descendants indexes of the given index.
The class that represents an item in a LayerTreeModel.