void QgsRelationReferenceWidget::highlightFeature( QgsFeature f, CanvasExtent canvasExtent )
{
  if ( !mCanvas )
    return;

  if ( !f.isValid() )
  {
    f = referencedFeature();
    if ( !f.isValid() )
      return;
  }

  if ( !f.hasGeometry() )
  {
    return;
  }

  QgsGeometry geom = f.geometry();

  // scale or pan
  if ( canvasExtent == Scale )
  {
    QgsRectangle featBBox = geom.boundingBox();
    featBBox = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, featBBox );
    QgsRectangle extent = mCanvas->extent();
    if ( !extent.contains( featBBox ) )
    {
      extent.combineExtentWith( featBBox );
      extent.scale( 1.1 );
      mCanvas->setExtent( extent );
      mCanvas->refresh();
    }
  }
  else if ( canvasExtent == Pan )
  {
    QgsGeometry centroid = geom.centroid();
    QgsPointXY center = centroid.asPoint();
    center = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, center );
    mCanvas->zoomByFactor( 1.0, &center ); // refresh is done in this method
  }

  // highlight
  deleteHighlight();
  mHighlight = new QgsHighlight( mCanvas, f, mReferencedLayer );
  QgsIdentifyMenu::styleHighlight( mHighlight );
  mHighlight->show();

  QTimer *timer = new QTimer( this );
  timer->setSingleShot( true );
  connect( timer, &QTimer::timeout, this, &QgsRelationReferenceWidget::deleteHighlight );
  timer->start( 3000 );
}
QgsVectorLayer *QgsAuxiliaryLayer::toSpatialLayer() const
{
  QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() );

  QString pkField = mJoinInfo.targetFieldName();
  QgsFeature joinFeature;
  QgsFeature targetFeature;
  QgsFeatureIterator it = getFeatures();

  layer->startEditing();
  while ( it.nextFeature( joinFeature ) )
  {
    QString filter = QgsExpression::createFieldEqualityExpression( pkField, joinFeature.attribute( AS_JOINFIELD ) );

    QgsFeatureRequest request;
    request.setFilterExpression( filter );

    mLayer->getFeatures( request ).nextFeature( targetFeature );

    if ( targetFeature.isValid() )
    {
      QgsFeature newFeature( joinFeature );
      newFeature.setGeometry( targetFeature.geometry() );
      layer->addFeature( newFeature );
    }
  }
  layer->commitChanges();

  return layer;
}
void QgsAttributeTableDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
{
  QgsVectorLayer *vl = layer( model );
  if ( !vl )
    return;

  int fieldIdx = model->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt();
  QgsFeatureId fid = model->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong();
  QVariant oldValue = model->data( index, Qt::EditRole );

  QVariant newValue;
  QgsEditorWidgetWrapper *eww = QgsEditorWidgetWrapper::fromWidget( editor );
  if ( !eww )
    return;

  newValue = eww->value();

  if ( ( oldValue != newValue && newValue.isValid() ) || oldValue.isNull() != newValue.isNull() )
  {
    // This fixes https://issues.qgis.org/issues/16492
    QgsFeatureRequest request( fid );
    request.setFlags( QgsFeatureRequest::NoGeometry );
    request.setSubsetOfAttributes( QgsAttributeList() );
    QgsFeature feature;
    vl->getFeatures( request ).nextFeature( feature );
    if ( feature.isValid() )
    {
      vl->beginEditCommand( tr( "Attribute changed" ) );
      vl->changeAttributeValue( fid, fieldIdx, newValue, oldValue );
      vl->endEditCommand();
    }
  }
}
Beispiel #4
0
QString QgsRelationReferenceFieldFormatter::representValue( QgsVectorLayer* layer, int fieldIndex, const QVariantMap& config, const QVariant& cache, const QVariant& value ) const
{
  Q_UNUSED( cache );

  // Some sanity checks
  if ( !config.contains( QStringLiteral( "Relation" ) ) )
  {
    QgsMessageLog::logMessage( "Missing Relation in configuration" );
    return value.toString();
  }
  QgsRelation relation = QgsProject::instance()->relationManager()->relation( config[QStringLiteral( "Relation" )].toString() );
  if ( !relation.isValid() )
  {
    QgsMessageLog::logMessage( "Invalid relation" );
    return value.toString();
  }
  QgsVectorLayer* referencingLayer = relation.referencingLayer();
  if ( layer != referencingLayer )
  {
    QgsMessageLog::logMessage( "representValue() with inconsistent layer parameter w.r.t relation referencingLayer" );
    return value.toString();
  }
  int referencingFieldIdx = referencingLayer->fields().lookupField( relation.fieldPairs().at( 0 ).first );
  if ( referencingFieldIdx != fieldIndex )
  {
    QgsMessageLog::logMessage( "representValue() with inconsistent fieldIndex parameter w.r.t relation referencingFieldIdx" );
    return value.toString();
  }
  QgsVectorLayer* referencedLayer = relation.referencedLayer();
  if ( !referencedLayer )
  {
    QgsMessageLog::logMessage( "Cannot find referenced layer" );
    return value.toString();
  }

  // Attributes from the referencing layer
  QgsAttributes attrs = QgsAttributes( layer->fields().count() );
  // Set the value on the foreign key field of the referencing record
  attrs[ referencingFieldIdx ] = value;

  QgsFeatureRequest request = relation.getReferencedFeatureRequest( attrs );
  QgsFeature feature;
  referencedLayer->getFeatures( request ).nextFeature( feature );
  if ( !feature.isValid() )
    return value.toString();

  QgsExpression expr( referencedLayer->displayExpression() );
  QgsExpressionContext context;
  context << QgsExpressionContextUtils::globalScope()
  << QgsExpressionContextUtils::projectScope()
  << QgsExpressionContextUtils::layerScope( referencedLayer );
  context.setFeature( feature );
  QString title = expr.evaluate( &context ).toString();
  if ( expr.hasEvalError() )
  {
    int referencedFieldIdx = referencedLayer->fields().lookupField( relation.fieldPairs().at( 0 ).second );
    title = feature.attribute( referencedFieldIdx ).toString();
  }
  return title;
}
void QgsRelationReferenceWidget::setForeignKey( const QVariant& value )
{
  if ( !value.isValid() || value.isNull() )
  {
    deleteForeignKey();
    return;
  }

  QgsFeature f;
  if ( !mReferencedLayer )
    return;

  // TODO: Rewrite using expression
  QgsFeatureIterator fit = mReferencedLayer->getFeatures( QgsFeatureRequest() );
  while ( fit.nextFeature( f ) )
  {
    if ( f.attribute( mFkeyFieldIdx ) == value )
    {
      break;
    }
  }

  if ( !f.isValid() )
  {
    deleteForeignKey();
    return;
  }

  mForeignKey = f.attribute( mFkeyFieldIdx );

  if ( mReadOnlySelector )
  {
    QgsExpression expr( mReferencedLayer->displayExpression() );
    QString title = expr.evaluate( &f ).toString();
    if ( expr.hasEvalError() )
    {
      title = f.attribute( mFkeyFieldIdx ).toString();
    }
    mLineEdit->setText( title );
    mFeatureId = f.id();
  }
  else
  {
    int i = mComboBox->findData( value );
    if ( i == -1 && mAllowNull )
    {
      mComboBox->setCurrentIndex( 0 );
    }
    else
    {
      mComboBox->setCurrentIndex( i );
    }
  }

  mRemoveFKButton->setEnabled( mIsEditable );
  highlightFeature( f );
  updateAttributeEditorFrame( f );
  emit foreignKeyChanged( foreignKey() );
}
void QgsRelationReferenceWidget::updateAttributeEditorFrame( const QgsFeature &feature )
{
  mOpenFormButton->setEnabled( feature.isValid() );
  // Check if we're running with an embedded frame we need to update
  if ( mAttributeEditorFrame && mReferencedAttributeForm )
  {
    mReferencedAttributeForm->setFeature( feature );
  }
}
void QgsRelationReferenceWidget::openForm()
{
  QgsFeature feat = referencedFeature();

  if ( !feat.isValid() )
    return;

  QgsAttributeEditorContext context( mEditorContext, mRelation, QgsAttributeEditorContext::Single, QgsAttributeEditorContext::StandaloneDialog );
  QgsAttributeDialog attributeDialog( mReferencedLayer, new QgsFeature( feat ), true, this, true, context );
  attributeDialog.exec();
}
Beispiel #8
0
bool QgsSpatialQuery::hasValidGeometry( QgsFeature &feature )
{
  if ( !feature.isValid() )
    return false;

  const QgsGeometry *geom = feature.constGeometry();

  if ( !geom || geom->isGeosEmpty() )
    return false;

  return true;

} // bool QgsSpatialQuery::hasValidGeometry(QgsFeature &feature)
Beispiel #9
0
bool QgsSpatialQuery::hasValidGeometry( QgsFeature &feature )
{
  if ( !feature.isValid() )
    return false;

  QgsGeometry geom = feature.geometry();

  if ( geom.isNull() || geom.isEmpty() )
    return false;

  return true;

} // bool QgsSpatialQuery::hasValidGeometry(QgsFeature &feature)
void QgsHtmlAnnotation::setAssociatedFeature( const QgsFeature &feature )
{
  QgsAnnotation::setAssociatedFeature( feature );
  QString newText;
  QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mapLayer() );
  if ( feature.isValid() && vectorLayer )
  {
    QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( vectorLayer ) );
    context.setFeature( feature );
    newText = QgsExpression::replaceExpressionText( mHtmlSource, &context );
  }
  else
  {
    newText = mHtmlSource;
  }
  mWebPage->mainFrame()->setHtml( newText );
  emit appearanceChanged();
}
Beispiel #11
0
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString& string, const QgsFields& fields, QTextCodec* encoding )
{
  QgsFeatureList features;
  if ( string.isEmpty() )
    return features;

  QString randomFileName = QString( "/vsimem/%1" ).arg( QUuid::createUuid().toString() );

  // create memory file system object from string buffer
  QByteArray ba = string.toUtf8();
  VSIFCloseL( VSIFileFromMemBuffer( TO8( randomFileName ), reinterpret_cast< GByte* >( ba.data() ),
                                    static_cast< vsi_l_offset >( ba.size() ), FALSE ) );

  OGRDataSourceH hDS = OGROpen( TO8( randomFileName ), false, nullptr );
  if ( !hDS )
  {
    VSIUnlink( TO8( randomFileName ) );
    return features;
  }

  OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
  if ( !ogrLayer )
  {
    OGR_DS_Destroy( hDS );
    VSIUnlink( TO8( randomFileName ) );
    return features;
  }

  OGRFeatureH oFeat;
  while (( oFeat = OGR_L_GetNextFeature( ogrLayer ) ) )
  {
    QgsFeature feat = readOgrFeature( oFeat, fields, encoding );
    if ( feat.isValid() )
      features << feat;

    OGR_F_Destroy( oFeat );
  }

  OGR_DS_Destroy( hDS );
  VSIUnlink( TO8( randomFileName ) );

  return features;
}
Beispiel #12
0
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString &string, const QgsFields &fields, QTextCodec *encoding )
{
  QgsFeatureList features;
  if ( string.isEmpty() )
    return features;

  QString randomFileName = QStringLiteral( "/vsimem/%1" ).arg( QUuid::createUuid().toString() );

  // create memory file system object from string buffer
  QByteArray ba = string.toUtf8();
  VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(), reinterpret_cast< GByte * >( ba.data() ),
                                    static_cast< vsi_l_offset >( ba.size() ), FALSE ) );

  gdal::ogr_datasource_unique_ptr hDS( OGROpen( randomFileName.toUtf8().constData(), false, nullptr ) );
  if ( !hDS )
  {
    VSIUnlink( randomFileName.toUtf8().constData() );
    return features;
  }

  OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
  if ( !ogrLayer )
  {
    hDS.reset();
    VSIUnlink( randomFileName.toUtf8().constData() );
    return features;
  }

  gdal::ogr_feature_unique_ptr oFeat;
  while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
  {
    QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding );
    if ( feat.isValid() )
      features << feat;
  }

  hDS.reset();
  VSIUnlink( randomFileName.toUtf8().constData() );

  return features;
}
Beispiel #13
0
bool QgsSpatialQuery::hasValidGeometry( QgsFeature &feature )
{
    if ( ! feature.isValid() )
    {
        return false;
    }

    const QgsGeometry *geom = feature.constGeometry();

    if ( NULL == geom )
    {
        return false;
    }

    if ( geom->isGeosEmpty() )
    {
        return false;
    }

    return true;

} // bool QgsSpatialQuery::hasValidGeometry(QgsFeature &feature)
void QgsEditorWidgetWrapper::updateConstraint( const QgsVectorLayer *layer, int index, const QgsFeature &ft, QgsFieldConstraints::ConstraintOrigin constraintOrigin )
{
  QStringList errors;
  QStringList softErrors;
  QStringList expressions;
  QStringList descriptions;
  bool toEmit( false );
  bool hardConstraintsOk( true );
  bool softConstraintsOk( true );

  QgsField field = layer->fields().at( index );
  QString expression = field.constraints().constraintExpression();

  if ( ft.isValid() )
  {
    if ( ! expression.isEmpty() )
    {
      expressions << expression;
      descriptions << field.constraints().constraintDescription();
      toEmit = true;
    }

    if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintNotNull )
    {
      descriptions << tr( "Not NULL" );
      if ( !expression.isEmpty() )
      {
        expressions << field.name() + QStringLiteral( " IS NOT NULL" );
      }
      else
      {
        expressions << QStringLiteral( "IS NOT NULL" );
      }
      toEmit = true;
    }

    if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintUnique )
    {
      descriptions << tr( "Unique" );
      if ( !expression.isEmpty() )
      {
        expressions << field.name() + QStringLiteral( " IS UNIQUE" );
      }
      else
      {
        expressions << QStringLiteral( "IS UNIQUE" );
      }
      toEmit = true;
    }

    hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin );

    softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin );
    errors << softErrors;
  }
  else // invalid feature
  {
    if ( ! expression.isEmpty() )
    {
      hardConstraintsOk = true;
      softConstraintsOk = false;

      errors << QStringLiteral( "Invalid feature" );

      toEmit = true;
    }
  }

  mValidConstraint = hardConstraintsOk && softConstraintsOk;
  mIsBlockingCommit = !hardConstraintsOk;

  mConstraintFailureReason = errors.join( QStringLiteral( ", " ) );

  if ( toEmit )
  {
    QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason;

    QString description = descriptions.join( QStringLiteral( ", " ) );
    QString expressionDesc;
    if ( expressions.size() > 1 )
      expressionDesc = "( " + expressions.join( QStringLiteral( " ) AND ( " ) ) + " )";
    else if ( !expressions.isEmpty() )
      expressionDesc = expressions.at( 0 );

    ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard
                              : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass );
    //set the constraint result
    mConstraintResult = result;
    updateConstraintWidgetStatus();
    emit constraintStatusChanged( expressionDesc, description, errStr, result );
  }
}
Beispiel #15
0
QVariant QgsProperty::propertyValue( const QgsExpressionContext &context, const QVariant &defaultValue, bool *ok ) const
{
  if ( ok )
    *ok = false;

  if ( !d->active )
    return defaultValue;

  switch ( d->type )
  {
    case StaticProperty:
    {
      if ( ok )
        *ok = true;
      return d->staticValue;
    }

    case FieldBasedProperty:
    {
      QgsFeature f = context.feature();
      if ( !f.isValid() )
        return defaultValue;

      //shortcut the field lookup
      if ( d->cachedFieldIdx >= 0 )
      {
        if ( ok )
          *ok = true;
        return f.attribute( d->cachedFieldIdx );
      }

      int fieldIdx = f.fieldNameIndex( d->fieldName );
      if ( fieldIdx < 0 )
        return defaultValue;

      if ( ok )
        *ok = true;
      return f.attribute( fieldIdx );
    }

    case ExpressionBasedProperty:
    {
      d.detach();
      if ( !d->expressionPrepared && !prepare( context ) )
        return defaultValue;

      QVariant result = d->expression.evaluate( &context );
      if ( result.isValid() )
      {
        if ( ok )
          *ok = true;
        return result;
      }
      else
      {
        return defaultValue;
      }
    }

    case InvalidProperty:
      return defaultValue;

  };

  return QVariant();
}