[QGIS Commit] r9437 - in trunk/qgis: python/core src/core src/core/raster src/core/renderer tests/src/core

svn_qgis at osgeo.org svn_qgis at osgeo.org
Mon Oct 6 09:00:45 EDT 2008


Author: jef
Date: 2008-10-06 09:00:45 -0400 (Mon, 06 Oct 2008)
New Revision: 9437

Modified:
   trunk/qgis/python/core/qgscontinuouscolorrenderer.sip
   trunk/qgis/python/core/qgsgraduatedsymbolrenderer.sip
   trunk/qgis/python/core/qgsmaplayer.sip
   trunk/qgis/python/core/qgsrasterlayer.sip
   trunk/qgis/python/core/qgsrenderer.sip
   trunk/qgis/python/core/qgssinglesymbolrenderer.sip
   trunk/qgis/python/core/qgsuniquevaluerenderer.sip
   trunk/qgis/src/core/qgsmaplayer.cpp
   trunk/qgis/src/core/qgsmaplayer.h
   trunk/qgis/src/core/qgsvectordataprovider.cpp
   trunk/qgis/src/core/qgsvectordataprovider.h
   trunk/qgis/src/core/qgsvectorlayer.cpp
   trunk/qgis/src/core/qgsvectorlayer.h
   trunk/qgis/src/core/raster/qgscontrastenhancement.h
   trunk/qgis/src/core/raster/qgsrasterlayer.cpp
   trunk/qgis/src/core/raster/qgsrasterlayer.h
   trunk/qgis/src/core/raster/qgsrastertransparency.cpp
   trunk/qgis/src/core/raster/qgsrastertransparency.h
   trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.cpp
   trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.h
   trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.cpp
   trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.h
   trunk/qgis/src/core/renderer/qgsrenderer.h
   trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.cpp
   trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.h
   trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.cpp
   trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.h
   trunk/qgis/tests/src/core/testqgsrenderers.cpp
Log:
apply patch for #1162 for timlinux

Modified: trunk/qgis/python/core/qgscontinuouscolorrenderer.sip
===================================================================
--- trunk/qgis/python/core/qgscontinuouscolorrenderer.sip	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/python/core/qgscontinuouscolorrenderer.sip	2008-10-06 13:00:45 UTC (rev 9437)
@@ -31,10 +31,10 @@
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read 
      @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML(const QDomNode& rnode, QgsVectorLayer& vl);
+    virtual int readXML(const QDomNode& rnode, QgsVectorLayer& vl);
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl  ) const;
     /** Returns true*/
     bool needsAttributes() const;
     /**Returns a list with the index of the classification attribute*/

Modified: trunk/qgis/python/core/qgsgraduatedsymbolrenderer.sip
===================================================================
--- trunk/qgis/python/core/qgsgraduatedsymbolrenderer.sip	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/python/core/qgsgraduatedsymbolrenderer.sip	2008-10-06 13:00:45 UTC (rev 9437)
@@ -30,10 +30,10 @@
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read 
      @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML(const QDomNode& rnode, QgsVectorLayer& vl);
+    virtual int readXML(const QDomNode& rnode, QgsVectorLayer& vl);
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, QgsVectorLayer& vl ) const;
     /** Returns true*/
     bool needsAttributes() const;
     /**Returns a list with the index to the classification field*/

Modified: trunk/qgis/python/core/qgsmaplayer.sip
===================================================================
--- trunk/qgis/python/core/qgsmaplayer.sip	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/python/core/qgsmaplayer.sip	2008-10-06 13:00:45 UTC (rev 9437)
@@ -140,6 +140,22 @@
     */
     bool writeXML(QDomNode & layer_node, QDomDocument & document);
 
+    /** Read the symbology for the current layer from the Dom node supplied. 
+     * @param QDomNode node that will contain the symbology definition for this layer.
+     * @param errorMessage reference to string that will be updated with any error messages
+     * @return true in case of success.
+    */
+    virtual bool readSymbology(const QDomNode& node, QString& errorMessage) = 0;
+
+    /** Write the symbology for the layer into the docment provided.
+     *  @param QDomNode the node that will have the style element added to it.
+     *  @param QDomDocument the document that will have the QDomNode added.
+     * @param errorMessage reference to string that will be updated with any error messages
+     *  @return true in case of success.
+     */
+    virtual bool writeSymbology(QDomNode&, QDomDocument& doc, QString& errorMessage) const = 0;
+
+
     /** Copies the symbology settings from another layer. Returns true in case of success */
     virtual bool copySymbologySettings(const QgsMapLayer& other) = 0;
 

Modified: trunk/qgis/python/core/qgsrasterlayer.sip
===================================================================
--- trunk/qgis/python/core/qgsrasterlayer.sip	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/python/core/qgsrasterlayer.sip	2008-10-06 13:00:45 UTC (rev 9437)
@@ -137,7 +137,7 @@
     // Accessor and mutator for mInvertPixelsFlag
     //
     /** \brief Accessor to find out whether the histogram should be inverted.   */
-    bool getInvertHistogramFlag();
+    bool getInvertHistogramFlag() const;
     
     /** \brief Mutator to alter the state of the invert histogram flag.  */
     void setInvertHistogramFlag(bool theFlag);
@@ -146,7 +146,7 @@
     // Accessor and mutator for mStandardDeviations
     //
     /** \brief Accessor to find out how many standard deviations are being plotted.  */
-    double getStdDevsToPlot();
+    double getStdDevsToPlot() const;
     
     /** \brief Mutator to alter the number of standard deviations that should be plotted.  */
     void setStdDevsToPlot(double the);
@@ -173,7 +173,7 @@
     /** \brief Call any inline image manipulation filters */
     void filterLayer(QImage * theQImage);
     /** \brief Accessor for red band name (allows alternate mappings e.g. map blue as red colour). */
-    QString getRedBandName();
+    QString getRedBandName() const;
     
     /** \brief Mutator for red band name (allows alternate mappings e.g. map blue as red colour). */
     void setRedBandName(const QString & theBandNameQString);
@@ -181,7 +181,7 @@
     // Accessor and mutator for green band name
     // 
     /** \brief Accessor for green band name mapping.  */
-    QString getGreenBandName();
+    QString getGreenBandName() const;
     
     /** \brief Mutator for green band name mapping.  */
     void setGreenBandName(const QString & theBandNameQString);
@@ -189,7 +189,7 @@
     // Accessor and mutator for blue band name
     // 
     /** \brief  Accessor for blue band name mapping. */
-    QString getBlueBandName();
+    QString getBlueBandName() const;
     
     /** \brief Mutator for blue band name mapping.  */
     void setBlueBandName(const QString & theBandNameQString);
@@ -203,7 +203,7 @@
     // Accessor and mutator for transparent band name
     // 
     /** \brief  Accessor for transparent band name mapping. */
-    QString getTransparentBandName();
+    QString getTransparentBandName() const;
     
     /** \brief Mutator for transparent band name mapping.  */
     void setTransparentBandName(const QString & theBandNameQString);
@@ -212,7 +212,7 @@
     // Accessor and mutator for gray band name
     //
     /** \brief Accessor for gray band name mapping.  */
-    QString getGrayBandName();
+    QString getGrayBandName() const;
     
     /** \brief Mutator for gray band name mapping.  */
     void setGrayBandName(const QString & theBandNameQString);
@@ -249,7 +249,7 @@
     QgsContrastEnhancement::CONTRAST_ENHANCEMENT_ALGORITHM getContrastEnhancementAlgorithm();
     
     /** \brief Accessor for contrast enhancement algorithm. */
-    QString getContrastEnhancementAlgorithmAsQString();
+    QString getContrastEnhancementAlgorithmAsString() const;
     
     /** \brief Mutator for contrast enhancement algorithm. */
     void setContrastEnhancementAlgorithm(QgsContrastEnhancement::CONTRAST_ENHANCEMENT_ALGORITHM theAlgorithm, bool theGenerateLookupTableFlag=true);
@@ -276,10 +276,10 @@
     // Accessor and mutator for the color shader algorithm
     //
     /** \brief Accessor for colour shader algorithm. */
-    COLOR_SHADING_ALGORITHM getColorShadingAlgorithm();
+    COLOR_SHADING_ALGORITHM getColorShadingAlgorithm() const;
 
     /** \brief Accessor for colour shader algorithm. */
-    QString getColorShadingAlgorithmAsQString();
+    QString getColorShadingAlgorithmAsString() const;
     
     /** \brief Mutator for color shader algorithm. */
     void setColorShadingAlgorithm(COLOR_SHADING_ALGORITHM theShaderAlgorithm);
@@ -319,7 +319,7 @@
      * Implementaed mainly for serialisation / deserialisation of settings to xml.
      * NOTE: May be deprecated in the future!. Use alternate implementation above rather.
      * */
-    QString getDrawingStyleAsQString();
+    QString getDrawingStyleAsString() const;
     
     /** \brief Mutator for drawing style.  */
     void setDrawingStyle(const DRAWING_STYLE &  theDrawingStyle);
@@ -435,13 +435,13 @@
     void setUserDefinedRGBMinMax(bool theBool);
 
     /** \brief Accessor for mUserDefinedRGBMinMaxFlag.  */
-    bool getUserDefinedRGBMinMax();
+    bool getUserDefinedRGBMinMax() const;
 
     /** \brief Mutator for mUserDefinedGrayMinMaxFlag */
     void setUserDefinedGrayMinMax(bool theBool);
 
     /** \brief Accessor for mUserDefinedGrayMinMaxFlag.  */
-    bool getUserDefinedGrayMinMax();
+    bool getUserDefinedGrayMinMax() const;
 
 public slots:    
     /**

Modified: trunk/qgis/python/core/qgsrenderer.sip
===================================================================
--- trunk/qgis/python/core/qgsrenderer.sip	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/python/core/qgsrenderer.sip	2008-10-06 13:00:45 UTC (rev 9437)
@@ -20,10 +20,10 @@
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read 
      @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML(const QDomNode& rnode, QgsVectorLayer& vl)=0;
+    virtual int readXML(const QDomNode& rnode, QgsVectorLayer& vl)=0;
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const=0;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document,  const QgsVectorLayer& vl  ) const=0;
     /** Returns true, if attribute values are used by the renderer and false otherwise*/
     virtual bool needsAttributes() const=0;
     /**Returns a list with indexes of classification attributes*/

Modified: trunk/qgis/python/core/qgssinglesymbolrenderer.sip
===================================================================
--- trunk/qgis/python/core/qgssinglesymbolrenderer.sip	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/python/core/qgssinglesymbolrenderer.sip	2008-10-06 13:00:45 UTC (rev 9437)
@@ -18,12 +18,12 @@
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read 
      @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML(const QDomNode& rnode, QgsVectorLayer& vl);
+    virtual int readXML(const QDomNode& rnode, QgsVectorLayer& vl);
     /**Writes the contents of the renderer to a configuration file*/
     /*virtual void writeXML(std::ostream& xml);*/
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl  ) const;
     /**Returns false, no attributes neede for single symbol*/
     bool needsAttributes() const;
     /**Returns an empty list, since no classification attributes are used*/

Modified: trunk/qgis/python/core/qgsuniquevaluerenderer.sip
===================================================================
--- trunk/qgis/python/core/qgsuniquevaluerenderer.sip	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/python/core/qgsuniquevaluerenderer.sip	2008-10-06 13:00:45 UTC (rev 9437)
@@ -15,10 +15,10 @@
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read 
      @param vl the vector layer which will be associated with the renderer*/
-    void readXML(const QDomNode& rnode, QgsVectorLayer& vl);
+    virtual int readXML(const QDomNode& rnode, QgsVectorLayer& vl);
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const;
     /** Returns true, if attribute values are used by the renderer and false otherwise*/
     bool needsAttributes() const;
     /**Returns a list with indexes of classification attributes*/

Modified: trunk/qgis/src/core/qgsmaplayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsmaplayer.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/qgsmaplayer.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -535,37 +535,15 @@
     return myErrorMessage;
   }
 
-  QDomElement myLayer = myRoot.firstChildElement( "maplayer" );
-  if ( myLayer.isNull() )
-  {
-    myErrorMessage = "Error: maplayer element could not be found in " + theURI;
-    theResultFlag = false;
-    return myErrorMessage;
-  }
+  QString errorMsg;
+  theResultFlag = readSymbology(myRoot, errorMsg);
+  if(!theResultFlag)
+    {
+      myErrorMessage = QObject::tr( "Loading style file " ) + theURI + QObject::tr(" failed because:") + "\n" + errorMsg;
+      return myErrorMessage;
+    }
 
-  //
-  // we need to ensure the data source matches the layers
-  // current datasource not the one specified in the qml
-  //
-  QDomElement myDataSource = myLayer.firstChildElement( "datasource" );
-  if ( myDataSource.isNull() )
-  {
-    myErrorMessage = "Error: datasource element could not be found in " + theURI;
-    theResultFlag = false;
-    return myErrorMessage;
-  }
-  QDomElement myNewDataSource = myDocument.createElement( "datasource" );
-  QDomText myDataSourceText = myDocument.createTextNode( source() );
-  myNewDataSource.appendChild( myDataSourceText );
-  myLayer.replaceChild( myNewDataSource, myLayer.firstChildElement( "datasource" ) );
-
-  //
-  // Now go on to parse the xml (QDomElement inherits QDomNode
-  // so we can just pass along the element to readXML)
-  //
-  theResultFlag = readXML( myLayer );
-
-  return QObject::tr( "Loaded default style file from " ) + theURI;
+  return ""; 
 }
 
 QString QgsMapLayer::saveDefaultStyle( bool & theResultFlag )
@@ -585,8 +563,13 @@
   QDomElement myRootNode = myDocument.createElement( "qgis" );
   myRootNode.setAttribute( "version", QString( "%1" ).arg( QGis::qgisVersion ) );
   myDocument.appendChild( myRootNode );
-  writeXML( myRootNode, myDocument );
 
+  QString errorMsg;
+  if(!writeSymbology(myRootNode, myDocument, errorMsg))
+    {
+      return QObject::tr("Could not save symbology because:") + "\n" + errorMsg;
+    }
+
   // check if the uri is a file or ends with .qml,
   // which indicates that it should become one
   // everything else goes to the database.

Modified: trunk/qgis/src/core/qgsmaplayer.h
===================================================================
--- trunk/qgis/src/core/qgsmaplayer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/qgsmaplayer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -244,6 +244,21 @@
      */
     virtual QString saveNamedStyle( const QString theURI, bool & theResultFlag );
 
+    /** Read the symbology for the current layer from the Dom node supplied. 
+     * @param QDomNode node that will contain the symbology definition for this layer.
+     * @param errorMessage reference to string that will be updated with any error messages
+     * @return true in case of success.
+    */
+    virtual bool readSymbology(const QDomNode& node, QString& errorMessage) = 0;
+
+    /** Write the symbology for the layer into the docment provided.
+     *  @param QDomNode the node that will have the style element added to it.
+     *  @param QDomDocument the document that will have the QDomNode added.
+     * @param errorMessage reference to string that will be updated with any error messages
+     *  @return true in case of success.
+     */
+    virtual bool writeSymbology(QDomNode&, QDomDocument& doc, QString& errorMessage) const = 0;
+
   public slots:
 
     /** Event handler for when a coordinate transform fails due to bad vertex error */

Modified: trunk/qgis/src/core/qgsvectordataprovider.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectordataprovider.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/qgsvectordataprovider.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -232,6 +232,20 @@
   return -1;
 }
 
+QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const
+{
+  QMap<QString, int> resultMap;
+
+  const QgsFieldMap& theFields = fields();
+  QgsFieldMap::const_iterator field_it = theFields.constBegin();
+  for(; field_it != theFields.constEnd(); ++field_it)
+    {
+      resultMap.insert(field_it.value().name(), field_it.key());
+    }
+
+  return resultMap;
+}
+
 QgsAttributeList QgsVectorDataProvider::allAttributesList()
 {
   uint count = fieldCount();

Modified: trunk/qgis/src/core/qgsvectordataprovider.h
===================================================================
--- trunk/qgis/src/core/qgsvectordataprovider.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/qgsvectordataprovider.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -267,6 +267,9 @@
      */
     int fieldNameIndex( const QString& fieldName ) const;
 
+    /**Return a map where the key is the name of the field and the value is its index*/
+    QMap<QString, int> fieldNameMap() const;
+
     /**
      * Return list of indexes to fetch all attributes in getNextFeature()
      */

Modified: trunk/qgis/src/core/qgsvectorlayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/qgsvectorlayer.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -2084,61 +2084,14 @@
     }
   }
 
-  // create and bind a renderer to this layer
+  QString errorMsg;
+  if(!readSymbology(layer_node, errorMsg))
+    {
+      return false;
+    }
 
-  QDomNode singlenode = layer_node.namedItem( "singlesymbol" );
-  QDomNode graduatednode = layer_node.namedItem( "graduatedsymbol" );
-  QDomNode continuousnode = layer_node.namedItem( "continuoussymbol" );
-  QDomNode singlemarkernode = layer_node.namedItem( "singlemarker" );
-  QDomNode graduatedmarkernode = layer_node.namedItem( "graduatedmarker" );
-  QDomNode uniquevaluenode = layer_node.namedItem( "uniquevalue" );
+  // Test if labeling is on or off
   QDomNode labelnode = layer_node.namedItem( "label" );
-  QDomNode uniquemarkernode = layer_node.namedItem( "uniquevaluemarker" );
-
-  //std::auto_ptr<QgsRenderer> renderer; actually the renderer SHOULD NOT be
-  //deleted when this function finishes, otherwise the application will
-  //crash
-  // XXX this seems to be a dangerous implementation; should re-visit design
-  QgsRenderer * renderer;
-
-  // XXX Kludge!
-
-
-  // if we don't have a coordinate transform, get one
-
-  //
-  // Im commenting this out - if the layer was serialied in a
-  //  >=0.7 project it should have been validated and have all
-  // coord xform info
-  //
-
-  //if ( ! coordinateTransform() )
-  //{
-  //    setCoordinateSystem();
-  //}
-
-  if ( !singlenode.isNull() )
-  {
-    renderer = new QgsSingleSymbolRenderer( vectorType() );
-    renderer->readXML( singlenode, *this );
-  }
-  else if ( !graduatednode.isNull() )
-  {
-    renderer = new QgsGraduatedSymbolRenderer( vectorType() );
-    renderer->readXML( graduatednode, *this );
-  }
-  else if ( !continuousnode.isNull() )
-  {
-    renderer = new QgsContinuousColorRenderer( vectorType() );
-    renderer->readXML( continuousnode, *this );
-  }
-  else if ( !uniquevaluenode.isNull() )
-  {
-    renderer = new QgsUniqueValueRenderer( vectorType() );
-    renderer->readXML( uniquevaluenode, *this );
-  }
-
-  // Test if labeling is on or off
   QDomElement element = labelnode.toElement();
   int hasLabelsEnabled = element.text().toInt();
   if ( hasLabelsEnabled < 1 )
@@ -2365,18 +2318,12 @@
 
   // renderer specific settings
 
-  const QgsRenderer * myRenderer = renderer();
-  if ( myRenderer )
-  {
-    myRenderer->writeXML( layer_node, document );
-  }
-  else
-  {
-    QgsDebugMsg( QString( "%1:%2 no renderer" ).arg( __FILE__ ).arg( __LINE__ ) );
+  QString errorMsg;
+  if(!writeSymbology( layer_node, document, errorMsg ))
+    {
+      return false;
+    }
 
-    // XXX return false?
-  }
-
   // Now we get to do all that all over again for QgsLabel
 
   // XXX Since this is largely a cut-n-paste from the previous, this
@@ -2449,6 +2396,75 @@
   return true;
 } // bool QgsVectorLayer::writeXml
 
+bool QgsVectorLayer::readSymbology(const QDomNode& node, QString& errorMessage)
+{
+  // create and bind a renderer to this layer
+
+  QDomNode singlenode = node.namedItem( "singlesymbol" );
+  QDomNode graduatednode = node.namedItem( "graduatedsymbol" );
+  QDomNode continuousnode = node.namedItem( "continuoussymbol" );
+  QDomNode uniquevaluenode = node.namedItem( "uniquevalue" );
+
+  QgsRenderer * renderer = 0;
+  int returnCode;
+
+  if ( !singlenode.isNull() )
+  {
+    renderer = new QgsSingleSymbolRenderer( vectorType() );
+    returnCode = renderer->readXML( singlenode, *this );
+  }
+  else if ( !graduatednode.isNull() )
+  {
+    renderer = new QgsGraduatedSymbolRenderer( vectorType() );
+    returnCode = renderer->readXML( graduatednode, *this );
+  }
+  else if ( !continuousnode.isNull() )
+  {
+    renderer = new QgsContinuousColorRenderer( vectorType() );
+    returnCode = renderer->readXML( continuousnode, *this );
+  }
+  else if ( !uniquevaluenode.isNull() )
+  {
+    renderer = new QgsUniqueValueRenderer( vectorType() );
+    returnCode = renderer->readXML( uniquevaluenode, *this );
+  }
+  
+  if(!renderer)
+    {
+      return false;
+    }
+
+  if(returnCode == 1)
+    {
+      errorMessage = tr("No renderer object"); delete renderer; return false;
+    }
+  else if(returnCode == 2)
+    {
+      errorMessage = tr("Classification field not found"); delete renderer; return false;
+    }
+
+  mRenderer = renderer;
+  return true;
+}
+
+bool QgsVectorLayer::writeSymbology(QDomNode& node, QDomDocument& doc, QString& errorMessage) const
+{
+  const QgsRenderer * myRenderer = renderer();
+  if ( myRenderer )
+  {
+    if(!myRenderer->writeXML( node, doc, *this ))
+      {
+	return false;
+      }
+  }
+  else
+  {
+    QgsDebugMsg( QString( "%1:%2 no renderer" ).arg( __FILE__ ).arg( __LINE__ ) );
+    return false;
+  }
+  return true;
+}
+
 bool QgsVectorLayer::changeAttributeValue( int fid, int field, QVariant value, bool emitSignal )
 {
   if ( !isEditable() )

Modified: trunk/qgis/src/core/qgsvectorlayer.h
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/qgsvectorlayer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -173,7 +173,22 @@
      */
     virtual bool writeXml( QDomNode & layer_node, QDomDocument & doc );
 
+     /** Read the symbology for the current layer from the Dom node supplied. 
+     * @param QDomNode node that will contain the symbology definition for this layer.
+     * @param errorMessage reference to string that will be updated with any error messages
+     * @return true in case of success.
+    */
+    bool readSymbology(const QDomNode& node, QString& errorMessage);
 
+    /** Write the symbology for the layer into the docment provided.
+     *  @param QDomNode the node that will have the style element added to it.
+     *  @param QDomDocument the document that will have the QDomNode added.
+     * @param errorMessage reference to string that will be updated with any error messages
+     *  @return true in case of success.
+     */
+    bool writeSymbology(QDomNode&, QDomDocument& doc, QString& errorMessage) const;
+
+
     /**
      * Number of features in the layer. This is necessary if features are
      * added/deleted or the layer has been subsetted. If the data provider

Modified: trunk/qgis/src/core/raster/qgscontrastenhancement.h
===================================================================
--- trunk/qgis/src/core/raster/qgscontrastenhancement.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/raster/qgscontrastenhancement.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -88,10 +88,10 @@
      *
      */
     /** \brief Return the maximum value for the contrast enhancement range. */
-    double getMaximumValue() { return mMaximumValue; }
+    double getMaximumValue() const { return mMaximumValue; }
 
     /** \brief Return the minimum value for the contrast enhancement range. */
-    double getMinimumValue() { return mMinimumValue; }
+    double getMinimumValue() const { return mMinimumValue; }
 
     CONTRAST_ENHANCEMENT_ALGORITHM getContrastEnhancementAlgorithm() { return mContrastEnhancementAlgorithm; }
 

Modified: trunk/qgis/src/core/raster/qgsrasterlayer.cpp
===================================================================
--- trunk/qgis/src/core/raster/qgsrasterlayer.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/raster/qgsrasterlayer.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -735,7 +735,7 @@
 }
 
 
-QString QgsRasterLayer::getDrawingStyleAsQString()
+QString QgsRasterLayer::getDrawingStyleAsString() const
 {
   switch ( drawingStyle )
   {
@@ -2469,7 +2469,7 @@
  */
 QPixmap QgsRasterLayer::getLegendQPixmap( bool theWithNameFlag )
 {
-  QgsDebugMsg( "called (" + getDrawingStyleAsQString() + ")" );
+  QgsDebugMsg( "called (" + getDrawingStyleAsString() + ")" );
 
   QPixmap myLegendQPixmap;      //will be initialised once we know what drawing style is active
   QPainter myQPainter;
@@ -3871,196 +3871,11 @@
     }
 
   }
+ 
+  QString theError;
+  return readSymbology(layer_node, theError);
+  
 
-  QDomNode mnl = layer_node.namedItem( "rasterproperties" );
-  QDomNode snode = mnl.namedItem( "drawingStyle" );
-  QDomElement myElement = snode.toElement();
-  setDrawingStyle( myElement.text() );
-
-  snode = mnl.namedItem( "mColorShadingAlgorithm" );
-  myElement = snode.toElement();
-  setColorShadingAlgorithm( myElement.text() );
-
-  snode = mnl.namedItem( "mInvertPixelsFlag" );
-  myElement = snode.toElement();
-  QVariant myVariant = ( QVariant ) myElement.attribute( "boolean" );
-  setInvertHistogramFlag( myVariant.toBool() );
-
-  snode = mnl.namedItem( "mRedBandName" );
-  myElement = snode.toElement();
-  setRedBandName( myElement.text() );
-
-  snode = mnl.namedItem( "mGreenBandName" );
-  myElement = snode.toElement();
-  setGreenBandName( myElement.text() );
-
-  snode = mnl.namedItem( "mBlueBandName" );
-  myElement = snode.toElement();
-  setBlueBandName( myElement.text() );
-
-  snode = mnl.namedItem( "mGrayBandName" );
-  myElement = snode.toElement();
-  QgsDebugMsg( QString( " Setting gray band to : " ) + myElement.text() );
-  setGrayBandName( myElement.text() );
-
-  snode = mnl.namedItem( "mStandardDeviations" );
-  myElement = snode.toElement();
-  setStdDevsToPlot( myElement.text().toDouble() );
-
-  snode = mnl.namedItem( "mUserDefinedRGBMinMaxFlag" );
-  myElement = snode.toElement();
-  myVariant = ( QVariant ) myElement.attribute( "boolean" );
-  setUserDefinedRGBMinMax( myVariant.toBool() );
-
-  snode = mnl.namedItem( "mRGBActualMinimumMaximum" );
-  myElement = snode.toElement();
-  myVariant = ( QVariant ) myElement.attribute( "boolean" );
-  setActualRGBMinMaxFlag( myVariant.toBool() );
-
-  snode = mnl.namedItem( "mUserDefinedGrayMinMaxFlag" );
-  myElement = snode.toElement();
-  myVariant = ( QVariant ) myElement.attribute( "boolean" );
-  setUserDefinedGrayMinMax( myVariant.toBool() );
-
-  snode = mnl.namedItem( "mGrayActualMinimumMaximum" );
-  myElement = snode.toElement();
-  myVariant = ( QVariant ) myElement.attribute( "boolean" );
-  setActualGrayMinMaxFlag( myVariant.toBool() );
-
-  snode = mnl.namedItem( "mContrastEnhancementAlgorithm" );
-  myElement = snode.toElement();
-  setContrastEnhancementAlgorithm( myElement.text(), false );
-
-  QDomNode contrastEnhancementMinMaxValues = mnl.namedItem( "contrastEnhancementMinMaxValues" );
-  QDomNodeList minMaxValueList = contrastEnhancementMinMaxValues.toElement().elementsByTagName( "minMaxEntry" );
-  for ( int i = 0; i < minMaxValueList.size(); ++i )
-  {
-    QDomNode minMaxEntry = minMaxValueList.at( i ).toElement();
-    if ( minMaxEntry.isNull() )
-    {
-      continue;
-    }
-    QDomNode minEntry = minMaxEntry.namedItem( "min" );
-    QDomNode maxEntry = minMaxEntry.namedItem( "max" );
-
-    setMinimumValue( i + 1, minEntry.toElement().text().toDouble(), false );
-    setMaximumValue( i + 1, maxEntry.toElement().text().toDouble(), false );
-  }
-
-  QgsDebugMsg( "ReadXml: gray band name " + mGrayBandName );
-  QgsDebugMsg( "ReadXml: red band name " + mRedBandName );
-  QgsDebugMsg( "ReadXml: green band name  " + mGreenBandName );
-  QgsDebugMsg( "Drawing style " + getDrawingStyleAsQString() );
-
-  /*
-   * Transparency tab
-   */
-  snode = mnl.namedItem( "mNoDataValue" );
-  myElement = snode.toElement();
-  setNoDataValue( myElement.text().toDouble() );
-  if ( myElement.attribute( "mValidNoDataValue", "false" ).compare( "true" ) )
-  {
-    // If flag element is not true, set to false.
-    mValidNoDataValue = false;
-  }
-
-  QDomNode singleValuePixelListNode = mnl.namedItem( "singleValuePixelList" );
-  if ( !singleValuePixelListNode.isNull() )
-  {
-    QList<QgsRasterTransparency::TransparentSingleValuePixel> newSingleValuePixelList;
-
-    //entries
-    QDomNodeList singleValuePixelList = singleValuePixelListNode.toElement().elementsByTagName( "pixelListEntry" );
-    for ( int i = 0; i < singleValuePixelList.size(); ++i )
-    {
-      QgsRasterTransparency::TransparentSingleValuePixel myNewItem;
-      QDomElement singleValuePixelListElement = singleValuePixelList.at( i ).toElement();
-      if ( singleValuePixelListElement.isNull() )
-      {
-        continue;
-      }
-
-      myNewItem.pixelValue = singleValuePixelListElement.attribute( "pixelValue" ).toDouble();
-      myNewItem.percentTransparent = singleValuePixelListElement.attribute( "percentTransparent" ).toDouble();
-
-      newSingleValuePixelList.push_back( myNewItem );
-    }
-    mRasterTransparency.setTransparentSingleValuePixelList( newSingleValuePixelList );
-  }
-
-  QDomNode threeValuePixelListNode = mnl.namedItem( "threeValuePixelList" );
-  if ( !threeValuePixelListNode.isNull() )
-  {
-    QList<QgsRasterTransparency::TransparentThreeValuePixel> newThreeValuePixelList;
-
-    //entries
-    QDomNodeList threeValuePixelList = threeValuePixelListNode.toElement().elementsByTagName( "pixelListEntry" );
-    for ( int i = 0; i < threeValuePixelList.size(); ++i )
-    {
-      QgsRasterTransparency::TransparentThreeValuePixel myNewItem;
-      QDomElement threeValuePixelListElement = threeValuePixelList.at( i ).toElement();
-      if ( threeValuePixelListElement.isNull() )
-      {
-        continue;
-      }
-
-      myNewItem.red = threeValuePixelListElement.attribute( "red" ).toDouble();
-      myNewItem.green = threeValuePixelListElement.attribute( "green" ).toDouble();
-      myNewItem.blue = threeValuePixelListElement.attribute( "blue" ).toDouble();
-      myNewItem.percentTransparent = threeValuePixelListElement.attribute( "percentTransparent" ).toDouble();
-
-      newThreeValuePixelList.push_back( myNewItem );
-    }
-    mRasterTransparency.setTransparentThreeValuePixelList( newThreeValuePixelList );
-  }
-
-  /*
-   * Color Ramp tab
-   */
-  //restore custom color ramp settings
-  QDomNode customColorRampNode = mnl.namedItem( "customColorRamp" );
-  if ( !customColorRampNode.isNull() )
-  {
-    QgsColorRampShader* myColorRampShader = ( QgsColorRampShader* ) mRasterShader->getRasterShaderFunction();
-
-    //TODO: Remove the customColorRampType check and following if() in v2.0, added for compatability with older ( bugged ) project files
-    QDomNode customColorRampTypeNode = customColorRampNode.namedItem( "customColorRampType" );
-    QDomNode colorRampTypeNode = customColorRampNode.namedItem( "colorRampType" );
-    QString myRampType = "";
-    if( "" == customColorRampTypeNode.toElement().text() )
-    {
-      myRampType = colorRampTypeNode.toElement().text();
-    }
-    else
-    {
-      myRampType = customColorRampTypeNode.toElement().text();
-    }
-    myColorRampShader->setColorRampType( myRampType );
-
-
-    //entries
-    QList<QgsColorRampShader::ColorRampItem> myColorRampItemList;
-    QDomNodeList colorRampEntryList = customColorRampNode.toElement().elementsByTagName( "colorRampEntry" );
-    for ( int i = 0; i < colorRampEntryList.size(); ++i )
-    {
-      QgsColorRampShader::ColorRampItem myNewItem;
-      QDomElement colorRampEntryElement = colorRampEntryList.at( i ).toElement();
-      if ( colorRampEntryElement.isNull() )
-      {
-        continue;
-      }
-
-      myNewItem.color = QColor( colorRampEntryElement.attribute( "red" ).toInt(), colorRampEntryElement.attribute( "green" ).toInt(), colorRampEntryElement.attribute( "blue" ).toInt() );
-      myNewItem.label = colorRampEntryElement.attribute( "label" );
-      myNewItem.value = colorRampEntryElement.attribute( "value" ).toDouble();
-
-      myColorRampItemList.push_back( myNewItem );
-    }
-    myColorRampShader->setColorRampItemList( myColorRampItemList );
-  }
-
-  return true;
-
 } // QgsRasterLayer::readXml( QDomNode & layer_node )
 
 
@@ -4087,10 +3902,17 @@
   QDomText providerText = document.createTextNode( mProviderKey );
   provider.appendChild( providerText );
   layer_node.appendChild( provider );
+  
+  //write out the symbology
+  QString errorMsg;
+  return writeSymbology ( layer_node, document, errorMsg );
+}
 
+bool QgsRasterLayer::writeSymbology ( QDomNode & layer_node, QDomDocument & document, QString& errorMessage) const
+{
   // <rasterproperties>
   QDomElement rasterPropertiesElement = document.createElement( "rasterproperties" );
-  mapLayerNode.appendChild( rasterPropertiesElement );
+  layer_node.appendChild( rasterPropertiesElement );
 
   if ( !mProviderKey.isEmpty() )
   {
@@ -4140,7 +3962,7 @@
 
   // <drawingStyle>
   QDomElement drawStyleElement = document.createElement( "drawingStyle" );
-  QDomText    drawStyleText    = document.createTextNode( getDrawingStyleAsQString() );
+  QDomText    drawStyleText    = document.createTextNode( getDrawingStyleAsString() );
 
   drawStyleElement.appendChild( drawStyleText );
 
@@ -4148,7 +3970,7 @@
 
   // <colorShadingAlgorithm>
   QDomElement colorShadingAlgorithmElement = document.createElement( "mColorShadingAlgorithm" );
-  QDomText    colorShadingAlgorithmText    = document.createTextNode( getColorShadingAlgorithmAsQString() );
+  QDomText    colorShadingAlgorithmText    = document.createTextNode( getColorShadingAlgorithmAsString() );
 
   colorShadingAlgorithmElement.appendChild( colorShadingAlgorithmText );
 
@@ -4293,16 +4115,16 @@
 
   // <contrastEnhancementAlgorithm>
   QDomElement contrastEnhancementAlgorithmElement = document.createElement( "mContrastEnhancementAlgorithm" );
-  QDomText    contrastEnhancementAlgorithmText    = document.createTextNode( getContrastEnhancementAlgorithmAsQString() );
+  QDomText    contrastEnhancementAlgorithmText    = document.createTextNode( getContrastEnhancementAlgorithmAsString() );
 
   contrastEnhancementAlgorithmElement.appendChild( contrastEnhancementAlgorithmText );
 
   rasterPropertiesElement.appendChild( contrastEnhancementAlgorithmElement );
 
   // <minMaxValues>
-  QList<QgsContrastEnhancement>::iterator it;
+  QList<QgsContrastEnhancement>::const_iterator it;
   QDomElement contrastEnhancementMinMaxValuesElement = document.createElement( "contrastEnhancementMinMaxValues" );
-  for ( it =  mContrastEnhancementList.begin(); it != mContrastEnhancementList.end(); ++it )
+  for ( it =  mContrastEnhancementList.constBegin(); it != mContrastEnhancementList.constEnd(); ++it )
   {
     QDomElement minMaxEntry = document.createElement( "minMaxEntry" );
     QDomElement minEntry = document.createElement( "min" );
@@ -4412,10 +4234,199 @@
   }
 
   return true;
-} // bool QgsRasterLayer::writeXml
+} // bool QgsRasterLayer::writeSymbology
 
+bool QgsRasterLayer::readSymbology(const QDomNode& layer_node, QString& errorMessage)
+{
+  QDomNode mnl = layer_node.namedItem( "rasterproperties" );
+  QDomNode snode = mnl.namedItem( "drawingStyle" );
+  QDomElement myElement = snode.toElement();
+  setDrawingStyle( myElement.text() );
 
+  snode = mnl.namedItem( "mColorShadingAlgorithm" );
+  myElement = snode.toElement();
+  setColorShadingAlgorithm( myElement.text() );
 
+  snode = mnl.namedItem( "mInvertPixelsFlag" );
+  myElement = snode.toElement();
+  QVariant myVariant = ( QVariant ) myElement.attribute( "boolean" );
+  setInvertHistogramFlag( myVariant.toBool() );
+
+  snode = mnl.namedItem( "mRedBandName" );
+  myElement = snode.toElement();
+  setRedBandName( myElement.text() );
+
+  snode = mnl.namedItem( "mGreenBandName" );
+  myElement = snode.toElement();
+  setGreenBandName( myElement.text() );
+
+  snode = mnl.namedItem( "mBlueBandName" );
+  myElement = snode.toElement();
+  setBlueBandName( myElement.text() );
+
+  snode = mnl.namedItem( "mGrayBandName" );
+  myElement = snode.toElement();
+  QgsDebugMsg( QString( " Setting gray band to : " ) + myElement.text() );
+  setGrayBandName( myElement.text() );
+
+  snode = mnl.namedItem( "mStandardDeviations" );
+  myElement = snode.toElement();
+  setStdDevsToPlot( myElement.text().toDouble() );
+
+  snode = mnl.namedItem( "mUserDefinedRGBMinMaxFlag" );
+  myElement = snode.toElement();
+  myVariant = ( QVariant ) myElement.attribute( "boolean" );
+  setUserDefinedRGBMinMax( myVariant.toBool() );
+
+  snode = mnl.namedItem( "mRGBActualMinimumMaximum" );
+  myElement = snode.toElement();
+  myVariant = ( QVariant ) myElement.attribute( "boolean" );
+  setActualRGBMinMaxFlag( myVariant.toBool() );
+
+  snode = mnl.namedItem( "mUserDefinedGrayMinMaxFlag" );
+  myElement = snode.toElement();
+  myVariant = ( QVariant ) myElement.attribute( "boolean" );
+  setUserDefinedGrayMinMax( myVariant.toBool() );
+
+  snode = mnl.namedItem( "mGrayActualMinimumMaximum" );
+  myElement = snode.toElement();
+  myVariant = ( QVariant ) myElement.attribute( "boolean" );
+  setActualGrayMinMaxFlag( myVariant.toBool() );
+
+  snode = mnl.namedItem( "mContrastEnhancementAlgorithm" );
+  myElement = snode.toElement();
+  setContrastEnhancementAlgorithm( myElement.text(), false );
+
+  QDomNode contrastEnhancementMinMaxValues = mnl.namedItem( "contrastEnhancementMinMaxValues" );
+  QDomNodeList minMaxValueList = contrastEnhancementMinMaxValues.toElement().elementsByTagName( "minMaxEntry" );
+  for ( int i = 0; i < minMaxValueList.size(); ++i )
+  {
+    QDomNode minMaxEntry = minMaxValueList.at( i ).toElement();
+    if ( minMaxEntry.isNull() )
+    {
+      continue;
+    }
+    QDomNode minEntry = minMaxEntry.namedItem( "min" );
+    QDomNode maxEntry = minMaxEntry.namedItem( "max" );
+
+    setMinimumValue( i + 1, minEntry.toElement().text().toDouble(), false );
+    setMaximumValue( i + 1, maxEntry.toElement().text().toDouble(), false );
+  }
+
+  QgsDebugMsg( "ReadXml: gray band name " + mGrayBandName );
+  QgsDebugMsg( "ReadXml: red band name " + mRedBandName );
+  QgsDebugMsg( "ReadXml: green band name  " + mGreenBandName );
+  QgsDebugMsg( "Drawing style " + getDrawingStyleAsString() );
+
+  /*
+   * Transparency tab
+   */
+  snode = mnl.namedItem( "mNoDataValue" );
+  myElement = snode.toElement();
+  setNoDataValue( myElement.text().toDouble() );
+  if ( myElement.attribute( "mValidNoDataValue", "false" ).compare( "true" ) )
+  {
+    // If flag element is not true, set to false.
+    mValidNoDataValue = false;
+  }
+
+  QDomNode singleValuePixelListNode = mnl.namedItem( "singleValuePixelList" );
+  if ( !singleValuePixelListNode.isNull() )
+  {
+    QList<QgsRasterTransparency::TransparentSingleValuePixel> newSingleValuePixelList;
+
+    //entries
+    QDomNodeList singleValuePixelList = singleValuePixelListNode.toElement().elementsByTagName( "pixelListEntry" );
+    for ( int i = 0; i < singleValuePixelList.size(); ++i )
+    {
+      QgsRasterTransparency::TransparentSingleValuePixel myNewItem;
+      QDomElement singleValuePixelListElement = singleValuePixelList.at( i ).toElement();
+      if ( singleValuePixelListElement.isNull() )
+      {
+        continue;
+      }
+
+      myNewItem.pixelValue = singleValuePixelListElement.attribute( "pixelValue" ).toDouble();
+      myNewItem.percentTransparent = singleValuePixelListElement.attribute( "percentTransparent" ).toDouble();
+
+      newSingleValuePixelList.push_back( myNewItem );
+    }
+    mRasterTransparency.setTransparentSingleValuePixelList( newSingleValuePixelList );
+  }
+
+  QDomNode threeValuePixelListNode = mnl.namedItem( "threeValuePixelList" );
+  if ( !threeValuePixelListNode.isNull() )
+  {
+    QList<QgsRasterTransparency::TransparentThreeValuePixel> newThreeValuePixelList;
+
+    //entries
+    QDomNodeList threeValuePixelList = threeValuePixelListNode.toElement().elementsByTagName( "pixelListEntry" );
+    for ( int i = 0; i < threeValuePixelList.size(); ++i )
+    {
+      QgsRasterTransparency::TransparentThreeValuePixel myNewItem;
+      QDomElement threeValuePixelListElement = threeValuePixelList.at( i ).toElement();
+      if ( threeValuePixelListElement.isNull() )
+      {
+        continue;
+      }
+
+      myNewItem.red = threeValuePixelListElement.attribute( "red" ).toDouble();
+      myNewItem.green = threeValuePixelListElement.attribute( "green" ).toDouble();
+      myNewItem.blue = threeValuePixelListElement.attribute( "blue" ).toDouble();
+      myNewItem.percentTransparent = threeValuePixelListElement.attribute( "percentTransparent" ).toDouble();
+
+      newThreeValuePixelList.push_back( myNewItem );
+    }
+    mRasterTransparency.setTransparentThreeValuePixelList( newThreeValuePixelList );
+  }
+
+  /*
+   * Color Ramp tab
+   */
+  //restore custom color ramp settings
+  QDomNode customColorRampNode = mnl.namedItem( "customColorRamp" );
+  if ( !customColorRampNode.isNull() )
+  {
+    QgsColorRampShader* myColorRampShader = ( QgsColorRampShader* ) mRasterShader->getRasterShaderFunction();
+
+    //TODO: Remove the customColorRampType check and following if() in v2.0, added for compatability with older ( bugged ) project files
+    QDomNode customColorRampTypeNode = customColorRampNode.namedItem( "customColorRampType" );
+    QDomNode colorRampTypeNode = customColorRampNode.namedItem( "colorRampType" );
+    QString myRampType = "";
+    if( "" == customColorRampTypeNode.toElement().text() )
+    {
+      myRampType = colorRampTypeNode.toElement().text();
+    }
+    else
+    {
+      myRampType = customColorRampTypeNode.toElement().text();
+    }
+    myColorRampShader->setColorRampType( myRampType );
+
+
+    //entries
+    QList<QgsColorRampShader::ColorRampItem> myColorRampItemList;
+    QDomNodeList colorRampEntryList = customColorRampNode.toElement().elementsByTagName( "colorRampEntry" );
+    for ( int i = 0; i < colorRampEntryList.size(); ++i )
+    {
+      QgsColorRampShader::ColorRampItem myNewItem;
+      QDomElement colorRampEntryElement = colorRampEntryList.at( i ).toElement();
+      if ( colorRampEntryElement.isNull() )
+      {
+        continue;
+      }
+
+      myNewItem.color = QColor( colorRampEntryElement.attribute( "red" ).toInt(), colorRampEntryElement.attribute( "green" ).toInt(), colorRampEntryElement.attribute( "blue" ).toInt() );
+      myNewItem.label = colorRampEntryElement.attribute( "label" );
+      myNewItem.value = colorRampEntryElement.attribute( "value" ).toDouble();
+
+      myColorRampItemList.push_back( myNewItem );
+    }
+    myColorRampShader->setColorRampItemList( myColorRampItemList );
+  }
+  return true; 
+} //readSymbology
+
 bool QgsRasterLayer::identify( const QgsPoint& point, QMap<QString, QString>& results )
 {
   results.clear();
@@ -4905,7 +4916,7 @@
                           paintYoffset );
 }
 
-QString QgsRasterLayer::getColorShadingAlgorithmAsQString()
+QString QgsRasterLayer::getColorShadingAlgorithmAsString() const
 {
   switch ( mColorShadingAlgorithm )
   {
@@ -4944,7 +4955,7 @@
     setColorShadingAlgorithm( UNDEFINED_SHADING_ALGORITHM );
 }
 
-QString QgsRasterLayer::getContrastEnhancementAlgorithmAsQString()
+QString QgsRasterLayer::getContrastEnhancementAlgorithmAsString() const
 {
   switch ( mContrastEnhancementAlgorithm )
   {

Modified: trunk/qgis/src/core/raster/qgsrasterlayer.h
===================================================================
--- trunk/qgis/src/core/raster/qgsrasterlayer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/raster/qgsrasterlayer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -331,7 +331,7 @@
     // Accessor and mutator for mInvertPixelsFlag
     //
     /** \brief Accessor to find out whether the histogram should be inverted.   */
-    bool getInvertHistogramFlag()
+    bool getInvertHistogramFlag() const
     {
       return mInvertPixelsFlag;
     }
@@ -344,7 +344,7 @@
     // Accessor and mutator for mStandardDeviations
     //
     /** \brief Accessor to find out how many standard deviations are being plotted.  */
-    double getStdDevsToPlot()
+    double getStdDevsToPlot() const
     {
       return mStandardDeviations;
     }
@@ -375,7 +375,7 @@
     /** \brief Call any inline image manipulation filters */
     void filterLayer( QImage * theQImage );
     /** \brief Accessor for red band name (allows alternate mappings e.g. map blue as red color). */
-    QString getRedBandName()
+    QString getRedBandName() const
     {
       return mRedBandName;
     }
@@ -385,7 +385,7 @@
     // Accessor and mutator for green band name
     //
     /** \brief Accessor for green band name mapping.  */
-    QString getGreenBandName()
+    QString getGreenBandName() const
     {
       return mGreenBandName;
     }
@@ -395,7 +395,7 @@
     // Accessor and mutator for blue band name
     //
     /** \brief  Accessor for blue band name mapping. */
-    QString getBlueBandName()
+    QString getBlueBandName() const
     {
       return mBlueBandName;
     }
@@ -412,7 +412,7 @@
     // Accessor and mutator for transparent band name
     //
     /** \brief  Accessor for transparent band name mapping. */
-    QString getTransparentBandName()
+    QString getTransparentBandName() const
     {
       return mTransparencyBandName;
     }
@@ -423,7 +423,7 @@
     // Accessor and mutator for gray band name
     //
     /** \brief Accessor for gray band name mapping.  */
-    QString getGrayBandName()
+    QString getGrayBandName() const
     {
       return mGrayBandName;
     }
@@ -540,7 +540,7 @@
     }
 
     /** \brief Accessor for contrast enhancement algorithm. */
-    QString getContrastEnhancementAlgorithmAsQString();
+    QString getContrastEnhancementAlgorithmAsString() const;
 
     /** \brief Mutator for contrast enhancement algorithm. */
     void setContrastEnhancementAlgorithm( QgsContrastEnhancement::CONTRAST_ENHANCEMENT_ALGORITHM theAlgorithm, bool theGenerateLookupTableFlag = true )
@@ -587,13 +587,13 @@
     // Accessor and mutator for the color shader algorithm
     //
     /** \brief Accessor for color shader algorithm. */
-    QgsRasterLayer::COLOR_SHADING_ALGORITHM getColorShadingAlgorithm()
+    QgsRasterLayer::COLOR_SHADING_ALGORITHM getColorShadingAlgorithm() const
     {
       return mColorShadingAlgorithm;
     }
 
     /** \brief Accessor for color shader algorithm. */
-    QString getColorShadingAlgorithmAsQString();
+    QString getColorShadingAlgorithmAsString() const;
 
     /** \brief Mutator for color shader algorithm. */
     void setColorShadingAlgorithm( QgsRasterLayer::COLOR_SHADING_ALGORITHM theShaderAlgorithm );
@@ -651,7 +651,7 @@
      * Implementaed mainly for serialisation / deserialisation of settings to xml.
      * NOTE: May be deprecated in the future!. Use alternate implementation above rather.
      * */
-    QString getDrawingStyleAsQString();
+    QString getDrawingStyleAsString() const;
     /** \brief Mutator for drawing style.  */
     void setDrawingStyle( const DRAWING_STYLE &  theDrawingStyle ) {drawingStyle = theDrawingStyle;}
     /** \brief Overloaded version of the above function for convenience when restoring from xml.
@@ -782,7 +782,7 @@
     }
 
     /** \brief Accessor for mUserDefinedRGBMinMaxFlag.  */
-    bool getUserDefinedRGBMinMax()
+    bool getUserDefinedRGBMinMax() const
     {
       return mUserDefinedRGBMinMaxFlag;
     }
@@ -794,7 +794,7 @@
     }
 
     /** \brief Accessor for mRGBActualMinimumMaximum.  */
-    bool getActualRGBMinMaxFlag()
+    bool getActualRGBMinMaxFlag() const
     {
       return mRGBActualMinimumMaximum;
     }
@@ -807,7 +807,7 @@
     }
 
     /** \brief Accessor for mUserDefinedGrayMinMaxFlag.  */
-    bool getUserDefinedGrayMinMax()
+    bool getUserDefinedGrayMinMax() const
     {
       return mUserDefinedGrayMinMaxFlag;
     }
@@ -819,7 +819,7 @@
     }
 
     /** \brief Accessor for mGrayActualMinimumMaximum.  */
-    bool getActualGrayMinMaxFlag()
+    bool getActualGrayMinMaxFlag() const
     {
       return mGrayActualMinimumMaximum;
     }
@@ -894,6 +894,21 @@
     */
     /* virtual */ bool writeXml( QDomNode & layer_node, QDomDocument & doc );
 
+     /** Read the symbology for the current layer from the Dom node supplied. 
+     * @param QDomNode node that will contain the symbology definition for this layer.
+     * @param errorMessage reference to string that will be updated with any error messages
+     * @return true in case of success.
+    */
+    bool readSymbology(const QDomNode& node, QString& errorMessage);
+
+    /** Write the symbology for the layer into the docment provided.
+     *  @param QDomNode the node that will have the style element added to it.
+     *  @param QDomDocument the document that will have the QDomNode added.
+     * @param errorMessage reference to string that will be updated with any error messages
+     *  @return true in case of success.
+     */
+    bool writeSymbology(QDomNode&, QDomDocument& doc, QString& errorMessage) const;
+
   private:
 
     //

Modified: trunk/qgis/src/core/raster/qgsrastertransparency.cpp
===================================================================
--- trunk/qgis/src/core/raster/qgsrastertransparency.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/raster/qgsrastertransparency.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -27,7 +27,7 @@
 /**
   Accessor for transparentSingleValuePixelList
 */
-QList<QgsRasterTransparency::TransparentSingleValuePixel> QgsRasterTransparency::getTransparentSingleValuePixelList()
+QList<QgsRasterTransparency::TransparentSingleValuePixel> QgsRasterTransparency::getTransparentSingleValuePixelList() const
 {
   return mTransparentSingleValuePixelList;
 }
@@ -35,7 +35,7 @@
 /**
   Accessor for transparentThreeValuePixelList
 */
-QList<QgsRasterTransparency::TransparentThreeValuePixel> QgsRasterTransparency::getTransparentThreeValuePixelList()
+QList<QgsRasterTransparency::TransparentThreeValuePixel> QgsRasterTransparency::getTransparentThreeValuePixelList() const
 {
   return mTransparentThreeValuePixelList;
 }
@@ -95,7 +95,7 @@
   @param theValue the needle to search for in the transparency hay stack
   @param theGlobalTransparency  the overal transparency level for the layer
 */
-int QgsRasterTransparency::getAlphaValue( double theValue, int theGlobalTransparency )
+int QgsRasterTransparency::getAlphaValue( double theValue, int theGlobalTransparency ) const
 {
   //if NaN return 0, transparent
   if ( theValue != theValue )
@@ -133,7 +133,7 @@
   @param theBlueValue the green portion of the needle to search for in the transparency hay stack
   @param theGlobalTransparency  the overal transparency level for the layer
 */
-int QgsRasterTransparency::getAlphaValue( double theRedValue, double theGreenValue, double theBlueValue, int theGlobalTransparency )
+int QgsRasterTransparency::getAlphaValue( double theRedValue, double theGreenValue, double theBlueValue, int theGlobalTransparency ) const
 {
   //if NaN return 0, transparent
   if ( theRedValue != theRedValue || theGreenValue != theGreenValue || theBlueValue != theBlueValue )

Modified: trunk/qgis/src/core/raster/qgsrastertransparency.h
===================================================================
--- trunk/qgis/src/core/raster/qgsrastertransparency.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/raster/qgsrastertransparency.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -49,10 +49,10 @@
     // Initializer, Accessor and mutator for transparency tables.
     //
     /** \brief Mutator for transparentSingleValuePixelList */
-    QList<QgsRasterTransparency::TransparentSingleValuePixel> getTransparentSingleValuePixelList();
+    QList<QgsRasterTransparency::TransparentSingleValuePixel> getTransparentSingleValuePixelList() const;
 
     /** \brief Mutator for transparentThreeValuePixelList */
-    QList<QgsRasterTransparency::TransparentThreeValuePixel> getTransparentThreeValuePixelList();
+    QList<QgsRasterTransparency::TransparentThreeValuePixel> getTransparentThreeValuePixelList() const;
 
     /** \brief Reset to the transparency list to a single value */
     void initializeTransparentPixelList( double );
@@ -67,9 +67,9 @@
     void setTransparentThreeValuePixelList( QList<QgsRasterTransparency::TransparentThreeValuePixel> );
 
     /** \brief Returns the transparency value for a single value Pixel */
-    int getAlphaValue( double, int theGlobalTransparency = 255 );
+    int getAlphaValue( double, int theGlobalTransparency = 255 ) const;
     /** \brief Return the transparency value for a RGB Pixel */
-    int getAlphaValue( double, double, double, int theGlobalTransparency = 255 );
+    int getAlphaValue( double, double, double, int theGlobalTransparency = 255 ) const;
 
   private:
     /** \brief The list to hold transparency values for RGB layers */

Modified: trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.cpp
===================================================================
--- trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -20,6 +20,7 @@
 #include "qgsmarkercatalogue.h"
 #include "qgssymbol.h"
 #include "qgssymbologyutils.h"
+#include "qgsvectordataprovider.h"
 #include "qgsvectorlayer.h"
 
 #include <cfloat>
@@ -179,13 +180,24 @@
   }
 }
 
-void QgsContinuousColorRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
+int QgsContinuousColorRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
 {
   mVectorType = vl.vectorType();
   QDomNode classnode = rnode.namedItem( "classificationfield" );
-  int classificationfield = classnode.toElement().text().toInt();
-  this->setClassificationField( classificationfield );
+  QString classificationField = classnode.toElement().text();
 
+  QgsVectorDataProvider* theProvider = vl.dataProvider();
+  if(!theProvider)
+    {
+      return 1;
+    }
+  int classificationId = theProvider->fieldNameIndex(classificationField);
+  if(classificationId == -1)
+    {
+      return 2; //@todo: handle gracefully in gui situation where user needs to nominate field 
+    }
+  this->setClassificationField(classificationId);
+
   //polygon outline
   QDomNode polyoutlinenode = rnode.namedItem( "polygonoutline" );
   QString polyoutline = polyoutlinenode.toElement().text();
@@ -216,6 +228,7 @@
     this->setMaximumSymbol( usy );
   }
   vl.setRenderer( this );
+  return 0;
 }
 
 QgsAttributeList QgsContinuousColorRenderer::classificationAttributes() const
@@ -230,14 +243,26 @@
   return "Continuous Color";
 }
 
-bool QgsContinuousColorRenderer::writeXML( QDomNode & layer_node, QDomDocument & document ) const
+bool QgsContinuousColorRenderer::writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const
 {
+  const QgsVectorDataProvider* theProvider = vl.dataProvider();
+  if(!theProvider)
+    {
+      return false;
+    }
+
+  QString classificationFieldName;
+  QgsFieldMap::const_iterator field_it = theProvider->fields().find(mClassificationField);
+  if(field_it != theProvider->fields().constEnd())
+    {
+      classificationFieldName = field_it.value().name();
+    }
   bool returnval = true;
 #ifndef WIN32
   QDomElement continuoussymbol = document.createElement( "continuoussymbol" );
   layer_node.appendChild( continuoussymbol );
   QDomElement classificationfield = document.createElement( "classificationfield" );
-  QDomText classificationfieldtxt = document.createTextNode( QString::number( mClassificationField ) );
+  QDomText classificationfieldtxt = document.createTextNode( classificationFieldName );
   classificationfield.appendChild( classificationfieldtxt );
   continuoussymbol.appendChild( classificationfield );
 

Modified: trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.h
===================================================================
--- trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgscontinuouscolorrenderer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -55,11 +55,13 @@
     bool drawPolygonOutline() const { return mDrawPolygonOutline; }
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read
-     @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML( const QDomNode& rnode, QgsVectorLayer& vl );
+     @param vl the vector layer which will be associated with the renderer
+     @return 0 in case of success, 1 if vector layer has no renderer, 2 if classification field not found
+    */
+    virtual int readXML( const QDomNode& rnode, QgsVectorLayer& vl );
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const;
     /** Returns true*/
     bool needsAttributes() const;
     /**Returns a list with the index of the classification attribute*/

Modified: trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.cpp
===================================================================
--- trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -22,6 +22,7 @@
 #include "qgsgraduatedsymbolrenderer.h"
 #include "qgssymbol.h"
 #include "qgssymbologyutils.h"
+#include "qgsvectordataprovider.h"
 #include "qgsvectorlayer.h"
 #include <math.h>
 #include <QDomNode>
@@ -190,13 +191,23 @@
   return ( *it );
 }
 
-void QgsGraduatedSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
+int QgsGraduatedSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
 {
   mVectorType = vl.vectorType();
   QDomNode classnode = rnode.namedItem( "classificationfield" );
-  int classificationfield = classnode.toElement().text().toInt();
+  QString classificationField = classnode.toElement().text();
 
-  this->setClassificationField( classificationfield );
+  QgsVectorDataProvider* theProvider = vl.dataProvider();
+  if(!theProvider)
+    {
+      return 1;
+    }
+  int classificationId = theProvider->fieldNameIndex(classificationField);
+  if(classificationId == -1)
+    {
+      return 2; //@todo: handle gracefully in gui situation where user needs to nominate field 
+    }
+  this->setClassificationField(classificationId);
 
   QDomNode symbolnode = rnode.namedItem( "symbol" );
   while ( !symbolnode.isNull() )
@@ -209,6 +220,7 @@
   }
   updateSymbolAttributes();
   vl.setRenderer( this );
+  return 0;
 }
 
 QgsAttributeList QgsGraduatedSymbolRenderer::classificationAttributes() const
@@ -249,13 +261,28 @@
   return "Graduated Symbol";
 }
 
-bool QgsGraduatedSymbolRenderer::writeXML( QDomNode & layer_node, QDomDocument & document ) const
+bool QgsGraduatedSymbolRenderer::writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl) const
 {
   bool returnval = true;
   QDomElement graduatedsymbol = document.createElement( "graduatedsymbol" );
   layer_node.appendChild( graduatedsymbol );
   QDomElement classificationfield = document.createElement( "classificationfield" );
-  QDomText classificationfieldtxt = document.createTextNode( QString::number( mClassificationField ) );
+
+  const QgsVectorDataProvider* theProvider = vl.dataProvider();
+  if(!theProvider)
+    {
+      return false;
+    }
+
+  QString classificationFieldName;
+  QgsFieldMap::const_iterator field_it = theProvider->fields().find(mClassificationField);
+  if(field_it != theProvider->fields().constEnd())
+    {
+      classificationFieldName = field_it.value().name();
+    }
+
+
+  QDomText classificationfieldtxt = document.createTextNode(classificationFieldName);
   classificationfield.appendChild( classificationfieldtxt );
   graduatedsymbol.appendChild( classificationfield );
   for ( QList<QgsSymbol*>::const_iterator it = mSymbols.begin(); it != mSymbols.end(); ++it )

Modified: trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.h
===================================================================
--- trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgsgraduatedsymbolrenderer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -34,7 +34,7 @@
     /**Adds a new item
     \param sy a pointer to the QgsSymbol to be inserted. It has to be created using the new operator and is automatically destroyed when 'removeItems' is called or when this object is destroyed*/
     void addSymbol( QgsSymbol* sy );
-    /**Returns the number of the classification field*/
+    /**Returns the indes of the classification field*/
     int classificationField() const;
     /**Removes all symbols*/
     void removeSymbols();
@@ -46,16 +46,18 @@
      \param f a pointer to a feature to render
      \param t the transform object containing the information how to transform the map coordinates to screen coordinates*/
     void renderFeature( QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0 );
-    /**Sets the number of the classicifation field
+    /**Sets the classicifation field by index
     \param field the number of the field to classify*/
-    void setClassificationField( int field );
+    void setClassificationField(int);
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read
-     @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML( const QDomNode& rnode, QgsVectorLayer& vl );
+     @param vl the vector layer which will be associated with the renderer
+     @return 0 in case of success, 1 if vector layer has no renderer, 2 if classification field not found
+    */
+    virtual int readXML( const QDomNode& rnode, QgsVectorLayer& vl );
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl) const;
     /** Returns true*/
     bool needsAttributes() const;
     /**Returns a list of all needed attributes*/
@@ -88,9 +90,9 @@
   return mClassificationField;
 }
 
-inline void QgsGraduatedSymbolRenderer::setClassificationField( int field )
+inline void QgsGraduatedSymbolRenderer::setClassificationField(int index)
 {
-  mClassificationField = field;
+  mClassificationField = index;
 }
 
 inline bool QgsGraduatedSymbolRenderer::needsAttributes() const

Modified: trunk/qgis/src/core/renderer/qgsrenderer.h
===================================================================
--- trunk/qgis/src/core/renderer/qgsrenderer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgsrenderer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -62,13 +62,14 @@
     virtual void renderFeature( QPainter* p, QgsFeature& f, QImage* pic, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0 ) = 0;
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read
-     @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML( const QDomNode& rnode, QgsVectorLayer& vl ) = 0;
+     @param vl the vector layer which will be associated with the renderer
+    @return 0 in case of success, 1 if vector layer has no renderer, 2 if classification field not found*/
+    virtual int readXML( const QDomNode& rnode, QgsVectorLayer& vl ) = 0;
     /**Writes the contents of the renderer to a configuration file*/
     // virtual void writeXML(std::ostream& xml)=0;
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const = 0;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl) const = 0;
     /** Returns true, if attribute values are used by the renderer and false otherwise*/
     virtual bool needsAttributes() const = 0;
     /**Returns a list with indexes of classification attributes*/

Modified: trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.cpp
===================================================================
--- trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -153,7 +153,7 @@
   }
 }
 
-void QgsSingleSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
+int QgsSingleSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
 {
   mVectorType = vl.vectorType();
   QgsSymbol* sy = new QgsSymbol( mVectorType );
@@ -174,9 +174,10 @@
   //create a renderer and add it to the vector layer
   this->addSymbol( sy );
   vl.setRenderer( this );
+  return 0;
 }
 
-bool QgsSingleSymbolRenderer::writeXML( QDomNode & layer_node, QDomDocument & document ) const
+bool QgsSingleSymbolRenderer::writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl) const
 {
   bool returnval = false;
   QDomElement singlesymbol = document.createElement( "singlesymbol" );

Modified: trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.h
===================================================================
--- trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgssinglesymbolrenderer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -38,13 +38,15 @@
     void renderFeature( QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0 );
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read
-     @param vl the vector layer which will be associated with the renderer*/
-    virtual void readXML( const QDomNode& rnode, QgsVectorLayer& vl );
+     @param vl the vector layer which will be associated with the renderer
+     @return 0 in case of success, 1 if vector layer has no renderer, 2 if classification field not found
+    */
+    virtual int readXML( const QDomNode& rnode, QgsVectorLayer& vl );
     /**Writes the contents of the renderer to a configuration file*/
     /*virtual void writeXML(std::ostream& xml);*/
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl) const;
     /**Returns true, attributes needed for single symbol*/
     bool needsAttributes() const;
     /**Returns a list of all needed attributes*/

Modified: trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.cpp
===================================================================
--- trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -18,6 +18,7 @@
 
 #include "qgsuniquevaluerenderer.h"
 #include "qgsfeature.h"
+#include "qgsvectordataprovider.h"
 #include "qgsvectorlayer.h"
 #include "qgssymbol.h"
 #include "qgssymbologyutils.h"
@@ -191,13 +192,25 @@
   }
 }
 
-void QgsUniqueValueRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
+int QgsUniqueValueRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
 {
   mVectorType = vl.vectorType();
   QDomNode classnode = rnode.namedItem( "classificationfield" );
-  int classificationfield = classnode.toElement().text().toInt();
-  this->setClassificationField( classificationfield );
+  QString classificationField = classnode.toElement().text();
 
+  QgsVectorDataProvider* theProvider = vl.dataProvider();
+  if(!theProvider)
+    {
+      return 1;
+    }
+
+  int classificationId = theProvider->fieldNameIndex(classificationField);
+  if(classificationId == -1)
+    {
+      return 2; //@todo: handle gracefully in gui situation where user needs to nominate field 
+    }
+  this->setClassificationField( classificationId );
+
   QDomNode symbolnode = rnode.namedItem( "symbol" );
   while ( !symbolnode.isNull() )
   {
@@ -208,6 +221,7 @@
   }
   updateSymbolAttributes();
   vl.setRenderer( this );
+  return 0;
 }
 
 void QgsUniqueValueRenderer::clearValues()
@@ -257,13 +271,26 @@
   return list;
 }
 
-bool QgsUniqueValueRenderer::writeXML( QDomNode & layer_node, QDomDocument & document ) const
+bool QgsUniqueValueRenderer::writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const
 {
+  const QgsVectorDataProvider* theProvider = vl.dataProvider();
+  if(!theProvider)
+    {
+      return false;
+    }
+
+  QString classificationFieldName;
+  QgsFieldMap::const_iterator field_it = theProvider->fields().find(mClassificationField);
+  if(field_it != theProvider->fields().constEnd())
+    {
+      classificationFieldName = field_it.value().name();
+    }
+
   bool returnval = true;
   QDomElement uniquevalue = document.createElement( "uniquevalue" );
   layer_node.appendChild( uniquevalue );
   QDomElement classificationfield = document.createElement( "classificationfield" );
-  QDomText classificationfieldtxt = document.createTextNode( QString::number( mClassificationField ) );
+  QDomText classificationfieldtxt = document.createTextNode( classificationFieldName );
   classificationfield.appendChild( classificationfieldtxt );
   uniquevalue.appendChild( classificationfield );
   for ( QMap<QString, QgsSymbol*>::const_iterator it = mSymbols.begin();it != mSymbols.end();++it )

Modified: trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.h
===================================================================
--- trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.h	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/src/core/renderer/qgsuniquevaluerenderer.h	2008-10-06 13:00:45 UTC (rev 9437)
@@ -34,11 +34,13 @@
     void renderFeature( QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0 );
     /**Reads the renderer configuration from an XML file
      @param rnode the Dom node to read
-     @param vl the vector layer which will be associated with the renderer*/
-    void readXML( const QDomNode& rnode, QgsVectorLayer& vl );
+     @param vl the vector layer which will be associated with the renderer
+     @return 0 in case of success, 1 if vector layer has no renderer, 2 if classification field not found
+    */
+    int readXML( const QDomNode& rnode, QgsVectorLayer& vl );
     /**Writes the contents of the renderer to a configuration file
      @ return true in case of success*/
-    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document ) const;
+    virtual bool writeXML( QDomNode & layer_node, QDomDocument & document, const QgsVectorLayer& vl ) const;
     /** Returns true, if attribute values are used by the renderer and false otherwise*/
     bool needsAttributes() const;
     /**Returns a list with indexes of classification attributes*/

Modified: trunk/qgis/tests/src/core/testqgsrenderers.cpp
===================================================================
--- trunk/qgis/tests/src/core/testqgsrenderers.cpp	2008-10-05 19:05:45 UTC (rev 9436)
+++ trunk/qgis/tests/src/core/testqgsrenderers.cpp	2008-10-06 13:00:45 UTC (rev 9437)
@@ -49,6 +49,7 @@
     void uniqueValue();
     void graduatedSymbol();
     void continuousSymbol();
+    void checkClassificationFieldMismatch();
   private:
     bool setQml( QString theType ); //uniquevalue / continuous / single /
     bool imageCheck( QString theType ); //as above
@@ -99,6 +100,7 @@
   // Register the layer with the registry
   QgsMapLayerRegistry::instance()->addMapLayer( mpPolysLayer );
 
+
   //
   // Create a line layer that will be used in all tests...
   //
@@ -162,6 +164,20 @@
   QVERIFY( setQml( "continuous" ) );
   QVERIFY( imageCheck( "continuous" ) );
 }
+
+void TestQgsRenderers::checkClassificationFieldMismatch()
+{
+  mReport += "<h2>Classification field mismatch test</h2>\n";
+  // Here we test to see that a qml created for one layer
+  // will raise an error properly if the 
+  // We will do this by trying to apply the points qml to the polys shpfile
+  // it should fail and raise an error
+  QString myFileName = mTestDataDir + "points_continuous_symbol.qml";
+  bool myStyleFlag = false;
+  mpPolysLayer->loadNamedStyle( myFileName, myStyleFlag );
+  QVERIFY( !myStyleFlag ); //we are expecting this to have raised an error
+}
+
 //
 // Private helper functions not called directly by CTest
 //



More information about the QGIS-commit mailing list