28#include "moc_qgsmaplayermodel.cpp"
30using namespace Qt::StringLiterals;
43 : QAbstractItemModel(
parent )
54 : QAbstractItemModel(
parent )
106 QMap<QString, Qt::CheckState>::iterator i =
mLayersChecked.begin();
118 if ( allowEmpty == mAllowEmpty )
123 beginInsertRows( QModelIndex(), 0, 0 );
129 beginRemoveRows( QModelIndex(), 0, 0 );
141 emit dataChanged(
index( 0, 0 ),
index(
rowCount() - 1, 0 ), QVector<int>() << Qt::DisplayRole );
146 QList<QgsMapLayer *> layers;
147 const auto constMLayers =
mLayers;
152 layers.append( layer );
160 QMap<QString, Qt::CheckState>::iterator i =
mLayersChecked.begin();
169 emit dataChanged(
index( 0, 0 ),
index(
rowCount() - 1, 0 ), QVector<int>() << Qt::CheckStateRole );
174 int r =
mLayers.indexOf( layer );
175 if ( r >= 0 && mAllowEmpty )
177 return index( r, 0 );
187 if ( items == mAdditionalItems )
197 if ( !mAdditionalItems.isEmpty() )
199 beginRemoveRows( QModelIndex(), offset, offset + mAdditionalItems.count() - 1 );
200 mAdditionalItems.clear();
205 beginInsertRows( QModelIndex(), offset, offset + items.count() - 1 );
206 mAdditionalItems = items;
215 QStringList layerIdsToRemove;
219 layerIdsToRemove << layer->id();
228 const QString layerId = layer->id();
247 for (
const QString &layerId : layerIds )
249 QModelIndex startIndex =
index( 0, 0 );
250 QModelIndexList list = match( startIndex,
static_cast< int >(
CustomRole::LayerId ), layerId, 1 );
251 if ( !list.isEmpty() )
253 QModelIndex
index = list[0];
254 beginRemoveRows( QModelIndex(),
index.row(),
index.row() );
264 if ( !layers.empty() )
270 beginInsertRows( QModelIndex(),
mLayers.count() + offset,
mLayers.count() + layers.count() - 1 + offset );
271 const auto constLayers = layers;
287 if ( hasIndex( row, column,
parent ) )
290 if ( row - offset >= 0 && row - offset <
mLayers.count() )
291 layer =
mLayers.at( row - offset );
293 return createIndex( row, column, layer );
296 return QModelIndex();
302 return QModelIndex();
311 return ( mAllowEmpty ? 1 : 0 ) +
mLayers.length() + mAdditionalItems.count();
323 if ( !
index.isValid() )
326 bool isEmpty =
index.row() == 0 && mAllowEmpty;
327 int additionalIndex =
index.row() - ( mAllowEmpty ? 1 : 0 ) -
mLayers.count();
331 case Qt::DisplayRole:
334 if (
index.row() == 0 && mAllowEmpty )
337 if ( additionalIndex >= 0 )
338 return mAdditionalItems.at( additionalIndex );
344 if ( !mShowCrs || !layer->
isSpatial() || role == Qt::EditRole )
346 return layer->
name();
350 return tr(
"%1 [%2]" ).arg( layer->
name(), layer->
crs().
authid() );
356 if ( isEmpty || additionalIndex >= 0 )
360 return layer ? layer->
id() : QVariant();
365 if ( isEmpty || additionalIndex >= 0 )
368 return QVariant::fromValue<QgsMapLayer *>(
mLayers.value(
index.row() - ( mAllowEmpty ? 1 : 0 ) ) );
375 return additionalIndex >= 0;
377 case Qt::CheckStateRole:
381 if ( isEmpty || additionalIndex >= 0 )
391 case Qt::ToolTipRole:
401 case Qt::DecorationRole:
404 return mEmptyIcon.isNull() ? QVariant() : mEmptyIcon;
406 if ( additionalIndex >= 0 )
425 QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
434 if ( !
index.isValid() )
437 return Qt::ItemIsDropEnabled;
439 return Qt::ItemFlags();
442 bool isEmpty =
index.row() == 0 && mAllowEmpty;
443 int additionalIndex =
index.row() - ( mAllowEmpty ? 1 : 0 ) -
mLayers.count();
445 Qt::ItemFlags
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
447 if (
mCanReorder && !isEmpty && additionalIndex < 0 )
449 flags |= Qt::ItemIsDragEnabled;
454 flags |= Qt::ItemIsUserCheckable;
468 beginInsertRows(
parent, row, row + count - 1 );
469 for (
int i = row; i < row + count; ++i )
470 mLayers.insert( i - offset,
nullptr );
478 if (
parent.isValid() || row < 0 )
490 if ( row - offset >
mLayers.count() - 1 )
495 beginRemoveRows(
parent, row, row + count - 1 );
496 for (
int i = 0; i != count; ++i )
497 mLayers.removeAt( row - offset );
506 types << u
"application/qgis.layermodeldata"_s;
512 if ( !
mCanReorder || action != Qt::MoveAction || !
data->hasFormat( u
"application/qgis.layermodeldata"_s ) )
519 auto mimeData = std::make_unique< QMimeData >();
521 QByteArray encodedData;
522 QDataStream stream( &encodedData, QIODevice::WriteOnly );
523 QSet< QString > addedLayers;
525 for (
const QModelIndex &i : indexes )
530 if ( !addedLayers.contains(
id ) )
532 addedLayers.insert(
id );
537 mimeData->setData( u
"application/qgis.layermodeldata"_s, encodedData );
546 if ( action == Qt::IgnoreAction )
548 else if ( action != Qt::MoveAction )
551 QByteArray encodedData =
data->data( u
"application/qgis.layermodeldata"_s );
552 QDataStream stream( &encodedData, QIODevice::ReadOnly );
553 QStringList newItems;
556 while ( !stream.atEnd() )
565 for (
const QString &text : std::as_const( newItems ) )
567 QModelIndex idx =
index( row, 0, QModelIndex() );
577 return Qt::MoveAction;
587 if ( !
index.isValid() )
590 bool isEmpty =
index.row() == 0 && mAllowEmpty;
591 int additionalIndex =
index.row() - ( mAllowEmpty ? 1 : 0 ) -
mLayers.count();
595 case Qt::CheckStateRole:
597 if ( !isEmpty && additionalIndex < 0 )
601 emit dataChanged(
index,
index, QVector< int >() << Qt::CheckStateRole );
608 if ( !isEmpty && additionalIndex < 0 )
static QIcon iconForLayer(const QgsMapLayer *layer)
Returns the icon corresponding to a specified map layer.
QList< QPointer< QgsMapLayer > > mAdditionalLayers
void setShowCrs(bool showCrs)
Sets whether the CRS of layers is also included in the model's display role.
void setItemsCanBeReordered(bool allow)
Sets whether items in the model can be reordered via drag and drop.
QHash< int, QByteArray > roleNames() const override
Returns strings for all roles supported by this model.
Qt::ItemFlags flags(const QModelIndex &index) const override
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QList< QgsMapLayer * > layersChecked(Qt::CheckState checkState=Qt::Checked)
Returns the list of layers which are checked (or unchecked).
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QModelIndex parent(const QModelIndex &child) const override
void setProject(QgsProject *project)
Sets the QgsProject from which map layers are shown.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QModelIndex indexFromLayer(QgsMapLayer *layer) const
indexFromLayer returns the model index for a given layer
void setAllowEmptyLayer(bool allowEmpty, const QString &text=QString(), const QIcon &icon=QIcon())
Sets whether an optional empty layer ("not set") option is present in the model.
void setAdditionalItems(const QStringList &items)
Sets a list of additional (non map layer) items to include at the end of the model.
QList< QgsMapLayer * > additionalLayers() const
Returns the list of additional layers added to the model.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
void setItemsCheckable(bool checkable)
Defines if layers should be selectable in the widget.
static QIcon iconForLayer(QgsMapLayer *layer)
Returns the icon corresponding to a specified map layer.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
QgsMapLayer * layerFromIndex(const QModelIndex &index) const
Returns the map layer corresponding to the specified index.
Qt::DropActions supportedDropActions() const override
void setLayersChecked(const QList< QgsMapLayer * > &layers)
Sets which layers are checked in the model.
void checkAll(Qt::CheckState checkState)
checkAll changes the checkstate for all the layers
void removeLayers(const QStringList &layerIds)
QStringList mimeTypes() const override
@ Additional
True if index corresponds to an additional (non map layer) item.
@ Layer
Stores pointer to the map layer itself.
@ LayerId
Stores the map layer ID.
@ Empty
True if index corresponds to the empty (not set) value.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
bool itemsCanBeReordered() const
Returns true if items in the model can be reordered via drag and drop.
QMap< QString, Qt::CheckState > mLayersChecked
QgsMapLayerModel(QObject *parent=nullptr, QgsProject *project=nullptr)
QgsMapLayerModel creates a model to display layers in widgets.
QList< QgsMapLayer * > mLayers
void setAdditionalLayers(const QList< QgsMapLayer * > &layers)
Sets a list of additional layers to include in the model.
void addLayers(const QList< QgsMapLayer * > &layers)
QMimeData * mimeData(const QModelIndexList &indexes) const override
static QString layerToolTip(const QgsMapLayer *layer)
Returns the consistent tooltip for the given layer.
Base class for all map layer types.
virtual bool isSpatial() const
Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated w...
QgsCoordinateReferenceSystem crs
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.