23 #include <QApplication> 
   24 #include <QGraphicsItem> 
   25 #include <QDomDocument> 
   26 #include <QDomElement> 
   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 static_cast<Qt::Alignment::Int
>( 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 static_cast<Qt::Alignment::Int
>( 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 ) )