@@ -721,6 +721,12 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
721
721
bool addUndoCommands, QPointF* pos, bool pasteInPlace )
722
722
{
723
723
QPointF* pasteInPlacePt = 0 ;
724
+
725
+ // if we are adding items to a composition which already contains items, we need to make sure
726
+ // these items are placed at the top of the composition and that zValues are not duplicated
727
+ // so, calculate an offset which needs to be added to the zValue of created items
728
+ int zOrderOffset = mItemZList .size ();
729
+
724
730
if ( pasteInPlace )
725
731
{
726
732
pasteInPlacePt = new QPointF ( 0 , pageNumberAt ( *pos ) * ( mPageHeight + mSpaceBetweenPages ) );
@@ -744,6 +750,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
744
750
}
745
751
}
746
752
addComposerLabel ( newLabel );
753
+ newLabel->setZValue ( newLabel->zValue () + zOrderOffset );
747
754
if ( addUndoCommands )
748
755
{
749
756
pushAddRemoveCommand ( newLabel, tr ( " Label added" ) );
@@ -764,7 +771,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
764
771
newMap->setPreviewMode ( QgsComposerMap::Rectangle );
765
772
}
766
773
addComposerMap ( newMap, false );
767
-
774
+ newMap-> setZValue ( newMap-> zValue () + zOrderOffset );
768
775
if ( pos )
769
776
{
770
777
if ( pasteInPlace )
@@ -818,6 +825,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
818
825
}
819
826
}
820
827
addComposerArrow ( newArrow );
828
+ newArrow->setZValue ( newArrow->zValue () + zOrderOffset );
821
829
if ( addUndoCommands )
822
830
{
823
831
pushAddRemoveCommand ( newArrow, tr ( " Arrow added" ) );
@@ -843,6 +851,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
843
851
}
844
852
}
845
853
addComposerScaleBar ( newScaleBar );
854
+ newScaleBar->setZValue ( newScaleBar->zValue () + zOrderOffset );
846
855
if ( addUndoCommands )
847
856
{
848
857
pushAddRemoveCommand ( newScaleBar, tr ( " Scale bar added" ) );
@@ -870,6 +879,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
870
879
}
871
880
}
872
881
addComposerShape ( newShape );
882
+ newShape->setZValue ( newShape->zValue () + zOrderOffset );
873
883
if ( addUndoCommands )
874
884
{
875
885
pushAddRemoveCommand ( newShape, tr ( " Shape added" ) );
@@ -895,6 +905,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
895
905
}
896
906
}
897
907
addComposerPicture ( newPicture );
908
+ newPicture->setZValue ( newPicture->zValue () + zOrderOffset );
898
909
if ( addUndoCommands )
899
910
{
900
911
pushAddRemoveCommand ( newPicture, tr ( " Picture added" ) );
@@ -920,6 +931,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
920
931
}
921
932
}
922
933
addComposerLegend ( newLegend );
934
+ newLegend->setZValue ( newLegend->zValue () + zOrderOffset );
923
935
if ( addUndoCommands )
924
936
{
925
937
pushAddRemoveCommand ( newLegend, tr ( " Legend added" ) );
@@ -945,12 +957,14 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
945
957
}
946
958
}
947
959
addComposerTable ( newTable );
960
+ newTable->setZValue ( newTable->zValue () + zOrderOffset );
948
961
if ( addUndoCommands )
949
962
{
950
963
pushAddRemoveCommand ( newTable, tr ( " Table added" ) );
951
964
}
952
965
}
953
966
// html
967
+ // TODO - fix this. pasting html items has no effect
954
968
QDomNodeList composerHtmlList = elem.elementsByTagName ( " ComposerHtml" );
955
969
for ( int i = 0 ; i < composerHtmlList.size (); ++i )
956
970
{
@@ -959,10 +973,19 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
959
973
newHtml->readXML ( currentHtmlElem, doc );
960
974
newHtml->setCreateUndoCommands ( true );
961
975
this ->addMultiFrame ( newHtml );
962
- }
963
976
977
+ // offset z values for frames
978
+ // TODO - fix this after fixing html item paste
979
+ /* for ( int frameIdx = 0; frameIdx < newHtml->frameCount(); ++frameIdx )
980
+ {
981
+ QgsComposerFrame * frame = newHtml->frame( frameIdx );
982
+ frame->setZValue( frame->zValue() + zOrderOffset );
983
+ }*/
984
+ }
964
985
965
986
// groups (must be last as it references uuids of above items)
987
+ // TODO - pasted groups lose group properties, since the uuids of group items
988
+ // changes
966
989
QDomNodeList groupList = elem.elementsByTagName ( " ComposerItemGroup" );
967
990
for ( int i = 0 ; i < groupList.size (); ++i )
968
991
{
@@ -971,6 +994,12 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
971
994
newGroup->readXML ( groupElem, doc );
972
995
addItem ( newGroup );
973
996
}
997
+
998
+ // Since this function adds items grouped by type, and each item is added to end of
999
+ // z order list in turn, it will now be inconsistent with the actual order of items in the scene.
1000
+ // Make sure z order list matches the actual order of items in the scene.
1001
+ refreshZList ();
1002
+
974
1003
}
975
1004
976
1005
void QgsComposition::addItemToZList ( QgsComposerItem* item )
@@ -1385,26 +1414,40 @@ void QgsComposition::unlockAllItems()
1385
1414
mUndoStack .push ( parentCommand );
1386
1415
}
1387
1416
1388
- void QgsComposition::updateZValues ()
1417
+ void QgsComposition::updateZValues ( bool addUndoCommands )
1389
1418
{
1390
1419
int counter = 1 ;
1391
1420
QLinkedList<QgsComposerItem*>::iterator it = mItemZList .begin ();
1392
1421
QgsComposerItem* currentItem = 0 ;
1393
1422
1394
- QUndoCommand* parentCommand = new QUndoCommand ( tr ( " Item z-order changed" ) );
1423
+ QUndoCommand* parentCommand;
1424
+ if ( addUndoCommands )
1425
+ {
1426
+ parentCommand = new QUndoCommand ( tr ( " Item z-order changed" ) );
1427
+ }
1395
1428
for ( ; it != mItemZList .end (); ++it )
1396
1429
{
1397
1430
currentItem = *it;
1398
1431
if ( currentItem )
1399
1432
{
1400
- QgsComposerItemCommand* subcommand = new QgsComposerItemCommand ( *it, " " , parentCommand );
1401
- subcommand->savePreviousState ();
1433
+ QgsComposerItemCommand* subcommand;
1434
+ if ( addUndoCommands )
1435
+ {
1436
+ subcommand = new QgsComposerItemCommand ( *it, " " , parentCommand );
1437
+ subcommand->savePreviousState ();
1438
+ }
1402
1439
currentItem->setZValue ( counter );
1403
- subcommand->saveAfterState ();
1440
+ if ( addUndoCommands )
1441
+ {
1442
+ subcommand->saveAfterState ();
1443
+ }
1404
1444
}
1405
1445
++counter;
1406
1446
}
1407
- mUndoStack .push ( parentCommand );
1447
+ if ( addUndoCommands )
1448
+ {
1449
+ mUndoStack .push ( parentCommand );
1450
+ }
1408
1451
}
1409
1452
1410
1453
void QgsComposition::sortZList ()
@@ -1433,6 +1476,35 @@ void QgsComposition::sortZList()
1433
1476
mItemZList = sortedList;
1434
1477
}
1435
1478
1479
+ void QgsComposition::refreshZList ()
1480
+ {
1481
+ QLinkedList<QgsComposerItem*> sortedList;
1482
+
1483
+ // rebuild the item z order list based on the current zValues of items in the scene
1484
+
1485
+ // get items in descending zValue order
1486
+ QList<QGraphicsItem*> itemList = items ();
1487
+ QList<QGraphicsItem*>::iterator itemIt = itemList.begin ();
1488
+ for ( ; itemIt != itemList.end (); ++itemIt )
1489
+ {
1490
+ QgsComposerItem* composerItem = dynamic_cast <QgsComposerItem*>( *itemIt );
1491
+ if ( composerItem )
1492
+ {
1493
+ if ( composerItem->type () != QgsComposerItem::ComposerPaper && composerItem->type () != QgsComposerItem::ComposerFrame )
1494
+ {
1495
+ // since the z order list is in ascending zValue order (opposite order to itemList), we prepend each item
1496
+ sortedList.prepend ( composerItem );
1497
+ }
1498
+ }
1499
+ }
1500
+
1501
+ mItemZList = sortedList;
1502
+
1503
+ // Finally, rebuild the zValue of all items to remove any duplicate zValues and make sure there's
1504
+ // no missing zValues.
1505
+ updateZValues ( false );
1506
+ }
1507
+
1436
1508
QPointF QgsComposition::snapPointToGrid ( const QPointF& scenePoint ) const
1437
1509
{
1438
1510
if ( !mSnapToGrid || mSnapGridResolution <= 0 )
0 commit comments