QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsfieldproxymodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsfieldproxymodel.cpp
3 --------------------------------------
4 Date : 01.04.2014
5 Copyright : (C) 2014 Denis Rouzaud
7***************************************************************************
8* *
9* This program is free software; you can redistribute it and/or modify *
10* it under the terms of the GNU General Public License as published by *
11* the Free Software Foundation; either version 2 of the License, or *
12* (at your option) any later version. *
13* *
14***************************************************************************/
15
16#include "qgsfieldproxymodel.h"
17#include "qgsfieldmodel.h"
18#include "qgsvariantutils.h"
19
21 : QSortFilterProxyModel( parent )
22 , mFilters( AllTypes )
23 , mModel( new QgsFieldModel( this ) )
24{
25 setSourceModel( mModel );
26}
27
29{
30 mFilters = filters;
31 invalidateFilter();
32 return this;
33}
34
35bool QgsFieldProxyModel::isReadOnly( const QModelIndex &index ) const
36{
37 const QVariant originVariant = sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldOrigin ) );
38 if ( QgsVariantUtils::isNull( originVariant ) )
39 {
40 //expression
41 return true;
42 }
43
44 const QgsFields::FieldOrigin origin = static_cast< QgsFields::FieldOrigin >( originVariant.toInt() );
45 switch ( origin )
46 {
48 {
49 // show joined fields (e.g. auxiliary fields) only if they have a non-hidden editor widget.
50 // This enables them to be bulk field-calculated when a user needs to, but hides them by default
51 // (since there's often MANY of these, e.g. after using the label properties tool on a layer)
52 if ( sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::EditorWidgetType ) ).toString() == QLatin1String( "Hidden" ) )
53 return true;
54
55 return !sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::JoinedFieldIsEditable ) ).toBool();
56 }
57
60 //read only
61 return true;
62
65 {
66 if ( !sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldIsWidgetEditable ) ).toBool() )
67 {
68 return true;
69 }
70 else
71 {
72 //not read only
73 return false;
74 }
75 }
76
77 }
78 return false; // avoid warnings
79}
80
81bool QgsFieldProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
82{
83 const QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
84
85 if ( mFilters.testFlag( HideReadOnly ) && isReadOnly( index ) )
86 return false;
87
88 if ( mFilters.testFlag( QgsFieldProxyModel::OriginProvider ) )
89 {
90 const QgsFields::FieldOrigin origin = static_cast< QgsFields::FieldOrigin >( sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldOrigin ) ).toInt() );
91 switch ( origin )
92 {
97 return false;
98
100 break;
101 }
102 }
103
104 if ( mFilters.testFlag( AllTypes ) )
105 return true;
106
107 const QVariant typeVar = sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldType ) );
108
109 // if expression, consider valid
110 if ( QgsVariantUtils::isNull( typeVar ) )
111 return true;
112
113 bool ok;
114 const QVariant::Type type = ( QVariant::Type )typeVar.toInt( &ok );
115 if ( !ok )
116 return true;
117
118 if ( ( mFilters.testFlag( String ) && type == QVariant::String ) ||
119 ( mFilters.testFlag( LongLong ) && type == QVariant::LongLong ) ||
120 ( mFilters.testFlag( Int ) && type == QVariant::Int ) ||
121 ( mFilters.testFlag( Double ) && type == QVariant::Double ) ||
122 ( mFilters.testFlag( Date ) && type == QVariant::Date ) ||
123 ( mFilters.testFlag( Date ) && type == QVariant::DateTime ) ||
124 ( mFilters.testFlag( DateTime ) && type == QVariant::DateTime ) ||
125 ( mFilters.testFlag( Time ) && type == QVariant::Time ) ||
126 ( mFilters.testFlag( Binary ) && type == QVariant::ByteArray ) ||
127 ( mFilters.testFlag( Boolean ) && type == QVariant::Bool ) )
128 return true;
129
130 return false;
131}
132
133bool QgsFieldProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
134{
135 // empty field is always first
136 if ( sourceModel()->data( left, static_cast< int >( QgsFieldModel::CustomRole::IsEmpty ) ).toBool() )
137 return true;
138 else if ( sourceModel()->data( right, static_cast< int >( QgsFieldModel::CustomRole::IsEmpty ) ).toBool() )
139 return false;
140
141 // order is field order, then expressions
142 bool lok, rok;
143 const int leftId = sourceModel()->data( left, static_cast< int >( QgsFieldModel::CustomRole::FieldIndex ) ).toInt( &lok );
144 const int rightId = sourceModel()->data( right, static_cast< int >( QgsFieldModel::CustomRole::FieldIndex ) ).toInt( &rok );
145
146 if ( !lok )
147 return false;
148 if ( !rok )
149 return true;
150
151 return leftId < rightId;
152}
The QgsFieldModel class is a model to display the list of fields in widgets (optionally associated wi...
Definition: qgsfieldmodel.h:38
@ FieldIsWidgetEditable
true if a is editable from the widget
@ FieldOrigin
Return the field origin (if a field, returns QVariant if expression)
@ IsEmpty
Return if the index corresponds to the empty value.
@ FieldIndex
Return field index if index corresponds to a field.
@ EditorWidgetType
Editor widget type.
@ FieldType
Return the field type (if a field, return QVariant if expression)
@ JoinedFieldIsEditable
true if a joined field is editable (returns QVariant if not a joined field)
The QgsFieldProxyModel class provides an easy to use model to display the list of fields of a layer.
@ DateTime
Datetime fields.
@ HideReadOnly
Hide read-only fields.
@ LongLong
Longlong fields.
@ Double
Double fields.
@ AllTypes
All field types.
@ Date
Date or datetime fields.
@ Binary
Binary fields, since QGIS 3.34.
@ Int
Integer fields.
@ String
String fields.
@ Boolean
Boolean fields, since QGIS 3.34.
@ OriginProvider
Fields with a provider origin, since QGIS 3.38.
const Filters & filters() const
Returns the filters controlling displayed fields.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
QgsFieldProxyModel(QObject *parent=nullptr)
QgsFieldProxModel creates a proxy model with a QgsFieldModel as source model.
QFlags< Filter > Filters
QgsFieldProxyModel * setFilters(QgsFieldProxyModel::Filters filters)
Set flags that affect how fields are filtered in the model.
@ OriginExpression
Field is calculated from an expression.
Definition: qgsfields.h:54
@ OriginEdit
Field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfields.h:53
@ OriginUnknown
It has not been specified where the field comes from.
Definition: qgsfields.h:50
@ OriginJoin
Field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfields.h:52
@ OriginProvider
Field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfields.h:51
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.