2121#include < QDoubleSpinBox>
2222#include < QGraphicsProxyWidget>
2323#include < QMouseEvent>
24+ #include " qgisapp.h"
2425
2526QgsMapToolOffsetCurve::QgsMapToolOffsetCurve ( QgsMapCanvas* canvas ): QgsMapToolEdit( canvas ), mRubberBand( 0 ),
2627 mOriginalGeometry( 0 ), mGeometryModified( false ), mDistanceItem( 0 ), mDistanceSpinBox( 0 )
@@ -176,8 +177,16 @@ QgsGeometry* QgsMapToolOffsetCurve::createOriginGeometry( QgsVectorLayer* vl, co
176177 // don't consider selected geometries, only the snap result
177178 return snappedFeature.geometryAndOwnership ();
178179 }
179- else
180+ else // snapped to a background layer
180181 {
182+ // if source layer is polygon / multipolygon, create a linestring from the snapped ring
183+ if ( vl->geometryType () == QGis::Polygon )
184+ {
185+ // make linestring from polygon ring and return this geometry
186+ return linestringFromPolygon ( snappedFeature.geometry (), sr.snappedVertexNr );
187+ }
188+
189+
181190 // for background layers, try to merge selected entries together if snapped feature is contained in selection
182191 const QgsFeatureIds& selection = vl->selectedFeaturesIds ();
183192 if ( selection.size () < 1 || !selection.contains ( sr.snappedAtGeometry ) )
@@ -217,14 +226,22 @@ void QgsMapToolOffsetCurve::createDistanceItem()
217226
218227 deleteDistanceItem ();
219228
220- mDistanceItem = new QGraphicsProxyWidget ();
221229 mDistanceSpinBox = new QDoubleSpinBox ();
222230 mDistanceSpinBox ->setMaximum ( 99999999 );
223231 mDistanceSpinBox ->setDecimals ( 2 );
232+ mDistanceSpinBox ->setPrefix ( tr ( " Offset: " ) );
233+ #ifndef Q_WS_X11
234+ mDistanceItem = new QGraphicsProxyWidget ();
224235 mDistanceItem ->setWidget ( mDistanceSpinBox );
225236 mCanvas ->scene ()->addItem ( mDistanceItem );
226- mDistanceSpinBox ->grabKeyboard ();
227237 mDistanceItem ->hide ();
238+ #else
239+ mDistanceItem = 0 ;
240+ QgisApp::instance ()->statusBar ()->addWidget ( mDistanceSpinBox );
241+ #endif
242+ mDistanceSpinBox ->grabKeyboard ();
243+ mDistanceSpinBox ->setFocus ( Qt::TabFocusReason );
244+
228245 QObject::connect ( mDistanceSpinBox , SIGNAL ( editingFinished () ), this , SLOT ( placeOffsetCurveToValue () ) );
229246}
230247
@@ -236,6 +253,10 @@ void QgsMapToolOffsetCurve::deleteDistanceItem()
236253 }
237254 delete mDistanceItem ;
238255 mDistanceItem = 0 ;
256+ #ifdef Q_WS_X11
257+ QgisApp::instance ()->statusBar ()->removeWidget ( mDistanceSpinBox );
258+ delete mDistanceSpinBox ;
259+ #endif
239260 mDistanceSpinBox = 0 ;
240261}
241262
@@ -273,3 +294,47 @@ void QgsMapToolOffsetCurve::setOffsetForRubberBand( double offset, bool leftSide
273294 }
274295 }
275296}
297+
298+ QgsGeometry* QgsMapToolOffsetCurve::linestringFromPolygon ( QgsGeometry* featureGeom, int vertex )
299+ {
300+ if ( !featureGeom )
301+ {
302+ return 0 ;
303+ }
304+
305+ QGis::WkbType geomType = featureGeom->wkbType ();
306+ int currentVertex = 0 ;
307+ QgsMultiPolygon multiPoly;
308+
309+ if ( geomType == QGis::WKBPolygon || geomType == QGis::WKBPolygon25D )
310+ {
311+ QgsPolygon polygon = featureGeom->asPolygon ();
312+ multiPoly.append ( polygon );
313+ }
314+ else if ( geomType == QGis::WKBMultiPolygon || geomType == QGis::WKBMultiPolygon25D )
315+ {
316+ // iterate all polygons / rings
317+ QgsMultiPolygon multiPoly = featureGeom->asMultiPolygon ();
318+ }
319+ else
320+ {
321+ return 0 ;
322+ }
323+
324+ QgsMultiPolygon::const_iterator multiPolyIt = multiPoly.constBegin ();
325+ for ( ; multiPolyIt != multiPoly.constEnd (); ++multiPolyIt )
326+ {
327+ QgsPolygon::const_iterator polyIt = multiPolyIt->constBegin ();
328+ for ( ; polyIt != multiPolyIt->constEnd (); ++polyIt )
329+ {
330+ currentVertex += polyIt->size ();
331+ if ( vertex < currentVertex )
332+ {
333+ // found, return ring
334+ return QgsGeometry::fromPolyline ( *polyIt );
335+ }
336+ }
337+ }
338+
339+ return 0 ;
340+ }
0 commit comments