int QgsUniqueValueRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
{
  mGeometryType = vl.geometryType();
  QDomNode classnode = rnode.namedItem( "classificationfield" );
  QString classificationField = classnode.toElement().text();

  QgsVectorDataProvider* theProvider = vl.dataProvider();
  if ( !theProvider )
  {
    return 1;
  }

  int classificationId = vl.fieldNameIndex( classificationField );
  if ( classificationId == -1 )
  {
    //go on. Because with joins, it might be the joined layer is not loaded yet
  }
  setClassificationField( classificationId );

  QDomNode symbolnode = rnode.namedItem( "symbol" );
  while ( !symbolnode.isNull() )
  {
    QgsSymbol* msy = new QgsSymbol( mGeometryType );
    msy->readXML( symbolnode, &vl );
    insertValue( msy->lowerValue(), msy );
    symbolnode = symbolnode.nextSibling();
  }
  updateSymbolAttributes();
  vl.setRenderer( this );
  return 0;
}
QgsSingleSymbolRenderer::QgsSingleSymbolRenderer( QGis::GeometryType type )
{
  mGeometryType = type;

  //initial setting based on random color
  QgsSymbol* sy = new QgsSymbol( mGeometryType );

  //random fill colors for points and polygons and pen colors for lines
  int red = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
  int green = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );
  int blue = 1 + ( int )( 255.0 * rand() / ( RAND_MAX + 1.0 ) );

  if ( type == QGis::Line )
  {
    sy->setColor( QColor( red, green, blue ) );
  }
  else
  {
    sy->setFillColor( QColor( red, green, blue ) );
    sy->setFillStyle( Qt::SolidPattern );
    sy->setColor( QColor( 0, 0, 0 ) );
  }
  mSymbol = sy;
  updateSymbolAttributes();
}
void QgsUniqueValueRenderer::clearValues()
{
  for ( QMap<QString, QgsSymbol*>::iterator it = mSymbols.begin(); it != mSymbols.end(); ++it )
  {
    delete it.value();
  }
  mSymbols.clear();
  updateSymbolAttributes();
}
QgsSingleSymbolRenderer& QgsSingleSymbolRenderer::operator=( const QgsSingleSymbolRenderer & other )
{
  if ( this != &other )
  {
    mGeometryType = other.mGeometryType;
    delete mSymbol;
    mSymbol = new QgsSymbol( *other.mSymbol );
  }
  updateSymbolAttributes();
  return *this;
}
QgsUniqueValueRenderer::QgsUniqueValueRenderer( const QgsUniqueValueRenderer& other )
{
  mGeometryType = other.mGeometryType;
  mClassificationField = other.mClassificationField;
  QMap<QString, QgsSymbol*> s = other.mSymbols;
  for ( QMap<QString, QgsSymbol*>::iterator it = s.begin(); it != s.end(); ++it )
  {
    QgsSymbol* s = new QgsSymbol( * it.value() );
    insertValue( it.key(), s );
  }
  updateSymbolAttributes();
}
void QgsGraduatedSymbolRenderer::removeSymbols()
{
  //free the memory first
  for ( QList<QgsSymbol*>::iterator it = mSymbols.begin(); it != mSymbols.end(); ++it )
  {
    delete *it;
  }

  //and remove the pointers then
  mSymbols.clear();
  updateSymbolAttributes();
}
QgsGraduatedSymbolRenderer::QgsGraduatedSymbolRenderer( const QgsGraduatedSymbolRenderer& other )
{
  mMode = other.mMode;
  mGeometryType = other.mGeometryType;
  mClassificationField = other.mClassificationField;
  const QList<QgsSymbol*> s = other.symbols();
  for ( QList<QgsSymbol*>::const_iterator it = s.begin(); it != s.end(); ++it )
  {
    addSymbol( new QgsSymbol( **it ) );
  }
  updateSymbolAttributes();
}
QgsUniqueValueRenderer& QgsUniqueValueRenderer::operator=( const QgsUniqueValueRenderer & other )
{
  if ( this != &other )
  {
    mGeometryType = other.mGeometryType;
    mClassificationField = other.mClassificationField;
    clearValues();
    for ( QMap<QString, QgsSymbol*>::iterator it = mSymbols.begin(); it != mSymbols.end(); ++it )
    {
      QgsSymbol* s = new QgsSymbol( *it.value() );
      insertValue( it.key(), s );
    }
    updateSymbolAttributes();
  }
  return *this;
}
int QgsGraduatedSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
{
  mGeometryType = vl.geometryType();
  QDomNode modeNode = rnode.namedItem( "mode" );
  QString modeValue = modeNode.toElement().text();
  QDomNode classnode = rnode.namedItem( "classificationfield" );
  QString classificationField = classnode.toElement().text();

  QgsVectorDataProvider* theProvider = vl.dataProvider();
  if ( !theProvider )
  {
    return 1;
  }
  if ( modeValue == "Empty" )
  {
    mMode = QgsGraduatedSymbolRenderer::Empty;
  }
  else if ( modeValue == "Quantile" )
  {
    mMode = QgsGraduatedSymbolRenderer::Quantile;
  }
  else //default
  {
    mMode = QgsGraduatedSymbolRenderer::EqualInterval;
  }

  int classificationId = theProvider->fieldNameIndex( classificationField );
  if ( classificationId == -1 )
  {
    return 2; //@todo: handle gracefully in gui situation where user needs to nominate field
  }
  setClassificationField( classificationId );

  QDomNode symbolnode = rnode.namedItem( "symbol" );
  while ( !symbolnode.isNull() )
  {
    QgsSymbol* sy = new QgsSymbol( mGeometryType );
    sy->readXML( symbolnode, &vl );
    addSymbol( sy );

    symbolnode = symbolnode.nextSibling();
  }
  updateSymbolAttributes();
  vl.setRenderer( this );
  return 0;
}
int QgsGraduatedSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
{
  mGeometryType = vl.geometryType();
  QDomNode modeNode = rnode.namedItem( "mode" );
  QString modeValue = modeNode.toElement().text();
  QDomNode classnode = rnode.namedItem( "classificationfield" );
  QString classificationField = classnode.toElement().text();

  QgsVectorDataProvider* theProvider = vl.dataProvider();
  if ( !theProvider )
  {
    return 1;
  }
  if ( modeValue == "Empty" )
  {
    mMode = QgsGraduatedSymbolRenderer::Empty;
  }
  else if ( modeValue == "Quantile" )
  {
    mMode = QgsGraduatedSymbolRenderer::Quantile;
  }
  else //default
  {
    mMode = QgsGraduatedSymbolRenderer::EqualInterval;
  }

  int classificationId = vl.fieldNameIndex( classificationField );
  if ( classificationId == -1 )
  {
    //go on. Because with joins, it might be the joined layer is not loaded yet
  }
  setClassificationField( classificationId );

  QDomNode symbolnode = rnode.namedItem( "symbol" );
  while ( !symbolnode.isNull() )
  {
    QgsSymbol* sy = new QgsSymbol( mGeometryType );
    sy->readXML( symbolnode, &vl );
    addSymbol( sy );

    symbolnode = symbolnode.nextSibling();
  }
  updateSymbolAttributes();
  vl.setRenderer( this );
  return 0;
}
int QgsSingleSymbolRenderer::readXML( const QDomNode& rnode, QgsVectorLayer& vl )
{
  mGeometryType = vl.geometryType();
  QgsSymbol* sy = new QgsSymbol( mGeometryType );

  QDomNode synode = rnode.namedItem( "symbol" );

  if ( synode.isNull() )
  {
    QgsDebugMsg( "No symbol node in project file's renderitem Dom" );
    // XXX abort?
  }
  else
  {
    sy->readXML( synode, &vl );
  }
  updateSymbolAttributes();

  //create a renderer and add it to the vector layer
  addSymbol( sy );
  vl.setRenderer( this );
  return 0;
}
void QgsSingleSymbolRenderer::addSymbol( QgsSymbol* sy )
{
  delete mSymbol;
  mSymbol = sy;
  updateSymbolAttributes();
}
QgsSingleSymbolRenderer::QgsSingleSymbolRenderer( const QgsSingleSymbolRenderer& other )
{
  mGeometryType = other.mGeometryType;
  mSymbol = new QgsSymbol( *other.mSymbol );
  updateSymbolAttributes();
}