Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[composer] Keep relative position of items when pasting (fix #8598)
  • Loading branch information
nyalldawson committed Feb 7, 2014
1 parent f3166a5 commit d0719b0
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
61 changes: 53 additions & 8 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -48,6 +48,7 @@
#include <QSettings>
#include <QDir>

#include <limits>

QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer )
: QGraphicsScene( 0 )
Expand Down Expand Up @@ -717,6 +718,35 @@ bool QgsComposition::loadFromTemplate( const QDomDocument& doc, QMap<QString, QS
return true;
}

QPointF QgsComposition::minPointFromXml( const QDomElement& elem ) const
{
double minX = std::numeric_limits<double>::max();
double minY = std::numeric_limits<double>::max();
QDomNodeList composerItemList = elem.elementsByTagName( "ComposerItem" );
for ( int i = 0; i < composerItemList.size(); ++i )
{
QDomElement currentComposerItemElem = composerItemList.at( i ).toElement();
double x, y;
bool xOk, yOk;
x = currentComposerItemElem.attribute( "x" ).toDouble( &xOk );
y = currentComposerItemElem.attribute( "y" ).toDouble( &yOk );
if ( !xOk || !yOk )
{
continue;
}
minX = qMin( minX, x );
minY = qMin( minY, y );
}
if ( minX < std::numeric_limits<double>::max() )
{
return QPointF( minX, minY );
}
else
{
return QPointF( 0, 0 );
}
}

void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocument& doc, QMap< QgsComposerMap*, int >* mapsToRestore,
bool addUndoCommands, QPointF* pos, bool pasteInPlace )
{
Expand All @@ -727,6 +757,18 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
//so, calculate an offset which needs to be added to the zValue of created items
int zOrderOffset = mItemZList.size();

QPointF pasteShiftPos;
if ( pos )
{
//If we are placing items relative to a certain point, then calculate how much we need
//to shift the items by so that they are placed at this point
//First, calculate the minimum position from the xml
QPointF minItemPos = minPointFromXml( elem );
//next, calculate how much each item needs to be shifted from its original position
//so that it's placed at the correct relative position
pasteShiftPos = *pos - minItemPos;
}

if ( pasteInPlace )
{
pasteInPlacePt = new QPointF( 0, pageNumberAt( *pos ) * ( mPageHeight + mSpaceBetweenPages ) );
Expand All @@ -746,7 +788,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newLabel->setItemPosition( pos->x(), pos->y() );
newLabel->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}
addComposerLabel( newLabel );
Expand Down Expand Up @@ -781,7 +823,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newMap->setItemPosition( pos->x(), pos->y() );
newMap->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}

Expand Down Expand Up @@ -821,7 +863,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newArrow->setItemPosition( pos->x(), pos->y() );
newArrow->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}
addComposerArrow( newArrow );
Expand All @@ -847,7 +889,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newScaleBar->setItemPosition( pos->x(), pos->y() );
newScaleBar->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}
addComposerScaleBar( newScaleBar );
Expand Down Expand Up @@ -875,7 +917,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newShape->setItemPosition( pos->x(), pos->y() );
newShape->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}
addComposerShape( newShape );
Expand All @@ -901,7 +943,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newPicture->setItemPosition( pos->x(), pos->y() );
newPicture->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}
addComposerPicture( newPicture );
Expand All @@ -927,7 +969,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newLegend->setItemPosition( pos->x(), pos->y() );
newLegend->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}
addComposerLegend( newLegend );
Expand All @@ -953,7 +995,7 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
}
else
{
newTable->setItemPosition( pos->x(), pos->y() );
newTable->move( pasteShiftPos.x(), pasteShiftPos.y() );
}
}
addComposerTable( newTable );
Expand Down Expand Up @@ -1000,6 +1042,9 @@ void QgsComposition::addItemsFromXML( const QDomElement& elem, const QDomDocumen
//Make sure z order list matches the actual order of items in the scene.
refreshZList();

delete pasteInPlacePt;
pasteInPlacePt = 0;

}

void QgsComposition::addItemToZList( QgsComposerItem* item )
Expand Down
3 changes: 3 additions & 0 deletions src/core/composer/qgscomposition.h
Expand Up @@ -526,6 +526,9 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
/**Loads composer settings which may change, eg grid color*/
void loadSettings();

/**Calculates the item minimum position from an xml string*/
QPointF minPointFromXml( const QDomElement& elem ) const;

void connectAddRemoveCommandSignals( QgsAddRemoveItemCommand* c );

void updatePaperItems();
Expand Down

0 comments on commit d0719b0

Please sign in to comment.