28#include "moc_qgsmaplayermodel.cpp"
30using namespace Qt::StringLiterals;
33 : QAbstractItemModel(
parent )
41 : QAbstractItemModel(
parent )
87 QMap<QString, Qt::CheckState>::iterator i =
mLayersChecked.begin();
99 if ( allowEmpty == mAllowEmpty )
104 beginInsertRows( QModelIndex(), 0, 0 );
110 beginRemoveRows( QModelIndex(), 0, 0 );
122 emit dataChanged(
index( 0, 0 ),
index(
rowCount() - 1, 0 ), QVector<int>() << Qt::DisplayRole );
127 QList<QgsMapLayer *> layers;
128 const auto constMLayers =
mLayers;
133 layers.append( layer );
141 QMap<QString, Qt::CheckState>::iterator i =
mLayersChecked.begin();
150 emit dataChanged(
index( 0, 0 ),
index(
rowCount() - 1, 0 ), QVector<int>() << Qt::CheckStateRole );
155 int r =
mLayers.indexOf( layer );
156 if ( r >= 0 && mAllowEmpty )
158 return index( r, 0 );
168 if ( items == mAdditionalItems )
178 if ( !mAdditionalItems.isEmpty() )
180 beginRemoveRows( QModelIndex(), offset, offset + mAdditionalItems.count() - 1 );
181 mAdditionalItems.clear();
186 beginInsertRows( QModelIndex(), offset, offset + items.count() - 1 );
187 mAdditionalItems = items;
196 QStringList layerIdsToRemove;
200 layerIdsToRemove << layer->id();
209 const QString layerId = layer->id();
228 for (
const QString &layerId : layerIds )
230 QModelIndex startIndex =
index( 0, 0 );
231 QModelIndexList list = match( startIndex,
static_cast< int >(
CustomRole::LayerId ), layerId, 1 );
232 if ( !list.isEmpty() )
234 QModelIndex
index = list[0];
235 beginRemoveRows( QModelIndex(),
index.row(),
index.row() );
245 if ( !layers.empty() )
251 beginInsertRows( QModelIndex(),
mLayers.count() + offset,
mLayers.count() + layers.count() - 1 + offset );
252 const auto constLayers = layers;
268 if ( hasIndex( row, column,
parent ) )
271 if ( row - offset >= 0 && row - offset <
mLayers.count() )
272 layer =
mLayers.at( row - offset );
274 return createIndex( row, column, layer );
277 return QModelIndex();
283 return QModelIndex();
292 return ( mAllowEmpty ? 1 : 0 ) +
mLayers.length() + mAdditionalItems.count();
304 if ( !
index.isValid() )
307 bool isEmpty =
index.row() == 0 && mAllowEmpty;
308 int additionalIndex =
index.row() - ( mAllowEmpty ? 1 : 0 ) -
mLayers.count();
312 case Qt::DisplayRole:
315 if (
index.row() == 0 && mAllowEmpty )
318 if ( additionalIndex >= 0 )
319 return mAdditionalItems.at( additionalIndex );
325 if ( !mShowCrs || !layer->
isSpatial() || role == Qt::EditRole )
327 return layer->
name();
331 return tr(
"%1 [%2]" ).arg( layer->
name(), layer->
crs().
authid() );
337 if ( isEmpty || additionalIndex >= 0 )
341 return layer ? layer->
id() : QVariant();
346 if ( isEmpty || additionalIndex >= 0 )
349 return QVariant::fromValue<QgsMapLayer *>(
mLayers.value(
index.row() - ( mAllowEmpty ? 1 : 0 ) ) );
356 return additionalIndex >= 0;
358 case Qt::CheckStateRole:
362 if ( isEmpty || additionalIndex >= 0 )
372 case Qt::ToolTipRole:
382 case Qt::DecorationRole:
385 return mEmptyIcon.isNull() ? QVariant() : mEmptyIcon;
387 if ( additionalIndex >= 0 )
406 QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
415 if ( !
index.isValid() )
418 return Qt::ItemIsDropEnabled;
420 return Qt::ItemFlags();
423 bool isEmpty =
index.row() == 0 && mAllowEmpty;
424 int additionalIndex =
index.row() - ( mAllowEmpty ? 1 : 0 ) -
mLayers.count();
426 Qt::ItemFlags
flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
428 if (
mCanReorder && !isEmpty && additionalIndex < 0 )
430 flags |= Qt::ItemIsDragEnabled;
435 flags |= Qt::ItemIsUserCheckable;
449 beginInsertRows(
parent, row, row + count - 1 );
450 for (
int i = row; i < row + count; ++i )
451 mLayers.insert( i - offset,
nullptr );
459 if (
parent.isValid() || row < 0 )
471 if ( row - offset >
mLayers.count() - 1 )
476 beginRemoveRows(
parent, row, row + count - 1 );
477 for (
int i = 0; i != count; ++i )
478 mLayers.removeAt( row - offset );
487 types << u
"application/qgis.layermodeldata"_s;
493 if ( !
mCanReorder || action != Qt::MoveAction || !
data->hasFormat( u
"application/qgis.layermodeldata"_s ) )
500 auto mimeData = std::make_unique< QMimeData >();
502 QByteArray encodedData;
503 QDataStream stream( &encodedData, QIODevice::WriteOnly );
504 QSet< QString > addedLayers;
506 for (
const QModelIndex &i : indexes )
511 if ( !addedLayers.contains(
id ) )
513 addedLayers.insert(
id );
518 mimeData->setData( u
"application/qgis.layermodeldata"_s, encodedData );
527 if ( action == Qt::IgnoreAction )
529 else if ( action != Qt::MoveAction )
532 QByteArray encodedData =
data->data( u
"application/qgis.layermodeldata"_s );
533 QDataStream stream( &encodedData, QIODevice::ReadOnly );
534 QStringList newItems;
537 while ( !stream.atEnd() )
546 for (
const QString &text : std::as_const( newItems ) )
548 QModelIndex idx =
index( row, 0, QModelIndex() );
558 return Qt::MoveAction;
568 if ( !
index.isValid() )
571 bool isEmpty =
index.row() == 0 && mAllowEmpty;
572 int additionalIndex =
index.row() - ( mAllowEmpty ? 1 : 0 ) -
mLayers.count();
576 case Qt::CheckStateRole:
578 if ( !isEmpty && additionalIndex < 0 )
582 emit dataChanged(
index,
index, QVector< int >() << Qt::CheckStateRole );
589 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,...
static QgsProject * instance()
Returns the QgsProject singleton instance.
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.