mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
Apply same logic regarding joined fields as is used in field calculator
to QgsFieldProxyModel set to hiding read only fields I.e. show editable joined fields, but only if they are set to a non-hidden editor widget
This commit is contained in:
parent
4a1115096b
commit
126ccb9736
@ -36,6 +36,8 @@ It can be associated with a QgsMapLayerModel to dynamically display a layer and
|
||||
FieldTypeRole,
|
||||
FieldOriginRole,
|
||||
IsEmptyRole,
|
||||
EditorWidgetType,
|
||||
JoinedFieldIsEditable,
|
||||
};
|
||||
|
||||
explicit QgsFieldModel( QObject *parent /TransferThis/ = 0 );
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsvectorlayerjoinbuffer.h"
|
||||
|
||||
QgsFieldModel::QgsFieldModel( QObject *parent )
|
||||
: QAbstractItemModel( parent )
|
||||
@ -359,6 +360,33 @@ QVariant QgsFieldModel::data( const QModelIndex &index, int role ) const
|
||||
return isEmpty;
|
||||
}
|
||||
|
||||
case EditorWidgetType:
|
||||
{
|
||||
if ( exprIdx < 0 && !isEmpty )
|
||||
{
|
||||
return mFields.at( index.row() - fieldOffset ).editorWidgetSetup().type();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
case JoinedFieldIsEditable:
|
||||
{
|
||||
if ( exprIdx < 0 && !isEmpty )
|
||||
{
|
||||
if ( mLayer && mFields.fieldOrigin( index.row() - fieldOffset ) == QgsFields::OriginJoin )
|
||||
{
|
||||
int srcFieldIndex;
|
||||
const QgsVectorLayerJoinInfo *info = mLayer->joinBuffer()->joinForFieldIndex( index.row() - fieldOffset, mLayer->fields(), srcFieldIndex );
|
||||
|
||||
if ( !info || !info->isEditable() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
case Qt::ToolTipRole:
|
||||
|
@ -55,6 +55,8 @@ class CORE_EXPORT QgsFieldModel : public QAbstractItemModel
|
||||
FieldTypeRole = Qt::UserRole + 6, //!< Return the field type (if a field, return QVariant if expression)
|
||||
FieldOriginRole = Qt::UserRole + 7, //!< Return the field origin (if a field, returns QVariant if expression)
|
||||
IsEmptyRole = Qt::UserRole + 8, //!< Return if the index corresponds to the empty value
|
||||
EditorWidgetType = Qt::UserRole + 9, //!< Editor widget type
|
||||
JoinedFieldIsEditable = Qt::UserRole + 10, //!< TRUE if a joined field is editable (returns QVariant if not a joined field)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -44,8 +44,18 @@ bool QgsFieldProxyModel::isReadOnly( const QModelIndex &index ) const
|
||||
QgsFields::FieldOrigin origin = static_cast< QgsFields::FieldOrigin >( originVariant.toInt() );
|
||||
switch ( origin )
|
||||
{
|
||||
case QgsFields::OriginUnknown:
|
||||
case QgsFields::OriginJoin:
|
||||
{
|
||||
// show joined fields (e.g. auxiliary fields) only if they have a non-hidden editor widget.
|
||||
// This enables them to be bulk field-calculated when a user needs to, but hides them by default
|
||||
// (since there's often MANY of these, e.g. after using the label properties tool on a layer)
|
||||
if ( sourceModel()->data( index, QgsFieldModel::EditorWidgetType ).toString() == QLatin1String( "Hidden" ) )
|
||||
return true;
|
||||
|
||||
return !sourceModel()->data( index, QgsFieldModel::JoinedFieldIsEditable ).toBool();
|
||||
}
|
||||
|
||||
case QgsFields::OriginUnknown:
|
||||
case QgsFields::OriginExpression:
|
||||
//read only
|
||||
return true;
|
||||
|
@ -15,7 +15,11 @@ import qgis # NOQA
|
||||
from qgis.core import (QgsField,
|
||||
QgsFields,
|
||||
QgsVectorLayer,
|
||||
QgsFieldModel)
|
||||
QgsFieldModel,
|
||||
QgsFieldProxyModel,
|
||||
QgsEditorWidgetSetup,
|
||||
QgsProject,
|
||||
QgsVectorLayerJoinInfo)
|
||||
from qgis.PyQt.QtCore import QVariant, Qt
|
||||
|
||||
from qgis.testing import start_app, unittest
|
||||
@ -26,6 +30,8 @@ start_app()
|
||||
def create_layer():
|
||||
layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
|
||||
"addfeat", "memory")
|
||||
layer.setEditorWidgetSetup(0, QgsEditorWidgetSetup('Hidden', {}))
|
||||
layer.setEditorWidgetSetup(1, QgsEditorWidgetSetup('ValueMap', {}))
|
||||
assert layer.isValid()
|
||||
return layer
|
||||
|
||||
@ -245,6 +251,86 @@ class TestQgsFieldModel(unittest.TestCase):
|
||||
m.setAllowEmptyFieldName(True)
|
||||
self.assertFalse(m.data(m.indexFromName(None), Qt.DisplayRole))
|
||||
|
||||
def testEditorWidgetTypeRole(self):
|
||||
l, m = create_model()
|
||||
self.assertEqual(m.data(m.indexFromName('fldtxt'), QgsFieldModel.EditorWidgetType), 'Hidden')
|
||||
self.assertEqual(m.data(m.indexFromName('fldint'), QgsFieldModel.EditorWidgetType), 'ValueMap')
|
||||
self.assertIsNone(m.data(m.indexFromName('an expression'), QgsFieldModel.EditorWidgetType))
|
||||
self.assertIsNone(m.data(m.indexFromName(None), QgsFieldModel.EditorWidgetType))
|
||||
m.setAllowExpression(True)
|
||||
m.setExpression('an expression')
|
||||
self.assertIsNone(m.data(m.indexFromName('an expression'), QgsFieldModel.EditorWidgetType))
|
||||
m.setAllowEmptyFieldName(True)
|
||||
self.assertIsNone(m.data(m.indexFromName(None), QgsFieldModel.EditorWidgetType))
|
||||
|
||||
def testJoinedFieldIsEditableRole(self):
|
||||
layer = QgsVectorLayer("Point?field=id_a:integer",
|
||||
"addfeat", "memory")
|
||||
layer2 = QgsVectorLayer("Point?field=id_b:integer&field=value_b",
|
||||
"addfeat", "memory")
|
||||
QgsProject.instance().addMapLayers([layer, layer2])
|
||||
|
||||
# editable join
|
||||
join_info = QgsVectorLayerJoinInfo()
|
||||
join_info.setTargetFieldName("id_a")
|
||||
join_info.setJoinLayer(layer2)
|
||||
join_info.setJoinFieldName("id_b")
|
||||
join_info.setPrefix("B_")
|
||||
join_info.setEditable(True)
|
||||
join_info.setUpsertOnEdit(True)
|
||||
layer.addJoin(join_info)
|
||||
|
||||
m = QgsFieldModel()
|
||||
m.setLayer(layer)
|
||||
|
||||
self.assertIsNone(m.data(m.indexFromName('id_a'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
self.assertTrue(m.data(m.indexFromName('B_value_b'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
self.assertIsNone(m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
self.assertIsNone(m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))
|
||||
m.setAllowExpression(True)
|
||||
m.setExpression('an expression')
|
||||
self.assertIsNone(m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
m.setAllowEmptyFieldName(True)
|
||||
self.assertIsNone(m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))
|
||||
|
||||
proxy_m = QgsFieldProxyModel()
|
||||
proxy_m.setFilters(QgsFieldProxyModel.AllTypes | QgsFieldProxyModel.HideReadOnly)
|
||||
proxy_m.sourceFieldModel().setLayer(layer)
|
||||
self.assertEqual(proxy_m.rowCount(), 2)
|
||||
self.assertEqual(proxy_m.data(proxy_m.index(0, 0)), 'id_a')
|
||||
self.assertEqual(proxy_m.data(proxy_m.index(1, 0)), 'B_value_b')
|
||||
|
||||
# not editable join
|
||||
layer3 = QgsVectorLayer("Point?field=id_a:integer",
|
||||
"addfeat", "memory")
|
||||
QgsProject.instance().addMapLayers([layer3])
|
||||
join_info = QgsVectorLayerJoinInfo()
|
||||
join_info.setTargetFieldName("id_a")
|
||||
join_info.setJoinLayer(layer2)
|
||||
join_info.setJoinFieldName("id_b")
|
||||
join_info.setPrefix("B_")
|
||||
join_info.setEditable(False)
|
||||
|
||||
layer3.addJoin(join_info)
|
||||
m = QgsFieldModel()
|
||||
m.setLayer(layer3)
|
||||
|
||||
self.assertIsNone(m.data(m.indexFromName('id_a'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
self.assertFalse(m.data(m.indexFromName('B_value_b'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
self.assertIsNone(m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
self.assertIsNone(m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))
|
||||
m.setAllowExpression(True)
|
||||
m.setExpression('an expression')
|
||||
self.assertIsNone(m.data(m.indexFromName('an expression'), QgsFieldModel.JoinedFieldIsEditable))
|
||||
m.setAllowEmptyFieldName(True)
|
||||
self.assertIsNone(m.data(m.indexFromName(None), QgsFieldModel.JoinedFieldIsEditable))
|
||||
|
||||
proxy_m = QgsFieldProxyModel()
|
||||
proxy_m.sourceFieldModel().setLayer(layer3)
|
||||
proxy_m.setFilters(QgsFieldProxyModel.AllTypes | QgsFieldProxyModel.HideReadOnly)
|
||||
self.assertEqual(proxy_m.rowCount(), 1)
|
||||
self.assertEqual(proxy_m.data(proxy_m.index(0, 0)), 'id_a')
|
||||
|
||||
def testFieldTooltip(self):
|
||||
f = QgsField('my_string', QVariant.String, 'string')
|
||||
self.assertEqual(QgsFieldModel.fieldToolTip(f), '<b>my_string</b><p>string</p>')
|
||||
|
Loading…
x
Reference in New Issue
Block a user