QGIS API Documentation  2.99.0-Master (0a63d1f)
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  qSort( 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
static unsigned index
virtual QString displayName() const
Get item display name.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
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.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
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
QModelIndex indexForItem(QgsComposerItem *item, const int column=0)
Returns the QModelIndex corresponding to a QgsComposerItem, if possible.
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.
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QList< QgsComposerItem * > mItemZList
Maintains z-Order of items. Starts with item at position 1 (position 0 is always paper item) ...
const QgsComposerItem * getComposerItemByUuid(const QString &theUuid) const
Returns a composer item given its unique identifier.
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.
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
QList< QgsComposerItem * > mItemsInScene
Cached list of items from mItemZList which are currently in the scene.
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.
QgsComposerModel(QgsComposition *composition, QObject *parent=nullptr)
Constructor.
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.
QgsComposerProxyModel(QgsComposition *composition, QObject *parent=nullptr)
Constructor for QgsComposerProxyModel.
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