[QGIS Commit] r14423 - in trunk/qgis/src: app core core/pal ui

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Oct 20 16:23:52 EDT 2010


Author: wonder
Date: 2010-10-20 13:23:52 -0700 (Wed, 20 Oct 2010)
New Revision: 14423

Modified:
   trunk/qgis/src/app/qgslabelinggui.cpp
   trunk/qgis/src/app/qgslabelinggui.h
   trunk/qgis/src/core/pal/feature.cpp
   trunk/qgis/src/core/pal/feature.h
   trunk/qgis/src/core/pal/labelposition.cpp
   trunk/qgis/src/core/pal/labelposition.h
   trunk/qgis/src/core/pal/layer.cpp
   trunk/qgis/src/core/pal/layer.h
   trunk/qgis/src/core/qgspallabeling.cpp
   trunk/qgis/src/core/qgspallabeling.h
   trunk/qgis/src/ui/qgslabelingguibase.ui
Log:
[FEATURE] Data defined label position in new labeling - from Marco Hugentobler.


Modified: trunk/qgis/src/app/qgslabelinggui.cpp
===================================================================
--- trunk/qgis/src/app/qgslabelinggui.cpp	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/app/qgslabelinggui.cpp	2010-10-20 20:23:52 UTC (rev 14423)
@@ -123,6 +123,7 @@
   chkMergeLines->setChecked( lyr.mergeLines );
   chkMultiLine->setChecked( lyr.multiLineLabels );
   mMinSizeSpinBox->setValue( lyr.minFeatureSize );
+  chkAddDirectionSymbol->setChecked( lyr.addDirectionSymbol );
 
   bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 );
   chkScaleBasedVisibility->setChecked( scaleBased );
@@ -139,7 +140,19 @@
 
   btnTextColor->setColor( lyr.textColor );
   btnBufferColor->setColor( lyr.bufferColor );
-  updateFont( lyr.textFont );
+
+  if ( lyr.fontSizeInMapUnits )
+  {
+    mFontSizeUnitComboBox->setCurrentIndex( 1 );
+  }
+  else
+  {
+    mFontSizeUnitComboBox->setCurrentIndex( 0 );
+  }
+
+  QFont textFont = lyr.textFont;
+  updateFont( textFont );
+  mFontSizeSpinBox->setValue( textFont.pointSizeF() );
   updateUi();
 
   updateOptions();
@@ -238,8 +251,18 @@
   {
     lyr.bufferSize = 0;
   }
+  if ( chkAddDirectionSymbol->isChecked() )
+  {
+    lyr.addDirectionSymbol = true;
+  }
+  else
+  {
+    lyr.addDirectionSymbol = false;
+  }
   lyr.minFeatureSize = mMinSizeSpinBox->value();
+  lyr.fontSizeInMapUnits = ( mFontSizeUnitComboBox->currentIndex() == 1 );
 
+
   //data defined labeling
   setDataDefinedProperty( mSizeAttributeComboBox, QgsPalLayerSettings::Size, lyr );
   setDataDefinedProperty( mColorAttributeComboBox, QgsPalLayerSettings::Color, lyr );
@@ -250,6 +273,12 @@
   setDataDefinedProperty( mFontFamilyAttributeComboBox, QgsPalLayerSettings::Family, lyr );
   setDataDefinedProperty( mBufferSizeAttributeComboBox, QgsPalLayerSettings:: BufferSize, lyr );
   setDataDefinedProperty( mBufferColorAttributeComboBox, QgsPalLayerSettings::BufferColor, lyr );
+  setDataDefinedProperty( mXCoordinateComboBox, QgsPalLayerSettings::PositionX, lyr );
+  setDataDefinedProperty( mYCoordinateComboBox, QgsPalLayerSettings::PositionY, lyr );
+  setDataDefinedProperty( mHorizontalAlignmentComboBox, QgsPalLayerSettings::Hali, lyr );
+  setDataDefinedProperty( mVerticalAlignmentComboBox, QgsPalLayerSettings::Vali, lyr );
+  setDataDefinedProperty( mLabelDistanceComboBox, QgsPalLayerSettings::LabelDistance, lyr );
+  setDataDefinedProperty( mRotationComboBox, QgsPalLayerSettings::Rotation, lyr );
 
   return lyr;
 }
@@ -308,6 +337,12 @@
   comboList << mFontFamilyAttributeComboBox;
   comboList << mBufferSizeAttributeComboBox;
   comboList << mBufferColorAttributeComboBox;
+  comboList << mXCoordinateComboBox;
+  comboList << mYCoordinateComboBox;
+  comboList << mHorizontalAlignmentComboBox;
+  comboList << mVerticalAlignmentComboBox;
+  comboList << mLabelDistanceComboBox;
+  comboList << mRotationComboBox;
 
   QList<QComboBox*>::iterator comboIt = comboList.begin();
   for ( ; comboIt != comboList.end(); ++comboIt )
@@ -335,6 +370,12 @@
   setCurrentComboValue( mFontFamilyAttributeComboBox, s, QgsPalLayerSettings::Family );
   setCurrentComboValue( mBufferSizeAttributeComboBox, s , QgsPalLayerSettings::BufferSize );
   setCurrentComboValue( mBufferColorAttributeComboBox, s, QgsPalLayerSettings::BufferColor );
+  setCurrentComboValue( mXCoordinateComboBox, s, QgsPalLayerSettings::PositionX );
+  setCurrentComboValue( mYCoordinateComboBox, s, QgsPalLayerSettings::PositionY );
+  setCurrentComboValue( mHorizontalAlignmentComboBox, s, QgsPalLayerSettings::Hali );
+  setCurrentComboValue( mVerticalAlignmentComboBox, s, QgsPalLayerSettings::Vali );
+  setCurrentComboValue( mLabelDistanceComboBox, s, QgsPalLayerSettings::LabelDistance );
+  setCurrentComboValue( mRotationComboBox, s, QgsPalLayerSettings::Rotation );
 }
 
 void QgsLabelingGui::changeTextColor()
@@ -352,14 +393,21 @@
   bool ok;
   QFont font = QFontDialog::getFont( &ok, lblFontPreview->font(), this );
   if ( ok )
+  {
     updateFont( font );
+  }
+  mFontSizeSpinBox->setValue( font.pointSizeF() );
 }
 
 void QgsLabelingGui::updateFont( QFont font )
 {
-  lblFontName->setText( QString( "%1, %2 %3" ).arg( font.family() ).arg( font.pointSize() ).arg( tr( "pt" ) ) );
+  QString fontSizeUnitString = tr( "pt" );
+  if ( mFontSizeUnitComboBox->currentIndex() == 1 )
+  {
+    fontSizeUnitString = tr( "map units" );
+  }
+  lblFontName->setText( QString( "%1, %2 %3" ).arg( font.family() ).arg( font.pointSize() ).arg( fontSizeUnitString ) );
   lblFontPreview->setFont( font );
-
   updatePreview();
 }
 
@@ -418,3 +466,57 @@
     stackedOptions->setCurrentWidget( pageOptionsEmpty );
   }
 }
+
+void QgsLabelingGui::on_mFontSizeSpinBox_valueChanged( double d )
+{
+  QFont font = lblFontPreview->font();
+  font.setPointSizeF( d );
+  lblFontPreview->setFont( font );
+  updateFont( font );
+}
+
+void QgsLabelingGui::on_mFontSizeUnitComboBox_currentIndexChanged( int index )
+{
+  updateFont( lblFontPreview->font() );
+}
+
+void QgsLabelingGui::on_mXCoordinateComboBox_currentIndexChanged( const QString & text )
+{
+  if ( text.isEmpty() ) //no data defined alignment without data defined position
+  {
+    disableDataDefinedAlignment();
+  }
+  else if ( !mYCoordinateComboBox->currentText().isEmpty() )
+  {
+    enableDataDefinedAlignment();
+  }
+}
+
+void QgsLabelingGui::on_mYCoordinateComboBox_currentIndexChanged( const QString & text )
+{
+  if ( text.isEmpty() ) //no data defined alignment without data defined position
+  {
+    disableDataDefinedAlignment();
+  }
+  else if ( !mXCoordinateComboBox->currentText().isEmpty() )
+  {
+    enableDataDefinedAlignment();
+  }
+}
+
+void QgsLabelingGui::disableDataDefinedAlignment()
+{
+  mHorizontalAlignmentComboBox->setCurrentIndex( mHorizontalAlignmentComboBox->findText( "" ) );
+  mHorizontalAlignmentComboBox->setEnabled( false );
+  mVerticalAlignmentComboBox->setCurrentIndex( mVerticalAlignmentComboBox->findText( "" ) );
+  mVerticalAlignmentComboBox->setEnabled( false );
+  mRotationComboBox->setCurrentIndex( mRotationComboBox->findText( "" ) );
+  mRotationComboBox->setEnabled( false );
+}
+
+void QgsLabelingGui::enableDataDefinedAlignment()
+{
+  mHorizontalAlignmentComboBox->setEnabled( true );
+  mVerticalAlignmentComboBox->setEnabled( true );
+  mRotationComboBox->setEnabled( true );
+}

Modified: trunk/qgis/src/app/qgslabelinggui.h
===================================================================
--- trunk/qgis/src/app/qgslabelinggui.h	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/app/qgslabelinggui.h	2010-10-20 20:23:52 UTC (rev 14423)
@@ -45,6 +45,11 @@
     void updatePreview();
     void updateOptions();
 
+    void on_mFontSizeSpinBox_valueChanged( double d );
+    void on_mFontSizeUnitComboBox_currentIndexChanged( int index );
+    void on_mXCoordinateComboBox_currentIndexChanged( const QString & text );
+    void on_mYCoordinateComboBox_currentIndexChanged( const QString & text );
+
   protected:
     void populatePlacementMethods();
     void populateFieldNames();
@@ -57,6 +62,9 @@
   private:
     QgsPalLabeling* mLBL;
     QgsVectorLayer* mLayer;
+
+    void disableDataDefinedAlignment();
+    void enableDataDefinedAlignment();
 };
 
 #endif

Modified: trunk/qgis/src/core/pal/feature.cpp
===================================================================
--- trunk/qgis/src/core/pal/feature.cpp	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/feature.cpp	2010-10-20 20:23:52 UTC (rev 14423)
@@ -61,7 +61,7 @@
 namespace pal
 {
   Feature::Feature( Layer* l, const char* geom_id, PalGeometry* userG, double lx, double ly )
-      : layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL )
+      : layer( l ), userGeom( userG ), label_x( lx ), label_y( ly ), distlabel( 0 ), labelInfo( NULL ), fixedPos( false ), fixedRotation( false )
   {
     uid = new char[strlen( geom_id ) +1];
     strcpy( uid, geom_id );
@@ -599,11 +599,11 @@
           reversed = ( alpha >= M_PI / 2 || alpha < -M_PI / 2 );
 
         if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) )
-          positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this ) ); // Line
+          positions->push_back( new LabelPosition( i, bx + cos( beta ) *distlabel , by + sin( beta ) *distlabel, xrm, yrm, alpha, cost, this, reversed ) ); // Line
         if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
-          positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this ) );   // Line
+          positions->push_back( new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ) , by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost, this, reversed ) );   // Line
         if ( flags & FLAG_ON_LINE )
-          positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this ) ); // Line
+          positions->push_back( new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost, this, reversed ) ); // Line
       }
       else if ( f->layer->arrangement == P_HORIZ )
       {
@@ -1245,40 +1245,54 @@
 
     double delta = bbox_max[0] - bbox_min[0];
 
-    switch ( type )
+    if ( f->fixedPosition() )
     {
-      case GEOS_POINT:
-        if ( f->layer->getArrangement() == P_POINT_OVER )
-          nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta );
-        else
-          nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta );
-        break;
-      case GEOS_LINESTRING:
-        if ( f->layer->getArrangement() == P_CURVED )
-          nbp = setPositionForLineCurved( lPos, mapShape );
-        else
-          nbp = setPositionForLine( scale, lPos, mapShape, delta );
-        break;
+      nbp = 1;
+      *lPos = new LabelPosition *[nbp];
+      double angle = 0.0;
+      if ( f->fixedRotation )
+      {
+        angle = f->fixedAngle;
+      }
+      ( *lPos )[0] = new LabelPosition( 0, f->fixedPosX, f->fixedPosY, f->label_x, f->label_y, angle, 0.0,  this );
+    }
+    else
+    {
+      switch ( type )
+      {
+        case GEOS_POINT:
+          if ( f->layer->getArrangement() == P_POINT_OVER )
+            nbp = setPositionOverPoint( x[0], y[0], scale, lPos, delta );
+          else
+            nbp = setPositionForPoint( x[0], y[0], scale, lPos, delta );
+          break;
+        case GEOS_LINESTRING:
+          if ( f->layer->getArrangement() == P_CURVED )
+            nbp = setPositionForLineCurved( lPos, mapShape );
+          else
+            nbp = setPositionForLine( scale, lPos, mapShape, delta );
+          break;
 
-      case GEOS_POLYGON:
-        switch ( f->layer->getArrangement() )
-        {
-          case P_POINT:
-          case P_POINT_OVER:
-            double cx, cy;
-            mapShape->getCentroid( cx, cy );
-            if ( f->layer->getArrangement() == P_POINT_OVER )
-              nbp = setPositionOverPoint( cx, cy, scale, lPos, delta );
-            else
-              nbp = setPositionForPoint( cx, cy, scale, lPos, delta );
-            break;
-          case P_LINE:
-            nbp = setPositionForLine( scale, lPos, mapShape, delta );
-            break;
-          default:
-            nbp = setPositionForPolygon( scale, lPos, mapShape, delta );
-            break;
-        }
+        case GEOS_POLYGON:
+          switch ( f->layer->getArrangement() )
+          {
+            case P_POINT:
+            case P_POINT_OVER:
+              double cx, cy;
+              mapShape->getCentroid( cx, cy );
+              if ( f->layer->getArrangement() == P_POINT_OVER )
+                nbp = setPositionOverPoint( cx, cy, scale, lPos, delta );
+              else
+                nbp = setPositionForPoint( cx, cy, scale, lPos, delta );
+              break;
+            case P_LINE:
+              nbp = setPositionForLine( scale, lPos, mapShape, delta );
+              break;
+            default:
+              nbp = setPositionForPolygon( scale, lPos, mapShape, delta );
+              break;
+          }
+      }
     }
 
     int rnbp = nbp;

Modified: trunk/qgis/src/core/pal/feature.h
===================================================================
--- trunk/qgis/src/core/pal/feature.h	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/feature.h	2010-10-20 20:23:52 UTC (rev 14423)
@@ -86,6 +86,11 @@
 
       void setLabelInfo( LabelInfo* info ) { labelInfo = info; }
       void setDistLabel( double dist ) { distlabel = dist; }
+      //Set label position of the feature to fixed x/y values
+      void setFixedPosition( double x, double y ) { fixedPos = true; fixedPosX = x; fixedPosY = y;}
+      bool fixedPosition() const { return fixedPos; }
+      //Set label rotation to fixed value
+      void setFixedAngle( double a ) { fixedRotation = true; fixedAngle = a; }
 
     protected:
       Layer *layer;
@@ -97,6 +102,13 @@
 
       char *uid;
 
+      bool fixedPos; //true in case of fixed position (only 1 candidate position with cost 0)
+      double fixedPosX;
+      double fixedPosY;
+      //Fixed (e.g. data defined) angle only makes sense together with fixed position
+      bool fixedRotation;
+      double fixedAngle; //fixed angle value (in rad)
+
       // array of parts - possibly not necessary
       //int nPart;
       //FeaturePart** parts;

Modified: trunk/qgis/src/core/pal/labelposition.cpp
===================================================================
--- trunk/qgis/src/core/pal/labelposition.cpp	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/labelposition.cpp	2010-10-20 20:23:52 UTC (rev 14423)
@@ -54,8 +54,8 @@
 
 namespace pal
 {
-  LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature )
-      : id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 )
+  LabelPosition::LabelPosition( int id, double x1, double y1, double w, double h, double alpha, double cost, FeaturePart *feature, bool isReversed )
+      : id( id ), cost( cost ), feature( feature ), nbOverlap( 0 ), alpha( alpha ), w( w ), h( h ), nextPart( NULL ), partId( -1 ), reversed( isReversed )
   {
 
     // alpha take his value bw 0 and 2*pi rad

Modified: trunk/qgis/src/core/pal/labelposition.h
===================================================================
--- trunk/qgis/src/core/pal/labelposition.h	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/labelposition.h	2010-10-20 20:23:52 UTC (rev 14423)
@@ -74,6 +74,11 @@
       LabelPosition* nextPart;
       int partId;
 
+      //True if label direction is the same as line / polygon ring direction.
+      //Could be used by the application to draw a directional arrow ('<' or '>')
+      //if the layer arrangement is P_LINE
+      bool reversed;
+
       bool isInConflictSinglePart( LabelPosition* lp );
       bool isInConflictMultiPart( LabelPosition* lp );
 
@@ -93,7 +98,7 @@
       LabelPosition( int id, double x1, double y1,
                      double w, double h,
                      double alpha, double cost,
-                     FeaturePart *feature );
+                     FeaturePart *feature, bool isReversed = false );
 
       /** copy constructor */
       LabelPosition( const LabelPosition& other );
@@ -190,6 +195,7 @@
        * \return alpha to rotate text (in rad)
        */
       double getAlpha() const;
+      bool getReversed() const { return reversed; }
 
       void print();
 

Modified: trunk/qgis/src/core/pal/layer.cpp
===================================================================
--- trunk/qgis/src/core/pal/layer.cpp	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/layer.cpp	2010-10-20 20:23:52 UTC (rev 14423)
@@ -226,7 +226,8 @@
 
 
 
-  bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText )
+  bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText,
+                               double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle )
   {
     if ( !geom_id || label_x < 0 || label_y < 0 )
       return false;
@@ -245,6 +246,14 @@
     GEOSGeometry *the_geom = userGeom->getGeosGeometry();
 
     Feature* f = new Feature( this, geom_id, userGeom, label_x, label_y );
+    if ( fixedPos )
+    {
+      f->setFixedPosition( labelPosX, labelPosY );
+    }
+    if ( fixedAngle )
+    {
+      f->setFixedAngle( angle );
+    }
 
     bool first_feat = true;
 
@@ -316,7 +325,7 @@
     modMutex->unlock();
 
     // if using only biggest parts...
-    if ( mode == LabelPerFeature && biggest_part != NULL )
+    if (( mode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL )
     {
       addFeaturePart( biggest_part, labelText );
       first_feat = false;

Modified: trunk/qgis/src/core/pal/layer.h
===================================================================
--- trunk/qgis/src/core/pal/layer.h	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/pal/layer.h	2010-10-20 20:23:52 UTC (rev 14423)
@@ -283,12 +283,16 @@
        * @param label_x label width
        * @param label_y label height
        * @param userGeom user's geometry that implements the PalGeometry interface
+       * @param labelPosX x position of the label (in case of fixed label position)
+       * @param labelPosY y position of the label (in case of fixed label position)
+       * @param fixedPos true if a single fixed position for this label is needed
        *
        * @throws PalException::FeatureExists
        *
        * @return true on success (i.e. valid geometry)
        */
-      bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1, const char* labelText = NULL );
+      bool registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x = -1, double label_y = -1,
+                            const char* labelText = NULL, double labelPosX = 0.0, double labelPosY = 0.0, bool fixedPos = false, double angle = 0.0, bool fixedAngle = false );
 
       /** return pointer to feature or NULL if doesn't exist */
       Feature* getFeature( const char* geom_id );

Modified: trunk/qgis/src/core/qgspallabeling.cpp
===================================================================
--- trunk/qgis/src/core/qgspallabeling.cpp	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/qgspallabeling.cpp	2010-10-20 20:23:52 UTC (rev 14423)
@@ -132,6 +132,8 @@
   minFeatureSize = 0.0;
   vectorScaleFactor = 1.0;
   rasterCompressFactor = 1.0;
+  addDirectionSymbol = false;
+  fontSizeInMapUnits = false;
 }
 
 QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
@@ -156,6 +158,8 @@
   minFeatureSize = s.minFeatureSize;
   vectorScaleFactor = s.vectorScaleFactor;
   rasterCompressFactor = s.rasterCompressFactor;
+  addDirectionSymbol = s.addDirectionSymbol;
+  fontSizeInMapUnits = s.fontSizeInMapUnits;
 
   dataDefinedProperties = s.dataDefinedProperties;
   fontMetrics = NULL;
@@ -193,7 +197,7 @@
     return;
   }
 
-  for ( int i = 0; i < 9; ++i )
+  for ( int i = 0; i < 15; ++i )
   {
     QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator it = propertyMap.find(( QgsPalLayerSettings::DataDefinedProperties )i );
     QVariant propertyValue;
@@ -242,6 +246,12 @@
   _readDataDefinedProperty( layer, QgsPalLayerSettings::Family, propertyMap );
   _readDataDefinedProperty( layer, QgsPalLayerSettings::BufferSize, propertyMap );
   _readDataDefinedProperty( layer, QgsPalLayerSettings::BufferColor, propertyMap );
+  _readDataDefinedProperty( layer,  QgsPalLayerSettings::PositionX, propertyMap );
+  _readDataDefinedProperty( layer,  QgsPalLayerSettings::PositionY, propertyMap );
+  _readDataDefinedProperty( layer,  QgsPalLayerSettings::Hali, propertyMap );
+  _readDataDefinedProperty( layer,  QgsPalLayerSettings::Vali, propertyMap );
+  _readDataDefinedProperty( layer, QgsPalLayerSettings::LabelDistance, propertyMap );
+  _readDataDefinedProperty( layer, QgsPalLayerSettings::Rotation, propertyMap );
 }
 
 void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
@@ -269,7 +279,9 @@
   labelPerPart = layer->customProperty( "labeling/labelPerPart" ).toBool();
   mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
   multiLineLabels = layer->customProperty( "labeling/multiLineLabels" ).toBool();
+  addDirectionSymbol = layer->customProperty( "labeling/addDirectionSymbol" ).toBool();
   minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble();
+  fontSizeInMapUnits = layer->customProperty( "labeling/fontSizeInMapUnits" ).toBool();
   _readDataDefinedPropertyMap( layer, dataDefinedProperties );
 }
 
@@ -299,7 +311,9 @@
   layer->setCustomProperty( "labeling/labelPerPart", labelPerPart );
   layer->setCustomProperty( "labeling/mergeLines", mergeLines );
   layer->setCustomProperty( "labeling/multiLineLabels", multiLineLabels );
+  layer->setCustomProperty( "labeling/addDirectionSymbol", addDirectionSymbol );
   layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize );
+  layer->setCustomProperty( "labeling/fontSizeInMapUnits", fontSizeInMapUnits );
   _writeDataDefinedPropertyMap( layer, dataDefinedProperties );
 }
 
@@ -358,6 +372,10 @@
     return;
   }
 
+  if ( addDirectionSymbol && !multiLineLabels && placement == QgsPalLayerSettings::Line ) //consider the space needed for the direction symbol
+  {
+    text.append( ">" );
+  }
   QRectF labelRect = fm->boundingRect( text );
   double w, h;
   if ( !multiLineLabels )
@@ -391,12 +409,12 @@
 {
   QString labelText = f.attributeMap()[fieldIndex].toString();
   double labelX, labelY; // will receive label size
+  QFont labelFont = textFont;
 
   //data defined label size?
   QMap< DataDefinedProperties, int >::const_iterator it = dataDefinedProperties.find( QgsPalLayerSettings::Size );
   if ( it != dataDefinedProperties.constEnd() )
   {
-    QFont labelFont = textFont;
     //find out size
     QVariant size = f.attributeMap().value( *it );
     if ( size.isValid() )
@@ -406,7 +424,7 @@
       {
         return;
       }
-      labelFont.setPointSize( sizeToPixel( sizeDouble, context ) );
+      labelFont.setPixelSize( sizeToPixel( sizeDouble, context ) );
     }
     QFontMetrics labelFontMetrics( labelFont );
     calculateLabelSize( &labelFontMetrics, labelText, labelX, labelY );
@@ -430,6 +448,88 @@
     return;
   }
 
+  //data defined position / alignment / rotation?
+  bool dataDefinedPosition = false;
+  bool dataDefinedRotation = false;
+  double xPos, yPos, angle;
+
+  QMap< DataDefinedProperties, int >::const_iterator dPosXIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionX );
+  if ( dPosXIt != dataDefinedProperties.constEnd() )
+  {
+    QMap< DataDefinedProperties, int >::const_iterator dPosYIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionY );
+    if ( dPosYIt != dataDefinedProperties.constEnd() )
+    {
+      //data defined position
+      dataDefinedPosition = true;
+      xPos = f.attributeMap().value( *dPosXIt ).toDouble();
+      yPos = f.attributeMap().value( *dPosYIt ).toDouble();
+
+      //x/y shift in case of alignment
+      double xdiff = 0;
+      double ydiff = 0;
+
+      //horizontal alignment
+      QMap< DataDefinedProperties, int >::const_iterator haliIt = dataDefinedProperties.find( QgsPalLayerSettings::Hali );
+      if ( haliIt != dataDefinedProperties.end() )
+      {
+        QString haliString = f.attributeMap().value( *haliIt ).toString();
+        if ( haliString.compare( "Center", Qt::CaseInsensitive ) == 0 )
+        {
+          xdiff -= labelX / 2.0;
+        }
+        else if ( haliString.compare( "Right", Qt::CaseInsensitive ) == 0 )
+        {
+          xdiff -= labelX;
+        }
+      }
+
+      //vertical alignment
+      QMap< DataDefinedProperties, int >::const_iterator valiIt = dataDefinedProperties.find( QgsPalLayerSettings::Vali );
+      if ( valiIt != dataDefinedProperties.constEnd() )
+      {
+        QString valiString = f.attributeMap().value( *valiIt ).toString();
+        if ( valiString.compare( "Bottom", Qt::CaseInsensitive ) != 0 )
+        {
+          if ( valiString.compare( "Top", Qt::CaseInsensitive ) == 0 || valiString.compare( "Cap", Qt::CaseInsensitive ) == 0 )
+          {
+            ydiff -= labelY;
+          }
+          else
+          {
+            QFontMetrics labelFontMetrics( labelFont );
+            double descentRatio = labelFontMetrics.descent() / labelFontMetrics.height();
+
+            if ( valiString.compare( "Base", Qt::CaseInsensitive ) == 0 )
+            {
+              ydiff -= labelY * descentRatio;
+            }
+            else if ( valiString.compare( "Half", Qt::CaseInsensitive ) == 0 )
+            {
+              ydiff -= labelY * descentRatio;
+              ydiff -= labelY * 0.5 * ( 1 - descentRatio );
+            }
+          }
+        }
+      }
+
+      //data defined rotation?
+      QMap< DataDefinedProperties, int >::const_iterator rotIt = dataDefinedProperties.find( QgsPalLayerSettings::Rotation );
+      if ( rotIt != dataDefinedProperties.constEnd() )
+      {
+        dataDefinedRotation = true;
+        angle = f.attributeMap().value( *rotIt ).toDouble() * M_PI / 180;
+        //adjust xdiff and ydiff because the hali/vali point needs to be the rotation center
+        double xd = xdiff * cos( angle ) - ydiff * sin( angle );
+        double yd = xdiff * sin( angle ) + ydiff * cos( angle );
+        xdiff = xd;
+        ydiff = yd;
+      }
+
+      yPos += ydiff;
+      xPos += xdiff;
+    }
+  }
+
   QgsPalGeometry* lbl = new QgsPalGeometry( f.id(), labelText, GEOSGeom_clone( geos_geom ) );
 
   // record the created geometry - it will be deleted at the end.
@@ -438,7 +538,8 @@
   // register feature to the layer
   try
   {
-    if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData() ) )
+    if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData(),
+                                     xPos, yPos, dataDefinedPosition, angle, dataDefinedRotation ) )
       return;
   }
   catch ( std::exception* e )
@@ -452,9 +553,20 @@
   feat->setLabelInfo( lbl->info( fontMetrics, xform, rasterCompressFactor ) );
 
   // TODO: allow layer-wide feature dist in PAL...?
-  if ( dist != 0 )
-    feat->setDistLabel( fabs( ptOne.x() - ptZero.x() )* dist * vectorScaleFactor );
 
+  //data defined label-feature distance?
+  double distance = dist;
+  QMap< DataDefinedProperties, int >::const_iterator dDistIt = dataDefinedProperties.find( QgsPalLayerSettings::LabelDistance );
+  if ( dDistIt != dataDefinedProperties.constEnd() )
+  {
+    distance = f.attributeMap().value( *dDistIt ).toDouble();
+  }
+
+  if ( distance != 0 )
+  {
+    feat->setDistLabel( fabs( ptOne.x() - ptZero.x() )* distance * vectorScaleFactor );
+  }
+
   //add parameters for data defined labeling to QgsPalGeometry
   QMap< DataDefinedProperties, int >::const_iterator dIt = dataDefinedProperties.constBegin();
   for ( ; dIt != dataDefinedProperties.constEnd(); ++dIt )
@@ -465,9 +577,17 @@
 
 int QgsPalLayerSettings::sizeToPixel( double size, const QgsRenderContext& c ) const
 {
-  // set font size from points to output size
-  double pixelSize = 0.3527 * size * c.scaleFactor() * c.rasterScaleFactor() + 0.5;
-  return ( int )pixelSize;
+  double pixelSize;
+  if ( fontSizeInMapUnits )
+  {
+    pixelSize = size / c.mapToPixel().mapUnitsPerPixel() * c.rasterScaleFactor();
+  }
+  else //font size in points
+  {
+    // set font size from points to output size
+    pixelSize = 0.3527 * size * c.scaleFactor() * c.rasterScaleFactor();
+  }
+  return ( int )( pixelSize + 0.5 );
 }
 
 
@@ -730,7 +850,7 @@
     QVariant dataDefinedSize = palGeometry->dataDefinedValues().value( QgsPalLayerSettings::Size );
     if ( dataDefinedSize.isValid() )
     {
-      fontForLabel.setPointSize( lyr.sizeToPixel( dataDefinedSize.toDouble(), context ) );
+      fontForLabel.setPixelSize( lyr.sizeToPixel( dataDefinedSize.toDouble(), context ) );
     }
     //font color
     QVariant dataDefinedColor = palGeometry->dataDefinedValues().value( QgsPalLayerSettings::Color );
@@ -871,6 +991,20 @@
   QString text = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();
   QString txt = ( label->getPartId() == -1 ? text : QString( text[label->getPartId()] ) );
 
+  //add the direction symbol if needed
+  if ( !txt.isEmpty() && lyr.placement == QgsPalLayerSettings::Line &&
+       lyr.addDirectionSymbol && !lyr.multiLineLabels )
+  {
+    if ( label->getReversed() )
+    {
+      txt.prepend( "<" );
+    }
+    else
+    {
+      txt.append( ">" );
+    }
+  }
+
   //QgsDebugMsg( "drawLabel " + QString::number( drawBuffer ) + " " + txt );
 
   QStringList multiLineList;
@@ -913,7 +1047,7 @@
     painter->restore();
 
     if ( label->getNextPart() )
-      drawLabel( label->getNextPart(), painter, f, c, xform, drawBuffer );
+      drawLabel( label->getNextPart(), painter, f, c, xform, bufferSize, bufferColor, drawBuffer );
   }
 }
 

Modified: trunk/qgis/src/core/qgspallabeling.h
===================================================================
--- trunk/qgis/src/core/qgspallabeling.h	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/core/qgspallabeling.h	2010-10-20 20:23:52 UTC (rev 14423)
@@ -83,6 +83,12 @@
       Family,
       BufferSize,
       BufferColor,
+      PositionX, //x-coordinate data defined label position
+      PositionY, //y-coordinate data defined label position
+      Hali, //horizontal alignment for data defined label position (Left, Center, Right)
+      Vali, //vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
+      LabelDistance,
+      Rotation //data defined rotation (only usefull in connection with data defined position)
     };
 
     QString fieldName;
@@ -103,6 +109,10 @@
     bool mergeLines;
     bool multiLineLabels; //draw labels on multiple lines if they contain '\n'
     double minFeatureSize; // minimum feature size to be labelled (in mm)
+    // Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring
+    // Works only if Placement == Line
+    bool addDirectionSymbol;
+    bool fontSizeInMapUnits; //true if font size is in map units (otherwise in points)
 
     // called from register feature hook
     void calculateLabelSize( const QFontMetrics* fm, QString text, double& labelX, double& labelY );
@@ -130,7 +140,7 @@
     /**Stores field indices for data defined layer properties*/
     QMap< DataDefinedProperties, int > dataDefinedProperties;
 
-    /**Calculates pixel size (considering scale factors and oversampling)
+    /**Calculates pixel size (considering output size should be in pixel or map units, scale factors and oversampling)
      @param size size to convert
      @param c rendercontext
      @return font pixel size*/

Modified: trunk/qgis/src/ui/qgslabelingguibase.ui
===================================================================
--- trunk/qgis/src/ui/qgslabelingguibase.ui	2010-10-20 20:01:27 UTC (rev 14422)
+++ trunk/qgis/src/ui/qgslabelingguibase.ui	2010-10-20 20:23:52 UTC (rev 14423)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>496</width>
-    <height>659</height>
+    <width>504</width>
+    <height>686</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -396,7 +396,7 @@
               </item>
              </layout>
             </item>
-            <item row="1" column="0">
+            <item row="2" column="0">
              <widget class="QLabel" name="label_29">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -412,7 +412,7 @@
               </property>
              </widget>
             </item>
-            <item row="1" column="1">
+            <item row="2" column="1">
              <layout class="QHBoxLayout" name="horizontalLayout_16">
               <item>
                <widget class="QgsColorButton" name="btnTextColor">
@@ -445,7 +445,7 @@
               </item>
              </layout>
             </item>
-            <item row="2" column="0">
+            <item row="3" column="0">
              <widget class="QLabel" name="label_30">
               <property name="text">
                <string>Buffer</string>
@@ -455,7 +455,7 @@
               </property>
              </widget>
             </item>
-            <item row="2" column="1">
+            <item row="3" column="1">
              <layout class="QHBoxLayout" name="horizontalLayout_17">
               <item>
                <widget class="QCheckBox" name="chkBuffer">
@@ -512,7 +512,7 @@
               </item>
              </layout>
             </item>
-            <item row="4" column="0">
+            <item row="5" column="0">
              <widget class="QLabel" name="label_33">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -528,8 +528,14 @@
               </property>
              </widget>
             </item>
-            <item row="4" column="1">
+            <item row="5" column="1">
              <widget class="QgsLabelPreview" name="lblFontPreview">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
               <property name="minimumSize">
                <size>
                 <width>30</width>
@@ -544,13 +550,45 @@
               </property>
              </widget>
             </item>
-            <item row="3" column="0" colspan="2">
+            <item row="4" column="0" colspan="2">
              <widget class="Line" name="line_4">
               <property name="orientation">
                <enum>Qt::Horizontal</enum>
               </property>
              </widget>
             </item>
+            <item row="1" column="0">
+             <widget class="QLabel" name="mFontSizeLabel">
+              <property name="text">
+               <string>Font size</string>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1">
+             <layout class="QHBoxLayout" name="horizontalLayout">
+              <item>
+               <widget class="QDoubleSpinBox" name="mFontSizeSpinBox">
+                <property name="maximum">
+                 <double>999999999.000000000000000</double>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QComboBox" name="mFontSizeUnitComboBox">
+                <item>
+                 <property name="text">
+                  <string>In points</string>
+                 </property>
+                </item>
+                <item>
+                 <property name="text">
+                  <string>In map units</string>
+                 </property>
+                </item>
+               </widget>
+              </item>
+             </layout>
+            </item>
            </layout>
           </widget>
          </item>
@@ -678,7 +716,7 @@
          </property>
         </widget>
        </item>
-       <item row="7" column="0">
+       <item row="8" column="0">
         <layout class="QHBoxLayout" name="horizontalLayout_19">
          <item>
           <widget class="QLabel" name="label_19">
@@ -696,7 +734,7 @@
          </item>
         </layout>
        </item>
-       <item row="8" column="0">
+       <item row="9" column="0">
         <layout class="QHBoxLayout" name="horizontalLayout_20">
          <item>
           <widget class="QCheckBox" name="chkNoObstacle">
@@ -733,13 +771,20 @@
          </item>
         </layout>
        </item>
+       <item row="7" column="0">
+        <widget class="QCheckBox" name="chkAddDirectionSymbol">
+         <property name="text">
+          <string>add direction symbol</string>
+         </property>
+        </widget>
+       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="tab_4">
       <attribute name="title">
        <string>Data defined settings</string>
       </attribute>
-      <layout class="QGridLayout" name="gridLayout_4">
+      <layout class="QGridLayout" name="gridLayout_3">
        <item row="0" column="0">
         <widget class="QGroupBox" name="mFontAttributePropertiesGroupBox">
          <property name="sizePolicy">
@@ -753,79 +798,75 @@
          </property>
          <layout class="QGridLayout" name="gridLayout">
           <item row="0" column="0">
-           <layout class="QGridLayout" name="gridLayout_11">
-            <item row="0" column="0">
-             <widget class="QLabel" name="mSizeLabel">
-              <property name="text">
-               <string>Size</string>
-              </property>
-             </widget>
-            </item>
-            <item row="0" column="1">
-             <widget class="QComboBox" name="mSizeAttributeComboBox"/>
-            </item>
-            <item row="2" column="0">
-             <widget class="QLabel" name="mBoldLabel">
-              <property name="text">
-               <string>Bold</string>
-              </property>
-             </widget>
-            </item>
-            <item row="2" column="1">
-             <widget class="QComboBox" name="mBoldAttributeComboBox"/>
-            </item>
-            <item row="1" column="1">
-             <widget class="QComboBox" name="mColorAttributeComboBox"/>
-            </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="mColorLabel">
-              <property name="text">
-               <string>Color</string>
-              </property>
-             </widget>
-            </item>
-            <item row="3" column="1">
-             <widget class="QComboBox" name="mItalicAttributeComboBox"/>
-            </item>
-            <item row="3" column="0">
-             <widget class="QLabel" name="mItalicLabel">
-              <property name="text">
-               <string>Italic</string>
-              </property>
-             </widget>
-            </item>
-            <item row="4" column="1">
-             <widget class="QComboBox" name="mUnderlineAttributeComboBox"/>
-            </item>
-            <item row="4" column="0">
-             <widget class="QLabel" name="mUnderlineLabel">
-              <property name="text">
-               <string>Underline</string>
-              </property>
-             </widget>
-            </item>
-            <item row="6" column="1">
-             <widget class="QComboBox" name="mFontFamilyAttributeComboBox"/>
-            </item>
-            <item row="6" column="0">
-             <widget class="QLabel" name="mFontFamilyLabel">
-              <property name="text">
-               <string>Font family</string>
-              </property>
-             </widget>
-            </item>
-            <item row="5" column="1">
-             <widget class="QComboBox" name="mStrikeoutAttributeComboBox"/>
-            </item>
-            <item row="5" column="0">
-             <widget class="QLabel" name="mStrikeoutLabel">
-              <property name="text">
-               <string>Strikeout</string>
-              </property>
-             </widget>
-            </item>
-           </layout>
+           <widget class="QLabel" name="mSizeLabel">
+            <property name="text">
+             <string>Size</string>
+            </property>
+           </widget>
           </item>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="mSizeAttributeComboBox"/>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="mColorLabel">
+            <property name="text">
+             <string>Color</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QComboBox" name="mColorAttributeComboBox"/>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="mBoldLabel">
+            <property name="text">
+             <string>Bold</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QComboBox" name="mBoldAttributeComboBox"/>
+          </item>
+          <item row="3" column="0">
+           <widget class="QLabel" name="mItalicLabel">
+            <property name="text">
+             <string>Italic</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1">
+           <widget class="QComboBox" name="mItalicAttributeComboBox"/>
+          </item>
+          <item row="4" column="0">
+           <widget class="QLabel" name="mUnderlineLabel">
+            <property name="text">
+             <string>Underline</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="1">
+           <widget class="QComboBox" name="mUnderlineAttributeComboBox"/>
+          </item>
+          <item row="5" column="0">
+           <widget class="QLabel" name="mStrikeoutLabel">
+            <property name="text">
+             <string>Strikeout</string>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="1">
+           <widget class="QComboBox" name="mStrikeoutAttributeComboBox"/>
+          </item>
+          <item row="6" column="0">
+           <widget class="QLabel" name="mFontFamilyLabel">
+            <property name="text">
+             <string>Font family</string>
+            </property>
+           </widget>
+          </item>
+          <item row="6" column="1">
+           <widget class="QComboBox" name="mFontFamilyAttributeComboBox"/>
+          </item>
          </layout>
         </widget>
        </item>
@@ -834,35 +875,100 @@
          <property name="title">
           <string>Buffer properties</string>
          </property>
-         <layout class="QGridLayout" name="gridLayout_3">
+         <layout class="QGridLayout" name="gridLayout_2">
           <item row="0" column="0">
-           <layout class="QGridLayout" name="gridLayout_2">
-            <item row="0" column="0">
-             <widget class="QLabel" name="mBufferSizeLabel">
-              <property name="text">
-               <string>Buffer size</string>
-              </property>
-             </widget>
-            </item>
-            <item row="0" column="1">
-             <widget class="QComboBox" name="mBufferSizeAttributeComboBox"/>
-            </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="mBufferColorLabel">
-              <property name="text">
-               <string>Buffer color</string>
-              </property>
-             </widget>
-            </item>
-            <item row="1" column="1">
-             <widget class="QComboBox" name="mBufferColorAttributeComboBox"/>
-            </item>
-           </layout>
+           <widget class="QLabel" name="mBufferSizeLabel">
+            <property name="text">
+             <string>Buffer size</string>
+            </property>
+           </widget>
           </item>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="mBufferSizeAttributeComboBox"/>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLabel" name="mBufferColorLabel">
+            <property name="text">
+             <string>Buffer color</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QComboBox" name="mBufferColorAttributeComboBox"/>
+          </item>
          </layout>
         </widget>
        </item>
        <item row="2" column="0">
+        <widget class="QGroupBox" name="mPositionAttributeGroupBox">
+         <property name="title">
+          <string>Position</string>
+         </property>
+         <layout class="QGridLayout" name="gridLayout_4">
+          <item row="1" column="0">
+           <widget class="QLabel" name="mXCoordinateLabel">
+            <property name="text">
+             <string>X Coordinate</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QComboBox" name="mXCoordinateComboBox"/>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="mYCoordinateLabel">
+            <property name="text">
+             <string>Y Coordinate</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QComboBox" name="mYCoordinateComboBox"/>
+          </item>
+          <item row="3" column="0">
+           <widget class="QLabel" name="mHorizontalAlignmentLabel">
+            <property name="text">
+             <string>Horizontal alignment</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1">
+           <widget class="QComboBox" name="mHorizontalAlignmentComboBox"/>
+          </item>
+          <item row="4" column="0">
+           <widget class="QLabel" name="mVerticalAlignmentLabel">
+            <property name="text">
+             <string>Vertical alignment</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="1">
+           <widget class="QComboBox" name="mVerticalAlignmentComboBox"/>
+          </item>
+          <item row="5" column="1">
+           <widget class="QComboBox" name="mRotationComboBox"/>
+          </item>
+          <item row="5" column="0">
+           <widget class="QLabel" name="mRotationLabel">
+            <property name="text">
+             <string>Rotation</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QComboBox" name="mLabelDistanceComboBox"/>
+          </item>
+          <item row="0" column="0">
+           <widget class="QLabel" name="mLabelDistanceLabel">
+            <property name="text">
+             <string>Label distance</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item row="3" column="0">
         <spacer name="verticalSpacer">
          <property name="orientation">
           <enum>Qt::Vertical</enum>



More information about the QGIS-commit mailing list