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;
194 if ( !index.isValid() )
203 switch ( index.column() )
217 item->
setId( value.toString() );
228 case Qt::DisplayRole:
237 case Qt::DecorationRole:
251 case Qt::TextAlignmentRole:
252 return Qt::AlignLeft & Qt::AlignVCenter;
255 return QAbstractItemModel::headerData( section, orientation, role );
262 return Qt::MoveAction;
268 types << QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" );
274 QMimeData *
mimeData =
new QMimeData();
275 QByteArray encodedData;
277 QDataStream stream( &encodedData, QIODevice::WriteOnly );
279 for (
const QModelIndex &
index : indexes )
288 QString text = item->
uuid();
293 mimeData->setData( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ), encodedData );
299 return item1->zValue() > item2->zValue();
303 Qt::DropAction action,
int row,
int column,
const QModelIndex &
parent )
310 if ( action == Qt::IgnoreAction )
315 if ( !data->hasFormat( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) ) )
320 if ( parent.isValid() )
325 int beginRow = row != -1 ? row :
rowCount( QModelIndex() );
327 QByteArray encodedData = data->data( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) );
328 QDataStream stream( &encodedData, QIODevice::ReadOnly );
329 QList<QgsLayoutItem *> droppedItems;
332 while ( !stream.atEnd() )
339 droppedItems << item;
344 if ( droppedItems.empty() )
360 destPos = mItemZList.indexOf( itemBefore );
365 destPos = mItemZList.size();
369 int insertPos = destPos;
372 int listPos = mItemZList.indexOf( item );
379 if ( listPos < destPos )
386 auto itemIt = droppedItems.begin();
387 for ( ; itemIt != droppedItems.end(); ++itemIt )
389 mItemZList.removeOne( *itemIt );
393 itemIt = droppedItems.begin();
394 for ( ; itemIt != droppedItems.end(); ++itemIt )
396 mItemZList.insert( insertPos, *itemIt );
400 rebuildSceneItemList();
410 if ( parent.isValid() )
425 void QgsLayoutModel::clear()
430 refreshItemsInScene();
434 int QgsLayoutModel::zOrderListSize()
const 436 return mItemZList.size();
439 void QgsLayoutModel::rebuildZList()
441 QList<QgsLayoutItem *> sortedList;
445 const QList<QGraphicsItem *> itemList = mLayout->items( Qt::DescendingOrder );
446 for ( QGraphicsItem *item : itemList )
448 if (
QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
452 sortedList.append( layoutItem );
457 mItemZList = sortedList;
458 rebuildSceneItemList();
462 void QgsLayoutModel::rebuildSceneItemList()
467 const QList< QGraphicsItem * > items = mLayout->items();
476 int sceneListPos = mItemsInScene.indexOf( item );
477 if ( sceneListPos == row )
482 else if ( sceneListPos != -1 )
485 beginMoveRows( QModelIndex(), sceneListPos, sceneListPos, QModelIndex(), row );
486 mItemsInScene.removeAt( sceneListPos );
487 mItemsInScene.insert( row, item );
493 beginInsertRows( QModelIndex(), row, row );
494 mItemsInScene.insert( row, item );
503 mItemZList.push_front( item );
504 refreshItemsInScene();
505 item->setZValue( mItemZList.size() );
516 int pos = mItemZList.indexOf( item );
525 if ( !itemIndex.isValid() )
530 mItemZList.removeAt( pos );
531 refreshItemsInScene();
536 int row = itemIndex.row();
537 beginRemoveRows( QModelIndex(), row, row );
538 mItemZList.removeAt( pos );
539 refreshItemsInScene();
551 int pos = mItemZList.indexOf( item );
560 if ( !itemIndex.isValid() )
566 int row = itemIndex.row();
567 beginRemoveRows( QModelIndex(), row, row );
568 mLayout->removeItem( item );
569 refreshItemsInScene();
574 void QgsLayoutModel::setItemRestored( QgsComposerItem *item )
582 int pos = mItemZList.indexOf( item );
589 item->setIsRemoved(
false );
590 rebuildSceneItemList();
594 void QgsLayoutModel::updateItemDisplayName(
QgsLayoutItem *item )
604 if ( !itemIndex.isValid() )
610 emit dataChanged( itemIndex, itemIndex );
613 void QgsLayoutModel::updateItemLockStatus(
QgsLayoutItem *item )
623 if ( !itemIndex.isValid() )
629 emit dataChanged( itemIndex, itemIndex );
632 void QgsLayoutModel::updateItemVisibility(
QgsLayoutItem *item )
642 if ( !itemIndex.isValid() )
648 emit dataChanged( itemIndex, itemIndex );
651 void QgsLayoutModel::updateItemSelectStatus(
QgsLayoutItem *item )
661 if ( !itemIndex.isValid() )
667 emit dataChanged( itemIndex, itemIndex );
677 if ( mItemsInScene.at( 0 ) == item )
684 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
685 if ( ! it.findNext( item ) )
691 const QList< QGraphicsItem * > sceneItems = mLayout->items();
694 while ( it.hasPrevious() )
698 if ( it.value() && sceneItems.contains( it.value() ) )
707 if ( !itemIndex.isValid() )
713 int row = itemIndex.row();
714 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row - 1 );
715 refreshItemsInScene();
727 if ( mItemsInScene.last() == item )
734 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
735 if ( ! it.findNext( item ) )
741 const QList< QGraphicsItem * > sceneItems = mLayout->items();
743 while ( it.hasNext() )
749 if ( it.value() && sceneItems.contains( it.value() ) )
758 if ( !itemIndex.isValid() )
764 int row = itemIndex.row();
765 beginMoveRows( QModelIndex(), row, row, QModelIndex(), row + 2 );
766 refreshItemsInScene();
773 if ( !item || !mItemsInScene.contains( item ) )
778 if ( mItemsInScene.at( 0 ) == item )
785 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
786 if ( it.findNext( item ) )
790 mItemZList.push_front( item );
794 if ( !itemIndex.isValid() )
800 int row = itemIndex.row();
801 beginMoveRows( QModelIndex(), row, row, QModelIndex(), 0 );
802 refreshItemsInScene();
807 bool QgsLayoutModel::reorderItemToBottom(
QgsLayoutItem *item )
809 if ( !item || !mItemsInScene.contains( item ) )
814 if ( mItemsInScene.last() == item )
821 QMutableListIterator<QgsLayoutItem *> it( mItemZList );
822 if ( it.findNext( item ) )
826 mItemZList.push_back( item );
830 if ( !itemIndex.isValid() )
836 int row = itemIndex.row();
837 beginMoveRows( QModelIndex(), row, row, QModelIndex(),
rowCount() );
838 refreshItemsInScene();
846 QListIterator<QgsLayoutItem *> it( mItemZList );
848 if ( it.findPrevious( item ) )
851 while ( it.hasPrevious() )
854 if ( it.hasPrevious() && !it.peekPrevious()->isGroupMember() )
856 return it.previous();
867 QListIterator<QgsLayoutItem *> it( mItemZList );
868 if ( it.findNext( item ) )
871 while ( it.hasNext() )
873 if ( !it.peekNext()->isGroupMember() )
883 QList<QgsLayoutItem *> &QgsLayoutModel::zOrderList()
892 Qt::ItemFlags
flags = QAbstractItemModel::flags( index );
894 if ( ! index.isValid() )
896 return flags | Qt::ItemIsDropEnabled;
899 switch ( index.column() )
903 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
905 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
907 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
915 return QModelIndex();
918 int row = mItemsInScene.indexOf( item );
922 return QModelIndex();
925 return index( row, column );
929 void QgsLayoutModel::setSelected(
const QModelIndex &
index )
946 : QSortFilterProxyModel( parent )
954 setDynamicSortFilter(
true );
955 setSortLocaleAware(
true );
979 QVariant itemAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole + 1 );
980 return qobject_cast<
QgsLayoutItem *>( itemAsVariant.value<QObject *>() );
985 mItemTypeFilter = filter;
991 if ( mExceptedList == items )
994 mExceptedList = items;
1001 QModelIndex index = sourceModel()->index( sourceRow, 0, sourceParent );
1008 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 a nullptr if a matching item could n...
int columnCount(const QModelIndex &parent=QModelIndex()) const override
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
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
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
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override