19#include "moc_qgsabstractrelationeditorwidget.cpp"
51 setObjectName( QStringLiteral(
"referenced/" ) +
mRelation.
name() );
73 for (
auto it = transactionGroups.constBegin(); it != transactionGroups.constEnd(); ++it )
87 setObjectName( QStringLiteral(
"referenced/" ) +
mRelation.
name() );
252 addedFeatureIds.insert( finalFeature.
id() );
265 const int index = fields.
indexOf( fieldPair.first );
266 linkAttributes.insert( index, editingFeature.attribute( fieldPair.second ) );
272 const int index = fields.
indexOf( fieldPair.first );
273 linkAttributes.insert( index, finalFeature.
attribute( fieldPair.second ) );
285 keyAttrs.insert( fields.
indexFromName( fieldPair.referencingField() ),
mFeatureList.first().attribute( fieldPair.referencedField() ) );
318 return addedFeatureIds;
352 QStringList deletedFeaturesPks;
363 QString linkingFeaturesRequestExpression;
364 if ( !deletedFeaturesPks.empty() )
371 int relatedLinkingFeaturesCount = 0;
374 relatedLinkingFeaturesCount++;
377 if ( deletedFeaturesPks.size() == 1 && relatedLinkingFeaturesCount > 1 )
379 QMessageBox messageBox( QMessageBox::Question, tr(
"Really delete entry?" ), tr(
"The entry on %1 is still linked to %2 features on %3. Do you want to delete it?" ).arg(
mNmRelation.
referencedLayer()->
name(), QLocale().toString( relatedLinkingFeaturesCount ),
mRelation.
referencedLayer()->
name() ), QMessageBox::NoButton,
this );
380 messageBox.addButton( QMessageBox::Cancel );
381 QAbstractButton *deleteButton = messageBox.addButton( tr(
"Delete" ), QMessageBox::AcceptRole );
384 if ( messageBox.clickedButton() != deleteButton )
387 else if ( deletedFeaturesPks.size() > 1 && relatedLinkingFeaturesCount > deletedFeaturesPks.size() )
389 QMessageBox messageBox( QMessageBox::Question, tr(
"Really delete entries?" ), tr(
"The %1 entries on %2 are still linked to %3 features on %4. Do you want to delete them?" ).arg( QLocale().toString( deletedFeaturesPks.size() ),
mNmRelation.
referencedLayer()->
name(), QLocale().toString( relatedLinkingFeaturesCount ),
mRelation.
referencedLayer()->
name() ), QMessageBox::NoButton,
this );
390 messageBox.addButton( QMessageBox::Cancel );
391 QAbstractButton *deleteButton = messageBox.addButton( tr(
"Delete" ), QMessageBox::AcceptRole );
394 if ( messageBox.clickedButton() != deleteButton )
407 QString childrenInfo;
408 int childrenCount = 0;
409 const auto infoContextLayers = infoContext.
layers();
413 childrenInfo += ( tr(
"%n feature(s) on layer \"%1\", ",
nullptr, infoContext.
duplicatedFeatures( chl ).size() ).arg( chl->name() ) );
417 const int res = QMessageBox::question(
this, tr(
"Delete at least %n feature(s) on other layer(s)",
nullptr, childrenCount ), tr(
"Delete %n feature(s) on layer \"%1\", %2 as well and all of its other descendants.\nDelete these features?",
nullptr, fids.count() ).arg( layer->
name() ).arg( childrenInfo ), QMessageBox::Yes | QMessageBox::No );
418 if ( res != QMessageBox::Yes )
427 if ( contextLayers.size() > 1 )
429 int deletedCount = 0;
430 QString feedbackMessage;
433 feedbackMessage += tr(
"%1 on layer %2. " ).arg( context.
handledFeatures( contextLayer ).size() ).arg( contextLayer->name() );
460 QgsLogger::warning( tr(
"For 1:n relations is not possible to link to multiple features" ) );
468 selectionDlg->setAttribute( Qt::WA_DeleteOnClose );
471 selectionDlg->setWindowTitle( tr(
"Link existing child features for parent %1 \"%2\"" ).arg(
mRelation.
referencedLayer()->
name(), displayString ) );
475 selectionDlg->show();
521 const int index = fields.
indexOf( fieldPair.first );
522 linkAttributes.insert( index, editFeature.attribute( fieldPair.second ) );
529 const int index = fields.
indexOf( fieldPair.first );
530 linkAttributes.insert( index, relatedFeature.
attribute( fieldPair.second ) );
544 const auto constNewFeatures = linkFeaturesList;
545 for (
const QgsFeature &f : constNewFeatures )
553 QgsLogger::warning( tr(
"For 1:n relations is not possible to link to multiple features" ) );
557 QMap<int, QVariant> keys;
562 const QVariant val =
mFeatureList.first().attribute( fieldPair.referencedField() );
563 keys.insert( idx, val );
585 QMapIterator<int, QVariant> it( keys );
586 while ( it.hasNext() )
613 .setFilterFids( fids )
626 QStringList featureFilters;
632 const QString filter = QStringLiteral(
"(%1) AND (%2)" ).arg( featureFilters.join( QLatin1String(
" OR " ) ), filters.join( QLatin1String(
" OR " ) ) );
636 .setFilterExpression( filter ) );
650 QMap<int, QgsField> keyFields;
657 QgsDebugError( QStringLiteral(
"referencing field %1 not found" ).arg( fieldPair.referencingField() ) );
661 keyFields.insert( idx, fld );
664 const auto constFeatureids = fids;
683 QMapIterator<int, QgsField> it( keyFields );
684 while ( it.hasNext() )
707 Q_UNUSED( newRelation )
708 Q_UNUSED( newFeature )
716 Q_UNUSED( newRelation )
717 Q_UNUSED( newNmRelation )
756 , mRelation( relation )
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ Success
Used for reporting a successful operation.
@ Generated
A generated relation is a child of a polymorphic relation.
@ Normal
A normal relation.
This class contains context information for attribute editor widgets.
void setFormFeature(const QgsFeature &feature)
Set current feature for the currently edited form or table row.
QString attributeFormModeString() const
Returns given attributeFormMode as string.
const QgsVectorLayerTools * vectorLayerTools() const
Returns the associated vector layer tools.
QgsMessageBar * mainMessageBar()
Returns the main message bar.
static QgsExpressionContextScope * parentFormScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current parent attribute form/tab...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QString expression() const
Returns the original, unmodified expression string.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsExpression * filterExpression() const
Returns the filter expression (if set).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
const QgsFeatureIds & selectedFeatures()
Gets the selected features.
void setFilterExpression(const QString &filter, QgsAttributeForm::FilterType type)
Set form filter expression.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
QgsField field(int fieldIdx) const
Returns the field at particular index (must be in range 0..N-1).
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
static void warning(const QString &msg)
Goes to qWarning.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
A polymorphic relation consists of the same properties like a normal relation except for the referenc...
QString layerRepresentation(const QgsVectorLayer *layer) const
Returns layer representation as evaluated string.
QString referencedLayerField
QgsRelationManager * relationManager
static QgsProject * instance()
Returns the QgsProject singleton instance.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Defines a relation between matching fields of the two involved tables of a relation.
Represents a relationship between two vector layers.
QgsVectorLayer * referencedLayer
Qgis::RelationshipType type() const
Returns the type of the relation.
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
QgsPolymorphicRelation polymorphicRelation
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
QgsVectorLayer * referencingLayer
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
Contains settings which reflect the context in which vector layer tool operations should consider.
void setParentWidget(QWidget *parent)
Sets the widget which should be parented to tools' dialogues.
void setHideParent(bool hide)
Sets whether the parent widget should be hidden when showing tools' dialogues.
void setAdditionalExpressionContextScope(const QgsExpressionContextScope *scope)
Sets an additional expression context scope to be made available when calculating expressions.
void setShowModal(bool modal)
Sets whether tools' dialogues should be modal.
Contains mainly the QMap with QgsVectorLayer and QgsFeatureIds do list all the duplicated features.
QgsFeatureIds duplicatedFeatures(QgsVectorLayer *layer) const
Returns the duplicated features in the given layer.
QList< QgsVectorLayer * > layers() const
Returns all the layers on which features have been duplicated.
Encapsulate geometry and attributes for new features, to be passed to createFeatures.
static QgsFeature duplicateFeature(QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, QgsDuplicateFeatureContext &duplicateFeatureContext, const int maxDepth=0, int depth=0, QList< QgsVectorLayer * > referencedLayersBranch=QList< QgsVectorLayer * >())
Duplicates a feature and it's children (one level deep).
QList< QgsVectorLayerUtils::QgsFeatureData > QgsFeaturesDataList
Alias for list of QgsFeatureData.
static QString getFeatureDisplayString(const QgsVectorLayer *layer, const QgsFeature &feature)
static QgsFeatureList createFeatures(const QgsVectorLayer *layer, const QgsFeaturesDataList &featuresData, QgsExpressionContext *context=nullptr)
Creates a set of new features ready for insertion into a layer.
static bool impactsCascadeFeatures(const QgsVectorLayer *layer, const QgsFeatureIds &fids, const QgsProject *project, QgsDuplicateFeatureContext &context, QgsVectorLayerUtils::CascadedFeatureFlags flags=QgsVectorLayerUtils::CascadedFeatureFlags())
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE bool deleteFeatures(const QgsFeatureIds &fids, QgsVectorLayer::DeleteContext *context=nullptr)
Deletes a set of features from the layer (but does not commit it)
Q_INVOKABLE bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant(), bool skipDefaultValues=false, QgsVectorLayerToolsContext *context=nullptr)
Changes an attribute value for a feature (but does not immediately commit the changes).
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a list of features to the sink.
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection)
Selects matching features using a list of feature IDs.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
QMap< int, QVariant > QgsAttributeMap
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
#define FID_TO_STRING(fid)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
Context for cascade delete features.
QList< QgsVectorLayer * > handledLayers(bool includeAuxiliaryLayers=true) const
Returns a list of all layers affected by the delete operation.
QgsFeatureIds handledFeatures(QgsVectorLayer *layer) const
Returns a list of feature IDs from the specified layer affected by the delete operation.