Skip to content
Permalink
Browse files
Applied suggestions from code review
  • Loading branch information
domi4484 committed Nov 17, 2021
1 parent dbb26cb commit 18564a29c395bf36bab19ecadc67ea509d4b843a
Showing with 167 additions and 160 deletions.
  1. +165 −160 src/gui/qgsrelationeditorwidget.cpp
  2. +2 −0 src/gui/qgsrelationeditorwidget.h
@@ -516,167 +516,10 @@ void QgsRelationEditorWidget::updateUi()
if ( !isVisible() )
return;

mFormViewButton->setVisible( !multiEditModeActive() );
mTableViewButton->setVisible( !multiEditModeActive() );
mMultiEditInfoLabel->setVisible( multiEditModeActive() );

if ( !multiEditModeActive() )
{
mStackedWidget->setCurrentWidget( mDualView );

const QgsFeatureRequest request = mRelation.getRelatedFeaturesRequest( mFeatureList.first() );

if ( mNmRelation.isValid() )
{
QgsFeatureIterator it = mRelation.referencingLayer()->getFeatures( request );
QgsFeature fet;
QStringList filters;

while ( it.nextFeature( fet ) )
{
QString filter = mNmRelation.getReferencedFeatureRequest( fet ).filterExpression()->expression();
filters << filter.prepend( '(' ).append( ')' );
}

QgsFeatureRequest nmRequest;
nmRequest.setFilterExpression( filters.join( QLatin1String( " OR " ) ) );

initDualView( mNmRelation.referencedLayer(), nmRequest );
}
else if ( mRelation.referencingLayer() )
{
initDualView( mRelation.referencingLayer(), request );
}
}
if ( multiEditModeActive() )
updateUiMultiEdit();
else
{
mStackedWidget->setCurrentWidget( mMultiEditStackedWidgetPage ) ;

QList<QTreeWidgetItem *> parentTreeWidgetItems;

QgsFeatureIds featureIdsMixedValues;
QMultiMap<QTreeWidgetItem *, QgsFeatureId> multimapChildFeatures;

mMultiEditTreeWidget->clear();
for ( const QgsFeature &feature : std::as_const( mFeatureList ) )
{
QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem( mMultiEditTreeWidget );
treeWidgetItem->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Parent ) );
treeWidgetItem->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mRelation.referencedLayer(), feature ) );
treeWidgetItem->setIcon( 0, QgsIconUtils::iconForLayer( mRelation.referencedLayer() ) );

// Parent feature items are not selectable
treeWidgetItem->setFlags( Qt::ItemIsEnabled );

parentTreeWidgetItems.append( treeWidgetItem );

// Get child features
const QgsFeatureRequest request = relation().getRelatedFeaturesRequest( feature );
QgsFeatureIterator featureIterator = mRelation.referencingLayer()->getFeatures( request );
QgsFeature featureChild;
while ( featureIterator.nextFeature( featureChild ) )
{
if ( mNmRelation.isValid() )
{
const QgsFeatureRequest requestFinalChild = mNmRelation.getReferencedFeatureRequest( featureChild );
QgsFeatureIterator featureIteratorFinalChild = mNmRelation.referencedLayer()->getFeatures( requestFinalChild );
QgsFeature featureChildChild;
while ( featureIteratorFinalChild.nextFeature( featureChildChild ) )
{
QTreeWidgetItem *treeWidgetItemChild = new QTreeWidgetItem( treeWidgetItem );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Child ) );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), featureChildChild.id() );
treeWidgetItemChild->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mNmRelation.referencedLayer(), featureChildChild ) );
treeWidgetItemChild->setIcon( 0, QgsIconUtils::iconForLayer( mNmRelation.referencedLayer() ) );

// For nm relations deleting/unlinking is not supported now, so selection
// is also not possible
if ( nmRelation().isValid() )
treeWidgetItem->setFlags( Qt::ItemIsEnabled );

treeWidgetItem->addChild( treeWidgetItemChild );

featureIdsMixedValues.insert( featureChildChild.id() );
multimapChildFeatures.insert( treeWidgetItem, featureChildChild.id() );
}
}
else
{
QTreeWidgetItem *treeWidgetItemChild = new QTreeWidgetItem( treeWidgetItem );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Child ) );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), featureChild.id() );
treeWidgetItemChild->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mRelation.referencingLayer(), featureChild ) );
treeWidgetItemChild->setIcon( 0, QgsIconUtils::iconForLayer( mRelation.referencingLayer() ) );
treeWidgetItem->addChild( treeWidgetItemChild );

featureIdsMixedValues.insert( featureChild.id() );
}
}

treeWidgetItem->setExpanded( true );
mMultiEditTreeWidget->addTopLevelItem( treeWidgetItem );
}

// Check for mixed values
if ( mNmRelation.isValid() )
{
QgsFeatureIds featureIdsNotMixed;
for ( const QgsFeatureId &featureId : featureIdsMixedValues )
{
bool mixedValues = false;
for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
{
if ( ! multimapChildFeatures.values( parentTreeWidgetItem ).contains( featureId ) )
{
mixedValues = true;
break;
}
}

if ( !mixedValues )
featureIdsNotMixed.insert( featureId );


}

featureIdsMixedValues -= featureIdsNotMixed;
}
else
{
for ( const QgsFeatureId &featureIdJustAdded : std::as_const( mMultiEdit1NJustAddedIds ) )
featureIdsMixedValues.remove( featureIdJustAdded );
}

// Set multiedit info label
if ( featureIdsMixedValues.isEmpty() )
{
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "/multieditSameValues.svg" ) );
mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(),
mMultiEditInfoLabel->height() ) );
mMultiEditInfoLabel->setToolTip( tr( "All features in selection have equal relations" ) );
}
else
{
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "/multieditMixedValues.svg" ) );
mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(),
mMultiEditInfoLabel->height() ) );
mMultiEditInfoLabel->setToolTip( tr( "Some features in selection have different relations" ) );

// Set italic font for mixed values
QFont fontItalic = mMultiEditTreeWidget->font();
fontItalic.setItalic( true );
for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
{
for ( int childIndex = 0; childIndex < parentTreeWidgetItem->childCount(); ++childIndex )
{
QTreeWidgetItem *childItem = parentTreeWidgetItem->child( childIndex );
const QgsFeatureId featureIdCurrentItem = childItem->data( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
if ( featureIdsMixedValues.contains( featureIdCurrentItem ) )
childItem->setFont( 0, fontItalic );
}
}
}
}
updateUiSingleEdit();
}

void QgsRelationEditorWidget::setVisibleButtons( const Buttons &buttons )
@@ -764,6 +607,168 @@ QgsFeatureIds QgsRelationEditorWidget::selectedChildFeatureIds() const
return mFeatureSelectionMgr->selectedFeatureIds();
}

void QgsRelationEditorWidget::updateUiSingleEdit()
{
mFormViewButton->setVisible( true );
mTableViewButton->setVisible( true );
mMultiEditInfoLabel->setVisible( false );

mStackedWidget->setCurrentWidget( mDualView );

const QgsFeatureRequest request = mRelation.getRelatedFeaturesRequest( mFeatureList.first() );

if ( mNmRelation.isValid() )
{
QgsFeatureIterator it = mRelation.referencingLayer()->getFeatures( request );
QgsFeature fet;
QStringList filters;

while ( it.nextFeature( fet ) )
{
QString filter = mNmRelation.getReferencedFeatureRequest( fet ).filterExpression()->expression();
filters << filter.prepend( '(' ).append( ')' );
}

QgsFeatureRequest nmRequest;
nmRequest.setFilterExpression( filters.join( QLatin1String( " OR " ) ) );

initDualView( mNmRelation.referencedLayer(), nmRequest );
}
else if ( mRelation.referencingLayer() )
{
initDualView( mRelation.referencingLayer(), request );
}
}

void QgsRelationEditorWidget::updateUiMultiEdit()
{
mFormViewButton->setVisible( false );
mTableViewButton->setVisible( false );
mMultiEditInfoLabel->setVisible( true );

mStackedWidget->setCurrentWidget( mMultiEditStackedWidgetPage ) ;

QList<QTreeWidgetItem *> parentTreeWidgetItems;

QgsFeatureIds featureIdsMixedValues;
QMultiMap<QTreeWidgetItem *, QgsFeatureId> multimapChildFeatures;

mMultiEditTreeWidget->clear();
for ( const QgsFeature &feature : std::as_const( mFeatureList ) )
{
QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem( mMultiEditTreeWidget );
treeWidgetItem->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Parent ) );
treeWidgetItem->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mRelation.referencedLayer(), feature ) );
treeWidgetItem->setIcon( 0, QgsIconUtils::iconForLayer( mRelation.referencedLayer() ) );

// Parent feature items are not selectable
treeWidgetItem->setFlags( Qt::ItemIsEnabled );

parentTreeWidgetItems.append( treeWidgetItem );

// Get child features
const QgsFeatureRequest request = relation().getRelatedFeaturesRequest( feature );
QgsFeatureIterator featureIterator = mRelation.referencingLayer()->getFeatures( request );
QgsFeature featureChild;
while ( featureIterator.nextFeature( featureChild ) )
{
if ( mNmRelation.isValid() )
{
const QgsFeatureRequest requestFinalChild = mNmRelation.getReferencedFeatureRequest( featureChild );
QgsFeatureIterator featureIteratorFinalChild = mNmRelation.referencedLayer()->getFeatures( requestFinalChild );
QgsFeature featureChildChild;
while ( featureIteratorFinalChild.nextFeature( featureChildChild ) )
{
QTreeWidgetItem *treeWidgetItemChild = new QTreeWidgetItem( treeWidgetItem );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Child ) );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), featureChildChild.id() );
treeWidgetItemChild->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mNmRelation.referencedLayer(), featureChildChild ) );
treeWidgetItemChild->setIcon( 0, QgsIconUtils::iconForLayer( mNmRelation.referencedLayer() ) );

treeWidgetItem->addChild( treeWidgetItemChild );

featureIdsMixedValues.insert( featureChildChild.id() );
multimapChildFeatures.insert( treeWidgetItem, featureChildChild.id() );
}
}
else
{
QTreeWidgetItem *treeWidgetItemChild = new QTreeWidgetItem( treeWidgetItem );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Child ) );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), featureChild.id() );
treeWidgetItemChild->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mRelation.referencingLayer(), featureChild ) );
treeWidgetItemChild->setIcon( 0, QgsIconUtils::iconForLayer( mRelation.referencingLayer() ) );
treeWidgetItem->addChild( treeWidgetItemChild );

featureIdsMixedValues.insert( featureChild.id() );
}
}

treeWidgetItem->setExpanded( true );
mMultiEditTreeWidget->addTopLevelItem( treeWidgetItem );
}

// Check for mixed values
if ( mNmRelation.isValid() )
{
QgsFeatureIds featureIdsNotMixed;
for ( const QgsFeatureId &featureId : featureIdsMixedValues )
{
bool mixedValues = false;
for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
{
if ( ! multimapChildFeatures.values( parentTreeWidgetItem ).contains( featureId ) )
{
mixedValues = true;
break;
}
}

if ( !mixedValues )
featureIdsNotMixed.insert( featureId );


}

featureIdsMixedValues -= featureIdsNotMixed;
}
else
{
for ( const QgsFeatureId &featureIdJustAdded : std::as_const( mMultiEdit1NJustAddedIds ) )
featureIdsMixedValues.remove( featureIdJustAdded );
}

// Set multiedit info label
if ( featureIdsMixedValues.isEmpty() )
{
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "/multieditSameValues.svg" ) );
mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(),
mMultiEditInfoLabel->height() ) );
mMultiEditInfoLabel->setToolTip( tr( "All features in selection have equal relations" ) );
}
else
{
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "/multieditMixedValues.svg" ) );
mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(),
mMultiEditInfoLabel->height() ) );
mMultiEditInfoLabel->setToolTip( tr( "Some features in selection have different relations" ) );

// Set italic font for mixed values
QFont fontItalic = mMultiEditTreeWidget->font();
fontItalic.setItalic( true );
for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
{
for ( int childIndex = 0; childIndex < parentTreeWidgetItem->childCount(); ++childIndex )
{
QTreeWidgetItem *childItem = parentTreeWidgetItem->child( childIndex );
const QgsFeatureId featureIdCurrentItem = childItem->data( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
if ( featureIdsMixedValues.contains( featureIdCurrentItem ) )
childItem->setFont( 0, fontItalic );
}
}
}
}

void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
{
if ( e->key() == Qt::Key_Escape )
@@ -217,6 +217,8 @@ class GUI_EXPORT QgsRelationEditorWidget : public QgsAbstractRelationEditorWidge
void setMapTool( QgsMapTool *mapTool );
void unsetMapTool();
QgsFeatureIds selectedChildFeatureIds() const;
void updateUiSingleEdit();
void updateUiMultiEdit();

enum class MultiEditFeatureType : int
{

0 comments on commit 18564a2

Please sign in to comment.