41
41
#include " qgsmessagebar.h"
42
42
#include " qgsexpressionselectiondialog.h"
43
43
#include " qgsfeaturelistmodel.h"
44
+ #include " qgsexpressionbuilderdialog.h"
44
45
45
46
class QgsAttributeTableDock : public QDockWidget
46
47
{
@@ -199,6 +200,13 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
199
200
filterShowAll ();
200
201
break ;
201
202
}
203
+
204
+ mFieldModel = new QgsFieldModel ();
205
+ mFieldModel ->setLayer ( mLayer );
206
+ mFieldComboButton ->setModel ( mFieldModel );
207
+ connect ( mOpenExpressionWidget , SIGNAL ( clicked () ), this , SLOT ( openExpressionBuilder () ) );
208
+ connect ( mRunFieldCalc , SIGNAL ( clicked () ), this , SLOT ( updateFieldFromExpression () ) );
209
+ editingToggled ();
202
210
}
203
211
204
212
QgsAttributeTableDialog::~QgsAttributeTableDialog ()
@@ -214,6 +222,11 @@ void QgsAttributeTableDialog::updateTitle()
214
222
.arg ( mMainView ->filteredFeatureCount () )
215
223
.arg ( mLayer ->selectedFeatureCount () )
216
224
);
225
+
226
+ if ( mMainView ->filterMode () == QgsAttributeTableFilterModel::ShowAll )
227
+ mRunFieldCalc ->setText ( tr ( " Update All" ) );
228
+ else
229
+ mRunFieldCalc ->setText ( tr ( " Update Filtered" ) );
217
230
}
218
231
219
232
void QgsAttributeTableDialog::closeEvent ( QCloseEvent* event )
@@ -275,6 +288,88 @@ void QgsAttributeTableDialog::columnBoxInit()
275
288
}
276
289
}
277
290
291
+ void QgsAttributeTableDialog::updateFieldFromExpression ()
292
+ {
293
+ QApplication::setOverrideCursor ( Qt::WaitCursor );
294
+
295
+ mLayer ->beginEditCommand ( " Field calculator" );
296
+
297
+ QModelIndex modelindex = mFieldModel ->indexFromName ( mFieldComboButton ->currentText () );
298
+ int fieldindex = modelindex.data ( QgsFieldModel::FieldIndexRole ).toInt ();
299
+
300
+ bool calculationSuccess = true ;
301
+ QString error;
302
+
303
+ QgsExpression exp ( mUpdateExpressionText ->text () );
304
+ bool useGeometry = exp .needsGeometry ();
305
+
306
+ QgsFeatureRequest request;
307
+ request.setFlags ( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry );
308
+ QgsFeatureIds filteredIds = mMainView ->filteredFeatures ();
309
+ QgsDebugMsg ( QString ( filteredIds.size () ) );
310
+
311
+ // This would be nice but doesn't work on all providers
312
+ // if ( mMainView->filterMode() != QgsAttributeTableFilterModel::ShowAll )
313
+ // {
314
+ // QgsDebugMsg( " Updating only selected features " );
315
+ // request.setFilterFids( mMainView->filteredFeatures() );
316
+ // }
317
+
318
+ bool filtered = mMainView ->filterMode () != QgsAttributeTableFilterModel::ShowAll;
319
+ int rownum = 1 ;
320
+
321
+ // go through all the features and change the new attributes
322
+ QgsFeatureIterator fit = mLayer ->getFeatures ( request );
323
+ QgsFeature feature;
324
+ while ( fit.nextFeature ( feature ) )
325
+ {
326
+ if ( filtered )
327
+ {
328
+ if ( !filteredIds.contains ( feature.id () ) )
329
+ {
330
+ continue ;
331
+ }
332
+ }
333
+
334
+ exp .setCurrentRowNumber ( rownum );
335
+ QVariant value = exp .evaluate ( &feature );
336
+ // Bail if we have a update error
337
+ if ( exp .hasEvalError () )
338
+ {
339
+ calculationSuccess = false ;
340
+ error = exp .evalErrorString ();
341
+ break ;
342
+ }
343
+ else
344
+ {
345
+ QVariant oldvalue = feature.attributes ().value ( fieldindex );
346
+ mLayer ->changeAttributeValue ( feature.id (), fieldindex, value, oldvalue );
347
+ }
348
+
349
+ rownum++;
350
+ }
351
+
352
+ QApplication::restoreOverrideCursor ();
353
+
354
+ if ( !calculationSuccess )
355
+ {
356
+ QMessageBox::critical ( 0 , tr ( " Error" ), tr ( " An error occured while evaluating the calculation string:\n %1" ).arg ( error ) );
357
+ mLayer ->destroyEditCommand ();
358
+ return ;
359
+ }
360
+
361
+ mLayer ->endEditCommand ();
362
+ }
363
+
364
+ void QgsAttributeTableDialog::openExpressionBuilder ()
365
+ {
366
+ QgsExpressionBuilderDialog dlg ( mLayer , mUpdateExpressionText ->text (), this );
367
+ if ( dlg.exec () )
368
+ {
369
+ mUpdateExpressionText ->setText ( dlg.expressionText () );
370
+ }
371
+ }
372
+
278
373
void QgsAttributeTableDialog::filterColumnChanged ( QObject* filterAction )
279
374
{
280
375
mFilterButton ->setDefaultAction ( qobject_cast<QAction *>( filterAction ) );
@@ -475,6 +570,7 @@ void QgsAttributeTableDialog::editingToggled()
475
570
mRemoveAttribute ->setEnabled ( canDeleteAttributes && mLayer ->isEditable () );
476
571
mAddFeature ->setEnabled ( canAddFeatures && mLayer ->isEditable () && mLayer ->geometryType () == QGis::NoGeometry );
477
572
573
+ mUpdateExpressionBox ->setVisible ( mLayer ->isEditable () );
478
574
// not necessary to set table read only if layer is not editable
479
575
// because model always reflects actual state when returning item flags
480
576
}
0 commit comments