22 #include <QApplication> 23 #include <QGraphicsItem> 24 #include <QDomDocument> 25 #include <QDomElement> 28 #include <QMessageBox> 32 : QAbstractItemModel( parent )
41 if ( !index.isValid() )
51 const QModelIndex &
parent )
const 59 if ( !parent.isValid() && row >= 0 && row < mItemsInScene.size() )
62 return createIndex( row, column, mItemsInScene.at( row ) );
69 void QgsLayoutModel::refreshItemsInScene()
71 mItemsInScene.clear();
73 const QList< QGraphicsItem * > items = mLayout->items();
80 mItemsInScene.push_back( item );
95 if ( !parent.isValid() )
97 return mItemsInScene.size();
104 return mItemsInScene.size();
121 if ( !index.isValid() )
132 case Qt::DisplayRole:
133 if ( index.column() ==
ItemId )
142 case Qt::DecorationRole:
143 if ( index.column() ==
ItemId )
153 if ( index.column() ==
ItemId )
167 return qVariantFromValue( qobject_cast<QObject *>( item ) );
169 case Qt::TextAlignmentRole:
170 return Qt::AlignLeft & Qt::AlignVCenter;
172 case Qt::CheckStateRole:
173 switch ( index.column() )
177 return item->isVisible() ? Qt::Checked : Qt::Unchecked;
180 return item->
isLocked() ? Qt::Checked : Qt::Unchecked;
186 if ( index.column() ==
ItemId && item->isSelected() )
190 boldFont.setBold(
true );
204 if ( !index.isValid() )
213 switch ( index.column() )
227 item->
setId( value.toString() );
238 case Qt::DisplayRole:
247 case Qt::DecorationRole:
261 case Qt::TextAlignmentRole:
262 return Qt::AlignLeft & Qt::AlignVCenter;
265 return QAbstractItemModel::headerData( section, orientation, role );
272 return Qt::MoveAction;
278 types << QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" );
284 QMimeData *
mimeData =
new QMimeData();
285 QByteArray encodedData;
287 QDataStream stream( &encodedData, QIODevice::WriteOnly );
289 for (
const QModelIndex &
index : indexes )
298 QString text = item->
uuid();
303 mimeData->setData( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ), encodedData );
309 return item1->zValue() > item2->zValue();
313 Qt::DropAction action,
int row,
int column,
const QModelIndex &
parent )
320 if ( action == Qt::IgnoreAction )
325 if ( !data->hasFormat( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) ) )
330 if ( parent.isValid() )
335 int beginRow = row != -1 ? row :
rowCount( QModelIndex() );
337 QByteArray encodedData = data->data( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) );
338 QDataStream stream( &encodedData, QIODevice::ReadOnly );
339 QList<QgsLayoutItem *> droppedItems;
342 while ( !stream.atEnd() )
349 droppedItems << item;
354 if ( droppedItems.empty() )
370 destPos = mItemZList.indexOf( itemBefore );
375 destPos = mItemZList.size();
379 int insertPos = destPos;
382 int listPos = mItemZList.indexOf( item );
389 if ( listPos < destPos )
396 auto itemIt = droppedItems.begin();
397 for ( ; itemIt != droppedItems.end(); ++itemIt )
399 mItemZList.removeOne( *itemIt );
403 itemIt = droppedItems.begin();
404 for ( ; itemIt != droppedItems.end(); ++itemIt )
406 mItemZList.insert( insertPos, *itemIt );
410 rebuildSceneItemList();
420 if ( parent.isValid() )
435 void QgsLayoutModel::clear()
440 refreshItemsInScene();
444 int QgsLayoutModel::zOrderListSize()
const 446 return mItemZList.size();
449 void QgsLayoutModel::rebuildZList()
451 QList<QgsLayoutItem *> sortedList;
455 const QList<QGraphicsItem *> itemList = mLayout->items( Qt::DescendingOrder );
456 for ( QGraphicsItem *item : itemList )
458 if (
QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
462 sortedList.append( layoutItem );
467 mItemZList = sortedList;
468 rebuildSceneItemList();
472 void QgsLayoutModel::rebuildSceneItemList()
477 const QList< QGraphicsItem * > items = mLayout->items();
486 int sceneListPos = mItemsInScene.indexOf( item );
487 if ( sceneListPos == row )
492 else if ( sceneListPos != -1 )
495 beginMoveRows( QModelIndex(), sceneListPos, sceneListPos, QModelIndex(), row );
496 mItemsInScene.removeAt( sceneListPos );
497 mItemsInScene.insert( row, item );
503 beginInsertRows( QModelIndex(), row, row );
504 mItemsInScene.insert( row, item );
513 mItemZList.push_front( item );
514 refreshItemsInScene();
515 item->setZValue( mItemZList.size() );
526 int pos = mItemZList.indexOf( item );
535 if ( !itemIndex.isValid() )
540 mItemZList.removeAt( pos );
541 refreshItemsInScene();
546 int row = itemIndex.row();
547 beginRemoveRows( QModelIndex(), row, row );
548 mItemZList.removeAt( pos );
549 refreshItemsInScene();
561 int pos = mItemZList.indexOf( item );
570 if ( !itemIndex.isValid() )
576 int row = itemIndex.row();
577 beginRemoveRows( QModelIndex(), row, row );
578 mLayout->removeItem( item );
579 refreshItemsInScene();
584 void QgsLayoutModel::setItemRestored( QgsComposerItem *item )
592 int pos = mItemZList.indexOf( item );
599 item->setIsRemoved(
false );
600 rebuildSceneItemList();
604 void QgsLayoutModel::updateItemDisplayName(
QgsLayoutItem *item )
614 if ( !itemIndex.isValid() )
620 emit dataChanged( itemIndex, itemIndex );
623 void QgsLayoutModel::updateItemLockStatus(
QgsLayoutItem *item )
633 if ( !itemIndex.isValid() )
639 emit dataChanged( itemIndex, itemIndex );
642 void QgsLayoutModel::updateItemVisibility(
QgsLayoutItem *item )
652 if ( !itemIndex.isValid() )
658 emit dataChanged( itemIndex, itemIndex );
661 void QgsLayoutModel::updateItemSelectStatus(
QgsLayoutItem *item )
671 if ( !itemIndex.isValid() )
677 emit dataChanged( itemIndex, itemIndex );
687 if ( mItemsInScene.at( 0 ) == item )
694 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
695 if ( ! it.findNext( item ) )
701 const QList< QGraphicsItem * > sceneItems = mLayout->items();
704 while ( it.hasPrevious() )
708 if ( it.value() && sceneItems.contains( it.value() ) )
717 if ( !itemIndex.isValid() )
723 int row = itemIndex.row();
724 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row - 1 );
725 refreshItemsInScene();
737 if ( mItemsInScene.last() == item )
744 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
745 if ( ! it.findNext( item ) )
751 const QList< QGraphicsItem * > sceneItems = mLayout->items();
753 while ( it.hasNext() )
759 if ( it.value() && sceneItems.contains( it.value() ) )
768 if ( !itemIndex.isValid() )
774 int row = itemIndex.row();
775 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row + 2 );
776 refreshItemsInScene();
783 if ( !item || !mItemsInScene.contains( item ) )
788 if ( mItemsInScene.at( 0 ) == item )
795 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
796 if ( it.findNext( item ) )
800 mItemZList.push_front( item );
804 if ( !itemIndex.isValid() )
810 int row = itemIndex.row();
811 beginMoveRows( QModelIndex(), row, row, QModelIndex(), 0 );
812 refreshItemsInScene();
817 bool QgsLayoutModel::reorderItemToBottom(
QgsLayoutItem *item )
819 if ( !item || !mItemsInScene.contains( item ) )
824 if ( mItemsInScene.last() == item )
831 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
832 if ( it.findNext( item ) )
836 mItemZList.push_back( item );
840 if ( !itemIndex.isValid() )
846 int row = itemIndex.row();
847 beginMoveRows( QModelIndex(), row, row, QModelIndex(),
rowCount() );
848 refreshItemsInScene();
856 QListIterator<QgsLayoutItem *> it( mItemZList );
858 if ( it.findPrevious( item ) )
861 while ( it.hasPrevious() )
864 if ( it.hasPrevious() && !it.peekPrevious()->isGroupMember() )
866 return it.previous();
877 QListIterator<QgsLayoutItem *> it( mItemZList );
878 if ( it.findNext( item ) )
881 while ( it.hasNext() )
883 if ( !it.peekNext()->isGroupMember() )
893 QList<QgsLayoutItem *> &QgsLayoutModel::zOrderList()
902 Qt::ItemFlags
flags = QAbstractItemModel::flags( index );
904 if ( ! index.isValid() )
906 return flags | Qt::ItemIsDropEnabled;
909 switch ( index.column() )
913 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
915 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
917 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
925 return QModelIndex();
928 int row = mItemsInScene.indexOf( item );
932 return QModelIndex();
935 return index( row, column );
939 void QgsLayoutModel::setSelected(
const QModelIndex &
index )
956 : QSortFilterProxyModel( parent )
964 setDynamicSortFilter(
true );
965 setSortLocaleAware(
true );
989 QVariant itemAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole + 1 );
990 return qobject_cast<
QgsLayoutItem *>( itemAsVariant.value<QObject *>() );
995 mItemTypeFilter = filter;
1001 if ( mExceptedList == items )
1004 mExceptedList = items;
1011 QModelIndex index = sourceModel()->index( sourceRow, 0, sourceParent );
1018 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
QModelIndex indexForItem(QgsLayoutItem *item, const int column=0)
Returns the QModelIndex corresponding to a QgsLayoutItem item and column, if possible.
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
void setLocked(const bool locked)
Sets whether the item is locked, preventing mouse interactions with the item.
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or a nullptr if a matching item could n...
int columnCount(const QModelIndex &parent=QModelIndex()) const override
virtual void setVisibility(const bool visible)
Sets whether the item is visible.
Qt::ItemFlags flags(const QModelIndex &index) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
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
virtual void setId(const QString &id)
Set the item's id name.
QStringList mimeTypes() const override
Item visibility checkbox.
void updateZValues(const bool addUndoCommands=true)
Resets the z-values of items based on their position in the internal z order list.
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.
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
Get 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
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override