void QgsLayerStylingWidget::apply()
{
  if ( !mCurrentLayer )
    return;

  disconnect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );

  QString undoName = "Style Change";

  QWidget* current = mWidgetStack->mainWidget();

  bool styleWasChanged = false;
  if ( QgsLabelingWidget* widget = qobject_cast<QgsLabelingWidget*>( current ) )
  {
    widget->apply();
    styleWasChanged = true;
    undoName = "Label Change";
  }
  if ( QgsPanelWidgetWrapper* wrapper = qobject_cast<QgsPanelWidgetWrapper*>( current ) )
  {
    if ( QgsRendererPropertiesDialog* widget = qobject_cast<QgsRendererPropertiesDialog*>( wrapper->widget() ) )
    {
      widget->apply();
      QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( mCurrentLayer );
      QgsRendererAbstractMetadata* m = QgsRendererRegistry::instance()->rendererMetadata( layer->renderer()->type() );
      undoName = QString( "Style Change - %1" ).arg( m->visibleName() );
      styleWasChanged = true;
    }
  }
  else if ( QgsRasterTransparencyWidget* widget = qobject_cast<QgsRasterTransparencyWidget*>( current ) )
  {
    widget->apply();
    styleWasChanged = true;
  }
  else if ( qobject_cast<QgsRasterHistogramWidget*>( current ) )
  {
    mRasterStyleWidget->apply();
    styleWasChanged = true;
  }
  else if ( QgsMapLayerConfigWidget* widget = qobject_cast<QgsMapLayerConfigWidget*>( current ) )
  {
    widget->apply();
    styleWasChanged = true;
  }

  pushUndoItem( undoName );

  if ( styleWasChanged )
  {
    emit styleChanged( mCurrentLayer );
    QgsProject::instance()->setDirty( true );
    mMapCanvas->clearCache();
    mMapCanvas->refresh();
  }
  connect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
}
void QgsLayerStylingWidget::blockUpdates( bool blocked )
{
  if ( !mCurrentLayer )
    return;

  if ( blocked )
  {
    disconnect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
  }
  else
  {
    connect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
  }
}
void QgsMapStylingWidget::setLayer( QgsMapLayer *layer )
{
  if ( !layer || !layer->isSpatial() )
  {
    mLayerTitleLabel->clear();
    mStackedWidget->setCurrentIndex( mNotSupportedPage );
    return;
  }

  mCurrentLayer = layer;

  // TODO Adjust for raster
  updateCurrentWidgetLayer( mMapStyleTabs->currentIndex() );
}
void QgsLayerStylingWidget::redo()
{
  mUndoWidget->redo();
  updateCurrentWidgetLayer();
}
void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer )
{
  if ( layer == mCurrentLayer )
    return;

  if ( mCurrentLayer )
  {
    disconnect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );
  }

  if ( !layer || !layer->isSpatial() )
  {
    mLayerCombo->setLayer( nullptr );
    mStackedWidget->setCurrentIndex( mNotSupportedPage );
    mLastStyleXml.clear();
    mCurrentLayer = nullptr;
    return;
  }

  bool sameLayerType = false;
  if ( mCurrentLayer )
  {
    sameLayerType =  mCurrentLayer->type() == layer->type();
  }

  mCurrentLayer = layer;

  mUndoWidget->setUndoStack( layer->undoStackStyles() );

  connect( mCurrentLayer, SIGNAL( styleChanged() ), this, SLOT( updateCurrentWidgetLayer() ) );

  int lastPage = mOptionsListWidget->currentIndex().row();
  mOptionsListWidget->blockSignals( true );
  mOptionsListWidget->clear();
  mUserPages.clear();
  if ( layer->type() == QgsMapLayer::VectorLayer )
  {
    QListWidgetItem* symbolItem = new QListWidgetItem( QgsApplication::getThemeIcon( "propertyicons/symbology.svg" ), QString() );
    symbolItem->setData( Qt::UserRole, Symbology );
    symbolItem->setToolTip( tr( "Symbology" ) );
    mOptionsListWidget->addItem( symbolItem );
    QListWidgetItem* labelItem = new QListWidgetItem( QgsApplication::getThemeIcon( "labelingSingle.svg" ), QString() );
    labelItem->setData( Qt::UserRole, VectorLabeling );
    labelItem->setToolTip( tr( "Labels" ) );
    mOptionsListWidget->addItem( labelItem );
  }
  else if ( layer->type() == QgsMapLayer::RasterLayer )
  {
    QListWidgetItem* symbolItem = new QListWidgetItem( QgsApplication::getThemeIcon( "propertyicons/symbology.svg" ), QString() );
    symbolItem->setData( Qt::UserRole, Symbology );
    symbolItem->setToolTip( tr( "Symbology" ) );
    mOptionsListWidget->addItem( symbolItem );
    QListWidgetItem* transparencyItem = new QListWidgetItem( QgsApplication::getThemeIcon( "propertyicons/transparency.png" ), QString() );
    transparencyItem->setToolTip( tr( "Transparency" ) );
    transparencyItem->setData( Qt::UserRole, RasterTransparency );
    mOptionsListWidget->addItem( transparencyItem );

    if ( static_cast<QgsRasterLayer*>( layer )->dataProvider()->capabilities() & QgsRasterDataProvider::Size )
    {
      QListWidgetItem* histogramItem = new QListWidgetItem( QgsApplication::getThemeIcon( "propertyicons/histogram.png" ), QString() );
      histogramItem->setData( Qt::UserRole, RasterHistogram );
      mOptionsListWidget->addItem( histogramItem );
      histogramItem->setToolTip( tr( "Histogram" ) );
    }
  }

  Q_FOREACH ( QgsMapLayerConfigWidgetFactory* factory, mPageFactories )
  {
    if ( factory->supportsStyleDock() && factory->supportsLayer( layer ) )
    {
      QListWidgetItem* item =  new QListWidgetItem( factory->icon(), QString() );
      item->setToolTip( factory->title() );
      mOptionsListWidget->addItem( item );
      int row = mOptionsListWidget->row( item );
      mUserPages[row] = factory;
    }
  }
  QListWidgetItem* historyItem = new QListWidgetItem( QgsApplication::getThemeIcon( "mActionHistory.svg" ), QString() );
  historyItem->setData( Qt::UserRole, History );
  historyItem->setToolTip( tr( "History" ) );
  mOptionsListWidget->addItem( historyItem );
  mOptionsListWidget->blockSignals( false );

  if ( sameLayerType )
  {
    mOptionsListWidget->setCurrentRow( lastPage );
  }
  else
  {
    mOptionsListWidget->setCurrentRow( 0 );
  }

  mStackedWidget->setCurrentIndex( 1 );

  QString errorMsg;
  QDomDocument doc( "style" );
  mLastStyleXml = doc.createElement( "style" );
  doc.appendChild( mLastStyleXml );
  mCurrentLayer->writeStyle( mLastStyleXml, doc, errorMsg );
}