Expand Up
@@ -58,8 +58,23 @@ QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer* vl )
mOutputFieldNameLineEdit ->setMaxLength ( 10 );
}
mUpdateExistingGroupBox ->setEnabled ( vl->dataProvider ()->capabilities () & QgsVectorDataProvider::ChangeAttributeValues );
mNewFieldGroupBox ->setEnabled ( vl->dataProvider ()->capabilities () & QgsVectorDataProvider::AddAttributes );
if ( !( vl->dataProvider ()->capabilities () & QgsVectorDataProvider::AddAttributes ) )
{
mCreateVirtualFieldCheckbox ->setChecked ( true );
mCreateVirtualFieldCheckbox ->setEnabled ( false );
mOnlyVirtualFieldsInfoLabel ->setVisible ( true );
}
else
{
mOnlyVirtualFieldsInfoLabel ->setVisible ( false );
}
if ( !( vl->dataProvider ()->capabilities () & QgsVectorDataProvider::ChangeAttributeValues ) )
{
mUpdateExistingGroupBox ->setEnabled ( false );
mCreateVirtualFieldCheckbox ->setChecked ( true );
mCreateVirtualFieldCheckbox ->setEnabled ( false );
}
Q_ASSERT ( mNewFieldGroupBox ->isEnabled () || mUpdateExistingGroupBox ->isEnabled () );
Expand All
@@ -85,13 +100,21 @@ QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer* vl )
mNewFieldGroupBox ->setCheckable ( false );
}
bool hasselection = vl->selectedFeaturesIds ().size () > 0 ;
if ( ( mNewFieldGroupBox ->isChecked () && mCreateVirtualFieldCheckbox ->isChecked () ) || mVectorLayer ->isEditable () )
{
mEditModeAutoTurnOnLabel ->setVisible ( false );
}
bool hasselection = vl->selectedFeatureCount () > 0 ;
mOnlyUpdateSelectedCheckBox ->setChecked ( hasselection );
mOnlyUpdateSelectedCheckBox ->setEnabled ( hasselection );
mOnlyUpdateSelectedCheckBox ->setText ( tr ( " Only update %1 selected features" ).arg ( vl->selectedFeaturesIds (). size () ) );
mOnlyUpdateSelectedCheckBox ->setText ( tr ( " Only update %1 selected features" ).arg ( vl->selectedFeatureCount () ) );
builder->loadRecent ( " fieldcalc" );
mEditModeAutoTurnOnLabel ->setPixmap ( style ()->standardPixmap ( QStyle::SP_MessageBoxInformation ) );
mOnlyVirtualFieldsInfoLabel ->setPixmap ( style ()->standardPixmap ( QStyle::SP_MessageBoxInformation ) );
QSettings settings;
restoreGeometry ( settings.value ( " /Windows/QgsFieldCalculator/geometry" ).toByteArray () );
}
Expand All
@@ -118,7 +141,7 @@ void QgsFieldCalculator::accept()
QgsExpression exp ( calcString );
exp .setGeomCalculator ( myDa );
if ( !mVectorLayer || ! mVectorLayer -> isEditable () )
if ( !mVectorLayer )
return ;
if ( ! exp .prepare ( mVectorLayer ->pendingFields () ) )
Expand All
@@ -127,118 +150,124 @@ void QgsFieldCalculator::accept()
return ;
}
QApplication::setOverrideCursor ( Qt::WaitCursor );
mVectorLayer ->beginEditCommand ( " Field calculator" );
// update existing field
if ( mUpdateExistingGroupBox ->isChecked () || !mNewFieldGroupBox ->isEnabled () )
if ( mNewFieldGroupBox ->isEnabled () && mCreateVirtualFieldCheckbox ->isChecked () )
{
QMap<QString, int >::const_iterator fieldIt = mFieldMap .find ( mExistingFieldComboBox ->currentText () );
if ( fieldIt != mFieldMap .end () )
{
mAttributeId = fieldIt.value ();
}
mVectorLayer ->addExpressionField ( calcString, fieldDefinition () );
}
else
{
// create new field
QgsField newField ( mOutputFieldNameLineEdit ->text (),
( QVariant::Type ) mOutputFieldTypeComboBox ->itemData ( mOutputFieldTypeComboBox ->currentIndex (), Qt::UserRole ).toInt (),
mOutputFieldTypeComboBox ->itemData ( mOutputFieldTypeComboBox ->currentIndex (), Qt::UserRole + 1 ).toString (),
mOutputFieldWidthSpinBox ->value (),
mOutputFieldPrecisionSpinBox ->value () );
if ( !mVectorLayer ->addAttribute ( newField ) )
if ( !mVectorLayer ->isEditable () )
mVectorLayer ->startEditing ();
QApplication::setOverrideCursor ( Qt::WaitCursor );
mVectorLayer ->beginEditCommand ( " Field calculator" );
// update existing field
if ( mUpdateExistingGroupBox ->isChecked () || !mNewFieldGroupBox ->isEnabled () )
{
QApplication::restoreOverrideCursor ();
QMessageBox::critical ( 0 , tr ( " Provider error" ), tr ( " Could not add the new field to the provider." ) );
mVectorLayer ->destroyEditCommand ();
return ;
QMap<QString, int >::const_iterator fieldIt = mFieldMap .find ( mExistingFieldComboBox ->currentText () );
if ( fieldIt != mFieldMap .end () )
{
mAttributeId = fieldIt.value ();
}
}
else
{
// create new field
const QgsField newField = fieldDefinition ();
// get index of the new field
const QgsFields& fields = mVectorLayer ->pendingFields ();
if ( !mVectorLayer ->addAttribute ( newField ) )
{
QApplication::restoreOverrideCursor ();
QMessageBox::critical ( 0 , tr ( " Provider error" ), tr ( " Could not add the new field to the provider." ) );
mVectorLayer ->destroyEditCommand ();
return ;
}
for ( int idx = 0 ; idx < fields.count (); ++idx )
{
if ( fields[idx].name () == mOutputFieldNameLineEdit ->text () )
// get index of the new field
const QgsFields& fields = mVectorLayer ->pendingFields ();
for ( int idx = 0 ; idx < fields.count (); ++idx )
{
mAttributeId = idx;
break ;
if ( fields[idx].name () == mOutputFieldNameLineEdit ->text () )
{
mAttributeId = idx;
break ;
}
}
if ( ! exp .prepare ( mVectorLayer ->pendingFields () ) )
{
QApplication::restoreOverrideCursor ();
QMessageBox::critical ( 0 , tr ( " Evaluation error" ), exp .evalErrorString () );
return ;
}
}
if ( ! exp . prepare ( mVectorLayer -> pendingFields () ) )
if ( mAttributeId == - 1 )
{
mVectorLayer ->destroyEditCommand ();
QApplication::restoreOverrideCursor ();
QMessageBox::critical ( 0 , tr ( " Evaluation error" ), exp .evalErrorString () );
return ;
}
}
if ( mAttributeId == -1 )
{
mVectorLayer ->destroyEditCommand ();
QApplication::restoreOverrideCursor ();
return ;
}
// go through all the features and change the new attribute
QgsFeature feature;
bool calculationSuccess = true ;
QString error;
// go through all the features and change the new attribute
QgsFeature feature;
bool calculationSuccess = true ;
QString error;
bool onlySelected = mOnlyUpdateSelectedCheckBox ->isChecked ();
QgsFeatureIds selectedIds = mVectorLayer ->selectedFeaturesIds ();
bool onlySelected = mOnlyUpdateSelectedCheckBox ->isChecked ();
QgsFeatureIds selectedIds = mVectorLayer ->selectedFeaturesIds ();
bool useGeometry = exp .needsGeometry ();
int rownum = 1 ;
bool useGeometry = exp .needsGeometry ();
int rownum = 1 ;
const QgsField& field = mVectorLayer ->pendingFields ()[mAttributeId ];
const QgsField& field = mVectorLayer ->pendingFields ()[mAttributeId ];
bool newField = !mUpdateExistingGroupBox ->isChecked ();
QVariant emptyAttribute;
if ( newField )
emptyAttribute = QVariant ( field.type () );
bool newField = !mUpdateExistingGroupBox ->isChecked ();
QVariant emptyAttribute;
if ( newField )
emptyAttribute = QVariant ( field.type () );
QgsFeatureIterator fit = mVectorLayer ->getFeatures ( QgsFeatureRequest ().setFlags ( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) );
while ( fit.nextFeature ( feature ) )
{
if ( onlySelected )
QgsFeatureIterator fit = mVectorLayer ->getFeatures ( QgsFeatureRequest ().setFlags ( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) );
while ( fit.nextFeature ( feature ) )
{
if ( !selectedIds. contains ( feature. id () ) )
if ( onlySelected )
{
continue ;
if ( !selectedIds.contains ( feature.id () ) )
{
continue ;
}
}
}
exp .setCurrentRowNumber ( rownum );
QVariant value = exp .evaluate ( &feature );
field.convertCompatible ( value );
if ( exp .hasEvalError () )
{
calculationSuccess = false ;
error = exp .evalErrorString ();
break ;
}
else
{
mVectorLayer ->changeAttributeValue ( feature.id (), mAttributeId , value, newField ? emptyAttribute : feature.attributes ().value ( mAttributeId ) );
exp .setCurrentRowNumber ( rownum );
QVariant value = exp .evaluate ( &feature );
field.convertCompatible ( value );
if ( exp .hasEvalError () )
{
calculationSuccess = false ;
error = exp .evalErrorString ();
break ;
}
else
{
mVectorLayer ->changeAttributeValue ( feature.id (), mAttributeId , value, newField ? emptyAttribute : feature.attributes ().value ( mAttributeId ) );
}
rownum++;
}
rownum++;
}
QApplication::restoreOverrideCursor ();
QApplication::restoreOverrideCursor ();
if ( !calculationSuccess )
{
QMessageBox::critical ( 0 , tr ( " Error" ), tr ( " An error occured while evaluating the calculation string:\n %1" ).arg ( error ) );
mVectorLayer ->destroyEditCommand ();
return ;
}
if ( !calculationSuccess )
{
QMessageBox::critical ( 0 , tr ( " Error" ), tr ( " An error occured while evaluating the calculation string:\n %1" ).arg ( error ) );
mVectorLayer ->destroyEditCommand ();
return ;
mVectorLayer ->endEditCommand ();
}
mVectorLayer ->endEditCommand ();
QDialog::accept ();
}
Expand Down
Expand Up
@@ -275,12 +304,53 @@ void QgsFieldCalculator::populateOutputFieldTypes()
void QgsFieldCalculator::on_mNewFieldGroupBox_toggled ( bool on )
{
mUpdateExistingGroupBox ->setChecked ( !on );
if ( on && ! ( mVectorLayer ->dataProvider ()->capabilities () & QgsVectorDataProvider::AddAttributes ) )
{
mOnlyVirtualFieldsInfoLabel ->setVisible ( true );
}
else
{
mOnlyVirtualFieldsInfoLabel ->setVisible ( false );
}
if ( ( mNewFieldGroupBox ->isChecked () && mCreateVirtualFieldCheckbox ->isChecked () ) || mVectorLayer ->isEditable () )
{
mEditModeAutoTurnOnLabel ->setVisible ( false );
}
else
{
mEditModeAutoTurnOnLabel ->setVisible ( true );
}
}
void QgsFieldCalculator::on_mUpdateExistingGroupBox_toggled ( bool on )
{
mNewFieldGroupBox ->setChecked ( !on );
setOkButtonState ();
if ( on )
{
mOnlyUpdateSelectedCheckBox ->setEnabled ( mVectorLayer ->selectedFeatureCount () > 0 );
}
else
{
on_mCreateVirtualFieldCheckbox_stateChanged ( mCreateVirtualFieldCheckbox ->checkState () );
}
}
void QgsFieldCalculator::on_mCreateVirtualFieldCheckbox_stateChanged ( int state )
{
mOnlyUpdateSelectedCheckBox ->setChecked ( false );
mOnlyUpdateSelectedCheckBox ->setEnabled ( state != Qt::Checked && mVectorLayer ->selectedFeatureCount () > 0 );
if ( ( mNewFieldGroupBox ->isChecked () && mCreateVirtualFieldCheckbox ->isChecked () ) || mVectorLayer ->isEditable () )
{
mEditModeAutoTurnOnLabel ->setVisible ( false );
}
else
{
mEditModeAutoTurnOnLabel ->setVisible ( true );
}
}
Expand Down