QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsattributetabledelegate.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  QgsAttributeTableDelegate.cpp
3  --------------------------------------
4  Date : Feb 2009
5  Copyright : (C) 2009 Vita Cizek
6  Email : weetya (at) gmail.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 <QItemDelegate>
17 #include <QLineEdit>
18 #include <QComboBox>
19 #include <QPainter>
20 #include <QToolButton>
21 
22 #include "qgsattributeeditor.h"
25 #include "qgsattributetablemodel.h"
26 #include "qgsattributetableview.h"
29 #include "qgslogger.h"
30 #include "qgsvectordataprovider.h"
31 #include "qgsactionmanager.h"
32 
33 
34 QgsVectorLayer* QgsAttributeTableDelegate::layer( const QAbstractItemModel *model )
35 {
36  const QgsAttributeTableModel *tm = qobject_cast<const QgsAttributeTableModel *>( model );
37  if ( tm )
38  return tm->layer();
39 
40  const QgsAttributeTableFilterModel *fm = dynamic_cast<const QgsAttributeTableFilterModel *>( model );
41  if ( fm )
42  return fm->layer();
43 
44  return nullptr;
45 }
46 
47 const QgsAttributeTableModel* QgsAttributeTableDelegate::masterModel( const QAbstractItemModel* model )
48 {
49  const QgsAttributeTableModel *tm = qobject_cast<const QgsAttributeTableModel *>( model );
50  if ( tm )
51  return tm;
52 
53  const QgsAttributeTableFilterModel *fm = dynamic_cast<const QgsAttributeTableFilterModel *>( model );
54  if ( fm )
55  return fm->masterModel();
56 
57  return nullptr;
58 }
59 
61 {
62  Q_UNUSED( option );
63  QgsVectorLayer *vl = layer( index.model() );
64  if ( !vl )
65  return nullptr;
66 
67  int fieldIdx = index.model()->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt();
68 
69  QString widgetType = vl->editFormConfig()->widgetType( fieldIdx );
70  QgsEditorWidgetConfig cfg = vl->editFormConfig()->widgetConfig( fieldIdx );
71  QgsAttributeEditorContext context( masterModel( index.model() )->editorContext(), QgsAttributeEditorContext::Popup );
72  QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( widgetType, vl, fieldIdx, cfg, nullptr, parent, context );
73  QWidget* w = eww->widget();
74 
75  w->setAutoFillBackground( true );
76 
77  eww->setEnabled( !vl->editFormConfig()->readOnly( fieldIdx ) );
78 
79  return w;
80 }
81 
83 {
84  QgsVectorLayer *vl = layer( model );
85  if ( !vl )
86  return;
87 
88  int fieldIdx = model->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt();
90  QVariant oldValue = model->data( index, Qt::EditRole );
91 
92  QVariant newValue;
94  if ( !eww )
95  return;
96 
97  newValue = eww->value();
98 
99  if (( oldValue != newValue && newValue.isValid() ) || oldValue.isNull() != newValue.isNull() )
100  {
101  // This fixes https://issues.qgis.org/issues/16492
102  QgsFeatureRequest request( fid );
105  QgsFeature feature;
106  vl->getFeatures( request ).nextFeature( feature );
107  if ( feature.isValid( ) )
108  {
109  vl->beginEditCommand( tr( "Attribute changed" ) );
110  vl->changeAttributeValue( fid, fieldIdx, newValue, oldValue );
111  vl->endEditCommand();
112  }
113  }
114 }
115 
117 {
119  if ( !eww )
120  return;
121 
122  eww->setValue( index.model()->data( index, Qt::EditRole ) );
123 }
124 
126 {
127  mFeatureSelectionModel = featureSelectionModel;
128 }
129 
131 {
133 
135  {
136  emit actionColumnItemPainted( index );
137  }
138  else
139  {
141 
142  QStyleOptionViewItem myOpt = option;
143 
144  if ( index.model()->data( index, Qt::EditRole ).isNull() )
145  {
146  myOpt.font.setItalic( true );
147  myOpt.palette.setColor( QPalette::Text, QColor( "gray" ) );
148  }
149 
150  if ( mFeatureSelectionModel && mFeatureSelectionModel->isSelected( fid ) )
151  myOpt.state |= QStyle::State_Selected;
152 
153  QItemDelegate::paint( painter, myOpt, index );
154 
155  if ( option.state & QStyle::State_HasFocus )
156  {
157  QRect r = option.rect.adjusted( 1, 1, -1, -1 );
158  QPen p( QBrush( QColor( 0, 255, 127 ) ), 2 );
159  painter->save();
160  painter->setPen( p );
161  painter->drawRect( r );
162  painter->restore();
163  }
164  }
165 }
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:199
qlonglong toLongLong(bool *ok) const
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
static unsigned index
virtual bool isSelected(QgsFeatureId fid)
Returns the selection status of a given feature id.
QgsAttributeTableModel * masterModel() const
Returns the table model this filter is using.
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Overloads the paint method form the QItemDelegate base class.
Get the field index of this column.
void beginEditCommand(const QString &text)
Create edit command for undo/redo operations.
This class contains context information for attribute editor widgets.
Manages an editor widget Widget and wrapper share the same parent.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
void save()
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
A model backed by a QgsVectorLayerCache which is able to provide feature/attribute information to a Q...
void actionColumnItemPainted(const QModelIndex &index) const
Is emitted when an action column item is painted.
static QgsEditorWidgetRegistry * instance()
This class is a singleton and has therefore to be accessed with this method instead of a constructor...
QString tr(const char *sourceText, const char *disambiguation, int n)
void setFeatureSelectionModel(QgsFeatureSelectionModel *featureSelectionModel)
QgsEditFormConfig * editFormConfig() const
Get the configuration of the form used to represent this vector layer.
Get the feature id of the feature in this row.
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
Used to create an editor for when the user tries to change the contents of a cell.
void drawRect(const QRectF &rectangle)
A widget was opened as a popup (e.g. attribute table editor widget)
QVariantMap QgsEditorWidgetConfig
Holds a set of configuration parameters for a editor widget wrapper.
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Sets data from model into the editor.
int toInt(bool *ok) const
bool isNull() const
void setPen(const QColor &color)
QgsEditorWidgetWrapper * create(const QString &widgetId, QgsVectorLayer *vl, int fieldIdx, const QgsEditorWidgetConfig &config, QWidget *editor, QWidget *parent, const QgsAttributeEditorContext &context=QgsAttributeEditorContext())
Create an attribute editor widget wrapper of a given type for a given field.
static QgsEditorWidgetWrapper * fromWidget(QWidget *widget)
Will return a wrapper for a given widget.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
virtual void setValue(const QVariant &value)=0
Is called, when the value of the widget needs to be changed.
virtual QVariant data(const QModelIndex &index, int role) const=0
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &value, bool emitSignal)
Changes an attribute value (but does not commit it)
void endEditCommand()
Finish edit command and add it to undo/redo stack.
void restore()
QgsEditorWidgetConfig widgetConfig(int fieldIdx) const
Get the configuration for the editor widget used to represent the field at the given index...
const QAbstractItemModel * model() const
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
Sets data from editor back to model.
virtual QVariant value() const =0
Will be used to access the widget&#39;s value.
qint64 QgsFeatureId
Definition: qgsfeature.h:31
bool isValid() const
void setAutoFillBackground(bool enabled)
bool readOnly(int idx) const
This returns true if the field is manually set to read only or if the field does not support editing ...
bool nextFeature(QgsFeature &f)
QString widgetType(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QObject * parent() const
Represents a vector layer which manages a vector based data sets.