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.