Skip to content
Permalink
Browse files
Cleanup code for composer item align
  • Loading branch information
mhugent committed Jan 17, 2013
1 parent cfcac52 commit 4495925ddbb251c7655f9f462c5a256c8c8e4b90
Showing with 88 additions and 112 deletions.
  1. +79 −108 src/core/composer/qgscomposition.cpp
  2. +9 −4 src/core/composer/qgscomposition.h
@@ -992,94 +992,25 @@ QPointF QgsComposition::alignItem( const QgsComposerItem* item, double& alignX,

QMap<double, const QgsComposerItem* > xAlignCoordinates;
QMap<double, const QgsComposerItem* > yAlignCoordinates;

QList<QGraphicsItem *> itemList = items();
QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
for ( ; itemIt != itemList.end(); ++itemIt )
{
const QgsComposerItem* currentItem = dynamic_cast<const QgsComposerItem *>( *itemIt );
if ( item )
{
if ( !currentItem || currentItem == item || currentItem->type() == QgsComposerItem::ComposerPaper )
{
continue;
}
xAlignCoordinates.insert( currentItem->transform().dx(), currentItem );
xAlignCoordinates.insert( currentItem->transform().dx() + currentItem->rect().width(), currentItem );
xAlignCoordinates.insert( currentItem->transform().dx() + currentItem->rect().center().x(), currentItem );
yAlignCoordinates.insert( currentItem->transform().dy() + currentItem->rect().top(), currentItem );
yAlignCoordinates.insert( currentItem->transform().dy() + currentItem->rect().center().y(), currentItem );
yAlignCoordinates.insert( currentItem->transform().dy() + currentItem->rect().bottom(), currentItem );
}
}
collectAlignCoordinates( xAlignCoordinates, yAlignCoordinates, item );

//find nearest matches x
double xItemLeft = left; //new left coordinate of the item
double xAlignCoord = 0;
double smallestDiffX = DBL_MAX;
double currentX = 0;
double currentDiffX = 0;

currentX = nearestItem( xAlignCoordinates, left );
currentDiffX = abs( left - currentX );
if ( currentDiffX < smallestDiffX )
{
xItemLeft = currentX;
xAlignCoord = currentX;
smallestDiffX = currentDiffX;
}

currentX = nearestItem( xAlignCoordinates, midH );
currentDiffX = abs( midH - currentX );
if ( currentDiffX < smallestDiffX )
{
xItemLeft = currentX - ( right - left ) / 2.0;
xAlignCoord = currentX;
smallestDiffX = currentDiffX;
}

currentX = nearestItem( xAlignCoordinates, right );
currentDiffX = abs( right - currentX );
if ( currentDiffX < smallestDiffX )
{
xItemLeft = currentX - ( right - left );
xAlignCoord = currentX;
smallestDiffX = currentDiffX;
}
checkNearestItem( left, xAlignCoordinates, smallestDiffX, 0, xItemLeft, xAlignCoord );
checkNearestItem( midH, xAlignCoordinates, smallestDiffX, ( left - right ) / 2.0, xItemLeft, xAlignCoord );
checkNearestItem( right, xAlignCoordinates, smallestDiffX, left - right, xItemLeft, xAlignCoord );

//find nearest matches y
double yItemTop = top; //new top coordinate of the item
double yAlignCoord = 0;
double smallestDiffY = DBL_MAX;
double currentY = 0;
double currentDiffY = 0;

currentY = nearestItem( yAlignCoordinates, top );
currentDiffY = abs( top - currentY );
if ( currentDiffY < smallestDiffY )
{
yItemTop = currentY;
yAlignCoord = currentY;
smallestDiffY = currentDiffY;
}

currentY = nearestItem( yAlignCoordinates, midV );
currentDiffY = abs( midV - currentY );
if ( currentDiffY < smallestDiffY )
{
yItemTop = currentY - ( bottom - top ) / 2.0;
yAlignCoord = currentY;
smallestDiffY = currentDiffY;
}

currentY = nearestItem( yAlignCoordinates, bottom );
currentDiffY = abs( bottom - currentY );
if ( currentDiffY < smallestDiffY )
{
yItemTop = currentY - ( bottom - top );
yAlignCoord = currentY;
smallestDiffY = currentDiffY;
}
checkNearestItem( top, yAlignCoordinates, smallestDiffY, 0, yItemTop, yAlignCoord );
checkNearestItem( midV, yAlignCoordinates, smallestDiffY, ( top - bottom ) / 2.0, yItemTop, yAlignCoord );
checkNearestItem( bottom, yAlignCoordinates, smallestDiffY, top - bottom, yItemTop, yAlignCoord );

double xCoord = ( smallestDiffX < 5 ) ? xItemLeft : item->transform().dx() + dx;
alignX = ( smallestDiffX < 5 ) ? xAlignCoord : -1;
@@ -1088,38 +1019,6 @@ QPointF QgsComposition::alignItem( const QgsComposerItem* item, double& alignX,
return QPointF( xCoord, yCoord );
}

double QgsComposition::nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value )
{
QMap< double, const QgsComposerItem* >::const_iterator it = coords.lowerBound( value );
if ( it == coords.constBegin() ) //value smaller than first map value
{
return it.key();
}
else if ( it == coords.constEnd() ) //value larger than last map value
{
--it;
return it.key();
}
else
{
//get smaller value and larger value and return the closer one
double upperVal = it.key();
--it;
double lowerVal = it.key();

double lowerDiff = value - lowerVal;
double upperDiff = upperVal - value;
if ( lowerDiff < upperDiff )
{
return lowerVal;
}
else
{
return upperVal;
}
}
}

int QgsComposition::boundingRectOfSelectedItems( QRectF& bRect )
{
QList<QgsComposerItem*> selectedItems = selectedComposerItems();
@@ -1778,3 +1677,75 @@ QString QgsComposition::encodeStringForXML( const QString& str )
return modifiedStr;
}

void QgsComposition::collectAlignCoordinates( QMap< double, const QgsComposerItem* >& alignCoordsX, QMap< double, const QgsComposerItem* >& alignCoordsY,
const QgsComposerItem* excludeItem )
{
alignCoordsX.clear();
alignCoordsY.clear();

QList<QGraphicsItem *> itemList = items();
QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
for ( ; itemIt != itemList.end(); ++itemIt )
{
const QgsComposerItem* currentItem = dynamic_cast<const QgsComposerItem *>( *itemIt );
if ( excludeItem )
{
if ( !currentItem || currentItem == excludeItem || currentItem->type() == QgsComposerItem::ComposerPaper )
{
continue;
}
alignCoordsX.insert( currentItem->transform().dx(), currentItem );
alignCoordsX.insert( currentItem->transform().dx() + currentItem->rect().width(), currentItem );
alignCoordsX.insert( currentItem->transform().dx() + currentItem->rect().center().x(), currentItem );
alignCoordsY.insert( currentItem->transform().dy() + currentItem->rect().top(), currentItem );
alignCoordsY.insert( currentItem->transform().dy() + currentItem->rect().center().y(), currentItem );
alignCoordsY.insert( currentItem->transform().dy() + currentItem->rect().bottom(), currentItem );
}
}
}

void QgsComposition::checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff,
double itemCoordOffset, double& itemCoord, double& alignCoord )
{
double currentCoord = nearestItem( alignCoords, checkCoord );
double currentDiff = abs( checkCoord - currentCoord );
if ( currentDiff < smallestDiff )
{
itemCoord = currentCoord + itemCoordOffset;
alignCoord = currentCoord;
smallestDiff = currentDiff;
}
}

double QgsComposition::nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value )
{
QMap< double, const QgsComposerItem* >::const_iterator it = coords.lowerBound( value );
if ( it == coords.constBegin() ) //value smaller than first map value
{
return it.key();
}
else if ( it == coords.constEnd() ) //value larger than last map value
{
--it;
return it.key();
}
else
{
//get smaller value and larger value and return the closer one
double upperVal = it.key();
--it;
double lowerVal = it.key();

double lowerDiff = value - lowerVal;
double upperDiff = upperVal - value;
if ( lowerDiff < upperDiff )
{
return lowerVal;
}
else
{
return upperVal;
}
}
}

@@ -245,10 +245,6 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
@return new upper left point after the align*/
QPointF alignItem( const QgsComposerItem* item, double& alignX, double& alignY, double dx = 0, double dy = 0 );

//helper functions
/**Returns the nearest double*/
double nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value );

/**Allocates new item command and saves initial state in it
@param item target item
@param commandText descriptive command text
@@ -384,6 +380,15 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene

static QString encodeStringForXML( const QString& str );

//helper functions for item align
void collectAlignCoordinates( QMap< double, const QgsComposerItem* >& alignCoordsX,
QMap< double, const QgsComposerItem* >& alignCoordsY, const QgsComposerItem* excludeItem );

static void checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff,
double itemCoordOffset, double& itemCoord, double& alignCoord );

static double nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value );

signals:
void paperSizeChanged();
void nPagesChanged();

0 comments on commit 4495925

Please sign in to comment.