void QgsLayerTreeMapCanvasBridge::defaultLayerOrder( QgsLayerTreeNode* node, QStringList& order ) const
{
  if ( QgsLayerTree::isLayer( node ) )
  {
    QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer( node );
    order << nodeLayer->layerId();
  }

  foreach ( QgsLayerTreeNode* child, node->children() )
    defaultLayerOrder( child, order );
}
void QgsLayerTreeMapCanvasBridge::setCustomLayerOrder( const QStringList& order )
{
  if ( mCustomLayerOrder == order )
    return;

  // verify that the new order is correct
  QStringList defOrder( defaultLayerOrder() );
  QStringList newOrder( order );
  QStringList sortedNewOrder( order );
  qSort( defOrder );
  qSort( sortedNewOrder );

  if ( defOrder.size() < sortedNewOrder.size() )
  {
    // might contain bad layers, but also duplicates
    QSet<QString> ids( defOrder.toSet() );

    for ( int i = 0; i < sortedNewOrder.size(); i++ )
    {
      if ( !ids.contains( sortedNewOrder[i] ) )
      {
        newOrder.removeAll( sortedNewOrder[i] );
        sortedNewOrder.removeAt( i-- );
      }
    }
  }

  if ( defOrder != sortedNewOrder )
    return; // must be permutation of the default order

  mCustomLayerOrder = newOrder;
  emit customLayerOrderChanged( mCustomLayerOrder );

  if ( mHasCustomLayerOrder )
    deferredSetCanvasLayers();
}
QStringList QgsLayerTreeMapCanvasBridge::defaultLayerOrder() const
{
  QStringList order;
  defaultLayerOrder( mRoot, order );
  return order;
}
void QgsLayerTreeMapCanvasBridge::clear()
{
  setHasCustomLayerOrder( false );
  setCustomLayerOrder( defaultLayerOrder() );
}
QStringList LayerTreeMapCanvasBridge::defaultLayerOrder() const
{
  QStringList order;
  defaultLayerOrder( mModel->rootGroup(), order );
  return order;
}