Skip to content

Commit

Permalink
Merge pull request #10037 from m-kuhn/expression_builder_show_represe…
Browse files Browse the repository at this point in the history
…nted_values

[Expression builder] show represented values in preview
  • Loading branch information
m-kuhn committed Jun 4, 2019
2 parents 8b83a46 + c698ba7 commit b9d5cde
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 38 deletions.
92 changes: 59 additions & 33 deletions src/gui/qgsexpressionbuilderwidget.cpp
Expand Up @@ -30,6 +30,8 @@
#include "qgsrelationmanager.h"
#include "qgsrelation.h"
#include "qgsexpressioncontextutils.h"
#include "qgsfieldformatterregistry.h"
#include "qgsfieldformatter.h"

#include <QMenu>
#include <QFile>
Expand Down Expand Up @@ -60,11 +62,11 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
mValueGroupBox->hide();
// highlighter = new QgsExpressionHighlighter( txtExpressionString->document() );

mModel = new QStandardItemModel();
mProxyModel = new QgsExpressionItemSearchProxy();
mModel = qgis::make_unique<QStandardItemModel>();
mProxyModel = qgis::make_unique<QgsExpressionItemSearchProxy>();
mProxyModel->setDynamicSortFilter( true );
mProxyModel->setSourceModel( mModel );
expressionTree->setModel( mProxyModel );
mProxyModel->setSourceModel( mModel.get() );
expressionTree->setModel( mProxyModel.get() );
expressionTree->setSortingEnabled( true );
expressionTree->sortByColumn( 0, Qt::AscendingOrder );

Expand All @@ -86,10 +88,10 @@ QgsExpressionBuilderWidget::QgsExpressionBuilderWidget( QWidget *parent )
txtSearchEdit->setShowSearchIcon( true );
txtSearchEdit->setPlaceholderText( tr( "Search…" ) );

mValuesModel = new QStringListModel();
mProxyValues = new QSortFilterProxyModel();
mProxyValues->setSourceModel( mValuesModel );
mValuesListView->setModel( mProxyValues );
mValuesModel = qgis::make_unique<QStandardItemModel>();
mProxyValues = qgis::make_unique<QSortFilterProxyModel>();
mProxyValues->setSourceModel( mValuesModel.get() );
mValuesListView->setModel( mProxyValues.get() );
txtSearchEditValues->setShowSearchIcon( true );
txtSearchEditValues->setPlaceholderText( tr( "Search…" ) );

Expand Down Expand Up @@ -210,11 +212,6 @@ QgsExpressionBuilderWidget::~QgsExpressionBuilderWidget()
settings.setValue( QStringLiteral( "Windows/QgsExpressionBuilderWidget/splitter" ), splitter->saveState() );
settings.setValue( QStringLiteral( "Windows/QgsExpressionBuilderWidget/editorsplitter" ), editorSplit->saveState() );
settings.setValue( QStringLiteral( "Windows/QgsExpressionBuilderWidget/functionsplitter" ), functionsplit->saveState() );

delete mModel;
delete mProxyModel;
delete mValuesModel;
delete mProxyValues;
}

void QgsExpressionBuilderWidget::setLayer( QgsVectorLayer *layer )
Expand All @@ -240,15 +237,7 @@ void QgsExpressionBuilderWidget::currentChanged( const QModelIndex &index, const
bool isField = mLayer && item->getItemType() == QgsExpressionItem::Field;
if ( isField )
{
if ( mFieldValues.contains( item->text() ) )
{
const QStringList &values = mFieldValues[item->text()];
mValuesModel->setStringList( values );
}
else
{
mValuesModel->setStringList( QStringList() );
}
loadFieldValues( mFieldValues.value( item->text() ) );
}
mValueGroupBox->setVisible( isField );
mShowHelpButton->setText( isField ? tr( "Show Values" ) : tr( "Show Help" ) );
Expand Down Expand Up @@ -429,10 +418,28 @@ void QgsExpressionBuilderWidget::loadFieldNames( const QgsFields &fields )
QIcon icon = fields.iconForField( i );
registerItem( QStringLiteral( "Fields and Values" ), fieldName, " \"" + fieldName + "\" ", QString(), QgsExpressionItem::Field, false, i, icon );
}
// highlighter->addFields( fieldNames );
// highlighter->addFields( fieldNames );
}

void QgsExpressionBuilderWidget::loadFieldsAndValues( const QMap<QString, QStringList> &fieldValues )
{
mFieldValues.clear();
QgsFields fields;
for ( auto it = fieldValues.constBegin(); it != fieldValues.constEnd(); ++it )
{
fields.append( QgsField( it.key() ) );
const QStringList values = it.value();
QVariantMap map;
for ( const QString &value : values )
{
map.insert( value, value );
}
mFieldValues.insert( it.key(), map );
}
loadFieldNames( fields );
}

void QgsExpressionBuilderWidget::loadFieldsAndValues( const QMap<QString, QVariantMap> &fieldValues )
{
QgsFields fields;
for ( auto it = fieldValues.constBegin(); it != fieldValues.constEnd(); ++it )
Expand All @@ -452,16 +459,19 @@ void QgsExpressionBuilderWidget::fillFieldValues( const QString &fieldName, int

// TODO We should thread this so that we don't hold the user up if the layer is massive.

int fieldIndex = mLayer->fields().lookupField( fieldName );
const QgsFields fields = mLayer->fields();
int fieldIndex = fields.lookupField( fieldName );

if ( fieldIndex < 0 )
return;

QStringList strValues;
const QgsEditorWidgetSetup setup = fields.at( fieldIndex ).editorWidgetSetup();
const QgsFieldFormatter *formatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );

QList<QVariant> values = mLayer->uniqueValues( fieldIndex, countLimit ).toList();
std::sort( values.begin(), values.end() );
const auto constValues = values;
for ( const QVariant &value : constValues )

for ( const QVariant &value : qgis::as_const( values ) )
{
QString strValue;
if ( value.isNull() )
Expand All @@ -470,10 +480,15 @@ void QgsExpressionBuilderWidget::fillFieldValues( const QString &fieldName, int
strValue = value.toString();
else
strValue = '\'' + value.toString().replace( '\'', QLatin1String( "''" ) ) + '\'';
strValues.append( strValue );

QString representedValue = formatter->representValue( mLayer, fieldIndex, setup.config(), QVariant(), value );
if ( representedValue != strValue )
representedValue = representedValue + QStringLiteral( " [" ) + strValue + ']';

QStandardItem *item = new QStandardItem( representedValue );
item->setData( strValue );
mValuesModel->appendRow( item );
}
mValuesModel->setStringList( strValues );
mFieldValues[fieldName] = strValues;
}

QString QgsExpressionBuilderWidget::getFunctionHelp( QgsExpressionFunction *function )
Expand All @@ -483,7 +498,7 @@ QString QgsExpressionBuilderWidget::getFunctionHelp( QgsExpressionFunction *func

QString helpContents = QgsExpression::helpText( function->name() );

return "<head><style>" + helpStylesheet() + "</style></head><body>" + helpContents + "</body>";
return QStringLiteral( "<head><style>" ) + helpStylesheet() + QStringLiteral( "</style></head><body>" ) + helpContents + QStringLiteral( "</body>" );

}

Expand Down Expand Up @@ -843,6 +858,17 @@ void QgsExpressionBuilderWidget::setParserError( bool parserError )
emit parserErrorChanged();
}

void QgsExpressionBuilderWidget::loadFieldValues( const QVariantMap &values )
{
mValuesModel->clear();
for ( QVariantMap::ConstIterator it = values.constBegin(); it != values.constEnd(); ++ it )
{
QStandardItem *item = new QStandardItem( it.key() );
item->setData( it.value() );
mValuesModel->appendRow( item );
}
}

bool QgsExpressionBuilderWidget::evalError() const
{
return mEvalError;
Expand All @@ -859,7 +885,7 @@ void QgsExpressionBuilderWidget::setEvalError( bool evalError )

QStandardItemModel *QgsExpressionBuilderWidget::model()
{
return mModel;
return mModel.get();
}

QgsProject *QgsExpressionBuilderWidget::project()
Expand Down Expand Up @@ -1035,7 +1061,7 @@ void QgsExpressionBuilderWidget::lblPreview_linkActivated( const QString &link )
void QgsExpressionBuilderWidget::mValuesListView_doubleClicked( const QModelIndex &index )
{
// Insert the item text or replace selected text
txtExpressionString->insertText( ' ' + index.data( Qt::DisplayRole ).toString() + ' ' );
txtExpressionString->insertText( ' ' + index.data( Qt::UserRole + 1 ).toString() + ' ' );
txtExpressionString->setFocus();
}

Expand Down
17 changes: 12 additions & 5 deletions src/gui/qgsexpressionbuilderwidget.h
Expand Up @@ -431,19 +431,26 @@ class GUI_EXPORT QgsExpressionBuilderWidget : public QWidget, private Ui::QgsExp
*/
void setParserError( bool parserError );

void loadFieldValues( const QVariantMap &values );

void loadFieldsAndValues( const QMap<QString, QVariantMap> &fieldValues );

bool mAutoSave = true;
QString mFunctionsPath;
QgsVectorLayer *mLayer = nullptr;
QStandardItemModel *mModel = nullptr;
QStringListModel *mValuesModel = nullptr;
QSortFilterProxyModel *mProxyValues = nullptr;
QgsExpressionItemSearchProxy *mProxyModel = nullptr;
std::unique_ptr<QStandardItemModel> mModel;
// Will hold items with
// * a display string that matches the represented field values
// * custom data in Qt::UserRole + 1 that contains a ready to use expression literal ('quoted string' or NULL or a plain number )
std::unique_ptr<QStandardItemModel> mValuesModel;
std::unique_ptr<QSortFilterProxyModel> mProxyValues;
std::unique_ptr<QgsExpressionItemSearchProxy> mProxyModel;
QMap<QString, QgsExpressionItem *> mExpressionGroups;
QgsExpressionHighlighter *highlighter = nullptr;
bool mExpressionValid = false;
QgsDistanceArea mDa;
QString mRecentKey;
QMap<QString, QStringList> mFieldValues;
QMap<QString, QVariantMap> mFieldValues;
QgsExpressionContext mExpressionContext;
QPointer< QgsProject > mProject;
bool mEvalError = true;
Expand Down

0 comments on commit b9d5cde

Please sign in to comment.