23 #include <QApplication>
24 #include <QGraphicsItem>
25 #include <QDomDocument>
26 #include <QDomElement>
29 #include <QMessageBox>
33 : QAbstractItemModel( parent )
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 );
102 return mItemsInScene.size() + 1;
127 if ( !
index.isValid() )
138 case Qt::DisplayRole:
148 case Qt::DecorationRole:
173 return QVariant::fromValue( 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 )
311 if ( column !=
ItemId && column != -1 )
316 if ( action == Qt::IgnoreAction )
321 if ( !
data->hasFormat( QStringLiteral(
"application/x-vnd.qgis.qgis.composeritemid" ) ) )
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() )
365 QgsLayoutItem *itemBefore = mItemsInScene.at( beginRow - 1 );
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();
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 )
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;
1016 mItemTypeFilter = filter;
1022 if ( mExceptedList == items )
1025 mExceptedList = items;
1032 QModelIndex index = sourceModel()->index( sourceRow, 0, sourceParent );
1039 if ( mExceptedList.contains( item ) )
1046 if ( mItemFlags && !( item->
itemFlags() & mItemFlags ) )