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