[QGIS Commit] r12777 - in trunk/qgis/src: core/symbology-ng gui/symbology-ng ui/symbollayer

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sat Jan 16 07:55:18 EST 2010


Author: mhugent
Date: 2010-01-16 07:55:17 -0500 (Sat, 16 Jan 2010)
New Revision: 12777

Added:
   trunk/qgis/src/ui/symbollayer/widget_svgfill.ui
Modified:
   trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.cpp
   trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.h
   trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.cpp
   trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.h
   trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp
   trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.cpp
   trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.h
   trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp
Log:
[FEATURE]: SVG fill symbol layer for polygon textures

Modified: trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.cpp	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.cpp	2010-01-16 12:55:17 UTC (rev 12777)
@@ -64,22 +64,7 @@
   p->setBrush( mBrush );
   p->setPen( mPen );
 
-  if ( rings == NULL )
-  {
-    // simple polygon without holes
-    p->drawPolygon( points );
-  }
-  else
-  {
-    // polygon with holes must be drawn using painter path
-    QPainterPath path;
-    path.addPolygon( points );
-    QList<QPolygonF>::iterator it;
-    for ( it = rings->begin(); it != rings->end(); ++it )
-      path.addPolygon( *it );
-
-    p->drawPath( path );
-  }
+  _renderPolygon( p, points, rings );
 }
 
 QgsStringMap QgsSimpleFillSymbolLayerV2::properties() const
@@ -97,3 +82,212 @@
 {
   return new QgsSimpleFillSymbolLayerV2( mColor, mBrushStyle, mBorderColor, mBorderStyle, mBorderWidth );
 }
+
+//QgsSVGFillSymbolLayer
+#include <QFile>
+#include <QSvgRenderer>
+
+QgsSVGFillSymbolLayer::QgsSVGFillSymbolLayer( const QString& svgFilePath, double width ): mPatternWidth( width ), mOutline( 0 )
+{
+  setSvgFilePath( svgFilePath );
+  mOutlineWidth = 0.3;
+  setSubSymbol( new QgsLineSymbolV2() );
+}
+
+QgsSVGFillSymbolLayer::QgsSVGFillSymbolLayer( const QByteArray& svgData, double width ): mSvgData( svgData ), mPatternWidth( width ), mOutline( 0 )
+{
+  storeViewBox();
+  mOutlineWidth = 0.3;
+  setSubSymbol( new QgsLineSymbolV2() );
+}
+
+QgsSVGFillSymbolLayer::~QgsSVGFillSymbolLayer()
+{
+  delete mOutline;
+}
+
+void QgsSVGFillSymbolLayer::setSvgFilePath( const QString& svgPath )
+{
+  QFile svgFile( svgPath );
+  if ( svgFile.open( QFile::ReadOnly ) )
+  {
+    mSvgData = svgFile.readAll();
+    storeViewBox();
+  }
+  mSvgFilePath = svgPath;
+}
+
+QgsSymbolLayerV2* QgsSVGFillSymbolLayer::create( const QgsStringMap& properties )
+{
+  QByteArray data;
+  double width = 20;
+  QString svgFilePath;
+
+
+  if ( properties.contains( "width" ) )
+  {
+    width = properties["width"].toDouble();
+  }
+  if ( properties.contains( "svgFile" ) )
+  {
+    svgFilePath = properties["svgFile"];
+  }
+
+  if ( !svgFilePath.isEmpty() )
+  {
+    return new QgsSVGFillSymbolLayer( svgFilePath, width );
+  }
+  else
+  {
+    if ( properties.contains( "data" ) )
+    {
+      data = QByteArray::fromHex( properties["data"].toLocal8Bit() );
+    }
+
+    return new QgsSVGFillSymbolLayer( data, width );
+  }
+}
+
+QString QgsSVGFillSymbolLayer::layerType() const
+{
+  return "SVGFill";
+}
+
+void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
+{
+  if ( mSvgViewBox.isNull() )
+  {
+    return;
+  }
+
+  //create QImage with appropriate dimensions
+  int pixelWidth = context.outputPixelSize( mPatternWidth );//mPatternWidth.value( context, QgsOutputUnit::Pixel );
+  int pixelHeight = pixelWidth / mSvgViewBox.width() * mSvgViewBox.height();
+
+  QImage textureImage( pixelWidth, pixelHeight, QImage::Format_ARGB32_Premultiplied );
+  textureImage.fill( QColor( 255, 255, 255, 0 ).rgba() );
+
+  //rasterise byte array to image
+  QPainter p( &textureImage );
+  QSvgRenderer r( mSvgData );
+  if ( !r.isValid() )
+  {
+    return;
+  }
+  r.render( &p );
+
+  QTransform brushTransform;
+  brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
+  mBrush.setTextureImage( textureImage );
+  mBrush.setTransform( brushTransform );
+
+  if ( mOutline )
+  {
+    mOutline->startRender( context.renderContext() );
+  }
+}
+
+void QgsSVGFillSymbolLayer::stopRender( QgsSymbolV2RenderContext& context )
+{
+  if ( mOutline )
+  {
+    mOutline->stopRender( context.renderContext() );
+  }
+}
+
+void QgsSVGFillSymbolLayer::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
+{
+  QPainter* p = context.renderContext().painter();
+  if ( !p )
+  {
+    return;
+  }
+  p->setBrush( mBrush );
+  p->setPen( QPen( Qt::NoPen ) );
+  _renderPolygon( p, points, rings );
+  if ( mOutline )
+  {
+    mOutline->renderPolyline( points, context.renderContext() );
+    if ( rings )
+    {
+      QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
+      for ( ; ringIt != rings->constEnd(); ++ringIt )
+      {
+        mOutline->renderPolyline( *ringIt, context.renderContext() );
+      }
+    }
+  }
+}
+
+QgsStringMap QgsSVGFillSymbolLayer::properties() const
+{
+  QgsStringMap map;
+  if ( !mSvgFilePath.isEmpty() )
+  {
+    map.insert( "svgFile", mSvgFilePath );
+  }
+  else
+  {
+    map.insert( "data", QString( mSvgData.toHex() ) );
+  }
+
+  map.insert( "width", QString::number( mPatternWidth ) );
+  return map;
+}
+
+QgsSymbolLayerV2* QgsSVGFillSymbolLayer::clone() const
+{
+  QgsSymbolLayerV2* clonedLayer = 0;
+  if ( !mSvgFilePath.isEmpty() )
+  {
+    clonedLayer = new QgsSVGFillSymbolLayer( mSvgFilePath, mPatternWidth );
+  }
+  else
+  {
+    clonedLayer = new QgsSVGFillSymbolLayer( mSvgData, mPatternWidth );
+  }
+
+  if ( mOutline )
+  {
+    clonedLayer->setSubSymbol( mOutline->clone() );
+  }
+  return clonedLayer;
+}
+
+void QgsSVGFillSymbolLayer::storeViewBox()
+{
+  if ( !mSvgData.isEmpty() )
+  {
+    QSvgRenderer r( mSvgData );
+    if ( r.isValid() )
+    {
+      mSvgViewBox = r.viewBoxF();
+      return;
+    }
+  }
+
+  mSvgViewBox = QRectF();
+  return;
+}
+
+bool QgsSVGFillSymbolLayer::setSubSymbol( QgsSymbolV2* symbol )
+{
+
+  if ( !symbol || symbol->type() != QgsSymbolV2::Line )
+  {
+    delete symbol;
+    return false;
+  }
+
+
+  QgsLineSymbolV2* lineSymbol = dynamic_cast<QgsLineSymbolV2*>( symbol );
+  if ( lineSymbol )
+  {
+    delete mOutline;
+    mOutline = lineSymbol;
+    return true;
+  }
+
+  delete symbol;
+  return false;
+}

Modified: trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.h
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.h	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/core/symbology-ng/qgsfillsymbollayerv2.h	2010-01-16 12:55:17 UTC (rev 12777)
@@ -61,4 +61,58 @@
     QPen mPen;
 };
 
+/**A class for svg fill patterns. The class automatically scales the pattern to
+   the appropriate pixel dimensions of the output device*/
+class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
+{
+  public:
+    QgsSVGFillSymbolLayer( const QString& svgFilePath = "", double width = 20 );
+    QgsSVGFillSymbolLayer( const QByteArray& svgData, double width = 20 );
+    ~QgsSVGFillSymbolLayer();
+
+    static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
+
+    // implemented from base classes
+
+    QString layerType() const;
+
+    void startRender( QgsSymbolV2RenderContext& context );
+    void stopRender( QgsSymbolV2RenderContext& context );
+
+    void renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
+
+    QgsStringMap properties() const;
+
+    QgsSymbolLayerV2* clone() const;
+
+    //gettersn and setters
+    void setSvgFilePath( const QString& svgPath );
+    QString svgFilePath() const { return mSvgFilePath; }
+    void setPatternWidth( double width ) { mPatternWidth = width;}
+    double patternWidth() const { return mPatternWidth; }
+
+    QgsSymbolV2* subSymbol() { return mOutline; }
+    bool setSubSymbol( QgsSymbolV2* symbol );
+
+  protected:
+    /**Width of the pattern (in QgsSymbolV2 output units)*/
+    double mPatternWidth;
+    /**SVG data*/
+    QByteArray mSvgData;
+    /**Path to the svg file (or empty if constructed directly from data)*/
+    QString mSvgFilePath;
+    /**SVG view box (to keep the aspect ratio */
+    QRectF mSvgViewBox;
+    /**Brush that receives rendered pixel image in startRender() method*/
+    QBrush mBrush;
+    /**Outline width*/
+    double mOutlineWidth;
+    /**Custom outline*/
+    QgsLineSymbolV2* mOutline;
+
+  private:
+    /**Helper function that gets the view box from the byte array*/
+    void storeViewBox();
+};
+
 #endif

Modified: trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.cpp	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.cpp	2010-01-16 12:55:17 UTC (rev 12777)
@@ -4,6 +4,7 @@
 #include "qgsrendercontext.h"
 
 #include <QSize>
+#include <QPainter>
 #include <QPointF>
 #include <QPolygonF>
 
@@ -50,3 +51,30 @@
   renderPolygon( poly, NULL, context );
   stopRender( context );
 }
+
+void QgsFillSymbolLayerV2::_renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings )
+{
+  if ( !p )
+  {
+    return;
+  }
+
+  if ( rings == NULL )
+  {
+    // simple polygon without holes
+    p->drawPolygon( points );
+  }
+  else
+  {
+    // polygon with holes must be drawn using painter path
+    QPainterPath path;
+    path.addPolygon( points );
+    QList<QPolygonF>::const_iterator it = rings->constBegin();
+    for ( ; it != rings->constEnd(); ++it )
+    {
+      path.addPolygon( *it );
+    }
+
+    p->drawPath( path );
+  }
+}

Modified: trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.h
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.h	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/core/symbology-ng/qgssymbollayerv2.h	2010-01-16 12:55:17 UTC (rev 12777)
@@ -114,6 +114,8 @@
 
   protected:
     QgsFillSymbolLayerV2( bool locked = false );
+    /**Default method to render polygon*/
+    void _renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings );
 };
 
 class QgsSymbolLayerV2Widget;

Modified: trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/core/symbology-ng/qgssymbollayerv2registry.cpp	2010-01-16 12:55:17 UTC (rev 12777)
@@ -24,11 +24,13 @@
 
   addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SimpleFill", QgsSymbolV2::Fill,
                       QgsSimpleFillSymbolLayerV2::create ) );
+
+  addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SVGFill", QgsSymbolV2::Fill, QgsSVGFillSymbolLayer::create ) );
 }
 
 QgsSymbolLayerV2Registry::~QgsSymbolLayerV2Registry()
 {
-  foreach (QString name, mMetadata.keys())
+  foreach( QString name, mMetadata.keys() )
   {
     delete mMetadata[name];
   }
@@ -91,7 +93,7 @@
   QMap<QString, QgsSymbolLayerV2AbstractMetadata*>::ConstIterator it = mMetadata.begin();
   for ( ; it != mMetadata.end(); ++it )
   {
-    if ( (*it)->type() == type )
+    if (( *it )->type() == type )
       lst.append( it.key() );
   }
   return lst;

Modified: trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.cpp
===================================================================
--- trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.cpp	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.cpp	2010-01-16 12:55:17 UTC (rev 12777)
@@ -498,3 +498,116 @@
   btnChangeColor->setColor( mLayer->color() );
   emit changed();
 }
+
+/////////////
+
+#include <QFileDialog>
+
+QgsSVGFillSymbolLayerWidget::QgsSVGFillSymbolLayerWidget( QWidget* parent ): QgsSymbolLayerV2Widget( parent )
+{
+  mLayer = 0;
+  setupUi( this );
+  insertIcons();
+}
+
+void QgsSVGFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer )
+{
+  if ( !layer )
+  {
+    return;
+  }
+
+  if ( layer->layerType() != "SVGFill" )
+  {
+    return;
+  }
+
+  mLayer = dynamic_cast<QgsSVGFillSymbolLayer*>( layer );
+  if ( mLayer )
+  {
+    double width = mLayer->patternWidth();
+    mTextureWidthSpinBox->setValue( width );
+    mSVGLineEdit->setText( mLayer->svgFilePath() );
+  }
+}
+
+QgsSymbolLayerV2* QgsSVGFillSymbolLayerWidget::symbolLayer()
+{
+  return mLayer;
+}
+
+void QgsSVGFillSymbolLayerWidget::on_mBrowseToolButton_clicked()
+{
+  QString filePath = QFileDialog::getOpenFileName( 0, tr( "Select svg texture file" ) );
+  if ( !filePath.isNull() )
+  {
+    mSVGLineEdit->setText( filePath );
+    emit changed();
+  }
+}
+
+void QgsSVGFillSymbolLayerWidget::on_mTextureWidthSpinBox_valueChanged( double d )
+{
+  if ( mLayer )
+  {
+    mLayer->setPatternWidth( d );
+    emit changed();
+  }
+}
+
+void QgsSVGFillSymbolLayerWidget::on_mSVGLineEdit_textChanged( const QString & text )
+{
+  if ( !mLayer )
+  {
+    return;
+  }
+
+  QFileInfo fi( text );
+  if ( !fi.exists() )
+  {
+    return;
+  }
+  mLayer->setSvgFilePath( text );
+  emit changed();
+}
+
+void QgsSVGFillSymbolLayerWidget::on_mSvgListWidget_itemActivated( QListWidgetItem* item )
+{
+  mSVGLineEdit->setText( item->data( Qt::UserRole ).toString() );
+}
+
+void QgsSVGFillSymbolLayerWidget::insertIcons()
+{
+  mSvgListWidget->clear();
+
+  QStringList svgFiles = QgsSvgMarkerSymbolLayerV2::listSvgFiles();
+  QSvgRenderer renderer;
+  QPainter painter;
+
+  QStringList::const_iterator it = svgFiles.constBegin();
+  for ( ; it != svgFiles.constEnd(); ++it )
+  {
+    renderer.load( *it );
+    QPixmap pixmap( renderer.defaultSize() );
+    pixmap.fill();
+    painter.begin( &pixmap );
+    renderer.render( &painter );
+    painter.end();
+
+    QListWidgetItem* item = new QListWidgetItem( mSvgListWidget );
+    item->setData( Qt::UserRole, *it );
+    item->setIcon( QIcon( pixmap ) );
+    item->setToolTip( *it );
+  }
+}
+
+void QgsSVGFillSymbolLayerWidget::on_mChangeOutlinePushButton_clicked()
+{
+  QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), this );
+  if ( dlg.exec() == 0 )
+  {
+    return;
+  }
+
+  emit changed();
+}

Modified: trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.h
===================================================================
--- trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.h	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/gui/symbology-ng/qgssymbollayerv2widget.h	2010-01-16 12:55:17 UTC (rev 12777)
@@ -206,5 +206,38 @@
     QgsLineDecorationSymbolLayerV2* mLayer;
 };
 
+//////////
 
+#include "ui_widget_svgfill.h"
+
+class QgsSVGFillSymbolLayer;
+
+class GUI_EXPORT QgsSVGFillSymbolLayerWidget : public QgsSymbolLayerV2Widget, private Ui::WidgetSVGFill
+{
+    Q_OBJECT
+
+  public:
+    QgsSVGFillSymbolLayerWidget( QWidget* parent = NULL );
+
+    static QgsSymbolLayerV2Widget* create() { return new QgsSVGFillSymbolLayerWidget(); }
+
+    // from base class
+    virtual void setSymbolLayer( QgsSymbolLayerV2* layer );
+    virtual QgsSymbolLayerV2* symbolLayer();
+
+  protected:
+    QgsSVGFillSymbolLayer* mLayer;
+    //sets new output unit. Is called on combo box or spin box change
+    void setOutputUnit();
+    void insertIcons();
+
+  private slots:
+    void on_mBrowseToolButton_clicked();
+    void on_mTextureWidthSpinBox_valueChanged( double d );
+    void on_mSVGLineEdit_textChanged( const QString & text );
+    void on_mSvgListWidget_itemActivated( QListWidgetItem* item );
+    void on_mChangeOutlinePushButton_clicked();
+};
+
+
 #endif

Modified: trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp
===================================================================
--- trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp	2010-01-16 11:43:46 UTC (rev 12776)
+++ trunk/qgis/src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp	2010-01-16 12:55:17 UTC (rev 12777)
@@ -74,26 +74,26 @@
 {
   QgsSymbolLayerV2Registry* reg = QgsSymbolLayerV2Registry::instance();
 
-  QgsSymbolLayerV2AbstractMetadata* abstractMetadata = reg->symbolLayerMetadata(name);
-  if (abstractMetadata == NULL)
+  QgsSymbolLayerV2AbstractMetadata* abstractMetadata = reg->symbolLayerMetadata( name );
+  if ( abstractMetadata == NULL )
   {
-    QgsDebugMsg("Failed to find symbol layer's entry in registry: "+name);
+    QgsDebugMsg( "Failed to find symbol layer's entry in registry: " + name );
     return false;
   }
-  QgsSymbolLayerV2Metadata* metadata = dynamic_cast<QgsSymbolLayerV2Metadata*>(abstractMetadata);
-  if (metadata == NULL)
+  QgsSymbolLayerV2Metadata* metadata = dynamic_cast<QgsSymbolLayerV2Metadata*>( abstractMetadata );
+  if ( metadata == NULL )
   {
-    QgsDebugMsg("Failed to cast symbol layer's metadata: "+name);
+    QgsDebugMsg( "Failed to cast symbol layer's metadata: " + name );
     return false;
   }
-  metadata->setWidgetFunction(f);
+  metadata->setWidgetFunction( f );
   return true;
 }
 
 static void _initWidgetFunctions()
 {
   static bool initialized = false;
-  if (initialized)
+  if ( initialized )
     return;
 
   _initWidgetFunction( "SimpleLine", QgsSimpleLineSymbolLayerV2Widget::create );
@@ -104,6 +104,7 @@
   _initWidgetFunction( "SvgMarker", QgsSvgMarkerSymbolLayerV2Widget::create );
 
   _initWidgetFunction( "SimpleFill", QgsSimpleFillSymbolLayerV2Widget::create );
+  _initWidgetFunction( "SVGFill", QgsSVGFillSymbolLayerWidget::create );
 
   initialized = true;
 }

Added: trunk/qgis/src/ui/symbollayer/widget_svgfill.ui
===================================================================
--- trunk/qgis/src/ui/symbollayer/widget_svgfill.ui	                        (rev 0)
+++ trunk/qgis/src/ui/symbollayer/widget_svgfill.ui	2010-01-16 12:55:17 UTC (rev 12777)
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WidgetSVGFill</class>
+ <widget class="QWidget" name="WidgetSVGFill">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>211</width>
+    <height>199</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="mTextureWidthLabel">
+       <property name="text">
+        <string>Texture width:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDoubleSpinBox" name="mTextureWidthSpinBox">
+       <property name="maximum">
+        <double>99999999.000000000000000</double>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_4">
+     <item>
+      <widget class="QLabel" name="mOutlineLabel">
+       <property name="text">
+        <string>Outline:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="mChangeOutlinePushButton">
+       <property name="text">
+        <string>Change</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="0">
+    <widget class="QListWidget" name="mSvgListWidget">
+     <property name="flow">
+      <enum>QListView::LeftToRight</enum>
+     </property>
+     <property name="viewMode">
+      <enum>QListView::IconMode</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLineEdit" name="mSVGLineEdit"/>
+     </item>
+     <item>
+      <widget class="QToolButton" name="mBrowseToolButton">
+       <property name="text">
+        <string>...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>



More information about the QGIS-commit mailing list