Skip to content
Permalink
Browse files

field proxy model to filter fields on their type (also fix #10181)

  • Loading branch information
3nids committed May 12, 2014
1 parent 003374f commit 09a9a6171ac26eaaa1705cd65ed72435d35f54d7
@@ -32,6 +32,7 @@
%Include qgsfieldexpressionwidget.sip
%Include qgsfieldmodel.sip
%Include qgsfieldvalidator.sip
%Include qgsfieldproxymodel.sip
%Include qgsfiledropedit.sip
%Include qgsfilterlineedit.sip
%Include qgsformannotationitem.sip
@@ -19,6 +19,12 @@ class QgsFieldComboBox : QComboBox
*/
explicit QgsFieldComboBox( QWidget *parent /TransferThis/ = 0 );

//! setFilters allows fitering according to the type of field
void setFilters( QgsFieldProxyModel::Filters filters );

//! currently used filter on list of fields
QgsFieldProxyModel::Filters filters();

//! return the currently selected field
QString currentField();

@@ -13,13 +13,19 @@ class QgsFieldExpressionWidget : QWidget

//! define the title used in the expression dialog
void setExpressionDialogTitle( QString title );

//! setFilters allows fitering according to the type of field
void setFilters( QgsFieldProxyModel::Filters filters );

//! set the geometry calculator used in the expression dialog
void setGeomCalculator( const QgsDistanceArea &da );
//! currently used filter on list of fields
QgsFieldProxyModel::Filters filters();

//! return the title used for the expression dialog
const QString expressionDialogTitle();

//! set the geometry calculator used in the expression dialog
void setGeomCalculator( const QgsDistanceArea &da );

/**
* @brief currentField returns the currently selected field or expression if allowed
* @param isExpression determines if the string returned is the name of a field or an expression
@@ -18,7 +18,8 @@ class QgsFieldModel : QAbstractItemModel
FieldIndexRole = 34, /* return field index if index corresponds to a field */
ExpressionRole = 35, /* return field name or expression */
IsExpressionRole = 36, /* return if index corresponds to an expression */
ExpressionValidityRole = 37 /* return if expression is valid or not */
ExpressionValidityRole = 37, /* return if expression is valid or not */
FieldTypeRole = 38 /* return the field type (if a field, return QVariant if expression) */
};

/**
@@ -0,0 +1,47 @@
/**
* @brief The QgsMapLayerProxModel class provides an easy to use model to display the list of layers in widgets.
* @note added in 2.3
*/
class QgsFieldProxyModel : QSortFilterProxyModel
{

%TypeHeaderCode
#include "qgsfieldproxymodel.h"
%End

public:
enum Filter
{
String = 1,
Int = 2,
LongLong = 4,
Double = 8,
Numeric = 14,
Date = 16,
All = 31
};
typedef QFlags<QgsFieldProxyModel::Filter> Filters;

/**
* @brief QgsFieldProxModel creates a proxy model with a QgsFieldModel as source model.
* It can be used to filter the fields based on their types.
*/
explicit QgsFieldProxyModel( QObject *parent /TransferThis/ = 0 );

//! sourceFieldModel returns the QgsFieldModel used in this QSortFilterProxyModel
QgsFieldModel* sourceFieldModel() ;

/**
* @brief setFilters set flags that affect how fields are filtered
* @param filters are Filter flags
* @note added in 2.3
*/
QgsFieldProxyModel* setFilters( Filters filters );
const Filters& filters() const ;

// QSortFilterProxyModel interface
public:
bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const;
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const;
};

@@ -92,6 +92,7 @@ qgsfieldcombobox.cpp
qgsfieldexpressionwidget.cpp
qgsfieldmodel.cpp
qgsfieldvalidator.cpp
qgsfieldproxymodel.cpp
qgsfiledropedit.cpp
qgsfilterlineedit.cpp
qgsformannotationitem.cpp
@@ -238,6 +239,7 @@ qgsfieldcombobox.h
qgsfieldexpressionwidget.h
qgsfieldmodel.h
qgsfieldvalidator.h
qgsfieldproxymodel.h
qgsfilterlineedit.h
qgsformannotationitem.h
qgsgenericprojectionselector.h
@@ -310,6 +312,7 @@ qgsfieldcombobox.h
qgsfieldexpressionwidget.h
qgsfieldmodel.h
qgsfieldvalidator.h
qgsfieldproxymodel.h
qgsfiledropedit.h
qgsfilterlineedit.h
qgsgenericprojectionselector.h
@@ -14,18 +14,24 @@
***************************************************************************/

#include "qgsfieldcombobox.h"
#include "qgsfieldmodel.h"
#include "qgsfieldproxymodel.h"
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"

QgsFieldComboBox::QgsFieldComboBox( QWidget *parent ) :
QComboBox( parent )
{
mFieldModel = new QgsFieldModel( this );
setModel( mFieldModel );
mFieldProxyModel = new QgsFieldProxyModel( this );
setModel( mFieldProxyModel );

connect( this, SIGNAL( currentIndexChanged( int ) ), this, SLOT( indexChanged( int ) ) );
}

void QgsFieldComboBox::setFilters( QgsFieldProxyModel::Filters filters )
{
mFieldProxyModel->setFilters( filters );
}

void QgsFieldComboBox::setLayer( QgsMapLayer *layer )
{
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
@@ -37,38 +43,46 @@ void QgsFieldComboBox::setLayer( QgsMapLayer *layer )

void QgsFieldComboBox::setLayer( QgsVectorLayer *layer )
{
mFieldModel->setLayer( layer );
mFieldProxyModel->sourceFieldModel()->setLayer( layer );
}

QgsVectorLayer *QgsFieldComboBox::layer()
{
return mFieldModel->layer();
return mFieldProxyModel->sourceFieldModel()->layer();
}

void QgsFieldComboBox::setField( QString fieldName )
{
QModelIndex idx = mFieldModel->indexFromName( fieldName );
QModelIndex idx = mFieldProxyModel->sourceFieldModel()->indexFromName( fieldName );
if ( idx.isValid() )
{
setCurrentIndex( idx.row() );
}
else
{
setCurrentIndex( -1 );
QModelIndex proxyIdx = mFieldProxyModel->mapFromSource( idx );
if ( proxyIdx.isValid() )
{
setCurrentIndex( idx.row() );
return;
}
}
setCurrentIndex( -1 );
}

QString QgsFieldComboBox::currentField()
{
int i = currentIndex();

const QModelIndex index = mFieldModel->index( i, 0 );
const QModelIndex proxyIndex = mFieldProxyModel->index( i, 0 );
if ( !proxyIndex.isValid() )
{
return "";
}

const QModelIndex index = mFieldProxyModel->mapToSource( proxyIndex );
if ( !index.isValid() )
{
return "";
}

QString name = mFieldModel->data( index, QgsFieldModel::FieldNameRole ).toString();
QString name = mFieldProxyModel->data( index, QgsFieldModel::FieldNameRole ).toString();
return name;
}

@@ -18,7 +18,8 @@

#include <QComboBox>

class QgsFieldModel;
#include "qgsfieldproxymodel.h"

class QgsMapLayer;
class QgsVectorLayer;

@@ -32,13 +33,21 @@ class QgsVectorLayer;
class GUI_EXPORT QgsFieldComboBox : public QComboBox
{
Q_OBJECT
Q_PROPERTY( QgsFieldProxyModel::Filters filters READ filters WRITE setFilters )

public:
/**
* @brief QgsFieldComboBox creates a combo box to display the fields of a layer.
* The layer can be either manually given or dynamically set by connecting the signal QgsMapLayerComboBox::layerChanged to the slot setLayer.
*/
explicit QgsFieldComboBox( QWidget *parent = 0 );

//! setFilters allows fitering according to the type of field
void setFilters( QgsFieldProxyModel::Filters filters );

//! currently used filter on list of fields
QgsFieldProxyModel::Filters filters() { return mFieldProxyModel->filters(); }

//! return the currently selected field
QString currentField();

@@ -63,7 +72,7 @@ class GUI_EXPORT QgsFieldComboBox : public QComboBox
void indexChanged( int i );

private:
QgsFieldModel* mFieldModel;
QgsFieldProxyModel* mFieldProxyModel;
};

#endif // QGSFIELDCOMBOBOX_H
@@ -19,7 +19,7 @@
#include "qgsapplication.h"
#include "qgsfieldexpressionwidget.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsfieldmodel.h"
#include "qgsfieldproxymodel.h"
#include "qgsdistancearea.h"

QgsFieldExpressionWidget::QgsFieldExpressionWidget( QWidget *parent )
@@ -32,9 +32,9 @@ QgsFieldExpressionWidget::QgsFieldExpressionWidget( QWidget *parent )
mCombo = new QComboBox( this );
mCombo->setEditable( true );
mCombo->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Minimum );
mFieldModel = new QgsFieldModel( mCombo );
mFieldModel->setAllowExpression( true );
mCombo->setModel( mFieldModel );
mFieldProxyModel = new QgsFieldProxyModel( mCombo );
mFieldProxyModel->sourceFieldModel()->setAllowExpression( true );
mCombo->setModel( mFieldProxyModel );

mButton = new QToolButton( this );
mButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
@@ -59,6 +59,11 @@ void QgsFieldExpressionWidget::setExpressionDialogTitle( QString title )
mExpressionDialogTitle = title;
}

void QgsFieldExpressionWidget::setFilters( QgsFieldProxyModel::Filters filters )
{
mFieldProxyModel->setFilters( filters );
}

void QgsFieldExpressionWidget::setGeomCalculator( const QgsDistanceArea &da )
{
mDa = QSharedPointer<const QgsDistanceArea>( new QgsDistanceArea( da ) );
@@ -76,27 +81,28 @@ QString QgsFieldExpressionWidget::currentField( bool *isExpression , bool *isVal
}

int i = mCombo->currentIndex();
const QModelIndex index = mFieldModel->index( i, 0 );
const QModelIndex proxyIndex = mFieldProxyModel->index( i, 0 );
if ( !proxyIndex.isValid() )
return "";
const QModelIndex index = mFieldProxyModel->mapToSource( proxyIndex );
if ( !index.isValid() )
{
return "";
}

if ( isExpression )
{
*isExpression = mFieldModel->data( index, QgsFieldModel::IsExpressionRole ).toBool();
*isExpression = mFieldProxyModel->data( index, QgsFieldModel::IsExpressionRole ).toBool();
}
if ( isValid )
{
*isValid = mFieldModel->data( index, QgsFieldModel::ExpressionValidityRole ).toBool();
*isValid = mFieldProxyModel->data( index, QgsFieldModel::ExpressionValidityRole ).toBool();
}
QString expression = mFieldModel->data( index, QgsFieldModel::ExpressionRole ).toString();
QString expression = mFieldProxyModel->data( index, QgsFieldModel::ExpressionRole ).toString();
return expression;
}

QgsVectorLayer *QgsFieldExpressionWidget::layer()
{
return mFieldModel->layer();
return mFieldProxyModel->sourceFieldModel()->layer();
}

void QgsFieldExpressionWidget::setLayer( QgsMapLayer *layer )
@@ -110,21 +116,24 @@ void QgsFieldExpressionWidget::setLayer( QgsMapLayer *layer )

void QgsFieldExpressionWidget::setLayer( QgsVectorLayer *layer )
{
mFieldModel->setLayer( layer );
mFieldProxyModel->sourceFieldModel()->setLayer( layer );
}

void QgsFieldExpressionWidget::setField( const QString fieldName )
{
if ( fieldName.isEmpty() )
return;

QModelIndex idx = mFieldModel->indexFromName( fieldName );
QModelIndex idx = mFieldProxyModel->sourceFieldModel()->indexFromName( fieldName );
if ( !idx.isValid() )
{
// new expression
idx = mFieldModel->setExpression( fieldName );
idx = mFieldProxyModel->sourceFieldModel()->setExpression( fieldName );
}
mCombo->setCurrentIndex( idx.row() );

QModelIndex proxyIndex = mFieldProxyModel->mapFromSource( idx );

mCombo->setCurrentIndex( proxyIndex.row() );

currentFieldChanged();
}
@@ -159,7 +168,7 @@ void QgsFieldExpressionWidget::expressionEdited( const QString expression )
void QgsFieldExpressionWidget::expressionEditingFinished()
{
const QString expression = mCombo->lineEdit()->text();
QModelIndex idx = mFieldModel->setExpression( expression );
QModelIndex idx = mFieldProxyModel->sourceFieldModel()->setExpression( expression );
mCombo->setCurrentIndex( idx.row() );
currentFieldChanged();
}

0 comments on commit 09a9a61

Please sign in to comment.
You can’t perform that action at this time.