23 #include <QApplication> 24 #include <QGraphicsItem> 25 #include <QDomDocument> 26 #include <QDomElement> 29 #include <QMessageBox> 33 : QAbstractItemModel( parent )
42 if ( !index.isValid() || index.row() == 0 )
52 const QModelIndex &
parent )
const 60 if ( !parent.isValid() && row == 0 )
62 return createIndex( row, column,
nullptr );
64 else if ( !parent.isValid() && row >= 1 && row < mItemsInScene.size() + 1 )
67 return createIndex( row, column, mItemsInScene.at( row - 1 ) );
74 void QgsLayoutModel::refreshItemsInScene()
76 mItemsInScene.clear();
78 const QList< QGraphicsItem * > items = mLayout->items();
85 mItemsInScene.push_back( item );
100 if ( !parent.isValid() )
102 return mItemsInScene.size() + 1;
109 return mItemsInScene.size() + 1;
126 if ( !index.isValid() )
137 case Qt::DisplayRole:
138 if ( index.column() ==
ItemId )
147 case Qt::DecorationRole:
148 if ( index.column() ==
ItemId )
158 if ( index.column() ==
ItemId )
172 return qVariantFromValue( qobject_cast<QObject *>( item ) );
174 case Qt::TextAlignmentRole:
175 return Qt::AlignLeft & Qt::AlignVCenter;
177 case Qt::CheckStateRole:
178 switch ( index.column() )
182 return item->isVisible() ? Qt::Checked : Qt::Unchecked;
185 return item->
isLocked() ? Qt::Checked : Qt::Unchecked;
199 if ( !index.isValid() )
208 switch ( index.column() )
222 item->
setId( value.toString() );
233 case Qt::DisplayRole:
242 case Qt::DecorationRole:
256 case Qt::TextAlignmentRole:
257 return Qt::AlignLeft & Qt::AlignVCenter;
260 return QAbstractItemModel::headerData( section, orientation, role );
267 return Qt::MoveAction;
273 types << QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" );
279 QMimeData *
mimeData =
new QMimeData();
280 QByteArray encodedData;
282 QDataStream stream( &encodedData, QIODevice::WriteOnly );
284 for (
const QModelIndex &
index : indexes )
293 QString text = item->
uuid();
298 mimeData->setData( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ), encodedData );
304 return item1->zValue() > item2->zValue();
308 Qt::DropAction action,
int row,
int column,
const QModelIndex &
parent )
315 if ( action == Qt::IgnoreAction )
320 if ( !data->hasFormat( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) ) )
325 if ( parent.isValid() )
330 int beginRow = row != -1 ? row :
rowCount( QModelIndex() );
332 QByteArray encodedData = data->data( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) );
333 QDataStream stream( &encodedData, QIODevice::ReadOnly );
334 QList<QgsLayoutItem *> droppedItems;
337 while ( !stream.atEnd() )
344 droppedItems << item;
349 if ( droppedItems.empty() )
365 destPos = mItemZList.indexOf( itemBefore );
370 destPos = mItemZList.size();
374 int insertPos = destPos;
377 int listPos = mItemZList.indexOf( item );
384 if ( listPos < destPos )
391 auto itemIt = droppedItems.begin();
392 for ( ; itemIt != droppedItems.end(); ++itemIt )
394 mItemZList.removeOne( *itemIt );
398 itemIt = droppedItems.begin();
399 for ( ; itemIt != droppedItems.end(); ++itemIt )
401 mItemZList.insert( insertPos, *itemIt );
405 rebuildSceneItemList();
415 if ( parent.isValid() )
430 void QgsLayoutModel::clear()
435 refreshItemsInScene();
439 int QgsLayoutModel::zOrderListSize()
const 441 return mItemZList.size();
444 void QgsLayoutModel::rebuildZList()
446 QList<QgsLayoutItem *> sortedList;
450 const QList<QGraphicsItem *> itemList = mLayout->items( Qt::DescendingOrder );
451 for ( QGraphicsItem *item : itemList )
453 if (
QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
457 sortedList.append( layoutItem );
462 mItemZList = sortedList;
463 rebuildSceneItemList();
467 void QgsLayoutModel::rebuildSceneItemList()
472 const QList< QGraphicsItem * > items = mLayout->items();
481 int sceneListPos = mItemsInScene.indexOf( item );
482 if ( sceneListPos == row )
487 else if ( sceneListPos != -1 )
490 beginMoveRows( QModelIndex(), sceneListPos + 1, sceneListPos + 1, QModelIndex(), row + 1 );
491 mItemsInScene.removeAt( sceneListPos );
492 mItemsInScene.insert( row, item );
498 beginInsertRows( QModelIndex(), row + 1, row + 1 );
499 mItemsInScene.insert( row, item );
508 mItemZList.push_front( item );
509 refreshItemsInScene();
510 item->setZValue( mItemZList.size() );
521 int pos = mItemZList.indexOf( item );
530 if ( !itemIndex.isValid() )
535 mItemZList.removeAt( pos );
536 refreshItemsInScene();
541 int row = itemIndex.row();
542 beginRemoveRows( QModelIndex(), row, row );
543 mItemZList.removeAt( pos );
544 refreshItemsInScene();
556 int pos = mItemZList.indexOf( item );
565 if ( !itemIndex.isValid() )
571 int row = itemIndex.row();
572 beginRemoveRows( QModelIndex(), row, row );
573 mLayout->removeItem( item );
574 refreshItemsInScene();
578 void QgsLayoutModel::updateItemDisplayName(
QgsLayoutItem *item )
588 if ( !itemIndex.isValid() )
594 emit dataChanged( itemIndex, itemIndex );
597 void QgsLayoutModel::updateItemLockStatus(
QgsLayoutItem *item )
607 if ( !itemIndex.isValid() )
613 emit dataChanged( itemIndex, itemIndex );
616 void QgsLayoutModel::updateItemVisibility(
QgsLayoutItem *item )
626 if ( !itemIndex.isValid() )
632 emit dataChanged( itemIndex, itemIndex );
635 void QgsLayoutModel::updateItemSelectStatus(
QgsLayoutItem *item )
645 if ( !itemIndex.isValid() )
651 emit dataChanged( itemIndex, itemIndex );
661 if ( mItemsInScene.at( 0 ) == item )
668 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
669 if ( ! it.findNext( item ) )
675 const QList< QGraphicsItem * > sceneItems = mLayout->items();
678 while ( it.hasPrevious() )
682 if ( it.value() && sceneItems.contains( it.value() ) )
691 if ( !itemIndex.isValid() )
697 int row = itemIndex.row();
698 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row - 1 );
699 refreshItemsInScene();
711 if ( mItemsInScene.last() == item )
718 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
719 if ( ! it.findNext( item ) )
725 const QList< QGraphicsItem * > sceneItems = mLayout->items();
727 while ( it.hasNext() )
733 if ( it.value() && sceneItems.contains( it.value() ) )
742 if ( !itemIndex.isValid() )
748 int row = itemIndex.row();
749 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row + 2 );
750 refreshItemsInScene();
757 if ( !item || !mItemsInScene.contains( item ) )
762 if ( mItemsInScene.at( 0 ) == item )
769 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
770 if ( it.findNext( item ) )
774 mItemZList.push_front( item );
778 if ( !itemIndex.isValid() )
784 int row = itemIndex.row();
785 beginMoveRows( QModelIndex(), row, row, QModelIndex(), 1 );
786 refreshItemsInScene();
791 bool QgsLayoutModel::reorderItemToBottom(
QgsLayoutItem *item )
793 if ( !item || !mItemsInScene.contains( item ) )
798 if ( mItemsInScene.last() == item )
805 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
806 if ( it.findNext( item ) )
810 mItemZList.push_back( item );
814 if ( !itemIndex.isValid() )
820 int row = itemIndex.row();
821 beginMoveRows( QModelIndex(), row, row, QModelIndex(),
rowCount() );
822 refreshItemsInScene();
830 QListIterator<QgsLayoutItem *> it( mItemZList );
832 if ( it.findPrevious( item ) )
835 while ( it.hasPrevious() )
838 if ( it.hasPrevious() && !it.peekPrevious()->isGroupMember() )
840 return it.previous();
851 QListIterator<QgsLayoutItem *> it( mItemZList );
852 if ( it.findNext( item ) )
855 while ( it.hasNext() )
857 if ( !it.peekNext()->isGroupMember() )
867 QList<QgsLayoutItem *> &QgsLayoutModel::zOrderList()
876 Qt::ItemFlags
flags = QAbstractItemModel::flags( index );
878 if ( ! index.isValid() )
880 return flags | Qt::ItemIsDropEnabled;
883 if ( index.row() == 0 )
885 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
889 switch ( index.column() )
893 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
895 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
897 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
906 return QModelIndex();
909 int row = mItemsInScene.indexOf( item );
913 return QModelIndex();
916 return index( row + 1, column );
920 void QgsLayoutModel::setSelected(
const QModelIndex &
index )
938 if ( group && group != item )
948 : QSortFilterProxyModel( parent )
955 setDynamicSortFilter(
true );
956 setSortLocaleAware(
true );
962 const QString leftText = sourceModel()->data( left, Qt::DisplayRole ).toString();
963 const QString rightText = sourceModel()->data( right, Qt::DisplayRole ).toString();
964 if ( leftText.isEmpty() )
966 if ( rightText.isEmpty() )
987 QVariant itemAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole + 1 );
988 return qobject_cast<
QgsLayoutItem *>( itemAsVariant.value<QObject *>() );
993 mAllowEmpty = allowEmpty;
1004 mItemTypeFilter = filter;
1010 if ( mExceptedList == items )
1013 mExceptedList = items;
1020 QModelIndex index = sourceModel()->index( sourceRow, 0, sourceParent );
1027 if ( mExceptedList.contains( item ) )
QgsLayoutProxyModel(QgsLayout *layout, QObject *parent=nullptr)
Constructor for QgsLayoutProxyModelm, attached to the specified layout.
virtual QIcon icon() const
Returns the item's icon.
bool setData(const QModelIndex &index, const QVariant &value, int role) override
void setSelectedItem(QgsLayoutItem *item)
Clears any selected items and sets item as the current selection.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QgsLayoutItem * itemFromIndex(const QModelIndex &index) const
Returns the QgsLayoutItem corresponding to a QModelIndex index, if possible.
Base class for graphical items within a QgsLayout.
int type() const override
Returns a unique graphics item type identifier.
QVariant data(const QModelIndex &index, int role) const override
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
int columnCount(const QModelIndex &parent=QModelIndex()) const override
A container for grouping several QgsLayoutItems.
QModelIndex indexForItem(QgsLayoutItem *item, int column=0)
Returns the QModelIndex corresponding to a QgsLayoutItem item and column, if possible.
Qt::ItemFlags flags(const QModelIndex &index) const override
void setAllowEmptyItem(bool allowEmpty)
Sets whether an optional empty layout item is present in the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
virtual void setSelected(bool selected)
Sets whether the item should be selected.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Qt::DropActions supportedDropActions() const override
void setExceptedItemList(const QList< QgsLayoutItem * > &items)
Sets a list of specific items to exclude from the model.
QMimeData * mimeData(const QModelIndexList &indexes) const override
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
void updateZValues(bool addUndoCommands=true)
Resets the z-values of items based on their position in the internal z order list.
virtual void setId(const QString &id)
Set the item's id name.
QStringList mimeTypes() const override
void setLocked(bool locked)
Sets whether the item is locked, preventing mouse interactions with the item.
Item visibility checkbox.
bool zOrderDescending(QgsLayoutItem *item1, QgsLayoutItem *item2)
QString id() const
Returns the item's ID name.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
void setFilterType(QgsLayoutItemRegistry::ItemType filter)
Sets the item type filter.
virtual void setVisibility(bool visible)
Sets whether the item is visible.
Item lock status checkbox.
QgsLayoutItem * itemFromSourceIndex(const QModelIndex &sourceIndex) const
Returns the QgsLayoutItem corresponding to an index from the source QgsLayoutModel model...
QgsLayoutModel * itemsModel()
Returns the items model attached to the layout.
virtual QString displayName() const
Gets item display name.
QModelIndex parent(const QModelIndex &index) const override
QgsLayoutModel(QgsLayout *layout, QObject *parent=nullptr)
Constructor for a QgsLayoutModel attached to the specified layout.
Registry of available layout item types.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
virtual QString uuid() const
Returns the item identification string.
bool isLocked() const
Returns true if the item is locked, and cannot be interacted with using the mouse.
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
bool allowEmptyItem() const
Returns true if the model includes the empty item choice.
QgsLayoutItemGroup * parentGroup() const
Returns the item's parent group, if the item is part of a QgsLayoutItemGroup group.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override