Skip to content

Commit d22f7e8

Browse files
committedFeb 6, 2014
[composer] Fix stacking of items breaks after pasting items. Make sure pasted items are always placed in correct order on top of composition.
1 parent 167d9b8 commit d22f7e8

File tree

4 files changed

+90
-10
lines changed

4 files changed

+90
-10
lines changed
 

‎python/core/composer/qgscomposition.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ class QgsComposition : QGraphicsScene
277277
after reading all the items from xml file*/
278278
void sortZList();
279279

280+
/**Rebuilds the z order list based on current order of items in scene*/
281+
void refreshZList();
282+
280283
/**Snaps a scene coordinate point to grid*/
281284
QPointF snapPointToGrid( const QPointF& scenePoint ) const;
282285

‎src/app/composer/qgscomposer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2628,7 +2628,9 @@ void QgsComposer::readXML( const QDomElement& composerElem, const QDomDocument&
26282628
mComposition->setWorldFileMap( worldFileMap );
26292629
}
26302630

2631-
mComposition->sortZList();
2631+
//make sure z values are consistent
2632+
mComposition->refreshZList();
2633+
26322634
mView->setComposition( mComposition );
26332635

26342636
if ( mUndoView )

‎src/core/composer/qgscomposition.cpp

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
721721
bool addUndoCommands, QPointF* pos, bool pasteInPlace )
722722
{
723723
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+
724730
if ( pasteInPlace )
725731
{
726732
pasteInPlacePt = new QPointF( 0, pageNumberAt( *pos ) * ( mPageHeight + mSpaceBetweenPages ) );
@@ -744,6 +750,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
744750
}
745751
}
746752
addComposerLabel( newLabel );
753+
newLabel->setZValue( newLabel->zValue() + zOrderOffset );
747754
if ( addUndoCommands )
748755
{
749756
pushAddRemoveCommand( newLabel, tr( "Label added" ) );
@@ -764,7 +771,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
764771
newMap->setPreviewMode( QgsComposerMap::Rectangle );
765772
}
766773
addComposerMap( newMap, false );
767-
774+
newMap->setZValue( newMap->zValue() + zOrderOffset );
768775
if ( pos )
769776
{
770777
if ( pasteInPlace )
@@ -818,6 +825,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
818825
}
819826
}
820827
addComposerArrow( newArrow );
828+
newArrow->setZValue( newArrow->zValue() + zOrderOffset );
821829
if ( addUndoCommands )
822830
{
823831
pushAddRemoveCommand( newArrow, tr( "Arrow added" ) );
@@ -843,6 +851,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
843851
}
844852
}
845853
addComposerScaleBar( newScaleBar );
854+
newScaleBar->setZValue( newScaleBar->zValue() + zOrderOffset );
846855
if ( addUndoCommands )
847856
{
848857
pushAddRemoveCommand( newScaleBar, tr( "Scale bar added" ) );
@@ -870,6 +879,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
870879
}
871880
}
872881
addComposerShape( newShape );
882+
newShape->setZValue( newShape->zValue() + zOrderOffset );
873883
if ( addUndoCommands )
874884
{
875885
pushAddRemoveCommand( newShape, tr( "Shape added" ) );
@@ -895,6 +905,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
895905
}
896906
}
897907
addComposerPicture( newPicture );
908+
newPicture->setZValue( newPicture->zValue() + zOrderOffset );
898909
if ( addUndoCommands )
899910
{
900911
pushAddRemoveCommand( newPicture, tr( "Picture added" ) );
@@ -920,6 +931,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
920931
}
921932
}
922933
addComposerLegend( newLegend );
934+
newLegend->setZValue( newLegend->zValue() + zOrderOffset );
923935
if ( addUndoCommands )
924936
{
925937
pushAddRemoveCommand( newLegend, tr( "Legend added" ) );
@@ -945,12 +957,14 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
945957
}
946958
}
947959
addComposerTable( newTable );
960+
newTable->setZValue( newTable->zValue() + zOrderOffset );
948961
if ( addUndoCommands )
949962
{
950963
pushAddRemoveCommand( newTable, tr( "Table added" ) );
951964
}
952965
}
953966
// html
967+
//TODO - fix this. pasting html items has no effect
954968
QDomNodeList composerHtmlList = elem.elementsByTagName( "ComposerHtml" );
955969
for ( int i = 0; i < composerHtmlList.size(); ++i )
956970
{
@@ -959,10 +973,19 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
959973
newHtml->readXML( currentHtmlElem, doc );
960974
newHtml->setCreateUndoCommands( true );
961975
this->addMultiFrame( newHtml );
962-
}
963976

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+
}
964985

965986
// 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
966989
QDomNodeList groupList = elem.elementsByTagName( "ComposerItemGroup" );
967990
for ( int i = 0; i < groupList.size(); ++i )
968991
{
@@ -971,6 +994,12 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
971994
newGroup->readXML( groupElem, doc );
972995
addItem( newGroup );
973996
}
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+
9741003
}
9751004

9761005
void QgsComposition::addItemToZList( QgsComposerItem* item )
@@ -1385,26 +1414,40 @@ void QgsComposition::unlockAllItems()
13851414
mUndoStack.push( parentCommand );
13861415
}
13871416

1388-
void QgsComposition::updateZValues()
1417+
void QgsComposition::updateZValues( bool addUndoCommands )
13891418
{
13901419
int counter = 1;
13911420
QLinkedList<QgsComposerItem*>::iterator it = mItemZList.begin();
13921421
QgsComposerItem* currentItem = 0;
13931422

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+
}
13951428
for ( ; it != mItemZList.end(); ++it )
13961429
{
13971430
currentItem = *it;
13981431
if ( currentItem )
13991432
{
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+
}
14021439
currentItem->setZValue( counter );
1403-
subcommand->saveAfterState();
1440+
if ( addUndoCommands )
1441+
{
1442+
subcommand->saveAfterState();
1443+
}
14041444
}
14051445
++counter;
14061446
}
1407-
mUndoStack.push( parentCommand );
1447+
if ( addUndoCommands )
1448+
{
1449+
mUndoStack.push( parentCommand );
1450+
}
14081451
}
14091452

14101453
void QgsComposition::sortZList()
@@ -1433,6 +1476,35 @@ void QgsComposition::sortZList()
14331476
mItemZList = sortedList;
14341477
}
14351478

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+
14361508
QPointF QgsComposition::snapPointToGrid( const QPointF& scenePoint ) const
14371509
{
14381510
if ( !mSnapToGrid || mSnapGridResolution <= 0 )

‎src/core/composer/qgscomposition.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
333333
after reading all the items from xml file*/
334334
void sortZList();
335335

336+
/**Rebuilds the z order list based on current order of items in scene*/
337+
void refreshZList();
338+
336339
/**Snaps a scene coordinate point to grid*/
337340
QPointF snapPointToGrid( const QPointF& scenePoint ) const;
338341

@@ -511,7 +514,7 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
511514
QgsComposition(); //default constructor is forbidden
512515

513516
/**Reset z-values of items based on position in z list*/
514-
void updateZValues();
517+
void updateZValues( bool addUndoCommands = true );
515518

516519
/**Returns the bounding rectangle of the selected items in scene coordinates
517520
@return 0 in case of success*/

0 commit comments

Comments
 (0)
Please sign in to comment.