mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[FEATURE] allow filtering for field values in expression widget
This commit is contained in:
parent
e655c2617a
commit
d493a69069
@ -173,8 +173,9 @@ class QgsExpressionBuilderWidget : QWidget
|
||||
void on_expressionTree_doubleClicked( const QModelIndex &index );
|
||||
void on_txtExpressionString_textChanged();
|
||||
void on_txtSearchEdit_textChanged();
|
||||
void on_txtSearchEditValues_textChanged();
|
||||
void on_lblPreview_linkActivated( QString link );
|
||||
void on_mValueListWidget_itemDoubleClicked( QListWidgetItem* item );
|
||||
void on_mValuesListView_doubleClicked( const QModelIndex &index );
|
||||
void operatorButtonClicked();
|
||||
void showContextMenu( const QPoint & );
|
||||
void loadSampleValues();
|
||||
|
@ -58,13 +58,19 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
|
||||
connect( btnLoadAll, SIGNAL( pressed() ), this, SLOT( loadAllValues() ) );
|
||||
connect( btnLoadSample, SIGNAL( pressed() ), this, SLOT( loadSampleValues() ) );
|
||||
|
||||
Q_FOREACH ( QPushButton* button, mOperatorsGroupBox->findChildren<QPushButton *>() )
|
||||
Q_FOREACH( QPushButton* button, mOperatorsGroupBox->findChildren<QPushButton *>() )
|
||||
{
|
||||
connect( button, SIGNAL( pressed() ), this, SLOT( operatorButtonClicked() ) );
|
||||
}
|
||||
|
||||
txtSearchEdit->setPlaceholderText( tr( "Search" ) );
|
||||
|
||||
mValuesModel = new QStringListModel();
|
||||
mProxyValues = new QSortFilterProxyModel();
|
||||
mProxyValues->setSourceModel( mValuesModel );
|
||||
mValuesListView->setModel( mProxyValues );
|
||||
txtSearchEditValues->setPlaceholderText( tr( "Search" ) );
|
||||
|
||||
QSettings settings;
|
||||
splitter->restoreState( settings.value( "/windows/QgsExpressionBuilderWidget/splitter" ).toByteArray() );
|
||||
functionsplit->restoreState( settings.value( "/windows/QgsExpressionBuilderWidget/functionsplitter" ).toByteArray() );
|
||||
@ -101,6 +107,8 @@ QgsExpressionBuilderWidget::~QgsExpressionBuilderWidget()
|
||||
|
||||
delete mModel;
|
||||
delete mProxyModel;
|
||||
delete mValuesModel;
|
||||
delete mProxyValues;
|
||||
}
|
||||
|
||||
void QgsExpressionBuilderWidget::setLayer( QgsVectorLayer *layer )
|
||||
@ -115,25 +123,22 @@ void QgsExpressionBuilderWidget::setLayer( QgsVectorLayer *layer )
|
||||
|
||||
void QgsExpressionBuilderWidget::currentChanged( const QModelIndex &index, const QModelIndex & )
|
||||
{
|
||||
txtSearchEditValues->setText( QString( "" ) );
|
||||
|
||||
// Get the item
|
||||
QModelIndex idx = mProxyModel->mapToSource( index );
|
||||
QgsExpressionItem* item = dynamic_cast<QgsExpressionItem*>( mModel->itemFromIndex( idx ) );
|
||||
if ( !item )
|
||||
return;
|
||||
|
||||
mValueListWidget->clear();
|
||||
if ( item->getItemType() == QgsExpressionItem::Field && mFieldValues.contains( item->text() ) )
|
||||
{
|
||||
const QStringList& values = mFieldValues[item->text()];
|
||||
mValueListWidget->setUpdatesEnabled( false );
|
||||
mValueListWidget->blockSignals( true );
|
||||
mValueListWidget->addItems( values );
|
||||
mValueListWidget->setUpdatesEnabled( true );
|
||||
mValueListWidget->blockSignals( false );
|
||||
mValuesModel->setStringList( values );
|
||||
}
|
||||
|
||||
mLoadGroupBox->setVisible( item->getItemType() == QgsExpressionItem::Field && mLayer );
|
||||
mValueGroupBox->setVisible(( item->getItemType() == QgsExpressionItem::Field && mLayer ) || mValueListWidget->count() > 0 );
|
||||
mValueGroupBox->setVisible( ( item->getItemType() == QgsExpressionItem::Field && mLayer ) || mValuesListView->model()->rowCount() > 0 );
|
||||
|
||||
// Show the help for the current item.
|
||||
QString help = loadFunctionHelp( item );
|
||||
@ -188,7 +193,7 @@ void QgsExpressionBuilderWidget::updateFunctionFileList( QString path )
|
||||
dir.setNameFilters( QStringList() << "*.py" );
|
||||
QStringList files = dir.entryList( QDir::Files );
|
||||
cmbFileNames->clear();
|
||||
Q_FOREACH ( const QString& name, files )
|
||||
Q_FOREACH( const QString& name, files )
|
||||
{
|
||||
QFileInfo info( mFunctionsPath + QDir::separator() + name );
|
||||
if ( info.baseName() == "__init__" ) continue;
|
||||
@ -292,7 +297,7 @@ void QgsExpressionBuilderWidget::loadFieldNames( const QgsFields& fields )
|
||||
void QgsExpressionBuilderWidget::loadFieldsAndValues( const QMap<QString, QStringList> &fieldValues )
|
||||
{
|
||||
QgsFields fields;
|
||||
Q_FOREACH ( const QString& fieldName, fieldValues.keys() )
|
||||
Q_FOREACH( const QString& fieldName, fieldValues.keys() )
|
||||
{
|
||||
fields.append( QgsField( fieldName ) );
|
||||
}
|
||||
@ -308,20 +313,16 @@ void QgsExpressionBuilderWidget::fillFieldValues( const QString& fieldName, int
|
||||
return;
|
||||
|
||||
// TODO We should thread this so that we don't hold the user up if the layer is massive.
|
||||
mValueListWidget->clear();
|
||||
|
||||
int fieldIndex = mLayer->fieldNameIndex( fieldName );
|
||||
|
||||
if ( fieldIndex < 0 )
|
||||
return;
|
||||
|
||||
mValueListWidget->setUpdatesEnabled( false );
|
||||
mValueListWidget->blockSignals( true );
|
||||
|
||||
QList<QVariant> values;
|
||||
QStringList strValues;
|
||||
mLayer->uniqueValues( fieldIndex, values, countLimit );
|
||||
Q_FOREACH ( const QVariant& value, values )
|
||||
Q_FOREACH( const QVariant& value, values )
|
||||
{
|
||||
QString strValue;
|
||||
if ( value.isNull() )
|
||||
@ -330,13 +331,10 @@ void QgsExpressionBuilderWidget::fillFieldValues( const QString& fieldName, int
|
||||
strValue = value.toString();
|
||||
else
|
||||
strValue = "'" + value.toString().replace( "'", "''" ) + "'";
|
||||
mValueListWidget->addItem( strValue );
|
||||
strValues.append( strValue );
|
||||
}
|
||||
mValuesModel->setStringList( strValues );
|
||||
mFieldValues[fieldName] = strValues;
|
||||
|
||||
mValueListWidget->setUpdatesEnabled( true );
|
||||
mValueListWidget->blockSignals( false );
|
||||
}
|
||||
|
||||
void QgsExpressionBuilderWidget::registerItem( QString group,
|
||||
@ -417,7 +415,7 @@ void QgsExpressionBuilderWidget::loadRecent( QString key )
|
||||
QSettings settings;
|
||||
QString location = QString( "/expressions/recent/%1" ).arg( key );
|
||||
QStringList expressions = settings.value( location ).toStringList();
|
||||
Q_FOREACH ( const QString& expression, expressions )
|
||||
Q_FOREACH( const QString& expression, expressions )
|
||||
{
|
||||
this->registerItem( name, expression, expression, expression );
|
||||
}
|
||||
@ -598,7 +596,7 @@ QString QgsExpressionBuilderWidget::formatPreviewString( const QString& previewS
|
||||
void QgsExpressionBuilderWidget::loadExpressionContext()
|
||||
{
|
||||
QStringList variableNames = mExpressionContext.filteredVariableNames();
|
||||
Q_FOREACH ( const QString& variable, variableNames )
|
||||
Q_FOREACH( const QString& variable, variableNames )
|
||||
{
|
||||
registerItem( "Variables", variable, " @" + variable + " ",
|
||||
QgsExpression::variableHelpText( variable, true, mExpressionContext.variable( variable ) ),
|
||||
@ -608,7 +606,7 @@ void QgsExpressionBuilderWidget::loadExpressionContext()
|
||||
|
||||
// Load the functions from the expression context
|
||||
QStringList contextFunctions = mExpressionContext.functionNames();
|
||||
Q_FOREACH ( const QString& functionName, contextFunctions )
|
||||
Q_FOREACH( const QString& functionName, contextFunctions )
|
||||
{
|
||||
QgsExpression::Function* func = mExpressionContext.function( functionName );
|
||||
QString name = func->name();
|
||||
@ -629,6 +627,12 @@ void QgsExpressionBuilderWidget::on_txtSearchEdit_textChanged()
|
||||
expressionTree->expandAll();
|
||||
}
|
||||
|
||||
void QgsExpressionBuilderWidget::on_txtSearchEditValues_textChanged()
|
||||
{
|
||||
mProxyValues->setFilterCaseSensitivity( Qt::CaseInsensitive );
|
||||
mProxyValues->setFilterWildcard( txtSearchEditValues->text() );
|
||||
}
|
||||
|
||||
void QgsExpressionBuilderWidget::on_lblPreview_linkActivated( QString link )
|
||||
{
|
||||
Q_UNUSED( link );
|
||||
@ -638,10 +642,10 @@ void QgsExpressionBuilderWidget::on_lblPreview_linkActivated( QString link )
|
||||
mv->exec();
|
||||
}
|
||||
|
||||
void QgsExpressionBuilderWidget::on_mValueListWidget_itemDoubleClicked( QListWidgetItem *item )
|
||||
void QgsExpressionBuilderWidget::on_mValuesListView_doubleClicked( const QModelIndex &index )
|
||||
{
|
||||
// Insert the item text or replace selected text
|
||||
txtExpressionString->insertText( " " + item->text() + " " );
|
||||
txtExpressionString->insertText( " " + index.data( Qt::DisplayRole ).toString() + " " );
|
||||
txtExpressionString->setFocus();
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "QStandardItemModel"
|
||||
#include "QStandardItem"
|
||||
#include "QSortFilterProxyModel"
|
||||
#include "QStringListModel"
|
||||
|
||||
/** An expression item that can be used in the QgsExpressionBuilderWidget tree.
|
||||
*/
|
||||
@ -136,6 +137,7 @@ class QgsExpressionItemSearchProxy : public QSortFilterProxyModel
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** A reusable widget that can be used to build a expression string.
|
||||
* See QgsExpressionBuilderDialog for exmaple of usage.
|
||||
*/
|
||||
@ -238,8 +240,9 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
|
||||
void on_expressionTree_doubleClicked( const QModelIndex &index );
|
||||
void on_txtExpressionString_textChanged();
|
||||
void on_txtSearchEdit_textChanged();
|
||||
void on_txtSearchEditValues_textChanged();
|
||||
void on_lblPreview_linkActivated( QString link );
|
||||
void on_mValueListWidget_itemDoubleClicked( QListWidgetItem* item );
|
||||
void on_mValuesListView_doubleClicked( const QModelIndex &index );
|
||||
void operatorButtonClicked();
|
||||
void showContextMenu( const QPoint & );
|
||||
void loadSampleValues();
|
||||
@ -274,6 +277,8 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
|
||||
QString mFunctionsPath;
|
||||
QgsVectorLayer *mLayer;
|
||||
QStandardItemModel *mModel;
|
||||
QStringListModel *mValuesModel;
|
||||
QSortFilterProxyModel *mProxyValues;
|
||||
QgsExpressionItemSearchProxy *mProxyModel;
|
||||
QMap<QString, QgsExpressionItem*> mExpressionGroups;
|
||||
QgsFeature mFeature;
|
||||
|
@ -321,15 +321,12 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="moperationListGroup">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="functionsplit">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="opaqueResize">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
@ -366,8 +363,8 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<widget class="QWidget" name="">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="txtHelpText">
|
||||
<property name="readOnly">
|
||||
@ -376,116 +373,77 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="mValueGroupBox">
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
<widget class="QFrame" name="mValueGroupBox">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Values</string>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsFilterLineEdit" name="txtSearchEditValues">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QListWidget" name="mValueListWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="viewMode">
|
||||
<enum>QListView::ListMode</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Values</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="mLoadGroupBox" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QListView" name="mValuesListView">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblLoad">
|
||||
<property name="text">
|
||||
<string>Load values</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLoadAll">
|
||||
<property name="text">
|
||||
<string>all unique</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLoadSample">
|
||||
<property name="text">
|
||||
<string>10 samples</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="mLoadGroupBox" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblLoad">
|
||||
<property name="text">
|
||||
<string>Load values</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLoadAll">
|
||||
<property name="text">
|
||||
<string>all unique</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnLoadSample">
|
||||
<property name="text">
|
||||
<string>10 samples</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
Loading…
x
Reference in New Issue
Block a user