QGIS API Documentation  2.99.0-Master (6a61179)
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 
24 #include "qgsattributetablemodel.h"
25 #include "qgsattributetableview.h"
27 #include "qgseditorwidgetwrapper.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 
60 QWidget* QgsAttributeTableDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
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  QgsAttributeEditorContext context( masterModel( index.model() )->editorContext(), QgsAttributeEditorContext::Popup );
70  QgsEditorWidgetWrapper* eww = QgsEditorWidgetRegistry::instance()->create( vl, fieldIdx, nullptr, parent, context );
71  QWidget* w = eww->widget();
72 
73  w->setAutoFillBackground( true );
74  w->setFocusPolicy( Qt::StrongFocus ); // to make sure QMouseEvents are propagated to the editor widget
75 
76  eww->setEnabled( !vl->editFormConfig().readOnly( fieldIdx ) );
77 
78  return w;
79 }
80 
81 void QgsAttributeTableDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
82 {
83  QgsVectorLayer *vl = layer( model );
84  if ( !vl )
85  return;
86 
87  int fieldIdx = model->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt();
88  QgsFeatureId fid = model->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong();
89  QVariant oldValue = model->data( index, Qt::EditRole );
90 
91  QVariant newValue;
93  if ( !eww )
94  return;
95 
96  newValue = eww->value();
97 
98  if (( oldValue != newValue && newValue.isValid() ) || oldValue.isNull() != newValue.isNull() )
99  {
100  vl->beginEditCommand( tr( "Attribute changed" ) );
101  vl->changeAttributeValue( fid, fieldIdx, newValue, oldValue );
102  vl->endEditCommand();
103  }
104 }
105 
106 void QgsAttributeTableDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
107 {
109  if ( !eww )
110  return;
111 
112  eww->setValue( index.model()->data( index, Qt::EditRole ) );
113 }
114 
116 {
117  mFeatureSelectionModel = featureSelectionModel;
118 }
119 
120 void QgsAttributeTableDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
121 {
123 
125  {
126  emit actionColumnItemPainted( index );
127  }
128  else
129  {
130  QgsFeatureId fid = index.model()->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong();
131 
132  QStyleOptionViewItem myOpt = option;
133 
134  if ( index.model()->data( index, Qt::EditRole ).isNull() )
135  {
136  myOpt.font.setItalic( true );
137  myOpt.palette.setColor( QPalette::Text, QColor( "gray" ) );
138  }
139 
140  if ( mFeatureSelectionModel && mFeatureSelectionModel->isSelected( fid ) )
141  myOpt.state |= QStyle::State_Selected;
142 
143  QItemDelegate::paint( painter, myOpt, index );
144 
145  if ( option.state & QStyle::State_HasFocus )
146  {
147  QRect r = option.rect.adjusted( 1, 1, -1, -1 );
148  QPen p( QBrush( QColor( 0, 255, 127 ) ), 2 );
149  painter->save();
150  painter->setPen( p );
151  painter->drawRect( r );
152  painter->restore();
153  }
154  }
155 }
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.
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...
void setFeatureSelectionModel(QgsFeatureSelectionModel *featureSelectionModel)
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.
A widget was opened as a popup (e.g. attribute table editor widget)
void setEditorData(QWidget *editor, const QModelIndex &index) const override
Sets data from model into the editor.
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.
virtual void setValue(const QVariant &value)=0
Is called, when the value of the widget needs to be changed.
QgsEditFormConfig editFormConfig
void endEditCommand()
Finish edit command and add it to undo/redo stack.
bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant())
Changes an attribute value (but does not commit it)
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:32
QWidget * widget()
Access the widget managed by this wrapper.
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 ...
Represents a vector layer which manages a vector based data sets.