40 #include <QHBoxLayout> 
   42 #include <QMessageBox> 
   43 #include <QPushButton> 
   55     if ( mRequest.acceptFeature( layer->
getFeature( fid ) ) )
 
   56       mSelectedFeatureIds << fid;
 
   61 const QgsFeatureIds &QgsFilteredSelectionManager::selectedFeatureIds()
 const 
   65   return mSelectedFeatureIds;
 
   68 int QgsFilteredSelectionManager::selectedFeatureCount()
 
   70   return mSelectedFeatureIds.count();
 
   73 void QgsFilteredSelectionManager::onSelectionChanged( 
const QgsFeatureIds &selected, 
const QgsFeatureIds &deselected, 
bool clearAndSelect )
 
   78     mSelectedFeatureIds.clear();
 
   82     for ( 
const auto fid : deselected )
 
   83       mSelectedFeatureIds.remove( fid );
 
   86   for ( 
const auto fid : selected )
 
   87     if ( mRequest.acceptFeature( layer()->getFeature( fid ) ) )
 
   88       mSelectedFeatureIds << fid;
 
   90       lselected.remove( fid );
 
   92   emit selectionChanged( lselected, deselected, clearAndSelect );
 
  100   , mShowFirstFeature( config.value( QStringLiteral( 
"show_first_feature" ), true ).toBool() )
 
  102   QVBoxLayout *rootLayout = 
new QVBoxLayout( 
this );
 
  103   rootLayout->setContentsMargins( 0, 9, 0, 0 );
 
  106   QHBoxLayout *buttonLayout = 
new QHBoxLayout();
 
  107   buttonLayout->setContentsMargins( 0, 0, 0, 0 );
 
  109   mToggleEditingButton = 
new QToolButton( 
this );
 
  110   mToggleEditingButton->setObjectName( QStringLiteral( 
"mToggleEditingButton" ) );
 
  112   mToggleEditingButton->setText( tr( 
"Toggle Editing" ) );
 
  113   mToggleEditingButton->setEnabled( 
false );
 
  114   mToggleEditingButton->setCheckable( 
true );
 
  115   mToggleEditingButton->setToolTip( tr( 
"Toggle editing mode for child layer" ) );
 
  116   buttonLayout->addWidget( mToggleEditingButton );
 
  118   mSaveEditsButton = 
new QToolButton( 
this );
 
  120   mSaveEditsButton->setText( tr( 
"Save Child Layer Edits" ) );
 
  121   mSaveEditsButton->setToolTip( tr( 
"Save child layer edits" ) );
 
  122   mSaveEditsButton->setEnabled( 
true );
 
  123   buttonLayout->addWidget( mSaveEditsButton );
 
  125   mAddFeatureGeometryButton = 
new QToolButton( 
this );
 
  126   mAddFeatureGeometryButton->setObjectName( QStringLiteral( 
"mAddFeatureGeometryButton" ) );
 
  127   buttonLayout->addWidget( mAddFeatureGeometryButton );
 
  129   mAddFeatureButton = 
new QToolButton( 
this );
 
  131   mAddFeatureButton->setText( tr( 
"Add Child Feature" ) );
 
  132   mAddFeatureButton->setToolTip( tr( 
"Add child feature" ) );
 
  133   mAddFeatureButton->setObjectName( QStringLiteral( 
"mAddFeatureButton" ) );
 
  134   buttonLayout->addWidget( mAddFeatureButton );
 
  136   mDuplicateFeatureButton = 
new QToolButton( 
this );
 
  138   mDuplicateFeatureButton->setText( tr( 
"Duplicate Child Feature" ) );
 
  139   mDuplicateFeatureButton->setToolTip( tr( 
"Duplicate selected child feature" ) );
 
  140   mDuplicateFeatureButton->setObjectName( QStringLiteral( 
"mDuplicateFeatureButton" ) );
 
  141   buttonLayout->addWidget( mDuplicateFeatureButton );
 
  143   mDeleteFeatureButton = 
new QToolButton( 
this );
 
  145   mDeleteFeatureButton->setText( tr( 
"Delete Child Feature" ) );
 
  146   mDeleteFeatureButton->setToolTip( tr( 
"Delete selected child feature" ) );
 
  147   mDeleteFeatureButton->setObjectName( QStringLiteral( 
"mDeleteFeatureButton" ) );
 
  148   buttonLayout->addWidget( mDeleteFeatureButton );
 
  150   mLinkFeatureButton = 
new QToolButton( 
this );
 
  152   mLinkFeatureButton->setText( tr( 
"Link Existing Features" ) );
 
  153   mLinkFeatureButton->setToolTip( tr( 
"Link existing child features" ) );
 
  154   mLinkFeatureButton->setObjectName( QStringLiteral( 
"mLinkFeatureButton" ) );
 
  155   buttonLayout->addWidget( mLinkFeatureButton );
 
  157   mUnlinkFeatureButton = 
new QToolButton( 
this );
 
  159   mUnlinkFeatureButton->setText( tr( 
"Unlink Feature" ) );
 
  160   mUnlinkFeatureButton->setToolTip( tr( 
"Unlink selected child feature" ) );
 
  161   mUnlinkFeatureButton->setObjectName( QStringLiteral( 
"mUnlinkFeatureButton" ) );
 
  162   buttonLayout->addWidget( mUnlinkFeatureButton );
 
  164   mZoomToFeatureButton = 
new QToolButton( 
this );
 
  166   mZoomToFeatureButton->setText( tr( 
"Zoom To Feature" ) );
 
  167   mZoomToFeatureButton->setToolTip( tr( 
"Zoom to selected child feature" ) );
 
  168   mZoomToFeatureButton->setObjectName( QStringLiteral( 
"mZoomToFeatureButton" ) );
 
  169   buttonLayout->addWidget( mZoomToFeatureButton );
 
  171   buttonLayout->addItem( 
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
 
  173   mFormViewButton = 
new QToolButton( 
this );
 
  174   mFormViewButton->setText( tr( 
"Form View" ) );
 
  175   mFormViewButton->setToolTip( tr( 
"Switch to form view" ) );
 
  177   mFormViewButton->setCheckable( 
true );
 
  179   buttonLayout->addWidget( mFormViewButton );
 
  181   mTableViewButton = 
new QToolButton( 
this );
 
  182   mTableViewButton->setText( tr( 
"Table View" ) );
 
  183   mTableViewButton->setToolTip( tr( 
"Switch to table view" ) );
 
  185   mTableViewButton->setCheckable( 
true );
 
  187   buttonLayout->addWidget( mTableViewButton );
 
  189   mViewModeButtonGroup = 
new QButtonGroup( 
this );
 
  194   rootLayout->addLayout( buttonLayout );
 
  197   QGridLayout *relationLayout = 
new QGridLayout();
 
  198   relationLayout->setContentsMargins( 0, 0, 0, 0 );
 
  200   mDualView->
setView( mViewMode );
 
  202   relationLayout->addWidget( mDualView );
 
  203   rootLayout->addLayout( relationLayout );
 
  205 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
  206   connect( mViewModeButtonGroup, 
static_cast<void ( QButtonGroup::* )( 
int )
>( &QButtonGroup::buttonClicked ),
 
  209   connect( mViewModeButtonGroup, &QButtonGroup::idClicked,
 
  212   connect( mToggleEditingButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::toggleEditing );
 
  214   connect( mAddFeatureButton, &QAbstractButton::clicked, 
this, [
this]() { 
addFeature(); } );
 
  215   connect( mAddFeatureGeometryButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::addFeatureGeometry );
 
  225   setLayout( rootLayout );
 
  233   mFeatureSelectionMgr = 
new QgsFilteredSelectionManager( layer, request, mDualView );
 
  243     text = tr( 
"Add Point Child Feature" );
 
  248     text = tr( 
"Add Line Child Feature" );
 
  253     text = tr( 
"Add Polygon Child Feature" );
 
  256   mAddFeatureGeometryButton->setIcon( icon );
 
  257   mAddFeatureGeometryButton->setText( text );
 
  258   mAddFeatureGeometryButton->setToolTip( text );
 
  270     mMapToolDigitize->
setButton( mAddFeatureGeometryButton );
 
  282 void QgsRelationEditorWidget::updateButtons()
 
  284   bool toggleEditingButtonEnabled = 
false;
 
  285   bool editable = 
false;
 
  286   bool linkable = 
false;
 
  287   bool spatial = 
false;
 
  288   const bool selectionNotEmpty = mFeatureSelectionMgr ? mFeatureSelectionMgr->
selectedFeatureCount() : 
false;
 
  305   mToggleEditingButton->setEnabled( toggleEditingButtonEnabled );
 
  306   mAddFeatureButton->setEnabled( editable );
 
  307   mAddFeatureGeometryButton->setEnabled( editable );
 
  308   mDuplicateFeatureButton->setEnabled( editable && selectionNotEmpty );
 
  309   mLinkFeatureButton->setEnabled( linkable );
 
  310   mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
 
  311   mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
 
  312   mZoomToFeatureButton->setEnabled( selectionNotEmpty );
 
  313   mToggleEditingButton->setChecked( editable );
 
  314   mSaveEditsButton->setEnabled( editable || linkable );
 
  318   mLinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Link ) );
 
  319   mUnlinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
 
  320   mSaveEditsButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) && !
mLayerInSameTransactionGroup );
 
  321   mAddFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
 
  323   mDuplicateFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
 
  324   mDeleteFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
 
  325   mZoomToFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) && 
mEditorContext.
mapCanvas() && spatial );
 
  328 void QgsRelationEditorWidget::addFeatureGeometry()
 
  336   mMapToolDigitize->
setLayer( layer );
 
  339   window()->setVisible( 
false );
 
  340   setMapTool( mMapToolDigitize );
 
  350     const QString msg = tr( 
"Digitize the geometry for the new feature on layer %1. Press <ESC> to cancel." )
 
  351                         .arg( layer->
name() );
 
  353     lMainMessageBar->pushItem( mMessageBarItem );
 
  358 void QgsRelationEditorWidget::onDigitizingCompleted( 
const QgsFeature &feature )
 
  365 void QgsRelationEditorWidget::toggleEditing( 
bool state )
 
  391       filters << filter.prepend( 
'(' ).append( 
')' );
 
  407   mButtonsVisibility = buttons;
 
  414   if ( mLinkFeatureButton->isVisible() )
 
  415     buttons |= Button::Link;
 
  416   if ( mUnlinkFeatureButton->isVisible() )
 
  417     buttons |= Button::Unlink;
 
  418   if ( mSaveEditsButton->isVisible() )
 
  419     buttons |= Button::SaveChildEdits;
 
  420   if ( mAddFeatureButton->isVisible() )
 
  421     buttons |= Button::AddChildFeature;
 
  422   if ( mDuplicateFeatureButton->isVisible() )
 
  423     buttons |= Button::DuplicateChildFeature;
 
  424   if ( mDeleteFeatureButton->isVisible() )
 
  425     buttons |= Button::DeleteChildFeature;
 
  426   if ( mZoomToFeatureButton->isVisible() )
 
  427     buttons |= Button::ZoomToChildFeature;
 
  440     QAction *qAction = 
nullptr;
 
  443     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { 
deleteFeature( fid ); } );
 
  446     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { 
unlinkFeature( fid ); } );
 
  450 void QgsRelationEditorWidget::setMapTool( 
QgsMapTool *mapTool )
 
  455   mapCanvas->window()->raise();
 
  456   mapCanvas->activateWindow();
 
  457   mapCanvas->setFocus();
 
  461 void QgsRelationEditorWidget::unsetMapTool()
 
  472 void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
 
  474   if ( e->key() == Qt::Key_Escape )
 
  480 void QgsRelationEditorWidget::mapToolDeactivated()
 
  482   window()->setVisible( 
true );
 
  484   window()->activateWindow();
 
  490   mMessageBarItem = 
nullptr;
 
  496     {
"show_first_feature", mShowFirstFeature}} );
 
  501   mButtonsVisibility = 
qgsFlagKeysToValue( 
config.value( QStringLiteral( 
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
 
  502   mShowFirstFeature = 
config.value( QStringLiteral( 
"show_first_feature" ), 
true ).toBool();
 
  508   Q_UNUSED( newRelation );
 
  509   Q_UNUSED( newFeature );
 
  537   Q_UNUSED( newRelation );
 
  538   Q_UNUSED( newNmRelation );
 
  572   return mFeatureSelectionMgr;
 
  619   QgsRelationEditorWidget::Buttons buttons;
 
  620   buttons.setFlag( QgsRelationEditorWidget::Button::Link, mRelationShowLinkCheckBox->isChecked() );
 
  621   buttons.setFlag( QgsRelationEditorWidget::Button::Unlink, mRelationShowUnlinkCheckBox->isChecked() );
 
  622   buttons.setFlag( QgsRelationEditorWidget::Button::AddChildFeature, mRelationShowAddChildCheckBox->isChecked() );
 
  623   buttons.setFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature, mRelationShowDuplicateChildFeatureCheckBox->isChecked() );
 
  624   buttons.setFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature, mRelationShowZoomToFeatureCheckBox->isChecked() );
 
  625   buttons.setFlag( QgsRelationEditorWidget::Button::DeleteChildFeature, mRelationDeleteChildFeatureCheckBox->isChecked() );
 
  626   buttons.setFlag( QgsRelationEditorWidget::Button::SaveChildEdits, mRelationShowSaveChildEditsCheckBox->isChecked() );
 
  631     {
"show_first_feature", mShowFirstFeature->isChecked()}
 
  637   const QgsRelationEditorWidget::Buttons buttons = 
qgsFlagKeysToValue( 
config.value( QStringLiteral( 
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
 
  639   mRelationShowLinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Link ) );
 
  640   mRelationShowUnlinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
 
  641   mRelationShowAddChildCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
 
  642   mRelationShowDuplicateChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
 
  643   mRelationShowZoomToFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) );
 
  644   mRelationDeleteChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
 
  645   mRelationShowSaveChildEditsCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) );
 
  646   mShowFirstFeature->setChecked( 
config.value( QStringLiteral( 
"show_first_feature" ), 
true ).toBool() );
 
  661   return QStringLiteral( 
"relation_editor" );
 
  666   return QObject::tr( 
"Relation Editor" );
 
void reset(T *p=nullptr)
Will reset the managed pointer to p.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
This class contains context information for attribute editor widgets.
QgsMapCanvas * mapCanvas() const
Returns the associated map canvas (e.g.
QgsMessageBar * mainMessageBar()
Returns the main message bar.
QgsAdvancedDigitizingDockWidget * cadDockWidget() const
Returns the associated CAD dock widget (e.g.
void setParentFormFeature(const QgsFeature &feature)
Sets the feature of the currently edited parent form.
This widget is used to show the attributes of a set of features of a QgsVectorLayer.
void showContextMenuExternally(QgsActionMenu *menu, QgsFeatureId fid)
Emitted when selecting context menu on the feature list to create the context menu individually.
ViewMode
The view modes, in which this widget can present information.
@ AttributeTable
Shows the features and attributes in a table layout.
@ AttributeEditor
Show a list of the features, where one can be chosen and the according attribute dialog will be prese...
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
Set the feature selection model.
void init(QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsAttributeEditorContext &context=QgsAttributeEditorContext(), bool loadFeatures=true, bool showFirstFeature=true)
Has to be called to initialize the dual view.
void parentFormValueChanged(const QString &attribute, const QVariant &value)
Called in embedded forms when an attribute value in the parent form has changed.
void setView(ViewMode view)
Change the current view mode.
QString expression() const
Returns the original, unmodified expression string.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsExpression * filterExpression() const
Returns the filter expression (if set).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
Is an interface class to abstract feature selection handling.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
Map canvas is a class for displaying all GIS data types on a canvas.
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
void keyPressed(QKeyEvent *e)
Emit key press event.
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void editingStarted()
Emitted when editing on this layer has started.
bool popWidget(QgsMessageBarItem *item)
Remove the specified item from the bar, and display the next most recent one in the stack.
static QgsMessageBarItem * createMessage(const QString &text, QWidget *parent=nullptr)
Creates message bar item widget containing a message text to be displayed on the bar.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
QgsVectorLayer * referencedLayer
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...
int selectedFeatureCount() override
Returns the number of features that are selected in this layer.
const QgsFeatureIds & selectedFeatureIds() const override
Returns reference to identifiers of selected features.
static QString getFeatureDisplayString(const QgsVectorLayer *layer, const QgsFeature &feature)
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue)
Returns the value corresponding to the given keys of a flag.
QString qgsFlagValueToKeys(const T &value)
Returns the value for the given keys of a flag.
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features