20 #include <QMessageBox>
21 #include <QPushButton>
22 #include <QStandardItemModel>
23 #include <QToolButton>
28 #include "qgsprocessingmodelalgorithm.h"
42 QgsProcessingAggregatePanelWidget::QgsProcessingAggregatePanelWidget( QWidget *parent )
47 mModel = mFieldsView->model();
49 mLayerCombo->setAllowEmptyLayer(
true );
52 connect( mResetButton, &QPushButton::clicked,
this, &QgsProcessingAggregatePanelWidget::loadFieldsFromLayer );
53 connect( mAddButton, &QPushButton::clicked,
this, &QgsProcessingAggregatePanelWidget::addField );
57 connect( mLoadLayerFieldsButton, &QPushButton::clicked,
this, &QgsProcessingAggregatePanelWidget::loadLayerFields );
61 if ( !mBlockChangedSignal )
68 void QgsProcessingAggregatePanelWidget::setLayer(
QgsVectorLayer *layer )
70 if ( layer == mLayer )
74 mFieldsView->setSourceLayer( mLayer );
75 if ( mModel->rowCount() == 0 )
77 loadFieldsFromLayer();
81 QMessageBox dlg(
this );
82 dlg.setText( tr(
"Do you want to reset the field mapping?" ) );
83 dlg.setStandardButtons(
84 QMessageBox::StandardButtons( QMessageBox::Yes |
86 dlg.setDefaultButton( QMessageBox::No );
87 if ( dlg.exec() == QMessageBox::Yes )
89 loadFieldsFromLayer();
98 QVariant QgsProcessingAggregatePanelWidget::value()
const
100 const QList<QgsAggregateMappingModel::Aggregate> mapping = mFieldsView->mapping();
102 QVariantList results;
103 results.reserve( mapping.size() );
107 def.insert( QStringLiteral(
"name" ), aggregate.field.name() );
108 def.insert( QStringLiteral(
"type" ),
static_cast< int >( aggregate.field.type() ) );
109 def.insert( QStringLiteral(
"length" ), aggregate.field.length() );
110 def.insert( QStringLiteral(
"precision" ), aggregate.field.precision() );
111 def.insert( QStringLiteral(
"input" ), aggregate.source );
112 def.insert( QStringLiteral(
"aggregate" ), aggregate.aggregate );
113 def.insert( QStringLiteral(
"delimiter" ), aggregate.delimiter );
114 results.append( def );
119 void QgsProcessingAggregatePanelWidget::setValue(
const QVariant &value )
121 if ( value.type() != QVariant::List )
124 QList< QgsAggregateMappingModel::Aggregate > aggregates;
126 const QVariantList fields = value.toList();
127 aggregates.reserve( fields.size() );
128 for (
const QVariant &
field : fields )
130 const QVariantMap map =
field.toMap();
131 QgsField f( map.value( QStringLiteral(
"name" ) ).toString(),
132 static_cast< QVariant::Type
>( map.value( QStringLiteral(
"type" ), QVariant::Invalid ).toInt() ),
133 QVariant::typeToName(
static_cast< QVariant::Type
>( map.value( QStringLiteral(
"type" ), QVariant::Invalid ).toInt() ) ),
134 map.value( QStringLiteral(
"length" ), 0 ).toInt(),
135 map.value( QStringLiteral(
"precision" ), 0 ).toInt() );
140 aggregate.
source = map.value( QStringLiteral(
"input" ) ).toString();
141 aggregate.
aggregate = map.value( QStringLiteral(
"aggregate" ) ).toString();
142 aggregate.
delimiter = map.value( QStringLiteral(
"delimiter" ) ).toString();
144 aggregates.append( aggregate );
147 mBlockChangedSignal =
true;
149 if ( aggregates.size() > 0 )
150 mFieldsView->setMapping( aggregates );
152 mBlockChangedSignal =
false;
159 mFieldsView->registerExpressionContextGenerator( generator );
162 void QgsProcessingAggregatePanelWidget::loadFieldsFromLayer()
166 mFieldsView->setSourceFields( mLayer->fields() );
170 void QgsProcessingAggregatePanelWidget::addField()
172 const int rowCount = mModel->rowCount();
173 mModel->appendField(
QgsField( QStringLiteral(
"new_field" ) ) );
174 QModelIndex index = mModel->index( rowCount, 0 );
175 mFieldsView->selectionModel()->select(
177 QItemSelectionModel::SelectionFlags(
178 QItemSelectionModel::Clear |
179 QItemSelectionModel::Select |
180 QItemSelectionModel::Current |
181 QItemSelectionModel::Rows ) );
182 mFieldsView->scrollTo( index );
185 void QgsProcessingAggregatePanelWidget::loadLayerFields()
187 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( mLayerCombo->currentLayer() ) )
189 mFieldsView->setSourceFields( vl->fields() );
200 QVBoxLayout *vlayout =
new QVBoxLayout();
201 vlayout->setContentsMargins( 0, 0, 0, 0 );
203 vlayout->addWidget(
new QLabel( tr(
"Parent layer" ) ) );
205 mParentLayerComboBox =
new QComboBox();
206 mParentLayerComboBox->addItem( tr(
"None" ), QVariant() );
208 QString initialParent;
210 initialParent = aggregateParam->parentLayerParameterName();
212 if (
auto *lModel = widgetContext.
model() )
215 const QMap<QString, QgsProcessingModelParameter> components = lModel->parameterComponents();
216 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
220 mParentLayerComboBox-> addItem( definition->
description(), definition->
name() );
221 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
223 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
228 mParentLayerComboBox-> addItem( definition->
description(), definition->
name() );
229 if ( !initialParent.isEmpty() && initialParent == definition->
name() )
231 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
237 if ( mParentLayerComboBox->count() == 1 && !initialParent.isEmpty() )
240 mParentLayerComboBox->addItem( initialParent, initialParent );
241 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
244 vlayout->addWidget( mParentLayerComboBox );
245 setLayout( vlayout );
248 QgsProcessingParameterDefinition *QgsProcessingAggregateParameterDefinitionWidget::createParameter(
const QString &name,
const QString &description, QgsProcessingParameterDefinition::Flags flags )
const
250 auto param = qgis::make_unique< QgsProcessingParameterAggregate >( name, description, mParentLayerComboBox->currentData().toString() );
251 param->setFlags( flags );
252 return param.release();
264 QString QgsProcessingAggregateWidgetWrapper::parameterType()
const
271 return new QgsProcessingAggregateWidgetWrapper( parameter, type );
274 QWidget *QgsProcessingAggregateWidgetWrapper::createWidget()
276 mPanel =
new QgsProcessingAggregatePanelWidget(
nullptr );
277 mPanel->setToolTip( parameterDefinition()->toolTip() );
278 mPanel->registerExpressionContextGenerator(
this );
280 connect( mPanel, &QgsProcessingAggregatePanelWidget::changed,
this, [ = ]
282 emit widgetValueHasChanged(
this );
290 return new QgsProcessingAggregateParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
293 void QgsProcessingAggregateWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
303 if ( wrapper->parameterDefinition()->name() ==
static_cast< const QgsProcessingParameterAggregate *
>( parameterDefinition() )->parentLayerParameterName() )
305 setParentLayerWrapperValue( wrapper );
308 setParentLayerWrapperValue( wrapper );
321 int QgsProcessingAggregateWidgetWrapper::stretch()
const
330 std::unique_ptr< QgsProcessingContext > tmpContext;
331 if ( mProcessingContextGenerator )
332 context = mProcessingContextGenerator->processingContext();
336 tmpContext = qgis::make_unique< QgsProcessingContext >();
337 context = tmpContext.get();
344 mPanel->setLayer(
nullptr );
350 std::unique_ptr< QgsMapLayer > ownedLayer( context->
takeResultLayer( layer->
id() ) );
353 mParentLayer.reset( qobject_cast< QgsVectorLayer * >( ownedLayer.release() ) );
354 layer = mParentLayer.get();
362 mPanel->setLayer( layer );
365 void QgsProcessingAggregateWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext & )
368 mPanel->setValue( value );
371 QVariant QgsProcessingAggregateWidgetWrapper::widgetValue()
const
373 return mPanel ? mPanel->value() : QVariant();
376 QStringList QgsProcessingAggregateWidgetWrapper::compatibleParameterTypes()
const
382 QStringList QgsProcessingAggregateWidgetWrapper::compatibleOutputTypes()
const
384 return QStringList();
387 QString QgsProcessingAggregateWidgetWrapper::modelerExpressionFormatString()
const
389 return tr(
"an array of map items, each containing a 'name', 'type', 'aggregate' and 'input' value (and optional 'length' and 'precision' values)." );
392 const QgsVectorLayer *QgsProcessingAggregateWidgetWrapper::linkedVectorLayer()
const
394 if ( mPanel && mPanel->layer() )
395 return mPanel->layer();