QGIS API Documentation  3.25.0-Master (10b47c2603)
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
6  Email : [email protected]mail.com
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 "qgsvectorlayer.h"
19 
21  : QSortFilterProxyModel( parent )
22  , mFilters( AllTypes )
23  , mModel( new QgsFieldModel( this ) )
24 {
25  setSourceModel( mModel );
26 }
27 
28 QgsFieldProxyModel *QgsFieldProxyModel::setFilters( QgsFieldProxyModel::Filters filters )
29 {
30  mFilters = filters;
31  invalidateFilter();
32  return this;
33 }
34 
35 bool QgsFieldProxyModel::isReadOnly( const QModelIndex &index ) const
36 {
37  const QVariant originVariant = sourceModel()->data( index, QgsFieldModel::FieldOriginRole );
38  if ( originVariant.isNull() )
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, QgsFieldModel::EditorWidgetType ).toString() == QLatin1String( "Hidden" ) )
53  return true;
54 
55  return !sourceModel()->data( index, QgsFieldModel::JoinedFieldIsEditable ).toBool();
56  }
57 
60  //read only
61  return true;
62 
65  {
66  if ( !sourceModel()->data( index, QgsFieldModel::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 
81 bool 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( AllTypes ) )
89  return true;
90 
91  const QVariant typeVar = sourceModel()->data( index, QgsFieldModel::FieldTypeRole );
92 
93  // if expression, consider valid
94  if ( typeVar.isNull() )
95  return true;
96 
97  bool ok;
98  const QVariant::Type type = ( QVariant::Type )typeVar.toInt( &ok );
99  if ( !ok )
100  return true;
101 
102  if ( ( mFilters.testFlag( String ) && type == QVariant::String ) ||
103  ( mFilters.testFlag( LongLong ) && type == QVariant::LongLong ) ||
104  ( mFilters.testFlag( Int ) && type == QVariant::Int ) ||
105  ( mFilters.testFlag( Double ) && type == QVariant::Double ) ||
106  ( mFilters.testFlag( Date ) && type == QVariant::Date ) ||
107  ( mFilters.testFlag( Date ) && type == QVariant::DateTime ) ||
108  ( mFilters.testFlag( DateTime ) && type == QVariant::DateTime ) ||
109  ( mFilters.testFlag( Time ) && type == QVariant::Time ) )
110  return true;
111 
112  return false;
113 }
114 
115 bool QgsFieldProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
116 {
117  // empty field is always first
118  if ( sourceModel()->data( left, QgsFieldModel::IsEmptyRole ).toBool() )
119  return true;
120  else if ( sourceModel()->data( right, QgsFieldModel::IsEmptyRole ).toBool() )
121  return false;
122 
123  // order is field order, then expressions
124  bool lok, rok;
125  const int leftId = sourceModel()->data( left, QgsFieldModel::FieldIndexRole ).toInt( &lok );
126  const int rightId = sourceModel()->data( right, QgsFieldModel::FieldIndexRole ).toInt( &rok );
127 
128  if ( !lok )
129  return false;
130  if ( !rok )
131  return true;
132 
133  return leftId < rightId;
134 }
The QgsFieldModel class is a model to display the list of fields in widgets (optionally associated wi...
Definition: qgsfieldmodel.h:39
@ FieldOriginRole
Return the field origin (if a field, returns QVariant if expression)
Definition: qgsfieldmodel.h:57
@ FieldIndexRole
Return field index if index corresponds to a field.
Definition: qgsfieldmodel.h:52
@ JoinedFieldIsEditable
true if a joined field is editable (returns QVariant if not a joined field)
Definition: qgsfieldmodel.h:60
@ FieldTypeRole
Return the field type (if a field, return QVariant if expression)
Definition: qgsfieldmodel.h:56
@ EditorWidgetType
Editor widget type.
Definition: qgsfieldmodel.h:59
@ IsEmptyRole
Return if the index corresponds to the empty value.
Definition: qgsfieldmodel.h:58
@ FieldIsWidgetEditable
true if a is editable from the widget
Definition: qgsfieldmodel.h:61
The QgsFieldProxyModel class provides an easy to use model to display the list of fields of a layer.
const Filters & filters() const
Returns the filters controlling displayed fields.
@ DateTime
Datetime fieldss.
@ HideReadOnly
Hide read-only fields.
@ LongLong
Longlong fields.
@ Double
Double fields.
@ AllTypes
All field types.
@ Date
Date or datetime fields.
@ Int
Integer fields.
@ String
String 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.
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