mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-07 00:03:52 -05:00
[feature][ui] Add a Show in Attribute Table action to the right click menu of legend class symbols (#49984)
This commit is contained in:
parent
ec51684f06
commit
b7e31d4508
@ -220,6 +220,12 @@ need to be filtered again (like on filter or on main model data change).
|
||||
.. versionadded:: 3.10.3
|
||||
%End
|
||||
|
||||
QString filterExpression() const;
|
||||
%Docstring
|
||||
Returns the stored filter expression string.
|
||||
|
||||
.. versionadded:: 3.28.0
|
||||
%End
|
||||
signals:
|
||||
|
||||
void sortColumnChanged( int column, Qt::SortOrder order );
|
||||
|
||||
@ -7747,7 +7747,7 @@ void QgisApp::fieldCalculator()
|
||||
}
|
||||
}
|
||||
|
||||
void QgisApp::attributeTable( QgsAttributeTableFilterModel::FilterMode filter )
|
||||
void QgisApp::attributeTable( QgsAttributeTableFilterModel::FilterMode filter, const QString &filterExpression )
|
||||
{
|
||||
QgsVectorLayer *myLayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
|
||||
if ( !myLayer || !myLayer->dataProvider() )
|
||||
@ -7755,7 +7755,7 @@ void QgisApp::attributeTable( QgsAttributeTableFilterModel::FilterMode filter )
|
||||
return;
|
||||
}
|
||||
|
||||
QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( myLayer, filter );
|
||||
QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( myLayer, filter, nullptr, Qt::Window, nullptr, filterExpression );
|
||||
mDialog->show();
|
||||
// the dialog will be deleted by itself on close
|
||||
}
|
||||
|
||||
@ -934,7 +934,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
|
||||
void layerProperties();
|
||||
|
||||
//! show the attribute table for the currently selected layer
|
||||
void attributeTable( QgsAttributeTableFilterModel::FilterMode filter = QgsAttributeTableFilterModel::ShowAll );
|
||||
void attributeTable( QgsAttributeTableFilterModel::FilterMode filter = QgsAttributeTableFilterModel::ShowAll, const QString &filterExpression = QString() );
|
||||
|
||||
void fieldCalculator();
|
||||
|
||||
|
||||
@ -802,7 +802,6 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
|
||||
{
|
||||
QAction *selectMatching = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelected.svg" ) ), tr( "Select Features" ), menu );
|
||||
menu->addAction( selectMatching );
|
||||
menu->addSeparator();
|
||||
connect( selectMatching, &QAction::triggered, this, [layerId, ruleKey ]
|
||||
{
|
||||
if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProject::instance()->mapLayer( layerId ) ) )
|
||||
@ -836,6 +835,29 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
QAction *showMatchingInAttributeTable = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/attributes.svg" ) ), tr( "Show in Attribute Table" ), menu );
|
||||
menu->addAction( showMatchingInAttributeTable );
|
||||
connect( showMatchingInAttributeTable, &QAction::triggered, this, [layerId, ruleKey ]
|
||||
{
|
||||
if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( QgsProject::instance()->mapLayer( layerId ) ) )
|
||||
{
|
||||
bool ok = false;
|
||||
QString filterExp = layer->renderer() ? layer->renderer()->legendKeyToExpression( ruleKey, layer, ok ) : QString();
|
||||
if ( ok )
|
||||
{
|
||||
const QString canvasFilter = QgsMapCanvasUtils::filterForLayer( QgisApp::instance()->mapCanvas(), layer );
|
||||
if ( canvasFilter == QLatin1String( "FALSE" ) )
|
||||
return;
|
||||
else if ( !canvasFilter.isEmpty() )
|
||||
filterExp = QStringLiteral( "(%1) AND (%2)" ).arg( filterExp, canvasFilter );
|
||||
|
||||
QgisApp::instance()->attributeTable( QgsAttributeTableFilterModel::ShowFilteredList, filterExp );
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
if ( layer && layer->type() == QgsMapLayerType::VectorLayer && symbolNode->symbol() )
|
||||
|
||||
@ -108,7 +108,7 @@ void QgsAttributeTableDialog::updateMultiEditButtonState()
|
||||
}
|
||||
}
|
||||
|
||||
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttributeTableFilterModel::FilterMode initialMode, QWidget *parent, Qt::WindowFlags flags, bool *initiallyDocked )
|
||||
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttributeTableFilterModel::FilterMode initialMode, QWidget *parent, Qt::WindowFlags flags, bool *initiallyDocked, const QString &filterExpression )
|
||||
: QDialog( parent, flags )
|
||||
, mLayer( layer )
|
||||
{
|
||||
@ -221,6 +221,10 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
|
||||
{
|
||||
r.setFilterFids( layer->editBuffer() ? layer->editBuffer()->allAddedOrEditedFeatures() : QgsFeatureIds() );
|
||||
}
|
||||
else if ( !filterExpression.isEmpty() )
|
||||
{
|
||||
r.setFilterExpression( filterExpression );
|
||||
}
|
||||
if ( !needsGeom )
|
||||
r.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
|
||||
@ -385,6 +389,10 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
|
||||
mFeatureFilterWidget->filterEdited();
|
||||
break;
|
||||
|
||||
case QgsAttributeTableFilterModel::ShowFilteredList:
|
||||
mFeatureFilterWidget->setFilterExpression( filterExpression );
|
||||
break;
|
||||
|
||||
case QgsAttributeTableFilterModel::ShowAll:
|
||||
default:
|
||||
mFeatureFilterWidget->filterShowAll();
|
||||
|
||||
@ -53,8 +53,12 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
|
||||
* \param parent parent object
|
||||
* \param flags window flags
|
||||
*/
|
||||
QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttributeTableFilterModel::FilterMode initialMode = QgsAttributeTableFilterModel::ShowAll, QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::Window,
|
||||
bool *initiallyDocked = nullptr );
|
||||
QgsAttributeTableDialog( QgsVectorLayer *layer,
|
||||
QgsAttributeTableFilterModel::FilterMode initialMode = QgsAttributeTableFilterModel::ShowAll,
|
||||
QWidget *parent = nullptr,
|
||||
Qt::WindowFlags flags = Qt::Window,
|
||||
bool *initiallyDocked = nullptr,
|
||||
const QString &filterExpression = QString() );
|
||||
~QgsAttributeTableDialog() override;
|
||||
|
||||
QgsExpressionContext createExpressionContext() const override;
|
||||
|
||||
@ -251,6 +251,13 @@ class GUI_EXPORT QgsAttributeTableFilterModel: public QSortFilterProxyModel, pub
|
||||
*/
|
||||
void setFilterExpression( const QgsExpression &expression, const QgsExpressionContext &context );
|
||||
|
||||
/**
|
||||
* Returns the stored filter expression string.
|
||||
*
|
||||
* \since QGIS 3.28.0
|
||||
*/
|
||||
QString filterExpression() const { return mFilterExpression; };
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
|
||||
@ -361,9 +361,14 @@ void QgsDualView::setFilterMode( QgsAttributeTableFilterModel::FilterMode filter
|
||||
|
||||
case QgsAttributeTableFilterModel::ShowAll:
|
||||
case QgsAttributeTableFilterModel::ShowFilteredList:
|
||||
{
|
||||
const QString filterExpression = filterMode == QgsAttributeTableFilterModel::ShowFilteredList ? mFilterModel->filterExpression() : QString();
|
||||
if ( !filterExpression.isEmpty() )
|
||||
r.setFilterExpression( mFilterModel->filterExpression() );
|
||||
connect( mFilterModel, &QgsAttributeTableFilterModel::featuresFiltered, this, &QgsDualView::filterChanged );
|
||||
connect( mFilterModel, &QgsAttributeTableFilterModel::filterError, this, &QgsDualView::filterError );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsAttributeTableFilterModel::ShowSelected:
|
||||
connect( masterModel()->layer(), &QgsVectorLayer::selectionChanged, this, &QgsDualView::updateSelectedFeatures );
|
||||
|
||||
@ -462,7 +462,6 @@ void QgsFeatureFilterWidget::setFilterExpression( const QString &filterString, Q
|
||||
}
|
||||
|
||||
mMainView->filterFeatures( filterExpression, context );
|
||||
|
||||
mMainView->setFilterMode( QgsAttributeTableFilterModel::ShowFilteredList );
|
||||
}
|
||||
|
||||
|
||||
@ -61,6 +61,7 @@ class TestQgsAttributeTable : public QObject
|
||||
void testSortByDisplayExpression();
|
||||
void testOrderColumn();
|
||||
void testFilteredFeatures();
|
||||
void testOpenWithFilterExpression();
|
||||
void testVisibleTemporal();
|
||||
void testCopySelectedRows();
|
||||
void testSortNumbers();
|
||||
@ -757,5 +758,40 @@ void TestQgsAttributeTable::testCopySelectedRows()
|
||||
QCOMPARE( clipboard->crs().authid(), "EPSG:3111" );
|
||||
}
|
||||
|
||||
void TestQgsAttributeTable::testOpenWithFilterExpression()
|
||||
{
|
||||
// test attribute table opening in show feature visible mode
|
||||
std::unique_ptr< QgsVectorLayer> tempLayer( new QgsVectorLayer( QStringLiteral( "LineString?crs=epsg:4326&field=pk:int&field=col1:date" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
|
||||
QgsPolylineXY line;
|
||||
line << QgsPointXY( 0, 0 ) << QgsPointXY( 1, 1 );
|
||||
QgsGeometry geometry = QgsGeometry::fromPolylineXY( line ) ;
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
f1.setGeometry( geometry );
|
||||
f1.setAttributes( QgsAttributes() << 1 << QDate( 2020, 1, 1 ) );
|
||||
QgsFeature f2( tempLayer->dataProvider()->fields(), 2 );
|
||||
f2.setGeometry( geometry );
|
||||
f2.setAttributes( QgsAttributes() << 2 << QDate( 2020, 3, 1 ) );
|
||||
QgsFeature f3( tempLayer->dataProvider()->fields(), 3 );
|
||||
line.clear();
|
||||
line << QgsPointXY( -3, -3 ) << QgsPointXY( -2, -2 );
|
||||
geometry = QgsGeometry::fromPolylineXY( line );
|
||||
f3.setGeometry( geometry );
|
||||
f3.setAttributes( QgsAttributes() << 3 << QDate( 2020, 1, 1 ) );
|
||||
QVERIFY( tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 << f3 ) );
|
||||
|
||||
const QString filterExpression = QStringLiteral( "col1 < to_date('2020-02-03')" );
|
||||
std::unique_ptr< QgsAttributeTableDialog > dlg( new QgsAttributeTableDialog( tempLayer.get(),
|
||||
QgsAttributeTableFilterModel::ShowFilteredList,
|
||||
nullptr,
|
||||
Qt::Window,
|
||||
nullptr,
|
||||
filterExpression ) );
|
||||
|
||||
// feature id 2 is filtered out due not matching the provided filter expression
|
||||
QCOMPARE( dlg->mMainView->filteredFeatures(), QgsFeatureIds() << 1 << 3 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsAttributeTable )
|
||||
#include "testqgsattributetable.moc"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user