20 #include <QMessageBox> 
   21 #include <QPushButton> 
   22 #include <QStandardItemModel> 
   23 #include <QToolButton> 
   24 #include <QItemSelectionModel> 
   43 QgsProcessingAggregatePanelWidget::QgsProcessingAggregatePanelWidget( QWidget *parent )
 
   48   mModel = mFieldsView->model();
 
   50   mLayerCombo->setAllowEmptyLayer( 
true );
 
   53   connect( mResetButton, &QPushButton::clicked, 
this, &QgsProcessingAggregatePanelWidget::loadFieldsFromLayer );
 
   54   connect( mAddButton, &QPushButton::clicked, 
this, &QgsProcessingAggregatePanelWidget::addField );
 
   58   connect( mLoadLayerFieldsButton, &QPushButton::clicked, 
this, &QgsProcessingAggregatePanelWidget::loadLayerFields );
 
   62     if ( !mBlockChangedSignal )
 
   69 void QgsProcessingAggregatePanelWidget::setLayer( 
QgsVectorLayer *layer )
 
   71   if ( layer == mLayer )
 
   75   mFieldsView->setSourceLayer( mLayer );
 
   76   if ( mModel->rowCount() == 0 )
 
   78     loadFieldsFromLayer();
 
   82   QMessageBox dlg( 
this );
 
   83   dlg.setText( tr( 
"Do you want to reset the field mapping?" ) );
 
   84   dlg.setStandardButtons(
 
   85     QMessageBox::StandardButtons( QMessageBox::Yes |
 
   87   dlg.setDefaultButton( QMessageBox::No );
 
   88   if ( dlg.exec() == QMessageBox::Yes )
 
   90     loadFieldsFromLayer();
 
   99 QVariant QgsProcessingAggregatePanelWidget::value()
 const 
  101   const QList<QgsAggregateMappingModel::Aggregate> mapping = mFieldsView->mapping();
 
  103   QVariantList results;
 
  104   results.reserve( mapping.size() );
 
  108     def.insert( QStringLiteral( 
"name" ), aggregate.field.name() );
 
  109     def.insert( QStringLiteral( 
"type" ), 
static_cast< int >( aggregate.field.type() ) );
 
  110     def.insert( QStringLiteral( 
"type_name" ), aggregate.field.typeName() );
 
  111     def.insert( QStringLiteral( 
"length" ), aggregate.field.length() );
 
  112     def.insert( QStringLiteral( 
"precision" ), aggregate.field.precision() );
 
  113     def.insert( QStringLiteral( 
"sub_type" ), 
static_cast< int >( aggregate.field.subType() ) );
 
  114     def.insert( QStringLiteral( 
"input" ), aggregate.source );
 
  115     def.insert( QStringLiteral( 
"aggregate" ), aggregate.aggregate );
 
  116     def.insert( QStringLiteral( 
"delimiter" ), aggregate.delimiter );
 
  117     results.append( def );
 
  122 void QgsProcessingAggregatePanelWidget::setValue( 
const QVariant &value )
 
  124   if ( value.type() != QVariant::List )
 
  127   QList< QgsAggregateMappingModel::Aggregate > aggregates;
 
  129   const QVariantList fields = value.toList();
 
  130   aggregates.reserve( fields.size() );
 
  131   for ( 
const QVariant &
field : fields )
 
  133     const QVariantMap map = 
field.toMap();
 
  134     const QgsField f( map.value( QStringLiteral( 
"name" ) ).toString(),
 
  135                       static_cast< QVariant::Type 
>( map.value( QStringLiteral( 
"type" ), QVariant::Invalid ).toInt() ),
 
  136                       map.value( QStringLiteral( 
"type_name" ), QVariant::typeToName( 
static_cast< QVariant::Type 
>( map.value( QStringLiteral( 
"type" ), QVariant::Invalid ).toInt() ) ) ).toString(),
 
  137                       map.value( QStringLiteral( 
"length" ), 0 ).toInt(),
 
  138                       map.value( QStringLiteral( 
"precision" ), 0 ).toInt(),
 
  140                       static_cast< QVariant::Type 
>( map.value( QStringLiteral( 
"sub_type" ), QVariant::Invalid ).toInt() ) );
 
  145     aggregate.
source = map.value( QStringLiteral( 
"input" ) ).toString();
 
  146     aggregate.
aggregate = map.value( QStringLiteral( 
"aggregate" ) ).toString();
 
  147     aggregate.
delimiter = map.value( QStringLiteral( 
"delimiter" ) ).toString();
 
  149     aggregates.append( aggregate );
 
  152   mBlockChangedSignal = 
true;
 
  154   if ( aggregates.size() > 0 )
 
  155     mFieldsView->setMapping( aggregates );
 
  157   mBlockChangedSignal = 
false;
 
  164   mFieldsView->registerExpressionContextGenerator( generator );
 
  167 void QgsProcessingAggregatePanelWidget::loadFieldsFromLayer()
 
  171     mFieldsView->setSourceFields( mLayer->fields() );
 
  175 void QgsProcessingAggregatePanelWidget::addField()
 
  177   const int rowCount = mModel->rowCount();
 
  178   mModel->appendField( 
QgsField( QStringLiteral( 
"new_field" ) ) );
 
  179   const QModelIndex index = mModel->index( rowCount, 0 );
 
  180   mFieldsView->selectionModel()->select(
 
  182     QItemSelectionModel::SelectionFlags(
 
  183       QItemSelectionModel::Clear |
 
  184       QItemSelectionModel::Select |
 
  185       QItemSelectionModel::Current |
 
  186       QItemSelectionModel::Rows ) );
 
  187   mFieldsView->scrollTo( index );
 
  190 void QgsProcessingAggregatePanelWidget::loadLayerFields()
 
  192   if ( 
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( mLayerCombo->currentLayer() ) )
 
  194     mFieldsView->setSourceFields( vl->fields() );
 
  205   QVBoxLayout *vlayout = 
new QVBoxLayout();
 
  206   vlayout->setContentsMargins( 0, 0, 0, 0 );
 
  208   vlayout->addWidget( 
new QLabel( tr( 
"Parent layer" ) ) );
 
  210   mParentLayerComboBox = 
new QComboBox();
 
  211   mParentLayerComboBox->addItem( tr( 
"None" ), QVariant() );
 
  213   QString initialParent;
 
  215     initialParent = aggregateParam->parentLayerParameterName();
 
  217   if ( 
auto *lModel = widgetContext.
model() )
 
  220     const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
 
  221     for ( 
auto it = components.constBegin(); it != components.constEnd(); ++it )
 
  225         mParentLayerComboBox-> addItem( definition->
description(), definition->
name() );
 
  226         if ( !initialParent.isEmpty() && initialParent == definition->
name() )
 
  228           mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
 
  233         mParentLayerComboBox-> addItem( definition->
description(), definition->
name() );
 
  234         if ( !initialParent.isEmpty() && initialParent == definition->
name() )
 
  236           mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
 
  242   if ( mParentLayerComboBox->count() == 1 && !initialParent.isEmpty() )
 
  245     mParentLayerComboBox->addItem( initialParent, initialParent );
 
  246     mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
 
  249   vlayout->addWidget( mParentLayerComboBox );
 
  250   setLayout( vlayout );
 
  253 QgsProcessingParameterDefinition *QgsProcessingAggregateParameterDefinitionWidget::createParameter( 
const QString &name, 
const QString &description, QgsProcessingParameterDefinition::Flags flags )
 const 
  255   auto param = std::make_unique< QgsProcessingParameterAggregate >( name, description, mParentLayerComboBox->currentData().toString() );
 
  256   param->setFlags( flags );
 
  257   return param.release();
 
  269 QString QgsProcessingAggregateWidgetWrapper::parameterType()
 const 
  276   return new QgsProcessingAggregateWidgetWrapper( parameter, type );
 
  279 QWidget *QgsProcessingAggregateWidgetWrapper::createWidget()
 
  281   mPanel = 
new QgsProcessingAggregatePanelWidget( 
nullptr );
 
  282   mPanel->setToolTip( parameterDefinition()->toolTip() );
 
  283   mPanel->registerExpressionContextGenerator( 
this );
 
  285   connect( mPanel, &QgsProcessingAggregatePanelWidget::changed, 
this, [ = ]
 
  287     emit widgetValueHasChanged( 
this );
 
  295   return new QgsProcessingAggregateParameterDefinitionWidget( context, widgetContext, definition, 
algorithm );
 
  298 void QgsProcessingAggregateWidgetWrapper::postInitialize( 
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
 
  308         if ( wrapper->parameterDefinition()->name() == 
static_cast< const QgsProcessingParameterAggregate * 
>( parameterDefinition() )->parentLayerParameterName() )
 
  310           setParentLayerWrapperValue( wrapper );
 
  313             setParentLayerWrapperValue( wrapper );
 
  326 int QgsProcessingAggregateWidgetWrapper::stretch()
 const 
  335   std::unique_ptr< QgsProcessingContext > tmpContext;
 
  336   if ( mProcessingContextGenerator )
 
  337     context = mProcessingContextGenerator->processingContext();
 
  341     tmpContext = std::make_unique< QgsProcessingContext >();
 
  342     context = tmpContext.get();
 
  349       mPanel->setLayer( 
nullptr );
 
  355   std::unique_ptr< QgsMapLayer > ownedLayer( context->
takeResultLayer( layer->
id() ) );
 
  358     mParentLayer.reset( qobject_cast< QgsVectorLayer * >( ownedLayer.release() ) );
 
  359     layer = mParentLayer.get();
 
  367     mPanel->setLayer( layer );
 
  370 void QgsProcessingAggregateWidgetWrapper::setWidgetValue( 
const QVariant &value, 
QgsProcessingContext & )
 
  373     mPanel->setValue( value );
 
  376 QVariant QgsProcessingAggregateWidgetWrapper::widgetValue()
 const 
  378   return mPanel ? mPanel->value() : QVariant();
 
  381 QStringList QgsProcessingAggregateWidgetWrapper::compatibleParameterTypes()
 const 
  387 QStringList QgsProcessingAggregateWidgetWrapper::compatibleOutputTypes()
 const 
  389   return QStringList();
 
  392 QString QgsProcessingAggregateWidgetWrapper::modelerExpressionFormatString()
 const 
  394   return tr( 
"an array of map items, each containing a 'name', 'type', 'aggregate' and 'input' value (and optional 'length' and 'precision' values)." );
 
  397 const QgsVectorLayer *QgsProcessingAggregateWidgetWrapper::linkedVectorLayer()
 const 
  399   if ( mPanel && mPanel->layer() )
 
  400     return mPanel->layer();