QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
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 "moc_qgsfieldproxymodel.cpp"
18#include "qgsfieldmodel.h"
19#include "qgsvariantutils.h"
20
22 : QSortFilterProxyModel( parent )
23 , mFilters( AllTypes )
24 , mModel( new QgsFieldModel( this ) )
25{
26 setSourceModel( mModel );
27}
28
30{
31 mFilters = filters;
32 invalidateFilter();
33 return this;
34}
35
36bool QgsFieldProxyModel::isReadOnly( const QModelIndex &index ) const
37{
38 const QVariant originVariant = sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldOrigin ) );
39 if ( QgsVariantUtils::isNull( originVariant ) )
40 {
41 //expression
42 return true;
43 }
44
45 const Qgis::FieldOrigin origin = static_cast< Qgis::FieldOrigin >( originVariant.toInt() );
46 switch ( origin )
47 {
49 {
50 // show joined fields (e.g. auxiliary fields) only if they have a non-hidden editor widget.
51 // This enables them to be bulk field-calculated when a user needs to, but hides them by default
52 // (since there's often MANY of these, e.g. after using the label properties tool on a layer)
53 if ( sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::EditorWidgetType ) ).toString() == QLatin1String( "Hidden" ) )
54 return true;
55
56 return !sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::JoinedFieldIsEditable ) ).toBool();
57 }
58
61 //read only
62 return true;
63
66 {
67 if ( !sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldIsWidgetEditable ) ).toBool() )
68 {
69 return true;
70 }
71 else
72 {
73 //not read only
74 return false;
75 }
76 }
77
78 }
79 return false; // avoid warnings
80}
81
82bool QgsFieldProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
83{
84 const QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
85
86 if ( mFilters.testFlag( HideReadOnly ) && isReadOnly( index ) )
87 return false;
88
89 if ( mFilters.testFlag( QgsFieldProxyModel::OriginProvider ) )
90 {
91 const Qgis::FieldOrigin origin = static_cast< Qgis::FieldOrigin >( sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldOrigin ) ).toInt() );
92 switch ( origin )
93 {
98 return false;
99
101 break;
102 }
103 }
104
105 if ( mFilters.testFlag( AllTypes ) )
106 return true;
107
108 const QVariant typeVar = sourceModel()->data( index, static_cast< int >( QgsFieldModel::CustomRole::FieldType ) );
109
110 // if expression, consider valid
111 if ( QgsVariantUtils::isNull( typeVar ) )
112 return true;
113
114 bool ok;
115 const QMetaType::Type type = static_cast<QMetaType::Type>( typeVar.toInt( &ok ) );
116 if ( !ok )
117 return true;
118
119 if ( ( mFilters.testFlag( String ) && type == QMetaType::Type::QString ) ||
120 ( mFilters.testFlag( LongLong ) && type == QMetaType::Type::LongLong ) ||
121 ( mFilters.testFlag( Int ) && type == QMetaType::Type::Int ) ||
122 ( mFilters.testFlag( Double ) && type == QMetaType::Type::Double ) ||
123 ( mFilters.testFlag( Date ) && type == QMetaType::Type::QDate ) ||
124 ( mFilters.testFlag( Date ) && type == QMetaType::Type::QDateTime ) ||
125 ( mFilters.testFlag( DateTime ) && type == QMetaType::Type::QDateTime ) ||
126 ( mFilters.testFlag( Time ) && type == QMetaType::Type::QTime ) ||
127 ( mFilters.testFlag( Binary ) && type == QMetaType::Type::QByteArray ) ||
128 ( mFilters.testFlag( Boolean ) && type == QMetaType::Type::Bool ) )
129 return true;
130
131 return false;
132}
133
134bool QgsFieldProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
135{
136 // empty field is always first
137 if ( sourceModel()->data( left, static_cast< int >( QgsFieldModel::CustomRole::IsEmpty ) ).toBool() )
138 return true;
139 else if ( sourceModel()->data( right, static_cast< int >( QgsFieldModel::CustomRole::IsEmpty ) ).toBool() )
140 return false;
141
142 // order is field order, then expressions
143 bool lok, rok;
144 const int leftId = sourceModel()->data( left, static_cast< int >( QgsFieldModel::CustomRole::FieldIndex ) ).toInt( &lok );
145 const int rightId = sourceModel()->data( right, static_cast< int >( QgsFieldModel::CustomRole::FieldIndex ) ).toInt( &rok );
146
147 if ( !lok )
148 return false;
149 if ( !rok )
150 return true;
151
152 return leftId < rightId;
153}
FieldOrigin
Field origin.
Definition qgis.h:1596
@ Provider
Field originates from the underlying data provider of the vector layer.
@ Edit
Field has been temporarily added in editing mode.
@ Unknown
The field origin has not been specified.
@ Expression
Field is calculated from an expression.
@ Join
Field originates from a joined layer.
The QgsFieldModel class is a model to display the list of fields in widgets (optionally associated wi...
@ 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.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.