Skip to content

Commit d0719b0

Browse files
committedFeb 7, 2014
[composer] Keep relative position of items when pasting (fix #8598)
1 parent f3166a5 commit d0719b0

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed
 

‎src/core/composer/qgscomposition.cpp

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <QSettings>
4949
#include <QDir>
5050

51+
#include <limits>
5152

5253
QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer )
5354
: QGraphicsScene( 0 )
@@ -717,6 +718,35 @@ bool QgsComposition::loadFromTemplate( const QDomDocument& doc, QMap<QString, QS
717718
return true;
718719
}
719720

721+
QPointF QgsComposition::minPointFromXml( const QDomElement& elem ) const
722+
{
723+
double minX = std::numeric_limits<double>::max();
724+
double minY = std::numeric_limits<double>::max();
725+
QDomNodeList composerItemList = elem.elementsByTagName( "ComposerItem" );
726+
for ( int i = 0; i < composerItemList.size(); ++i )
727+
{
728+
QDomElement currentComposerItemElem = composerItemList.at( i ).toElement();
729+
double x, y;
730+
bool xOk, yOk;
731+
x = currentComposerItemElem.attribute( "x" ).toDouble( &xOk );
732+
y = currentComposerItemElem.attribute( "y" ).toDouble( &yOk );
733+
if ( !xOk || !yOk )
734+
{
735+
continue;
736+
}
737+
minX = qMin( minX, x );
738+
minY = qMin( minY, y );
739+
}
740+
if ( minX < std::numeric_limits<double>::max() )
741+
{
742+
return QPointF( minX, minY );
743+
}
744+
else
745+
{
746+
return QPointF( 0, 0 );
747+
}
748+
}
749+
720750
void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocument& doc, QMap< QgsComposerMap*, int >* mapsToRestore,
721751
bool addUndoCommands, QPointF* pos, bool pasteInPlace )
722752
{
@@ -727,6 +757,18 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
727757
//so, calculate an offset which needs to be added to the zValue of created items
728758
int zOrderOffset = mItemZList.size();
729759

760+
QPointF pasteShiftPos;
761+
if ( pos )
762+
{
763+
//If we are placing items relative to a certain point, then calculate how much we need
764+
//to shift the items by so that they are placed at this point
765+
//First, calculate the minimum position from the xml
766+
QPointF minItemPos = minPointFromXml( elem );
767+
//next, calculate how much each item needs to be shifted from its original position
768+
//so that it's placed at the correct relative position
769+
pasteShiftPos = *pos - minItemPos;
770+
}
771+
730772
if ( pasteInPlace )
731773
{
732774
pasteInPlacePt = new QPointF( 0, pageNumberAt( *pos ) * ( mPageHeight + mSpaceBetweenPages ) );
@@ -746,7 +788,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
746788
}
747789
else
748790
{
749-
newLabel->setItemPosition( pos->x(), pos->y() );
791+
newLabel->move( pasteShiftPos.x(), pasteShiftPos.y() );
750792
}
751793
}
752794
addComposerLabel( newLabel );
@@ -781,7 +823,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
781823
}
782824
else
783825
{
784-
newMap->setItemPosition( pos->x(), pos->y() );
826+
newMap->move( pasteShiftPos.x(), pasteShiftPos.y() );
785827
}
786828
}
787829

@@ -821,7 +863,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
821863
}
822864
else
823865
{
824-
newArrow->setItemPosition( pos->x(), pos->y() );
866+
newArrow->move( pasteShiftPos.x(), pasteShiftPos.y() );
825867
}
826868
}
827869
addComposerArrow( newArrow );
@@ -847,7 +889,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
847889
}
848890
else
849891
{
850-
newScaleBar->setItemPosition( pos->x(), pos->y() );
892+
newScaleBar->move( pasteShiftPos.x(), pasteShiftPos.y() );
851893
}
852894
}
853895
addComposerScaleBar( newScaleBar );
@@ -875,7 +917,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
875917
}
876918
else
877919
{
878-
newShape->setItemPosition( pos->x(), pos->y() );
920+
newShape->move( pasteShiftPos.x(), pasteShiftPos.y() );
879921
}
880922
}
881923
addComposerShape( newShape );
@@ -901,7 +943,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
901943
}
902944
else
903945
{
904-
newPicture->setItemPosition( pos->x(), pos->y() );
946+
newPicture->move( pasteShiftPos.x(), pasteShiftPos.y() );
905947
}
906948
}
907949
addComposerPicture( newPicture );
@@ -927,7 +969,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
927969
}
928970
else
929971
{
930-
newLegend->setItemPosition( pos->x(), pos->y() );
972+
newLegend->move( pasteShiftPos.x(), pasteShiftPos.y() );
931973
}
932974
}
933975
addComposerLegend( newLegend );
@@ -953,7 +995,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
953995
}
954996
else
955997
{
956-
newTable->setItemPosition( pos->x(), pos->y() );
998+
newTable->move( pasteShiftPos.x(), pasteShiftPos.y() );
957999
}
9581000
}
9591001
addComposerTable( newTable );
@@ -1000,6 +1042,9 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
10001042
//Make sure z order list matches the actual order of items in the scene.
10011043
refreshZList();
10021044

1045+
delete pasteInPlacePt;
1046+
pasteInPlacePt = 0;
1047+
10031048
}
10041049

10051050
void QgsComposition::addItemToZList( QgsComposerItem* item )

‎src/core/composer/qgscomposition.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,9 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
526526
/**Loads composer settings which may change, eg grid color*/
527527
void loadSettings();
528528

529+
/**Calculates the item minimum position from an xml string*/
530+
QPointF minPointFromXml( const QDomElement& elem ) const;
531+
529532
void connectAddRemoveCommandSignals( QgsAddRemoveItemCommand* c );
530533

531534
void updatePaperItems();

0 commit comments

Comments
 (0)
Please sign in to comment.