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 ( 
auto fid : deselected )
 
   83       mSelectedFeatureIds.remove( fid );
 
   86   for ( 
auto fid : selected )
 
   87     if ( mRequest.acceptFeature( layer()->getFeature( fid ) ) )
 
   88       mSelectedFeatureIds << fid;
 
   90       lselected.remove( fid );
 
   92   emit selectionChanged( lselected, deselected, clearAndSelect );
 
  101   QVBoxLayout *rootLayout = 
new QVBoxLayout( 
this );
 
  102   rootLayout->setContentsMargins( 0, 9, 0, 0 );
 
  105   QHBoxLayout *buttonLayout = 
new QHBoxLayout();
 
  106   buttonLayout->setContentsMargins( 0, 0, 0, 0 );
 
  108   mToggleEditingButton = 
new QToolButton( 
this );
 
  109   mToggleEditingButton->setObjectName( QStringLiteral( 
"mToggleEditingButton" ) );
 
  111   mToggleEditingButton->setText( tr( 
"Toggle Editing" ) );
 
  112   mToggleEditingButton->setEnabled( 
false );
 
  113   mToggleEditingButton->setCheckable( 
true );
 
  114   mToggleEditingButton->setToolTip( tr( 
"Toggle editing mode for child layer" ) );
 
  115   buttonLayout->addWidget( mToggleEditingButton );
 
  117   mSaveEditsButton = 
new QToolButton( 
this );
 
  119   mSaveEditsButton->setText( tr( 
"Save Child Layer Edits" ) );
 
  120   mSaveEditsButton->setToolTip( tr( 
"Save child layer edits" ) );
 
  121   mSaveEditsButton->setEnabled( 
true );
 
  122   buttonLayout->addWidget( mSaveEditsButton );
 
  124   mAddFeatureGeometryButton = 
new QToolButton( 
this );
 
  125   mAddFeatureGeometryButton->setObjectName( QStringLiteral( 
"mAddFeatureGeometryButton" ) );
 
  126   buttonLayout->addWidget( mAddFeatureGeometryButton );
 
  128   mAddFeatureButton = 
new QToolButton( 
this );
 
  130   mAddFeatureButton->setText( tr( 
"Add Child Feature" ) );
 
  131   mAddFeatureButton->setToolTip( tr( 
"Add child feature" ) );
 
  132   mAddFeatureButton->setObjectName( QStringLiteral( 
"mAddFeatureButton" ) );
 
  133   buttonLayout->addWidget( mAddFeatureButton );
 
  135   mDuplicateFeatureButton = 
new QToolButton( 
this );
 
  137   mDuplicateFeatureButton->setText( tr( 
"Duplicate Child Feature" ) );
 
  138   mDuplicateFeatureButton->setToolTip( tr( 
"Duplicate selected child feature" ) );
 
  139   mDuplicateFeatureButton->setObjectName( QStringLiteral( 
"mDuplicateFeatureButton" ) );
 
  140   buttonLayout->addWidget( mDuplicateFeatureButton );
 
  142   mDeleteFeatureButton = 
new QToolButton( 
this );
 
  144   mDeleteFeatureButton->setText( tr( 
"Delete Child Feature" ) );
 
  145   mDeleteFeatureButton->setToolTip( tr( 
"Delete selected child feature" ) );
 
  146   mDeleteFeatureButton->setObjectName( QStringLiteral( 
"mDeleteFeatureButton" ) );
 
  147   buttonLayout->addWidget( mDeleteFeatureButton );
 
  149   mLinkFeatureButton = 
new QToolButton( 
this );
 
  151   mLinkFeatureButton->setText( tr( 
"Link Existing Features" ) );
 
  152   mLinkFeatureButton->setToolTip( tr( 
"Link existing child features" ) );
 
  153   mLinkFeatureButton->setObjectName( QStringLiteral( 
"mLinkFeatureButton" ) );
 
  154   buttonLayout->addWidget( mLinkFeatureButton );
 
  156   mUnlinkFeatureButton = 
new QToolButton( 
this );
 
  158   mUnlinkFeatureButton->setText( tr( 
"Unlink Feature" ) );
 
  159   mUnlinkFeatureButton->setToolTip( tr( 
"Unlink selected child feature" ) );
 
  160   mUnlinkFeatureButton->setObjectName( QStringLiteral( 
"mUnlinkFeatureButton" ) );
 
  161   buttonLayout->addWidget( mUnlinkFeatureButton );
 
  163   mZoomToFeatureButton = 
new QToolButton( 
this );
 
  165   mZoomToFeatureButton->setText( tr( 
"Zoom To Feature" ) );
 
  166   mZoomToFeatureButton->setToolTip( tr( 
"Zoom to selected child feature" ) );
 
  167   mZoomToFeatureButton->setObjectName( QStringLiteral( 
"mZoomToFeatureButton" ) );
 
  168   buttonLayout->addWidget( mZoomToFeatureButton );
 
  170   buttonLayout->addItem( 
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
 
  172   mFormViewButton = 
new QToolButton( 
this );
 
  173   mFormViewButton->setText( tr( 
"Form View" ) );
 
  174   mFormViewButton->setToolTip( tr( 
"Switch to form view" ) );
 
  176   mFormViewButton->setCheckable( 
true );
 
  178   buttonLayout->addWidget( mFormViewButton );
 
  180   mTableViewButton = 
new QToolButton( 
this );
 
  181   mTableViewButton->setText( tr( 
"Table View" ) );
 
  182   mTableViewButton->setToolTip( tr( 
"Switch to table view" ) );
 
  184   mTableViewButton->setCheckable( 
true );
 
  186   buttonLayout->addWidget( mTableViewButton );
 
  188   mViewModeButtonGroup = 
new QButtonGroup( 
this );
 
  193   rootLayout->addLayout( buttonLayout );
 
  196   QGridLayout *relationLayout = 
new QGridLayout();
 
  197   relationLayout->setContentsMargins( 0, 0, 0, 0 );
 
  199   mDualView->
setView( mViewMode );
 
  201   relationLayout->addWidget( mDualView );
 
  202   rootLayout->addLayout( relationLayout );
 
  204   connect( mViewModeButtonGroup, 
static_cast<void ( QButtonGroup::* )( 
int )
>( &QButtonGroup::buttonClicked ),
 
  206   connect( mToggleEditingButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::toggleEditing );
 
  208   connect( mAddFeatureButton, &QAbstractButton::clicked, 
this, [
this]() { 
addFeature(); } );
 
  209   connect( mAddFeatureGeometryButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::addFeatureGeometry );
 
  225   mFeatureSelectionMgr = 
new QgsFilteredSelectionManager( layer, request, mDualView );
 
  235     text = tr( 
"Add Point child Feature" );
 
  240     text = tr( 
"Add Line child Feature" );
 
  245     text = tr( 
"Add Polygon Feature" );
 
  248   mAddFeatureGeometryButton->setIcon( icon );
 
  249   mAddFeatureGeometryButton->setText( text );
 
  250   mAddFeatureGeometryButton->setToolTip( text );
 
  262     mMapToolDigitize->
setButton( mAddFeatureGeometryButton );
 
  274 void QgsRelationEditorWidget::updateButtons()
 
  276   bool toggleEditingButtonEnabled = 
false;
 
  277   bool editable = 
false;
 
  278   bool linkable = 
false;
 
  279   bool spatial = 
false;
 
  280   bool selectionNotEmpty = mFeatureSelectionMgr ? mFeatureSelectionMgr->
selectedFeatureCount() : 
false;
 
  297   mToggleEditingButton->setEnabled( toggleEditingButtonEnabled );
 
  298   mAddFeatureButton->setEnabled( editable );
 
  299   mAddFeatureGeometryButton->setEnabled( editable );
 
  300   mDuplicateFeatureButton->setEnabled( editable && selectionNotEmpty );
 
  301   mLinkFeatureButton->setEnabled( linkable );
 
  302   mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
 
  303   mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
 
  304   mZoomToFeatureButton->setEnabled( selectionNotEmpty );
 
  305   mToggleEditingButton->setChecked( editable );
 
  306   mSaveEditsButton->setEnabled( editable || linkable );
 
  310   mLinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Link ) );
 
  311   mUnlinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
 
  312   mSaveEditsButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) && !
mLayerInSameTransactionGroup );
 
  313   mAddFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
 
  315   mDuplicateFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
 
  316   mDeleteFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
 
  317   mZoomToFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) && 
mEditorContext.
mapCanvas() && spatial );
 
  320 void QgsRelationEditorWidget::addFeatureGeometry()
 
  328   mMapToolDigitize->
setLayer( layer );
 
  331   window()->setVisible( 
false );
 
  332   setMapTool( mMapToolDigitize );
 
  342     QString msg = tr( 
"Digitize the geometry for the new feature on layer %1. Press <ESC> to cancel." )
 
  343                   .arg( layer->
name() );
 
  345     lMainMessageBar->pushItem( mMessageBarItem );
 
  350 void QgsRelationEditorWidget::onDigitizingCompleted( 
const QgsFeature &feature )
 
  357 void QgsRelationEditorWidget::toggleEditing( 
bool state )
 
  383       filters << filter.prepend( 
'(' ).append( 
')' );
 
  399   mButtonsVisibility = buttons;
 
  406   if ( mLinkFeatureButton->isVisible() )
 
  407     buttons |= Button::Link;
 
  408   if ( mUnlinkFeatureButton->isVisible() )
 
  409     buttons |= Button::Unlink;
 
  410   if ( mSaveEditsButton->isVisible() )
 
  411     buttons |= Button::SaveChildEdits;
 
  412   if ( mAddFeatureButton->isVisible() )
 
  413     buttons |= Button::AddChildFeature;
 
  414   if ( mDuplicateFeatureButton->isVisible() )
 
  415     buttons |= Button::DuplicateChildFeature;
 
  416   if ( mDeleteFeatureButton->isVisible() )
 
  417     buttons |= Button::DeleteChildFeature;
 
  418   if ( mZoomToFeatureButton->isVisible() )
 
  419     buttons |= Button::ZoomToChildFeature;
 
  432     QAction *qAction = 
nullptr;
 
  435     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { 
deleteFeature( fid ); } );
 
  438     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { 
unlinkFeature( fid ); } );
 
  442 void QgsRelationEditorWidget::setMapTool( 
QgsMapTool *mapTool )
 
  447   mapCanvas->window()->raise();
 
  448   mapCanvas->activateWindow();
 
  449   mapCanvas->setFocus();
 
  453 void QgsRelationEditorWidget::unsetMapTool()
 
  464 void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
 
  466   if ( e->key() == Qt::Key_Escape )
 
  472 void QgsRelationEditorWidget::mapToolDeactivated()
 
  474   window()->setVisible( 
true );
 
  476   window()->activateWindow();
 
  482   mMessageBarItem = 
nullptr;
 
  492   mButtonsVisibility = 
qgsFlagKeysToValue( 
config.value( QStringLiteral( 
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
 
  498   Q_UNUSED( newRelation );
 
  499   Q_UNUSED( newFeature );
 
  527   Q_UNUSED( newRelation );
 
  528   Q_UNUSED( newNmRelation );
 
  562   return mFeatureSelectionMgr;
 
  609   QgsRelationEditorWidget::Buttons buttons;
 
  610   buttons.setFlag( QgsRelationEditorWidget::Button::Link, mRelationShowLinkCheckBox->isChecked() );
 
  611   buttons.setFlag( QgsRelationEditorWidget::Button::Unlink, mRelationShowUnlinkCheckBox->isChecked() );
 
  612   buttons.setFlag( QgsRelationEditorWidget::Button::AddChildFeature, mRelationShowAddChildCheckBox->isChecked() );
 
  613   buttons.setFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature, mRelationShowDuplicateChildFeatureCheckBox->isChecked() );
 
  614   buttons.setFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature, mRelationShowZoomToFeatureCheckBox->isChecked() );
 
  615   buttons.setFlag( QgsRelationEditorWidget::Button::DeleteChildFeature, mRelationDeleteChildFeatureCheckBox->isChecked() );
 
  616   buttons.setFlag( QgsRelationEditorWidget::Button::SaveChildEdits, mRelationShowSaveChildEditsCheckBox->isChecked() );
 
  626   const QgsRelationEditorWidget::Buttons buttons = 
qgsFlagKeysToValue( 
config.value( QStringLiteral( 
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
 
  628   mRelationShowLinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Link ) );
 
  629   mRelationShowUnlinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
 
  630   mRelationShowAddChildCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
 
  631   mRelationShowDuplicateChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
 
  632   mRelationShowZoomToFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) );
 
  633   mRelationDeleteChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
 
  634   mRelationShowSaveChildEditsCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) );
 
  649   return QStringLiteral( 
"relation_editor" );
 
  654   return QStringLiteral( 
"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 parentFormValueChanged(const QString &attribute, const QVariant &value)
Called in embedded forms when an attribute value in the parent form has changed.
void init(QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsAttributeEditorContext &context=QgsAttributeEditorContext(), bool loadFeatures=true)
Has to be called to initialize the dual view.
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.
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.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
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.
void editingStarted()
Emitted when editing on this layer has started.
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