QGIS API Documentation  2.99.0-Master (d55fa22)
qgscomposermodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposermodel.cpp
3  -----------------
4  begin : July 2014
5  copyright : (C) 2014 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsapplication.h"
19 #include "qgscomposermodel.h"
20 #include "qgscomposition.h"
21 #include "qgspaperitem.h"
22 #include "qgslogger.h"
23 #include <QApplication>
24 #include <QGraphicsItem>
25 #include <QDomDocument>
26 #include <QDomElement>
27 #include <QMimeData>
28 #include <QSettings>
29 #include <QMessageBox>
30 #include <QIcon>
31 
32 QgsComposerModel::QgsComposerModel( QgsComposition *composition, QObject *parent )
33  : QAbstractItemModel( parent )
34  , mComposition( composition )
35 {
36 
37 }
38 
39 QgsComposerItem *QgsComposerModel::itemFromIndex( const QModelIndex &index ) const
40 {
41  //try to return the QgsComposerItem corresponding to a QModelIndex
42  if ( !index.isValid() )
43  {
44  return nullptr;
45  }
46 
47  QgsComposerItem *item = static_cast<QgsComposerItem *>( index.internalPointer() );
48  return item;
49 }
50 
51 QModelIndex QgsComposerModel::index( int row, int column,
52  const QModelIndex &parent ) const
53 {
54  if ( column < 0 || column >= columnCount() )
55  {
56  //column out of bounds
57  return QModelIndex();
58  }
59 
60  if ( !parent.isValid() && row >= 0 && row < mItemsInScene.size() )
61  {
62  //return an index for the composer item at this position
63  return createIndex( row, column, mItemsInScene.at( row ) );
64  }
65 
66  //only top level supported for now
67  return QModelIndex();
68 }
69 
70 void QgsComposerModel::refreshItemsInScene()
71 {
72  mItemsInScene.clear();
73 
74  //filter deleted and paper items from list
75  //TODO - correctly handle grouped item z order placement
76  QList<QgsComposerItem *>::const_iterator itemIt = mItemZList.constBegin();
77  for ( ; itemIt != mItemZList.constEnd(); ++itemIt )
78  {
79  if ( ( ( *itemIt )->type() != QgsComposerItem::ComposerPaper ) && !( *itemIt )->isRemoved() )
80  {
81  mItemsInScene.push_back( ( *itemIt ) );
82  }
83  }
84 }
85 
86 QModelIndex QgsComposerModel::parent( const QModelIndex &index ) const
87 {
88  Q_UNUSED( index );
89 
90  //all items are top level for now
91  return QModelIndex();
92 }
93 
94 int QgsComposerModel::rowCount( const QModelIndex &parent ) const
95 {
96  if ( !parent.isValid() )
97  {
98  return mItemsInScene.size();
99  }
100 
101  QGraphicsItem *parentItem = itemFromIndex( parent );
102 
103  if ( !parentItem )
104  {
105  return mItemsInScene.size();
106  }
107  else
108  {
109  //no children for now
110  return 0;
111  }
112 }
113 
114 int QgsComposerModel::columnCount( const QModelIndex &parent ) const
115 {
116  Q_UNUSED( parent );
117  return 3;
118 }
119 
120 QVariant QgsComposerModel::data( const QModelIndex &index, int role ) const
121 {
122  if ( !index.isValid() )
123  return QVariant();
124 
125  QgsComposerItem *item = itemFromIndex( index );
126  if ( !item )
127  {
128  return QVariant();
129  }
130 
131  switch ( role )
132  {
133  case Qt::DisplayRole:
134  if ( index.column() == ItemId )
135  {
136  return item->displayName();
137  }
138  else
139  {
140  return QVariant();
141  }
142 
143  case Qt::EditRole:
144  if ( index.column() == ItemId )
145  {
146  return item->id();
147  }
148  else
149  {
150  return QVariant();
151  }
152 
153  case Qt::UserRole:
154  //store item uuid in userrole so we can later get the QModelIndex for a specific item
155  return item->uuid();
156  case Qt::UserRole+1:
157  //user role stores reference in column object
158  return qVariantFromValue( qobject_cast<QObject *>( item ) );
159 
160  case Qt::TextAlignmentRole:
161  return Qt::AlignLeft & Qt::AlignVCenter;
162 
163  case Qt::CheckStateRole:
164  switch ( index.column() )
165  {
166  case Visibility:
167  //column 0 is visibility of item
168  return item->isVisible() ? Qt::Checked : Qt::Unchecked;
169  case LockStatus:
170  //column 1 is locked state of item
171  return item->positionLock() ? Qt::Checked : Qt::Unchecked;
172  default:
173  return QVariant();
174  }
175 
176  case Qt::FontRole:
177  if ( index.column() == ItemId && item->isSelected() )
178  {
179  //draw name of selected items in bold
180  QFont boldFont;
181  boldFont.setBold( true );
182  return boldFont;
183  }
184  return QVariant();
185 
186  default:
187  return QVariant();
188  }
189 }
190 
191 bool QgsComposerModel::setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole )
192 {
193  Q_UNUSED( role );
194 
195  if ( !index.isValid() )
196  return false;
197 
198  QgsComposerItem *item = itemFromIndex( index );
199  if ( !item )
200  {
201  return false;
202  }
203 
204  switch ( index.column() )
205  {
206  case Visibility:
207  //first column is item visibility
208  item->setVisibility( value.toBool() );
209  return true;
210 
211  case LockStatus:
212  //second column is item lock state
213  item->setPositionLock( value.toBool() );
214  return true;
215 
216  case ItemId:
217  //last column is item id
218  item->setId( value.toString() );
219  return true;
220  }
221 
222  return false;
223 }
224 
225 QVariant QgsComposerModel::headerData( int section, Qt::Orientation orientation, int role ) const
226 {
227  switch ( role )
228  {
229  case Qt::DisplayRole:
230  {
231  if ( section == ItemId )
232  {
233  return tr( "Item" );
234  }
235  return QVariant();
236  }
237 
238  case Qt::DecorationRole:
239  {
240  if ( section == Visibility )
241  {
242  return qVariantFromValue( QgsApplication::getThemeIcon( QStringLiteral( "/mActionShowAllLayers.svg" ) ) );
243  }
244  else if ( section == LockStatus )
245  {
246  return qVariantFromValue( QgsApplication::getThemeIcon( QStringLiteral( "/locked.svg" ) ) );
247  }
248 
249  return QVariant();
250  }
251 
252  case Qt::TextAlignmentRole:
253  return Qt::AlignLeft & Qt::AlignVCenter;
254 
255  default:
256  return QAbstractItemModel::headerData( section, orientation, role );
257  }
258 
259 }
260 
262 {
263  return Qt::MoveAction;
264 }
265 
266 QStringList QgsComposerModel::mimeTypes() const
267 {
268  QStringList types;
269  types << QStringLiteral( "application/x-vnd.qgis.qgis.composeritemid" );
270  return types;
271 }
272 
273 QMimeData *QgsComposerModel::mimeData( const QModelIndexList &indexes ) const
274 {
275  QMimeData *mimeData = new QMimeData();
276  QByteArray encodedData;
277 
278  QDataStream stream( &encodedData, QIODevice::WriteOnly );
279 
280  Q_FOREACH ( const QModelIndex &index, indexes )
281  {
282  if ( index.isValid() && index.column() == ItemId )
283  {
284  QgsComposerItem *item = itemFromIndex( index );
285  if ( !item )
286  {
287  continue;
288  }
289  QString text = item->uuid();
290  stream << text;
291  }
292  }
293 
294  mimeData->setData( QStringLiteral( "application/x-vnd.qgis.qgis.composeritemid" ), encodedData );
295  return mimeData;
296 }
297 
299 {
300  return item1->zValue() > item2->zValue();
301 }
302 
303 bool QgsComposerModel::dropMimeData( const QMimeData *data,
304  Qt::DropAction action, int row, int column, const QModelIndex &parent )
305 {
306  if ( column != ItemId )
307  {
308  return false;
309  }
310 
311  if ( action == Qt::IgnoreAction )
312  {
313  return true;
314  }
315 
316  if ( !data->hasFormat( QStringLiteral( "application/x-vnd.qgis.qgis.composeritemid" ) ) )
317  {
318  return false;
319  }
320 
321  if ( parent.isValid() )
322  {
323  return false;
324  }
325 
326  int beginRow = row != -1 ? row : rowCount( QModelIndex() );
327 
328  QByteArray encodedData = data->data( QStringLiteral( "application/x-vnd.qgis.qgis.composeritemid" ) );
329  QDataStream stream( &encodedData, QIODevice::ReadOnly );
330  QList<QgsComposerItem *> droppedItems;
331  int rows = 0;
332 
333  while ( !stream.atEnd() )
334  {
335  QString text;
336  stream >> text;
337  const QgsComposerItem *item = mComposition->getComposerItemByUuid( text );
338  if ( item )
339  {
340  droppedItems << const_cast<QgsComposerItem *>( item );
341  ++rows;
342  }
343  }
344 
345  if ( droppedItems.length() == 0 )
346  {
347  //no dropped items
348  return false;
349  }
350 
351  //move dropped items
352 
353  //first sort them by z-order
354  std::sort( droppedItems.begin(), droppedItems.end(), zOrderDescending );
355 
356  //calculate position in z order list to drop items at
357  int destPos = 0;
358  if ( beginRow < rowCount() )
359  {
360  QgsComposerItem *itemBefore = mItemsInScene.at( beginRow );
361  destPos = mItemZList.indexOf( itemBefore );
362  }
363  else
364  {
365  //place items at end
366  destPos = mItemZList.size();
367  }
368 
369  //calculate position to insert moved rows to
370  int insertPos = destPos;
371  QList<QgsComposerItem *>::iterator itemIt = droppedItems.begin();
372  for ( ; itemIt != droppedItems.end(); ++itemIt )
373  {
374  int listPos = mItemZList.indexOf( *itemIt );
375  if ( listPos == -1 )
376  {
377  //should be impossible
378  continue;
379  }
380 
381  if ( listPos < destPos )
382  {
383  insertPos--;
384  }
385  }
386 
387  //remove rows from list
388  itemIt = droppedItems.begin();
389  for ( ; itemIt != droppedItems.end(); ++itemIt )
390  {
391  mItemZList.removeOne( *itemIt );
392  }
393 
394  //insert items
395  itemIt = droppedItems.begin();
396  for ( ; itemIt != droppedItems.end(); ++itemIt )
397  {
398  mItemZList.insert( insertPos, *itemIt );
399  insertPos++;
400  }
401 
402  rebuildSceneItemList();
403  mComposition->updateZValues( false );
404 
405  return true;
406 }
407 
408 bool QgsComposerModel::removeRows( int row, int count, const QModelIndex &parent )
409 {
410  Q_UNUSED( count );
411  if ( parent.isValid() )
412  {
413  return false;
414  }
415 
416  if ( row >= rowCount() )
417  {
418  return false;
419  }
420 
421  //do nothing - moves are handled by the dropMimeData method
422  return true;
423 }
424 
426 {
427  //totally reset model
428  beginResetModel();
429  mItemZList.clear();
430  refreshItemsInScene();
431  endResetModel();
432 }
433 
435 {
436  return mItemZList.size();
437 }
438 
440 {
441  QList<QgsComposerItem *> sortedList;
442  //rebuild the item z order list based on the current zValues of items in the scene
443 
444  //get items in descending zValue order
445  QList<QGraphicsItem *> itemList = mComposition->items( Qt::DescendingOrder );
446  QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
447  for ( ; itemIt != itemList.end(); ++itemIt )
448  {
449  QgsComposerItem *composerItem = dynamic_cast<QgsComposerItem *>( *itemIt );
450  if ( composerItem )
451  {
452  if ( composerItem->type() != QgsComposerItem::ComposerPaper )
453  {
454  sortedList.append( composerItem );
455  }
456  }
457  }
458 
459  mItemZList = sortedList;
460  rebuildSceneItemList();
461 }
462 
463 void QgsComposerModel::rebuildSceneItemList()
464 {
465  //step through the z list and rebuild the items in scene list,
466  //emitting signals as required
467  int row = 0;
468  Q_FOREACH ( QgsComposerItem *item, mItemZList )
469  {
470  if ( ( item->type() == QgsComposerItem::ComposerPaper ) || item->isRemoved() )
471  {
472  //item not in scene, skip it
473  continue;
474  }
475 
476  int sceneListPos = mItemsInScene.indexOf( item );
477  if ( sceneListPos == row )
478  {
479  //already in list in correct position, nothing to do
480 
481  }
482  else if ( sceneListPos != -1 )
483  {
484  //in list, but in wrong spot
485  beginMoveRows( QModelIndex(), sceneListPos, sceneListPos, QModelIndex(), row );
486  mItemsInScene.removeAt( sceneListPos );
487  mItemsInScene.insert( row, item );
488  endMoveRows();
489  }
490  else
491  {
492  //needs to be inserted into list
493  beginInsertRows( QModelIndex(), row, row );
494  mItemsInScene.insert( row, item );
495  endInsertRows();
496  }
497  row++;
498  }
499 }
500 
502 {
503  beginInsertRows( QModelIndex(), 0, 0 );
504  mItemZList.push_front( item );
505  refreshItemsInScene();
506  item->setZValue( mItemZList.size() );
507  endInsertRows();
508 }
509 
511 {
512  if ( !item )
513  {
514  //nothing to do
515  return;
516  }
517 
518  int pos = mItemZList.indexOf( item );
519  if ( pos == -1 )
520  {
521  //item not in z list, nothing to do
522  return;
523  }
524 
525  //need to get QModelIndex of item
526  QModelIndex itemIndex = indexForItem( item );
527  if ( !itemIndex.isValid() )
528  {
529  //removing an item not in the scene (e.g., deleted item)
530  //we need to remove it from the list, but don't need to call
531  //beginRemoveRows or endRemoveRows since the item was not used by the model
532  mItemZList.removeAt( pos );
533  refreshItemsInScene();
534  return;
535  }
536 
537  //remove item from model
538  int row = itemIndex.row();
539  beginRemoveRows( QModelIndex(), row, row );
540  mItemZList.removeAt( pos );
541  refreshItemsInScene();
542  endRemoveRows();
543 }
544 
546 {
547  if ( !item )
548  {
549  //nothing to do
550  return;
551  }
552 
553  int pos = mItemZList.indexOf( item );
554  if ( pos == -1 )
555  {
556  //item not in z list, nothing to do
557  return;
558  }
559 
560  //need to get QModelIndex of item
561  QModelIndex itemIndex = indexForItem( item );
562  if ( !itemIndex.isValid() )
563  {
564  return;
565  }
566 
567  //removing item
568  int row = itemIndex.row();
569  beginRemoveRows( QModelIndex(), row, row );
570  item->setIsRemoved( true );
571  refreshItemsInScene();
572  endRemoveRows();
573 }
574 
576 {
577  if ( !item )
578  {
579  //nothing to do
580  return;
581  }
582 
583  int pos = mItemZList.indexOf( item );
584  if ( pos == -1 )
585  {
586  //item not in z list, nothing to do
587  return;
588  }
589 
590  item->setIsRemoved( false );
591  rebuildSceneItemList();
592 }
593 
595 {
596  if ( !item )
597  {
598  //nothing to do
599  return;
600  }
601 
602  //need to get QModelIndex of item
603  QModelIndex itemIndex = indexForItem( item, ItemId );
604  if ( !itemIndex.isValid() )
605  {
606  return;
607  }
608 
609  //emit signal for item id change
610  emit dataChanged( itemIndex, itemIndex );
611 }
612 
614 {
615  if ( !item )
616  {
617  //nothing to do
618  return;
619  }
620 
621  //need to get QModelIndex of item
622  QModelIndex itemIndex = indexForItem( item, LockStatus );
623  if ( !itemIndex.isValid() )
624  {
625  return;
626  }
627 
628  //emit signal for item lock status change
629  emit dataChanged( itemIndex, itemIndex );
630 }
631 
633 {
634  if ( !item )
635  {
636  //nothing to do
637  return;
638  }
639 
640  //need to get QModelIndex of item
641  QModelIndex itemIndex = indexForItem( item, Visibility );
642  if ( !itemIndex.isValid() )
643  {
644  return;
645  }
646 
647  //emit signal for item visibility change
648  emit dataChanged( itemIndex, itemIndex );
649 }
650 
652 {
653  if ( !item )
654  {
655  //nothing to do
656  return;
657  }
658 
659  //need to get QModelIndex of item
660  QModelIndex itemIndex = indexForItem( item, ItemId );
661  if ( !itemIndex.isValid() )
662  {
663  return;
664  }
665 
666  //emit signal for item visibility change
667  emit dataChanged( itemIndex, itemIndex );
668 }
669 
671 {
672  if ( !item )
673  {
674  return false;
675  }
676 
677  if ( mItemsInScene.at( 0 ) == item )
678  {
679  //item is already topmost item present in scene, nothing to do
680  return false;
681  }
682 
683  //move item in z list
684  QMutableListIterator<QgsComposerItem *> it( mItemZList );
685  if ( ! it.findNext( item ) )
686  {
687  //can't find item in z list, nothing to do
688  return false;
689  }
690 
691  it.remove();
692  while ( it.hasPrevious() )
693  {
694  //search through item z list to find previous item which is present in the scene
695  //(deleted items still exist in the z list so that they can be restored to their correct stacking order,
696  //but since they are not in the scene they should be ignored here)
697  it.previous();
698  if ( it.value() && !( it.value()->isRemoved() ) )
699  {
700  break;
701  }
702  }
703  it.insert( item );
704 
705  //also move item in scene items z list and notify of model changes
706  QModelIndex itemIndex = indexForItem( item );
707  if ( !itemIndex.isValid() )
708  {
709  return true;
710  }
711 
712  //move item up in scene list
713  int row = itemIndex.row();
714  beginMoveRows( QModelIndex(), row, row, QModelIndex(), row - 1 );
715  refreshItemsInScene();
716  endMoveRows();
717  return true;
718 }
719 
721 {
722  if ( !item )
723  {
724  return false;
725  }
726 
727  if ( mItemsInScene.last() == item )
728  {
729  //item is already lowest item present in scene, nothing to do
730  return false;
731  }
732 
733  //move item in z list
734  QMutableListIterator<QgsComposerItem *> it( mItemZList );
735  if ( ! it.findNext( item ) )
736  {
737  //can't find item in z list, nothing to do
738  return false;
739  }
740 
741  it.remove();
742  while ( it.hasNext() )
743  {
744  //search through item z list to find next item which is present in the scene
745  //(deleted items still exist in the z list so that they can be restored to their correct stacking order,
746  //but since they are not in the scene they should be ignored here)
747  it.next();
748  if ( it.value() && !( it.value()->isRemoved() ) )
749  {
750  break;
751  }
752  }
753  it.insert( item );
754 
755  //also move item in scene items z list and notify of model changes
756  QModelIndex itemIndex = indexForItem( item );
757  if ( !itemIndex.isValid() )
758  {
759  return true;
760  }
761 
762  //move item down in scene list
763  int row = itemIndex.row();
764  beginMoveRows( QModelIndex(), row, row, QModelIndex(), row + 2 );
765  refreshItemsInScene();
766  endMoveRows();
767  return true;
768 }
769 
771 {
772  if ( !item || !mItemsInScene.contains( item ) )
773  {
774  return false;
775  }
776 
777  if ( mItemsInScene.at( 0 ) == item )
778  {
779  //item is already topmost item present in scene, nothing to do
780  return false;
781  }
782 
783  //move item in z list
784  QMutableListIterator<QgsComposerItem *> it( mItemZList );
785  if ( it.findNext( item ) )
786  {
787  it.remove();
788  }
789  mItemZList.push_front( item );
790 
791  //also move item in scene items z list and notify of model changes
792  QModelIndex itemIndex = indexForItem( item );
793  if ( !itemIndex.isValid() )
794  {
795  return true;
796  }
797 
798  //move item to top
799  int row = itemIndex.row();
800  beginMoveRows( QModelIndex(), row, row, QModelIndex(), 0 );
801  refreshItemsInScene();
802  endMoveRows();
803  return true;
804 }
805 
807 {
808  if ( !item || !mItemsInScene.contains( item ) )
809  {
810  return false;
811  }
812 
813  if ( mItemsInScene.last() == item )
814  {
815  //item is already lowest item present in scene, nothing to do
816  return false;
817  }
818 
819  //move item in z list
820  QMutableListIterator<QgsComposerItem *> it( mItemZList );
821  if ( it.findNext( item ) )
822  {
823  it.remove();
824  }
825  mItemZList.push_back( item );
826 
827  //also move item in scene items z list and notify of model changes
828  QModelIndex itemIndex = indexForItem( item );
829  if ( !itemIndex.isValid() )
830  {
831  return true;
832  }
833 
834  //move item to bottom
835  int row = itemIndex.row();
836  beginMoveRows( QModelIndex(), row, row, QModelIndex(), rowCount() );
837  refreshItemsInScene();
838  endMoveRows();
839  return true;
840 }
841 
843 {
844  //search item z list for selected item
845  QListIterator<QgsComposerItem *> it( mItemZList );
846  it.toBack();
847  if ( it.findPrevious( item ) )
848  {
849  //move position to before selected item
850  while ( it.hasPrevious() )
851  {
852  //now find previous item, since list is sorted from lowest->highest items
853  if ( it.hasPrevious() && !it.peekPrevious()->isGroupMember() )
854  {
855  return it.previous();
856  }
857  it.previous();
858  }
859  }
860  return nullptr;
861 }
862 
864 {
865  //search item z list for selected item
866  QListIterator<QgsComposerItem *> it( mItemZList );
867  if ( it.findNext( item ) )
868  {
869  //return next item (list is sorted from lowest->highest items)
870  while ( it.hasNext() )
871  {
872  if ( !it.peekNext()->isGroupMember() )
873  {
874  return it.next();
875  }
876  it.next();
877  }
878  }
879  return nullptr;
880 }
881 
882 QList<QgsComposerItem *> *QgsComposerModel::zOrderList()
883 {
884  return &mItemZList;
885 }
886 
887 
888 Qt::ItemFlags QgsComposerModel::flags( const QModelIndex &index ) const
889 {
890  Qt::ItemFlags flags = QAbstractItemModel::flags( index );
891 
892  if ( ! index.isValid() )
893  {
894  return flags | Qt::ItemIsDropEnabled;
895  }
896 
897  switch ( index.column() )
898  {
899  case Visibility:
900  case LockStatus:
901  return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
902  case ItemId:
903  return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
904  default:
905  return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
906  }
907 }
908 
909 QModelIndex QgsComposerModel::indexForItem( QgsComposerItem *item, const int column )
910 {
911  if ( !item )
912  {
913  return QModelIndex();
914  }
915 
916  int row = mItemsInScene.indexOf( item );
917  if ( row == -1 )
918  {
919  //not found
920  return QModelIndex();
921  }
922 
923  return index( row, column );
924 }
925 
926 void QgsComposerModel::setSelected( const QModelIndex &index )
927 {
928  QgsComposerItem *item = itemFromIndex( index );
929  if ( !item )
930  {
931  return;
932  }
933 
934  mComposition->setSelectedItem( item );
935 }
936 
937 
938 //
939 // QgsComposerFilteredModel
940 //
941 
943  : QSortFilterProxyModel( parent )
944  , mComposition( composition )
945  , mItemTypeFilter( QgsComposerItem::ComposerItem )
946 {
947  if ( mComposition )
948  setSourceModel( mComposition->itemsModel() );
949 
950  // TODO doesn't seem to work correctly - not updated when item changes
951  setDynamicSortFilter( true );
952  setSortLocaleAware( true );
953  sort( QgsComposerModel::ItemId );
954 }
955 
956 bool QgsComposerProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
957 {
958  //sort by item id
959  const QgsComposerItem *item1 = itemFromSourceIndex( left );
960  const QgsComposerItem *item2 = itemFromSourceIndex( right );
961  if ( !item1 )
962  return false;
963 
964  if ( !item2 )
965  return true;
966 
967  return QString::localeAwareCompare( item1->displayName(), item2->displayName() ) < 0;
968 }
969 
970 QgsComposerItem *QgsComposerProxyModel::itemFromSourceIndex( const QModelIndex &sourceIndex ) const
971 {
972  if ( !mComposition )
973  return nullptr;
974 
975  //get column corresponding to an index from the source model
976  QVariant itemAsVariant = sourceModel()->data( sourceIndex, Qt::UserRole + 1 );
977  return qobject_cast<QgsComposerItem *>( itemAsVariant.value<QObject *>() );
978 }
979 
981 {
982  mItemTypeFilter = itemType;
983  invalidate();
984 }
985 
986 void QgsComposerProxyModel::setExceptedItemList( const QList< QgsComposerItem *> &exceptList )
987 {
988  if ( mExceptedList == exceptList )
989  return;
990 
991  mExceptedList = exceptList;
992  invalidateFilter();
993 }
994 
995 bool QgsComposerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
996 {
997  //get QgsComposerItem corresponding to row
998  QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
999  QgsComposerItem *item = itemFromSourceIndex( index );
1000 
1001  if ( !item )
1002  return false;
1003 
1004  // specific exceptions
1005  if ( mExceptedList.contains( item ) )
1006  return false;
1007 
1008  // filter by type
1009  if ( mItemTypeFilter != QgsComposerItem::ComposerItem && item->type() != mItemTypeFilter )
1010  return false;
1011 
1012  return true;
1013 }
1014 
Qt::DropActions supportedDropActions() const override
virtual QString displayName() const
Get item display name.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
QgsComposerModel(QgsComposition *composition, QObject *parent=0)
Constructor.
QgsComposerModel * itemsModel()
Returns the items model attached to the composition.
void rebuildZList()
Rebuilds the z-order list, based on the current stacking of items in the composition.
QgsComposerProxyModel(QgsComposition *composition, QObject *parent=0)
Constructor for QgsComposerProxyModel.
A item that forms part of a map composition.
void setSelectedItem(QgsComposerItem *item)
Clears any selected items and sets an item as the current selection.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
const QgsComposerItem * getComposerItemByUuid(const QString &uuid) const
Returns a composer item given its unique identifier.
QModelIndex indexForItem(QgsComposerItem *item, const int column=0)
Returns the QModelIndex corresponding to a QgsComposerItem, if possible.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
void updateItemVisibility(QgsComposerItem *item)
Must be called when an item&#39;s visibility changes.
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
virtual QStringList mimeTypes() const override
virtual QMimeData * mimeData(const QModelIndexList &indexes) const override
Item lock status check box.
void setItemRestored(QgsComposerItem *item)
Restores an item to the composition.
bool reorderItemDown(QgsComposerItem *item)
Moves an item down the z-order list.
void updateItemDisplayName(QgsComposerItem *item)
Must be called when an item&#39;s display name is modified.
bool zOrderDescending(QgsComposerItem *item1, QgsComposerItem *item2)
void setExceptedItemList(const QList< QgsComposerItem * > &exceptList)
Sets a list of specific items to exclude from the model.
QList< QgsComposerItem * > * zOrderList()
Returns the item z-order list.
QModelIndex parent(const QModelIndex &index) const override
void updateItemLockStatus(QgsComposerItem *item)
Must be called when an item&#39;s lock status changes.
QList< QgsComposerItem * > mItemZList
Maintains z-Order of items. Starts with item at position 1 (position 0 is always paper item) ...
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QgsComposerItem * getComposerItemAbove(QgsComposerItem *item) const
Finds the next composer item above an item.
QgsComposerItem * getComposerItemBelow(QgsComposerItem *item) const
Finds the next composer item below an item.
QList< QgsComposerItem * > mItemsInScene
Cached list of items from mItemZList which are currently in the scene.
void setIsRemoved(const bool removed)
Sets whether this item has been removed from the composition.
void clear()
Clears all items from z-order list and resets the model.
QString uuid() const
Get item identification name.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Graphics scene for map printing.
QVariant data(const QModelIndex &index, int role) const override
virtual bool isRemoved() const
Returns whether this item has been removed from the composition.
void removeItem(QgsComposerItem *item)
Removes an item from the z-order list.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void setPositionLock(const bool lock)
Locks / unlocks the item position for mouse drags.
void setSelected(const QModelIndex &index)
Sets an item as the current selection from a QModelIndex.
bool reorderItemUp(QgsComposerItem *item)
Moves an item up the z-order list.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
virtual void setId(const QString &id)
Set item&#39;s id (which is not necessarly unique)
int columnCount(const QModelIndex &parent=QModelIndex()) const override
void updateItemSelectStatus(QgsComposerItem *item)
Must be called when an item&#39;s selection status changes.
int zOrderListSize() const
Returns the size of the z-order list, which includes items which may have been removed from the compo...
void setItemRemoved(QgsComposerItem *item)
Marks an item as removed from the composition.
bool positionLock() const
Returns whether position lock for mouse drags is enabled returns true if item is locked for mouse mov...
bool reorderItemToTop(QgsComposerItem *item)
Moves an item to the top of the z-order list.
void setFilterType(QgsComposerItem::ItemType itemType)
Sets the item type filter.
void addItemAtTop(QgsComposerItem *item)
Adds an item to the top of the composition z stack.
virtual void setVisibility(const bool visible)
Sets visibility for item.
QString id() const
Get item&#39;s id (which is not necessarly unique)
bool reorderItemToBottom(QgsComposerItem *item)
Moves an item to the bottom of the z-order list.
Item visibility check box.
virtual int type() const override
Return correct graphics item type.
QgsComposerItem * itemFromSourceIndex(const QModelIndex &sourceIndex) const
Returns the QgsComposerItem corresponding to an index from the source QgsComposerModel model...
Qt::ItemFlags flags(const QModelIndex &index) const override