Skip to content

Commit a2a26c2

Browse files
committed
[composer] Use pixels for snapping rather than mm, allowing for finer work when zoomed in. Merge grid and guide snapping settings to a single snap tolerance setting.
1 parent b43d131 commit a2a26c2

10 files changed

+184
-179
lines changed

python/core/composer/qgscomposition.sip

+47-5
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,6 @@ class QgsComposition : QGraphicsScene
112112
void setSnapGridResolution( double r );
113113
double snapGridResolution() const;
114114

115-
void setSnapGridTolerance( double tolerance );
116-
double snapGridTolerance() const;
117-
118115
void setSnapGridOffsetX( double offset );
119116
double snapGridOffsetX() const;
120117

@@ -127,8 +124,53 @@ class QgsComposition : QGraphicsScene
127124
void setGridStyle( GridStyle s );
128125
GridStyle gridStyle() const;
129126

130-
void setAlignmentSnapTolerance( double t );
131-
double alignmentSnapTolerance() const;
127+
/**Sets the snap tolerance to use when automatically snapping items during movement and resizing to the
128+
* composition grid.
129+
* @param tolerance snap tolerance in pixels
130+
* @see snapGridTolerance
131+
* @deprecated Use setSnapTolerance instead
132+
*/
133+
void setSnapGridTolerance( double tolerance ) /Deprecated/;
134+
135+
/**Returns the snap tolerance to use when automatically snapping items during movement and resizing to the
136+
* composition grid.
137+
* @returns snap tolerance in pixels
138+
* @see setSnapGridTolerance
139+
* @deprecated Use snapTolerance instead
140+
*/
141+
double snapGridTolerance() const /Deprecated/;
142+
143+
/**Sets the snap tolerance to use when automatically snapping items during movement and resizing to guides
144+
* and the edges and centers of other items.
145+
* @param t snap tolerance in pixels
146+
* @see alignmentSnapTolerance
147+
* @deprecated Use setSnapTolerance instead
148+
*/
149+
void setAlignmentSnapTolerance( double t ) /Deprecated/;
150+
151+
/**Returns the snap tolerance to use when automatically snapping items during movement and resizing to guides
152+
* and the edges and centers of other items.
153+
* @returns snap tolerance in pixels
154+
* @see setAlignmentSnapTolerance
155+
* @deprecated Use snapTolerance instead
156+
*/
157+
double alignmentSnapTolerance() const /Deprecated/;
158+
159+
/**Sets the snap tolerance to use when automatically snapping items during movement and resizing to guides
160+
* and the edges and centers of other items.
161+
* @param t snap tolerance in pixels
162+
* @see alignmentSnapTolerance
163+
* @note Added in QGIS 2.5
164+
*/
165+
void setSnapTolerance( int snapTolerance );
166+
167+
/**Returns the snap tolerance to use when automatically snapping items during movement and resizing to guides
168+
* and the edges and centers of other items.
169+
* @returns snap tolerance in pixels
170+
* @see setAlignmentSnapTolerance
171+
* @note Added in QGIS 2.5
172+
*/
173+
int snapTolerance() const;
132174

133175
/**Returns pointer to undo/redo command storage*/
134176
QUndoStack* undoStack();

src/app/composer/qgscompositionwidget.cpp

+4-15
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,12 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
7979
connect( mComposition, SIGNAL( composerMapAdded( QgsComposerMap* ) ), this, SLOT( onComposerMapAdded( QgsComposerMap* ) ) );
8080
connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( onItemRemoved( QgsComposerItem* ) ) );
8181

82-
mAlignmentToleranceSpinBox->setValue( mComposition->alignmentSnapTolerance() );
82+
mSnapToleranceSpinBox->setValue( mComposition->snapTolerance() );
8383

8484
//snap grid
8585
mGridResolutionSpinBox->setValue( mComposition->snapGridResolution() );
8686
mOffsetXSpinBox->setValue( mComposition->snapGridOffsetX() );
8787
mOffsetYSpinBox->setValue( mComposition->snapGridOffsetY() );
88-
89-
mGridToleranceSpinBox->setValue( mComposition->snapGridTolerance() );
9088
}
9189
blockSignals( false );
9290
}
@@ -559,19 +557,11 @@ void QgsCompositionWidget::on_mOffsetYSpinBox_valueChanged( double d )
559557
}
560558
}
561559

562-
void QgsCompositionWidget::on_mGridToleranceSpinBox_valueChanged( double d )
563-
{
564-
if ( mComposition )
565-
{
566-
mComposition->setSnapGridTolerance( d );
567-
}
568-
}
569-
570-
void QgsCompositionWidget::on_mAlignmentToleranceSpinBox_valueChanged( double d )
560+
void QgsCompositionWidget::on_mSnapToleranceSpinBox_valueChanged( int tolerance )
571561
{
572562
if ( mComposition )
573563
{
574-
mComposition->setAlignmentSnapTolerance( d );
564+
mComposition->setSnapTolerance( tolerance );
575565
}
576566
}
577567

@@ -589,7 +579,6 @@ void QgsCompositionWidget::blockSignals( bool block )
589579
mGridResolutionSpinBox->blockSignals( block );
590580
mOffsetXSpinBox->blockSignals( block );
591581
mOffsetYSpinBox->blockSignals( block );
592-
mGridToleranceSpinBox->blockSignals( block );
593-
mAlignmentToleranceSpinBox->blockSignals( block );
582+
mSnapToleranceSpinBox->blockSignals( block );
594583
}
595584

src/app/composer/qgscompositionwidget.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
5757
void on_mGridResolutionSpinBox_valueChanged( double d );
5858
void on_mOffsetXSpinBox_valueChanged( double d );
5959
void on_mOffsetYSpinBox_valueChanged( double d );
60-
void on_mGridToleranceSpinBox_valueChanged( double d );
61-
void on_mAlignmentToleranceSpinBox_valueChanged( double d );
60+
void on_mSnapToleranceSpinBox_valueChanged( int tolerance );
6261

6362
/**Sets GUI elements to width/height from composition*/
6463
void displayCompositionWidthHeight();

src/app/qgsoptions.cpp

+4-10
Original file line numberDiff line numberDiff line change
@@ -723,15 +723,12 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :
723723
mGridStyleComboBox->setCurrentIndex( 1 );
724724
}
725725

726-
//grid defaults
726+
//grid and guide defaults
727727
mGridResolutionSpinBox->setValue( settings.value( "/Composer/defaultSnapGridResolution", 10.0 ).toDouble() );
728-
mGridToleranceSpinBox->setValue( settings.value( "/Composer/defaultSnapGridTolerance", 2 ).toDouble() );
728+
mSnapToleranceSpinBox->setValue( settings.value( "/Composer/defaultSnapTolerancePixels", 10 ).toInt() );
729729
mOffsetXSpinBox->setValue( settings.value( "/Composer/defaultSnapGridOffsetX", 0 ).toDouble() );
730730
mOffsetYSpinBox->setValue( settings.value( "/Composer/defaultSnapGridOffsetY", 0 ).toDouble() );
731731

732-
//guide defaults
733-
mGuideToleranceSpinBox->setValue( settings.value( "/Composer/defaultSnapGuideTolerance", 2 ).toDouble() );
734-
735732
//
736733
// Locale settings
737734
//
@@ -1311,15 +1308,12 @@ void QgsOptions::saveOptions()
13111308
settings.setValue( "/Composer/gridStyle", "Crosses" );
13121309
}
13131310

1314-
//grid defaults
1311+
//grid and guide defaults
13151312
settings.setValue( "/Composer/defaultSnapGridResolution", mGridResolutionSpinBox->value() );
1316-
settings.setValue( "/Composer/defaultSnapGridTolerance", mGridToleranceSpinBox->value() );
1313+
settings.setValue( "/Composer/defaultSnapTolerancePixels", mSnapToleranceSpinBox->value() );
13171314
settings.setValue( "/Composer/defaultSnapGridOffsetX", mOffsetXSpinBox->value() );
13181315
settings.setValue( "/Composer/defaultSnapGridOffsetY", mOffsetYSpinBox->value() );
13191316

1320-
//guide defaults
1321-
settings.setValue( "/Composer/defaultSnapGuideTolerance", mGuideToleranceSpinBox->value() );
1322-
13231317
//
13241318
// Locale settings
13251319
//

src/core/composer/qgscomposermousehandles.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -1229,8 +1229,12 @@ QPointF QgsComposerMouseHandles::alignPos( const QPointF& pos, double& alignX, d
12291229
return pos;
12301230
}
12311231

1232+
//convert snap tolerance from pixels to mm
1233+
double viewScaleFactor = graphicsView()->transform().m11();
1234+
double alignThreshold = mComposition->snapTolerance() / viewScaleFactor;
1235+
12321236
QPointF result( pos.x(), pos.y() );
1233-
if ( abs( nearestX - pos.x() ) < mComposition->alignmentSnapTolerance() )
1237+
if ( fabs( nearestX - pos.x() ) < alignThreshold )
12341238
{
12351239
result.setX( nearestX );
12361240
alignX = nearestX;
@@ -1240,7 +1244,7 @@ QPointF QgsComposerMouseHandles::alignPos( const QPointF& pos, double& alignX, d
12401244
alignX = -1;
12411245
}
12421246

1243-
if ( abs( nearestY - pos.y() ) < mComposition->alignmentSnapTolerance() )
1247+
if ( fabs( nearestY - pos.y() ) < alignThreshold )
12441248
{
12451249
result.setY( nearestY );
12461250
alignY = nearestY;
@@ -1309,16 +1313,20 @@ void QgsComposerMouseHandles::collectAlignCoordinates( QMap< double, const QgsCo
13091313
}
13101314
}
13111315

1312-
void QgsComposerMouseHandles::checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff, double itemCoordOffset, double& itemCoord, double& alignCoord ) const
1316+
void QgsComposerMouseHandles::checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff, double itemCoordOffset, double& itemCoord, double& alignCoord )
13131317
{
13141318
double currentCoord = 0;
13151319
if ( !nearestItem( alignCoords, checkCoord, currentCoord ) )
13161320
{
13171321
return;
13181322
}
13191323

1320-
double currentDiff = abs( checkCoord - currentCoord );
1321-
if ( currentDiff < mComposition->alignmentSnapTolerance() && currentDiff < smallestDiff )
1324+
double currentDiff = fabs( checkCoord - currentCoord );
1325+
//convert snap tolerance from pixels to mm
1326+
double viewScaleFactor = graphicsView()->transform().m11();
1327+
double alignThreshold = mComposition->snapTolerance() / viewScaleFactor;
1328+
1329+
if ( currentDiff < alignThreshold && currentDiff < smallestDiff )
13221330
{
13231331
itemCoord = currentCoord + itemCoordOffset;
13241332
alignCoord = currentCoord;

src/core/composer/qgscomposermousehandles.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ class CORE_EXPORT QgsComposerMouseHandles: public QObject, public QGraphicsRectI
188188
//helper functions for item align
189189
void collectAlignCoordinates( QMap< double, const QgsComposerItem* >& alignCoordsX, QMap< double, const QgsComposerItem* >& alignCoordsY );
190190
bool nearestItem( const QMap< double, const QgsComposerItem* >& coords, double value, double& nearestValue ) const;
191-
void checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff, double itemCoordOffset, double& itemCoord, double& alignCoord ) const;
191+
void checkNearestItem( double checkCoord, const QMap< double, const QgsComposerItem* >& alignCoords, double& smallestDiff, double itemCoordOffset, double& itemCoord, double& alignCoord );
192192

193193
//tries to return the current QGraphicsView attached to the composition
194194
QGraphicsView* graphicsView();

src/core/composer/qgscomposition.cpp

+25-16
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <QDomDocument>
4444
#include <QDomElement>
4545
#include <QGraphicsRectItem>
46+
#include <QGraphicsView>
4647
#include <QPainter>
4748
#include <QPrinter>
4849
#include <QSettings>
@@ -83,13 +84,12 @@ void QgsComposition::init()
8384
mSnapToGrid = false;
8485
mGridVisible = false;
8586
mSnapGridResolution = 0;
86-
mSnapGridTolerance = 0;
8787
mSnapGridOffsetX = 0;
8888
mSnapGridOffsetY = 0;
8989
mAlignmentSnap = true;
9090
mGuidesVisible = true;
9191
mSmartGuides = true;
92-
mAlignmentSnapTolerance = 0;
92+
mSnapTolerance = 0;
9393
mSelectionHandles = 0;
9494
mActiveItemCommand = 0;
9595
mActiveMultiFrameCommand = 0;
@@ -170,10 +170,9 @@ void QgsComposition::loadDefaults()
170170
{
171171
QSettings settings;
172172
mSnapGridResolution = settings.value( "/Composer/defaultSnapGridResolution", 10.0 ).toDouble();
173-
mSnapGridTolerance = settings.value( "/Composer/defaultSnapGridTolerance", 2 ).toDouble();
174173
mSnapGridOffsetX = settings.value( "/Composer/defaultSnapGridOffsetX", 0 ).toDouble();
175174
mSnapGridOffsetY = settings.value( "/Composer/defaultSnapGridOffsetY", 0 ).toDouble();
176-
mAlignmentSnapTolerance = settings.value( "/Composer/defaultSnapGuideTolerance", 2 ).toDouble();
175+
mSnapTolerance = settings.value( "/Composer/defaultSnapTolerancePixels", 10 ).toInt();
177176
}
178177

179178
void QgsComposition::updateBounds()
@@ -640,7 +639,6 @@ bool QgsComposition::writeXML( QDomElement& composerElem, QDomDocument& doc )
640639
compositionElem.setAttribute( "gridVisible", "0" );
641640
}
642641
compositionElem.setAttribute( "snapGridResolution", QString::number( mSnapGridResolution ) );
643-
compositionElem.setAttribute( "snapGridTolerance", QString::number( mSnapGridTolerance ) );
644642
compositionElem.setAttribute( "snapGridOffsetX", QString::number( mSnapGridOffsetX ) );
645643
compositionElem.setAttribute( "snapGridOffsetY", QString::number( mSnapGridOffsetY ) );
646644

@@ -669,7 +667,7 @@ bool QgsComposition::writeXML( QDomElement& composerElem, QDomDocument& doc )
669667
compositionElem.setAttribute( "alignmentSnap", mAlignmentSnap ? 1 : 0 );
670668
compositionElem.setAttribute( "guidesVisible", mGuidesVisible ? 1 : 0 );
671669
compositionElem.setAttribute( "smartGuides", mSmartGuides ? 1 : 0 );
672-
compositionElem.setAttribute( "alignmentSnapTolerance", mAlignmentSnapTolerance );
670+
compositionElem.setAttribute( "snapTolerancePixels", mSnapTolerance );
673671

674672
//save items except paper items and frame items (they are saved with the corresponding multiframe)
675673
QList<QGraphicsItem*> itemList = items();
@@ -733,14 +731,13 @@ bool QgsComposition::readXML( const QDomElement& compositionElem, const QDomDocu
733731
mGridVisible = compositionElem.attribute( "gridVisible", "0" ).toInt() == 0 ? false : true;
734732

735733
mSnapGridResolution = compositionElem.attribute( "snapGridResolution" ).toDouble();
736-
mSnapGridTolerance = compositionElem.attribute( "snapGridTolerance", "2.0" ).toDouble();
737734
mSnapGridOffsetX = compositionElem.attribute( "snapGridOffsetX" ).toDouble();
738735
mSnapGridOffsetY = compositionElem.attribute( "snapGridOffsetY" ).toDouble();
739736

740737
mAlignmentSnap = compositionElem.attribute( "alignmentSnap", "1" ).toInt() == 0 ? false : true;
741738
mGuidesVisible = compositionElem.attribute( "guidesVisible", "1" ).toInt() == 0 ? false : true;
742739
mSmartGuides = compositionElem.attribute( "smartGuides", "1" ).toInt() == 0 ? false : true;
743-
mAlignmentSnapTolerance = compositionElem.attribute( "alignmentSnapTolerance", "2.0" ).toDouble();
740+
mSnapTolerance = compositionElem.attribute( "snapTolerancePixels", "10" ).toInt();
744741

745742
//custom snap lines
746743
QDomNodeList snapLineNodes = compositionElem.elementsByTagName( "SnapLine" );
@@ -1733,7 +1730,7 @@ void QgsComposition::refreshZList()
17331730

17341731
QPointF QgsComposition::snapPointToGrid( const QPointF& scenePoint ) const
17351732
{
1736-
if ( !mSnapToGrid || mSnapGridResolution <= 0 )
1733+
if ( !mSnapToGrid || mSnapGridResolution <= 0 || !graphicsView() )
17371734
{
17381735
return scenePoint;
17391736
}
@@ -1750,12 +1747,16 @@ QPointF QgsComposition::snapPointToGrid( const QPointF& scenePoint ) const
17501747
double xSnapped = xRatio * mSnapGridResolution + mSnapGridOffsetX;
17511748
double ySnapped = yRatio * mSnapGridResolution + mSnapGridOffsetY + yOffset;
17521749

1753-
if ( abs( xSnapped - scenePoint.x() ) > mSnapGridTolerance )
1750+
//convert snap tolerance from pixels to mm
1751+
double viewScaleFactor = graphicsView()->transform().m11();
1752+
double alignThreshold = mSnapTolerance / viewScaleFactor;
1753+
1754+
if ( fabs( xSnapped - scenePoint.x() ) > alignThreshold )
17541755
{
17551756
//snap distance is outside of tolerance
17561757
xSnapped = scenePoint.x();
17571758
}
1758-
if ( abs( ySnapped - scenePoint.y() ) > mSnapGridTolerance )
1759+
if ( fabs( ySnapped - scenePoint.y() ) > alignThreshold )
17591760
{
17601761
//snap distance is outside of tolerance
17611762
ySnapped = scenePoint.y();
@@ -1961,11 +1962,6 @@ void QgsComposition::setSnapGridResolution( double r )
19611962
updatePaperItems();
19621963
}
19631964

1964-
void QgsComposition::setSnapGridTolerance( double tolerance )
1965-
{
1966-
mSnapGridTolerance = tolerance;
1967-
}
1968-
19691965
void QgsComposition::setSnapGridOffsetX( double offset )
19701966
{
19711967
mSnapGridOffsetX = offset;
@@ -2578,6 +2574,19 @@ QString QgsComposition::encodeStringForXML( const QString& str )
25782574
return modifiedStr;
25792575
}
25802576

2577+
QGraphicsView *QgsComposition::graphicsView() const
2578+
{
2579+
//try to find current view attached to composition
2580+
QList<QGraphicsView*> viewList = views();
2581+
if ( viewList.size() > 0 )
2582+
{
2583+
return viewList.at( 0 );
2584+
}
2585+
2586+
//no view attached to composition
2587+
return 0;
2588+
}
2589+
25812590
void QgsComposition::computeWorldFileParameters( double& a, double& b, double& c, double& d, double& e, double& f ) const
25822591
{
25832592
//

0 commit comments

Comments
 (0)