QgsPalettedRasterRenderer* QgsPalettedRasterRenderer::clone() const
{
  QgsPalettedRasterRenderer * renderer = new QgsPalettedRasterRenderer( nullptr, mBand, rgbArray(), mNColors );
  renderer->copyCommonProperties( this );

  renderer->mLabels = mLabels;
  return renderer;
}
QgsRasterRenderer* QgsPalettedRasterRenderer::create( const QDomElement& elem, QgsRasterInterface* input )
{
    if ( elem.isNull() )
    {
        return 0;
    }

    int bandNumber = elem.attribute( "band", "-1" ).toInt();
    int nColors = 0;
    QRgb* colors = 0;
    QVector<QString> labels;

    QDomElement paletteElem = elem.firstChildElement( "colorPalette" );
    if ( !paletteElem.isNull() )
    {
        QDomNodeList paletteEntries = paletteElem.elementsByTagName( "paletteEntry" );

        QDomElement entryElem;
        int value;
        nColors = 0;

        // We cannot believe that data are correct, check first max value
        for ( int i = 0; i < paletteEntries.size(); ++i )
        {
            entryElem = paletteEntries.at( i ).toElement();
            // Could be written as doubles (with .0000) in old project files
            value = ( int )entryElem.attribute( "value", "0" ).toDouble();
            if ( value >= nColors && value <= 10000 ) nColors = value + 1;
        }
        QgsDebugMsg( QString( "nColors = %1" ).arg( nColors ) );

        colors = new QRgb[ nColors ];

        for ( int i = 0; i < nColors; ++i )
        {
            entryElem = paletteEntries.at( i ).toElement();
            value = ( int )entryElem.attribute( "value", "0" ).toDouble();
            QgsDebugMsg( entryElem.attribute( "color", "#000000" ) );
            if ( value >= 0 && value < nColors )
            {
                colors[value] = QColor( entryElem.attribute( "color", "#000000" ) ).rgba();
                QString label = entryElem.attribute( "label" );
                if ( !label.isEmpty() )
                {
                    if ( value >= labels.size() ) labels.resize( value + 1 );
                    labels[value] = label;
                }
            }
            else
            {
                QgsDebugMsg( QString( "value %1 out of range" ).arg( value ) );
            }
        }
    }
    QgsPalettedRasterRenderer* r = new QgsPalettedRasterRenderer( input, bandNumber, colors, nColors, labels );
    r->readXML( elem );
    return r;
}
QgsRasterInterface * QgsPalettedRasterRenderer::clone() const
{
    QgsPalettedRasterRenderer * renderer = new QgsPalettedRasterRenderer( 0, mBand, rgbArray(), mNColors );
    renderer->setOpacity( mOpacity );
    renderer->setAlphaBand( mAlphaBand );
    renderer->setRasterTransparency( mRasterTransparency );
    renderer->mLabels = mLabels;
    return renderer;
}
QgsPalettedRasterRenderer *QgsPalettedRasterRenderer::clone() const
{
  QgsPalettedRasterRenderer *renderer = new QgsPalettedRasterRenderer( nullptr, mBand, mClassData );
  if ( mSourceColorRamp )
    renderer->setSourceColorRamp( mSourceColorRamp->clone() );

  renderer->copyCommonProperties( this );
  return renderer;
}
QgsRasterRenderer *QgsPalettedRendererWidget::renderer()
{
  QgsPalettedRasterRenderer::ClassData classes = mModel->classData();
  int bandNumber = mBandComboBox->currentBand();

  QgsPalettedRasterRenderer *r = new QgsPalettedRasterRenderer( mRasterLayer->dataProvider(), bandNumber, classes );
  if ( !btnColorRamp->isNull() )
  {
    r->setSourceColorRamp( btnColorRamp->colorRamp() );
  }
  return r;
}
QgsRasterRenderer *QgsPalettedRasterRenderer::create( const QDomElement &elem, QgsRasterInterface *input )
{
  if ( elem.isNull() )
  {
    return nullptr;
  }

  int bandNumber = elem.attribute( QStringLiteral( "band" ), QStringLiteral( "-1" ) ).toInt();
  ClassData classData;

  QDomElement paletteElem = elem.firstChildElement( QStringLiteral( "colorPalette" ) );
  if ( !paletteElem.isNull() )
  {
    QDomNodeList paletteEntries = paletteElem.elementsByTagName( QStringLiteral( "paletteEntry" ) );

    QDomElement entryElem;
    int value;

    for ( int i = 0; i < paletteEntries.size(); ++i )
    {
      QColor color;
      QString label;
      entryElem = paletteEntries.at( i ).toElement();
      value = static_cast<int>( entryElem.attribute( QStringLiteral( "value" ), QStringLiteral( "0" ) ).toDouble() );
      QgsDebugMsgLevel( entryElem.attribute( "color", "#000000" ), 4 );
      color = QColor( entryElem.attribute( QStringLiteral( "color" ), QStringLiteral( "#000000" ) ) );
      color.setAlpha( entryElem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "255" ) ).toInt() );
      label = entryElem.attribute( QStringLiteral( "label" ) );
      classData << Class( value, color, label );
    }
  }

  QgsPalettedRasterRenderer *r = new QgsPalettedRasterRenderer( input, bandNumber, classData );
  r->readXml( elem );

  // try to load color ramp (optional)
  QDomElement sourceColorRampElem = elem.firstChildElement( QStringLiteral( "colorramp" ) );
  if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral( "name" ) ) == QLatin1String( "[source]" ) )
  {
    r->setSourceColorRamp( QgsSymbolLayerUtils::loadColorRamp( sourceColorRampElem ) );
  }

  return r;
}