[QGIS Commit] r14107 - in branches/table_join_branch: images images/themes/default/propertyicons src/app src/core src/providers/ogr src/ui

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Aug 18 16:31:17 EDT 2010


Author: mhugent
Date: 2010-08-18 20:31:17 +0000 (Wed, 18 Aug 2010)
New Revision: 14107

Added:
   branches/table_join_branch/images/themes/default/propertyicons/join.png
Modified:
   branches/table_join_branch/images/images.qrc
   branches/table_join_branch/src/app/qgsaddjoindialog.cpp
   branches/table_join_branch/src/app/qgsaddjoindialog.h
   branches/table_join_branch/src/app/qgsvectorlayerproperties.cpp
   branches/table_join_branch/src/core/qgsproject.cpp
   branches/table_join_branch/src/core/qgsvectorlayer.cpp
   branches/table_join_branch/src/core/qgsvectorlayer.h
   branches/table_join_branch/src/providers/ogr/qgsogrprovider.cpp
   branches/table_join_branch/src/ui/qgsaddjoindialogbase.ui
   branches/table_join_branch/src/ui/qgsvectorlayerpropertiesbase.ui
Log:
Added possibility to cache join layer in memory. Still experimental code

Modified: branches/table_join_branch/images/images.qrc
===================================================================
--- branches/table_join_branch/images/images.qrc	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/images/images.qrc	2010-08-18 20:31:17 UTC (rev 14107)
@@ -257,6 +257,7 @@
     <file>themes/default/propertyicons/digitising.png</file>
     <file>themes/default/propertyicons/general.png</file>
     <file>themes/default/propertyicons/histogram.png</file>
+    <file>themes/default/propertyicons/join.png</file>
     <file>themes/default/propertyicons/labels.png</file>
     <file>themes/default/propertyicons/locale.png</file>
     <file>themes/default/propertyicons/map_tools.png</file>

Added: branches/table_join_branch/images/themes/default/propertyicons/join.png
===================================================================
(Binary files differ)


Property changes on: branches/table_join_branch/images/themes/default/propertyicons/join.png
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Modified: branches/table_join_branch/src/app/qgsaddjoindialog.cpp
===================================================================
--- branches/table_join_branch/src/app/qgsaddjoindialog.cpp	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/app/qgsaddjoindialog.cpp	2010-08-18 20:31:17 UTC (rev 14107)
@@ -58,6 +58,8 @@
   {
     mTargetFieldComboBox->addItem(fieldIt.value().name(), fieldIt.key() );
   }
+
+  mCacheInMemoryCheckBox->setChecked( true );
 }
 
 QgsAddJoinDialog::~QgsAddJoinDialog()
@@ -89,6 +91,11 @@
    return mTargetFieldComboBox->itemText( mTargetFieldComboBox->currentIndex() );
 }
 
+bool QgsAddJoinDialog::cacheInMemory() const
+{
+  return mCacheInMemoryCheckBox->isChecked();
+}
+
 bool QgsAddJoinDialog::createAttributeIndex() const
 {
   return mCreateIndexCheckBox->isChecked();
@@ -121,7 +128,6 @@
   if( dp && (dp->capabilities() & QgsVectorDataProvider::CreateAttributeIndex) )
   {
     mCreateIndexCheckBox->setEnabled( true );
-    mCreateIndexCheckBox->setChecked( true );
   }
   else
   {

Modified: branches/table_join_branch/src/app/qgsaddjoindialog.h
===================================================================
--- branches/table_join_branch/src/app/qgsaddjoindialog.h	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/app/qgsaddjoindialog.h	2010-08-18 20:31:17 UTC (rev 14107)
@@ -40,6 +40,8 @@
     int targetField() const;
     /**Returns the name of the target field (join-to field)*/
     QString targetFieldName() const;
+    /**True if joined layer should be cached in virtual memory*/
+    bool cacheInMemory() const;
     /**Returns true if user wants to create an attribute index on the join field*/
     bool createAttributeIndex() const;
 

Modified: branches/table_join_branch/src/app/qgsvectorlayerproperties.cpp
===================================================================
--- branches/table_join_branch/src/app/qgsvectorlayerproperties.cpp	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/app/qgsvectorlayerproperties.cpp	2010-08-18 20:31:17 UTC (rev 14107)
@@ -1190,7 +1190,7 @@
         }
       }
 
-      layer->addJoin( info );
+      layer->addJoin( info, d.cacheInMemory() );
       loadRows(); //update attribute tab
       addJoinToTreeWidget( info );
     }

Modified: branches/table_join_branch/src/core/qgsproject.cpp
===================================================================
--- branches/table_join_branch/src/core/qgsproject.cpp	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/core/qgsproject.cpp	2010-08-18 20:31:17 UTC (rev 14107)
@@ -736,13 +736,14 @@
     emit layerLoaded( i + 1, nl.count() );
   }
 
-  //Update field map of layers with joins.
+  //Update field map of layers with joins and create join caches if necessary
   //Needs to be done here once all dependent layers are loaded
   QList<QgsVectorLayer*>::iterator vIt = vLayerList.begin();
   for(; vIt != vLayerList.end(); ++vIt )
   {
     if( (*vIt)->vectorJoins().size() > 0 )
     {
+      (*vIt)->createJoinCaches();
       (*vIt)->updateFieldMap();
     }
   }

Modified: branches/table_join_branch/src/core/qgsvectorlayer.cpp
===================================================================
--- branches/table_join_branch/src/core/qgsvectorlayer.cpp	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/core/qgsvectorlayer.cpp	2010-08-18 20:31:17 UTC (rev 14107)
@@ -1486,31 +1486,8 @@
           continue;
         }
 
-        //set subset string
-        QString bkSubsetString = joinLayer->dataProvider()->subsetString(); //provider might already have a subset string
-        QString subsetString;
-        if( !bkSubsetString.isEmpty() )
-        {
-          subsetString.append(" AND ");
-        }
-        subsetString.append( "\"" + joinFieldName + "\"" + " = " + "\"" + targetFieldValue.toString() + "\"" );
-        joinLayer->dataProvider()->setSubsetString( subsetString, false );
+        addJoinedFeatureAttributes( f, *joinIt, joinFieldName, targetFieldValue, joinLayer->pendingAllAttributesList(), index );
 
-        //select (no geometry)
-        joinLayer->select( joinLayer->pendingAllAttributesList(), QgsRectangle(), false, false );
-
-        //get first feature
-        QgsFeature fet;
-        if( joinLayer->nextFeature( fet ) )
-        {
-          QgsAttributeMap attMap = fet.attributeMap();
-          QgsAttributeMap::const_iterator attIt = attMap.constBegin();
-          for(; attIt != attMap.constEnd(); ++attIt )
-          {
-            f.addAttribute( attIt.key() + index, attIt.value() );
-          }
-        }
-        joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
         maxIndex( joinLayer->pendingFields(), currentMaxIndex );
         index += ( currentMaxIndex + 1 );
       }
@@ -1526,44 +1503,19 @@
           continue;
         }
 
-        QString joinFieldName = joinLayer->pendingFields().value( joinIt.value().joinInfo.joinField ).name();
+        QString joinFieldName = joinLayer->pendingFields().value( joinIt.value().joinInfo->joinField ).name();
         if( joinFieldName.isEmpty() )
         {
           continue;
         }
 
-        QVariant targetFieldValue = f.attributeMap().value( joinIt->joinInfo.targetField );
+        QVariant targetFieldValue = f.attributeMap().value( joinIt->joinInfo->targetField );
         if( !targetFieldValue.isValid() )
         {
           continue;
         }
 
-        //set subset string
-        QString bkSubsetString = joinLayer->dataProvider()->subsetString(); //provider might already have a subset string
-        QString subsetString;
-        if( !bkSubsetString.isEmpty() )
-        {
-          subsetString.append(" AND ");
-        }
-        subsetString.append( "\"" + joinFieldName + "\"" + " = " + "\"" + targetFieldValue.toString() + "\"" );
-        joinLayer->dataProvider()->setSubsetString( subsetString, false );
-
-        //select (no geometry)
-        joinLayer->select( joinIt.value().attributes, QgsRectangle(), false, false );
-
-        //get first feature
-        QgsFeature fet;
-        if( joinLayer->nextFeature( fet ) )
-        {
-          QgsAttributeMap attMap = fet.attributeMap();
-          QgsAttributeMap::const_iterator attIt = attMap.constBegin();
-          for(; attIt != attMap.constEnd(); ++attIt )
-          {
-            f.addAttribute( attIt.key() + joinIt.value().indexOffset, attIt.value() );
-          }
-        }
-
-      joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
+        addJoinedFeatureAttributes( f, *(joinIt.value().joinInfo), joinFieldName, targetFieldValue, joinIt.value().attributes, joinIt.value().indexOffset );
       }
     }
   }
@@ -1592,6 +1544,73 @@
       f.changeAttribute( it.key(), QVariant( QString::null ) );
 }
 
+void QgsVectorLayer::addJoinedFeatureAttributes( QgsFeature& f, const QgsVectorJoinInfo& joinInfo, const QString& joinFieldName,
+                                                 const QVariant& joinValue, const QgsAttributeList& attributes, int attributeIndexOffset )
+{
+  const QHash< QString, QgsAttributeMap>& memoryCache = joinInfo.cachedAttributes;
+  if( !memoryCache.isEmpty() ) //use join memory cache
+  {
+    QgsAttributeMap featureAttributes = memoryCache.value( joinValue.toString() );
+    bool found = !featureAttributes.isEmpty();
+    QgsAttributeList::const_iterator attIt = attributes.constBegin();
+    for(; attIt != attributes.constEnd(); ++attIt )
+    {
+      if( found )
+      {
+        f.addAttribute( *attIt + attributeIndexOffset, featureAttributes.value( *attIt ) );
+      }
+      else
+      {
+        f.addAttribute( *attIt + attributeIndexOffset, QVariant() );
+      }
+    }
+  }
+  else //work with subset string
+  {
+    QgsVectorLayer* joinLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) );
+    if( !joinLayer )
+    {
+      return;
+    }
+
+    //no memory cache, query the joined values by setting substring
+    QString subsetString = joinLayer->dataProvider()->subsetString(); //provider might already have a subset string
+    QString bkSubsetString = subsetString;
+    if( !subsetString.isEmpty() )
+    {
+      subsetString.append(" AND ");
+    }
+
+    subsetString.append( "\"" + joinFieldName + "\"" + " = " + "\"" + joinValue.toString() + "\"" );
+    joinLayer->dataProvider()->setSubsetString( subsetString, false );
+
+    //select (no geometry)
+    joinLayer->select( attributes, QgsRectangle(), false, false );
+
+    //get first feature
+    QgsFeature fet;
+    if( joinLayer->nextFeature( fet ) )
+    {
+      QgsAttributeMap attMap = fet.attributeMap();
+      QgsAttributeMap::const_iterator attIt = attMap.constBegin();
+      for(; attIt != attMap.constEnd(); ++attIt )
+      {
+        f.addAttribute( attIt.key() + attributeIndexOffset, attIt.value() );
+      }
+    }
+    else //no suitable join feature found, insert invalid variants
+    {
+      QgsAttributeList::const_iterator attIt = attributes.constBegin();
+      for(; attIt != attributes.constEnd(); ++attIt )
+      {
+        f.addAttribute( *attIt + attributeIndexOffset, QVariant() );
+      }
+    }
+
+    joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
+  }
+}
+
 void QgsVectorLayer::updateFeatureGeometry( QgsFeature &f )
 {
   if ( mChangedGeometries.contains( f.id() ) )
@@ -1632,21 +1651,21 @@
           }
         else
         {
-          QgsVectorJoinInfo joinInfo;
           int indexOffset;
-          if( joinForFieldIndex( *it, joinInfo, indexOffset ) )
+          const QgsVectorJoinInfo* joinInfo= joinForFieldIndex( *it, indexOffset );
+          if( joinInfo )
             {
-              QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) );
+              QgsVectorLayer* joinLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo->joinLayerId ) );
               if( joinLayer )
               {
                 mFetchJoinInfos[ joinLayer ].joinInfo = joinInfo;
                 mFetchJoinInfos[ joinLayer].attributes.push_back( *it - indexOffset ); //store provider index
                 mFetchJoinInfos[ joinLayer ].indexOffset = indexOffset;
                 //for joined fields, we always need to request the targetField from the provider too
-                if( !mFetchAttributes.contains( joinInfo.targetField ))
+                if( !mFetchAttributes.contains( joinInfo->targetField ))
                 {
-                  targetJoinFieldList << joinInfo.targetField;
-                  mFetchProvAttributes << joinInfo.targetField;
+                  targetJoinFieldList << joinInfo->targetField;
+                  mFetchProvAttributes << joinInfo->targetField;
                 }
               }
             }
@@ -2628,7 +2647,8 @@
       info.joinField = infoElem.attribute("joinField").toInt();
       info.joinLayerId = infoElem.attribute("joinLayerId");
       info.targetField = infoElem.attribute("targetField").toInt();
-      addJoin( info );
+      bool memoryCache = infoElem.attribute("memoryCache").toInt();
+      addJoin( info, memoryCache );
     }
   }
 
@@ -2787,6 +2807,7 @@
     joinElem.setAttribute( "targetField", joinIt->targetField );
     joinElem.setAttribute( "joinLayerId", joinIt->joinLayerId );
     joinElem.setAttribute( "joinField", joinIt->joinField);
+    joinElem.setAttribute( "memoryCache", !joinIt->cachedAttributes.isEmpty() );
     vectorJoinsElem.appendChild( joinElem );
   }
 
@@ -4746,9 +4767,50 @@
   return -1;
 }
 
-void QgsVectorLayer::addJoin( QgsVectorJoinInfo joinInfo )
+void QgsVectorLayer::cacheJoinLayer( QgsVectorJoinInfo& joinInfo )
 {
+    //memory cache not required or already done
+    if( !joinInfo.memoryCache || joinInfo.cachedAttributes.size() > 0 )
+    {
+        return;
+    }
+
+    QgsVectorLayer* cacheLayer = dynamic_cast<QgsVectorLayer*>(QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) );
+    if( cacheLayer )
+    {
+      joinInfo.cachedAttributes.clear();
+      cacheLayer->select( cacheLayer->pendingAllAttributesList(), QgsRectangle(), false, false );
+      QgsFeature f;
+      while( cacheLayer->nextFeature( f ) )
+      {
+        const QgsAttributeMap& map = f.attributeMap();
+        joinInfo.cachedAttributes.insert( map.value( joinInfo.joinField).toString(), map );
+      }
+    }
+}
+
+void QgsVectorLayer::addJoin( QgsVectorJoinInfo joinInfo, bool cacheInMemory )
+{
+  joinInfo.memoryCache = cacheInMemory;
   mVectorJoins.push_back( joinInfo );
+
+  //cache joined layer to virtual memory if specified by user
+  if( cacheInMemory )
+  {
+    cacheJoinLayer( mVectorJoins.last() );
+    /*QgsVectorLayer* cacheLayer = dynamic_cast<QgsVectorLayer*>(QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) );
+    if( cacheLayer )
+    {
+      cacheLayer->select( cacheLayer->pendingAllAttributesList(), QgsRectangle(), false, false );
+      QgsFeature f;
+      while( cacheLayer->nextFeature( f ) )
+      {
+        const QgsAttributeMap& map = f.attributeMap();
+        mVectorJoins.last().cachedAttributes.insert( map.value( joinInfo.joinField).toString(), map );
+      }
+    }*/
+  }
+
   updateFieldMap();
 }
 
@@ -4849,6 +4911,15 @@
   }
 }
 
+void QgsVectorLayer::createJoinCaches()
+{
+    QList< QgsVectorJoinInfo >::iterator joinIt = mVectorJoins.begin();
+    for(; joinIt != mVectorJoins.end(); ++joinIt)
+    {
+        cacheJoinLayer( *joinIt);
+    }
+}
+
 void QgsVectorLayer::stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer )
 {
   mRendererV2->stopRender( rendererContext );
@@ -4883,7 +4954,7 @@
   map.remove( oldIndex );
 }
 
-bool QgsVectorLayer::joinForFieldIndex( int index, QgsVectorJoinInfo& joinInfo, int& indexOffset ) const
+const QgsVectorJoinInfo* QgsVectorLayer::joinForFieldIndex( int index, int& indexOffset ) const
 {
   int currentMaxIndex = 0;
   int totIndex = 0;
@@ -4893,7 +4964,7 @@
   {
     if( mDataProvider->fields().contains( index ) )
     {
-      return false;
+      return 0;
     }
   }
   maxIndex( mDataProvider->fields(), totIndex );
@@ -4911,9 +4982,8 @@
 
     if( joinLayer->pendingFields().contains( index - totIndex ) )
     {
-      joinInfo = *joinIt;
       indexOffset = totIndex;
-      return true;
+      return &(*joinIt);
     }
 
     maxIndex(joinLayer->pendingFields(), currentMaxIndex );
@@ -4921,5 +4991,5 @@
   }
 
   //else an added field
-  return false;
+  return 0;
 }

Modified: branches/table_join_branch/src/core/qgsvectorlayer.h
===================================================================
--- branches/table_join_branch/src/core/qgsvectorlayer.h	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/core/qgsvectorlayer.h	2010-08-18 20:31:17 UTC (rev 14107)
@@ -62,11 +62,15 @@
   QString joinLayerId;
   /**Join field in the source layer*/
   int joinField;
+  /**True if the join is cached in virtual memory*/
+  bool memoryCache;
+  /**Cache for joined attributes to provide fast lookup (size is 0 if no memory caching)*/
+  QHash< QString, QgsAttributeMap> cachedAttributes;
 };
 
 struct QgsFetchJoinInfo
 {
-  QgsVectorJoinInfo joinInfo;
+  const QgsVectorJoinInfo* joinInfo;
   QgsAttributeList attributes; //attributes to fetch
   int indexOffset; //index offset between this layer and join layer
 };
@@ -144,8 +148,10 @@
     /** Setup the coordinate system tranformation for the layer */
     void setCoordinateSystem();
 
-    /**Joins another vector layer to this layer*/
-    void addJoin( QgsVectorJoinInfo joinInfo );
+    /**Joins another vector layer to this layer
+      @param joinInfo join object containing join layer id, target and source field
+      @param cacheInMemory if true: caches the content of the join layer in virtual memory*/
+    void addJoin( QgsVectorJoinInfo joinInfo, bool cacheInMemory = false );
 
     /**Removes  a vector layer join*/
     void removeJoin( const QString& joinLayerId );
@@ -585,6 +591,8 @@
       @note added in version 1.6*/
     void updateFieldMap();
 
+    /**Caches joined attributes if required (and not already done)*/
+    void createJoinCaches();
 
 
   public slots:
@@ -686,9 +694,19 @@
     /**Reads vertex marker size from settings*/
     static int currentVertexMarkerSize();
 
-    /**Update feature with uncommited attribute updates*/
+    /**Update feature with uncommited attribute updates and joined attributes*/
     void updateFeatureAttributes( QgsFeature &f, bool all = false );
 
+    /**Adds joined attributes to a feature
+      @param f the feature to add the attributes
+      @param joinInfo vector join
+      @param joinFieldName name of the (source) join Field
+      @param joinValue lookup value for join
+      @param attributes (join layer) attribute indices to add
+      @param attributeOffset index offset to get from join layer attribute index to layer index*/
+    void addJoinedFeatureAttributes( QgsFeature& f, const QgsVectorJoinInfo& joinInfo, const QString& joinFieldName, const QVariant& joinValue,
+                                     const QgsAttributeList& attributes, int attributeIndexOffset );
+
     /**Update feature with uncommited geometry updates*/
     void updateFeatureGeometry( QgsFeature &f );
 
@@ -715,12 +733,13 @@
     void updateAttributeMapIndex( QgsAttributeMap& map, int oldIndex, int newIndex ) const;
 
     /**Finds the vector join for a layer field index.
-      @param attribute index
-      @param info out: join info for the attribute
+      @param index this layers attribute index
       @param indexOffset out: offset between layer index and original provider index
-       @return true if the index belongs to a joined field, otherwise false (possibily provider field or added field)*/
-    bool joinForFieldIndex( int index, QgsVectorJoinInfo& info, int& indexOffset ) const;
+       @return pointer to the join if the index belongs to a joined field, otherwise 0 (possibily provider field or added field)*/
+    const QgsVectorJoinInfo* joinForFieldIndex( int index, int& indexOffset ) const;
 
+    /**Caches attributes of join layer in memory if QgsVectorJoinInfo.memoryCache is true (and the cache is not already there)*/
+    void cacheJoinLayer( QgsVectorJoinInfo& joinInfo );
 
   private:                       // Private attributes
 

Modified: branches/table_join_branch/src/providers/ogr/qgsogrprovider.cpp
===================================================================
--- branches/table_join_branch/src/providers/ogr/qgsogrprovider.cpp	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/providers/ogr/qgsogrprovider.cpp	2010-08-18 20:31:17 UTC (rev 14107)
@@ -1802,7 +1802,14 @@
 
 void QgsOgrProvider::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
 {
-  QgsField fld = mAttributeFields[index];
+  uniqueValues.clear();
+
+  QgsField fld = mAttributeFields.value( index );
+  if( fld.name().isNull() )
+  {
+    return; //not a provider field
+  }
+
   QString theLayerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrLayer ) );
 
   QString sql = QString( "SELECT DISTINCT %1 FROM %2" )
@@ -1816,8 +1823,6 @@
 
   sql += QString( " ORDER BY %1" ).arg( fld.name() );
 
-  uniqueValues.clear();
-
   QgsDebugMsg( QString( "SQL: %1" ).arg( sql ) );
   OGRLayerH l = OGR_DS_ExecuteSQL( ogrDataSource, mEncoding->fromUnicode( sql ).data(), NULL, "SQL" );
   if ( l == 0 )

Modified: branches/table_join_branch/src/ui/qgsaddjoindialogbase.ui
===================================================================
--- branches/table_join_branch/src/ui/qgsaddjoindialogbase.ui	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/ui/qgsaddjoindialogbase.ui	2010-08-18 20:31:17 UTC (rev 14107)
@@ -44,7 +44,7 @@
    <item row="2" column="1">
     <widget class="QComboBox" name="mTargetFieldComboBox"/>
    </item>
-   <item row="4" column="0" colspan="2">
+   <item row="5" column="0" colspan="2">
     <widget class="QDialogButtonBox" name="buttonBox">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
@@ -54,13 +54,20 @@
      </property>
     </widget>
    </item>
-   <item row="3" column="0" colspan="2">
+   <item row="4" column="0" colspan="2">
     <widget class="QCheckBox" name="mCreateIndexCheckBox">
      <property name="text">
       <string>Create attribute index on join field</string>
      </property>
     </widget>
    </item>
+   <item row="3" column="0" colspan="2">
+    <widget class="QCheckBox" name="mCacheInMemoryCheckBox">
+     <property name="text">
+      <string>Cache join layer in virtual memory</string>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <resources/>

Modified: branches/table_join_branch/src/ui/qgsvectorlayerpropertiesbase.ui
===================================================================
--- branches/table_join_branch/src/ui/qgsvectorlayerpropertiesbase.ui	2010-08-18 20:21:30 UTC (rev 14106)
+++ branches/table_join_branch/src/ui/qgsvectorlayerpropertiesbase.ui	2010-08-18 20:31:17 UTC (rev 14107)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>589</width>
+    <width>591</width>
     <height>426</height>
    </rect>
   </property>
@@ -302,8 +302,8 @@
            <rect>
             <x>0</x>
             <y>0</y>
-            <width>439</width>
-            <height>419</height>
+            <width>383</width>
+            <height>401</height>
            </rect>
           </property>
           <layout class="QGridLayout" name="gridLayout_3">
@@ -788,6 +788,10 @@
       <property name="text">
        <string>Joins</string>
       </property>
+      <property name="icon">
+       <iconset resource="../../images/images.qrc">
+        <normaloff>:/images/themes/default/propertyicons/join.png</normaloff>:/images/themes/default/propertyicons/join.png</iconset>
+      </property>
      </item>
      <item>
       <property name="text">



More information about the QGIS-commit mailing list