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;
127 if ( !index.isValid() )
138 case Qt::DisplayRole:
139 if ( index.column() ==
ItemId )
148 case Qt::DecorationRole:
149 if ( index.column() ==
ItemId )
159 if ( index.column() ==
ItemId )
173 return qVariantFromValue( qobject_cast<QObject *>( item ) );
175 case Qt::TextAlignmentRole:
176 return Qt::AlignLeft & Qt::AlignVCenter;
178 case Qt::CheckStateRole:
179 switch ( index.column() )
183 return item->isVisible() ? Qt::Checked : Qt::Unchecked;
186 return item->
isLocked() ? Qt::Checked : Qt::Unchecked;
200 if ( !index.isValid() )
209 switch ( index.column() )
223 item->
setId( value.toString() );
234 case Qt::DisplayRole:
243 case Qt::DecorationRole:
257 case Qt::TextAlignmentRole:
258 return Qt::AlignLeft & Qt::AlignVCenter;
261 return QAbstractItemModel::headerData( section, orientation, role );
268 return Qt::MoveAction;
274 types << QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" );
280 QMimeData *
mimeData =
new QMimeData();
281 QByteArray encodedData;
283 QDataStream stream( &encodedData, QIODevice::WriteOnly );
285 for (
const QModelIndex &
index : indexes )
294 QString text = item->
uuid();
299 mimeData->setData( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ), encodedData );
305 return item1->zValue() > item2->zValue();
309 Qt::DropAction action,
int row,
int column,
const QModelIndex &
parent )
316 if ( action == Qt::IgnoreAction )
321 if ( !data->hasFormat( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) ) )
326 if ( parent.isValid() )
331 int beginRow = row != -1 ? row :
rowCount( QModelIndex() );
333 QByteArray encodedData = data->data( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) );
334 QDataStream stream( &encodedData, QIODevice::ReadOnly );
335 QList<QgsLayoutItem *> droppedItems;
338 while ( !stream.atEnd() )
345 droppedItems << item;
350 if ( droppedItems.empty() )
366 destPos = mItemZList.indexOf( itemBefore );
371 destPos = mItemZList.size();
375 int insertPos = destPos;
378 int listPos = mItemZList.indexOf( item );
385 if ( listPos < destPos )
392 auto itemIt = droppedItems.begin();
393 for ( ; itemIt != droppedItems.end(); ++itemIt )
395 mItemZList.removeOne( *itemIt );
399 itemIt = droppedItems.begin();
400 for ( ; itemIt != droppedItems.end(); ++itemIt )
402 mItemZList.insert( insertPos, *itemIt );
406 rebuildSceneItemList();
416 if ( parent.isValid() )
431 void QgsLayoutModel::clear()
436 refreshItemsInScene();
440 int QgsLayoutModel::zOrderListSize()
const 442 return mItemZList.size();
445 void QgsLayoutModel::rebuildZList()
447 QList<QgsLayoutItem *> sortedList;
451 const QList<QGraphicsItem *> itemList = mLayout->items( Qt::DescendingOrder );
452 for ( QGraphicsItem *item : itemList )
454 if (
QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
458 sortedList.append( layoutItem );
463 mItemZList = sortedList;
464 rebuildSceneItemList();
468 void QgsLayoutModel::rebuildSceneItemList()
473 const QList< QGraphicsItem * > items = mLayout->items();
482 int sceneListPos = mItemsInScene.indexOf( item );
483 if ( sceneListPos == row )
488 else if ( sceneListPos != -1 )
491 beginMoveRows( QModelIndex(), sceneListPos + 1, sceneListPos + 1, QModelIndex(), row + 1 );
492 mItemsInScene.removeAt( sceneListPos );
493 mItemsInScene.insert( row, item );
499 beginInsertRows( QModelIndex(), row + 1, row + 1 );
500 mItemsInScene.insert( row, item );
509 mItemZList.push_front( item );
510 refreshItemsInScene();
511 item->setZValue( mItemZList.size() );
522 int pos = mItemZList.indexOf( item );
531 if ( !itemIndex.isValid() )
536 mItemZList.removeAt( pos );
537 refreshItemsInScene();
542 int row = itemIndex.row();
543 beginRemoveRows( QModelIndex(), row, row );
544 mItemZList.removeAt( pos );
545 refreshItemsInScene();
557 int pos = mItemZList.indexOf( item );
566 if ( !itemIndex.isValid() )
572 int row = itemIndex.row();
573 beginRemoveRows( QModelIndex(), row, row );
574 mLayout->removeItem( item );
575 refreshItemsInScene();
579 void QgsLayoutModel::updateItemDisplayName(
QgsLayoutItem *item )
589 if ( !itemIndex.isValid() )
595 emit dataChanged( itemIndex, itemIndex );
598 void QgsLayoutModel::updateItemLockStatus(
QgsLayoutItem *item )
608 if ( !itemIndex.isValid() )
614 emit dataChanged( itemIndex, itemIndex );
617 void QgsLayoutModel::updateItemVisibility(
QgsLayoutItem *item )
627 if ( !itemIndex.isValid() )
633 emit dataChanged( itemIndex, itemIndex );
636 void QgsLayoutModel::updateItemSelectStatus(
QgsLayoutItem *item )
646 if ( !itemIndex.isValid() )
652 emit dataChanged( itemIndex, itemIndex );
662 if ( mItemsInScene.at( 0 ) == item )
669 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
670 if ( ! it.findNext( item ) )
676 const QList< QGraphicsItem * > sceneItems = mLayout->items();
679 while ( it.hasPrevious() )
683 if ( it.value() && sceneItems.contains( it.value() ) )
692 if ( !itemIndex.isValid() )
698 int row = itemIndex.row();
699 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row - 1 );
700 refreshItemsInScene();
712 if ( mItemsInScene.last() == item )
719 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
720 if ( ! it.findNext( item ) )
726 const QList< QGraphicsItem * > sceneItems = mLayout->items();
728 while ( it.hasNext() )
734 if ( it.value() && sceneItems.contains( it.value() ) )
743 if ( !itemIndex.isValid() )
749 int row = itemIndex.row();
750 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row + 2 );
751 refreshItemsInScene();
758 if ( !item || !mItemsInScene.contains( item ) )
763 if ( mItemsInScene.at( 0 ) == item )
770 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
771 if ( it.findNext( item ) )
775 mItemZList.push_front( item );
779 if ( !itemIndex.isValid() )
785 int row = itemIndex.row();
786 beginMoveRows( QModelIndex(), row, row, QModelIndex(), 1 );
787 refreshItemsInScene();
792 bool QgsLayoutModel::reorderItemToBottom(
QgsLayoutItem *item )
794 if ( !item || !mItemsInScene.contains( item ) )
799 if ( mItemsInScene.last() == item )
806 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
807 if ( it.findNext( item ) )
811 mItemZList.push_back( item );
815 if ( !itemIndex.isValid() )
821 int row = itemIndex.row();
822 beginMoveRows( QModelIndex(), row, row, QModelIndex(),
rowCount() );
823 refreshItemsInScene();
831 QListIterator<QgsLayoutItem *> it( mItemZList );
833 if ( it.findPrevious( item ) )
836 while ( it.hasPrevious() )
839 if ( it.hasPrevious() && !it.peekPrevious()->isGroupMember() )
841 return it.previous();
852 QListIterator<QgsLayoutItem *> it( mItemZList );
853 if ( it.findNext( item ) )
856 while ( it.hasNext() )
858 if ( !it.peekNext()->isGroupMember() )
868 QList<QgsLayoutItem *> &QgsLayoutModel::zOrderList()
877 Qt::ItemFlags
flags = QAbstractItemModel::flags( index );
879 if ( ! index.isValid() )
881 return flags | Qt::ItemIsDropEnabled;
884 if ( index.row() == 0 )
886 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
890 switch ( index.column() )
894 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
896 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
898 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
907 return QModelIndex();
910 int row = mItemsInScene.indexOf( item );
914 return QModelIndex();
917 return index( row + 1, column );
921 void QgsLayoutModel::setSelected(
const QModelIndex &
index )
939 if ( group && group != item )
949 : QSortFilterProxyModel( parent )
956 setDynamicSortFilter(
true );
957 setSortLocaleAware(
true );
963 const QString leftText = sourceModel()->data( left, Qt::DisplayRole ).toString();
964 const QString rightText = sourceModel()->data( right, Qt::DisplayRole ).toString();
965 if ( leftText.isEmpty() )
967 if ( rightText.isEmpty() )
988 QVariant itemAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole + 1 );
989 return qobject_cast<
QgsLayoutItem *>( itemAsVariant.value<QObject *>() );
994 mAllowEmpty = allowEmpty;
1005 mItemTypeFilter = filter;
1011 if ( mExceptedList == items )
1014 mExceptedList = items;
1021 QModelIndex index = sourceModel()->index( sourceRow, 0, sourceParent );
1028 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