QgsFields QgsAuxiliaryLayer::auxiliaryFields() const
{
  QgsFields afields;

  for ( int i = 2; i < fields().count(); i++ ) // ignore rowid and PK field
    afields.append( createAuxiliaryField( fields().field( i ) ) );

  return afields;
}
QgsField QgsAuxiliaryLayer::createAuxiliaryField( const QgsField &field )
{
  QgsPropertyDefinition def = propertyDefinitionFromField( field );
  QgsField afield;

  if ( !def.name().isEmpty() || !def.comment().isEmpty() )
  {
    afield = createAuxiliaryField( def );
    afield.setTypeName( field.typeName() );
  }

  return afield;
}
bool QgsAuxiliaryLayer::addAuxiliaryField( const QgsPropertyDefinition &definition )
{
  if ( ( definition.name().isEmpty() && definition.comment().isEmpty() ) || exists( definition ) )
    return false;

  const QgsField af = createAuxiliaryField( definition );
  const bool rc = addAttribute( af );
  updateFields();
  mLayer->updateFields();

  if ( rc )
  {
    int auxIndex = indexOfPropertyDefinition( definition );
    int index = mLayer->fields().indexOf( nameFromProperty( definition, true ) );

    if ( index >= 0 && auxIndex >= 0 )
    {
      if ( isHiddenProperty( auxIndex ) )
      {
        // update editor widget
        QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Hidden" ), QVariantMap() );
        setEditorWidgetSetup( auxIndex, setup );

        // column is hidden
        QgsAttributeTableConfig attrCfg = mLayer->attributeTableConfig();
        attrCfg.update( mLayer->fields() );
        QVector<QgsAttributeTableConfig::ColumnConfig> columns = attrCfg.columns();
        QVector<QgsAttributeTableConfig::ColumnConfig>::iterator it;

        for ( it = columns.begin(); it != columns.end(); ++it )
        {
          if ( it->name.compare( mLayer->fields().field( index ).name() ) == 0 )
            it->hidden = true;
        }

        attrCfg.setColumns( columns );
        mLayer->setAttributeTableConfig( attrCfg );
      }
      else if ( definition.standardTemplate() == QgsPropertyDefinition::ColorNoAlpha
                || definition.standardTemplate() == QgsPropertyDefinition::ColorWithAlpha )
      {
        QgsEditorWidgetSetup setup = QgsEditorWidgetSetup( QStringLiteral( "Color" ), QVariantMap() );
        setEditorWidgetSetup( auxIndex, setup );
      }

      mLayer->setEditorWidgetSetup( index, editorWidgetSetup( auxIndex ) );
    }
  }

  return rc;
}
void QgsPropertyOverrideButton::menuActionTriggered( QAction *action )
{
  if ( action == mActionActive )
  {
    setActivePrivate( mActionActive->data().toBool() );
    updateGui();
    emit changed();
  }
  else if ( action == mActionDescription )
  {
    showDescriptionDialog();
  }
  else if ( action == mActionExpDialog )
  {
    showExpressionDialog();
  }
  else if ( action == mActionExpression )
  {
    mProperty.setExpressionString( mExpressionString );
    mProperty.setTransformer( nullptr );
    setActivePrivate( true );
    updateSiblingWidgets( isActive() );
    updateGui();
    emit changed();
  }
  else if ( action == mActionCopyExpr )
  {
    QApplication::clipboard()->setText( mExpressionString );
  }
  else if ( action == mActionPasteExpr )
  {
    QString exprString = QApplication::clipboard()->text();
    if ( !exprString.isEmpty() )
    {
      mExpressionString = exprString;
      mProperty.setExpressionString( mExpressionString );
      mProperty.setTransformer( nullptr );
      setActivePrivate( true );
      updateSiblingWidgets( isActive() );
      updateGui();
      emit changed();
    }
  }
  else if ( action == mActionClearExpr )
  {
    setActivePrivate( false );
    mProperty.setStaticValue( QVariant() );
    mProperty.setTransformer( nullptr );
    mExpressionString.clear();
    updateSiblingWidgets( isActive() );
    updateGui();
    emit changed();
  }
  else if ( action == mActionAssistant )
  {
    showAssistant();
  }
  else if ( action == mActionCreateAuxiliaryField )
  {
    emit createAuxiliaryField();
  }
  else if ( mFieldsMenu->actions().contains( action ) )  // a field name clicked
  {
    if ( action->isEnabled() )
    {
      if ( mFieldName != action->text() )
      {
        mFieldName = action->data().toString();
      }
      mProperty.setField( mFieldName );
      mProperty.setTransformer( nullptr );
      setActivePrivate( true );
      updateSiblingWidgets( isActive() );
      updateGui();
      emit changed();
    }
  }
  else if ( mVariablesMenu->actions().contains( action ) )  // a variable name clicked
  {
    if ( mExpressionString != action->text().prepend( "@" ) )
    {
      mExpressionString = action->data().toString().prepend( "@" );
    }
    mProperty.setExpressionString( mExpressionString );
    mProperty.setTransformer( nullptr );
    setActivePrivate( true );
    updateSiblingWidgets( isActive() );
    updateGui();
    emit changed();
  }
}