Rename QgsFields::fieldNameIndex() to lookupField()

To have two clearly different names for tolerant/intolerant index lookup
This commit is contained in:
Matthias Kuhn 2016-09-22 07:57:13 +02:00
parent 9a261cfbbc
commit b6779f63ff
177 changed files with 1324 additions and 1217 deletions

View File

@ -746,6 +746,7 @@ None will need to be modified, as the method will return an empty geometry if th
<ul>
<li>All const methods which return a field from QgsFields now return a QgsField value, not a reference.</li>
<li>fieldNameIndex has been renamed to lookupField. See the API documentation for details.</li>
</ul>
\subsection qgis_api_break_3_0_QgsFieldExpressionWidget QgsFieldExpressionWidget
@ -1414,6 +1415,7 @@ displayExpression instead. For the map tip use mapTipTemplate() instead.</li>
<li>Deleted attributeEditorElementFromDomElement
<li>editFormConfig() returns a copy instead of direct access (Use setEditFormConfig to update)
<li>Removed valueRelation(), replaced with QgsEditFormConfig::editorWidgetConfig
<li>Removed fieldNameIndex(), use QgsFields::lookupField() or QgsFields::indexFromName() instead
</ul>
\subsection qgis_api_break_3_0_QgsVectorLayerEditBuffer QgsVectorLayerEditBuffer

View File

@ -55,6 +55,7 @@
%Include qgsfeaturerequest.sip
%Include qgsfeedback.sip
%Include qgsfield.sip
%Include qgsfields.sip
%Include qgsgeometrysimplifier.sip
%Include qgsgeometryvalidator.sip
%Include qgsgml.sip

View File

@ -53,6 +53,13 @@ class QgsExpression
*/
QStringList referencedColumns() const;
/**
* Return a list of field name indexes obtained from the provided fields.
*
* @note Added in QGIS 3.0
*/
QSet<int> referencedAttributeIndexes( const QgsFields& fields ) const;
//! Returns true if the expression uses feature geometry for some computation
bool needsGeometry() const;

View File

@ -254,224 +254,3 @@ class QgsField
*/
const QgsEditorWidgetSetup& editorWidgetSetup() const;
}; // class QgsField
/** \class QgsFields
* \ingroup core
* Container of fields for a vector layer.
*
* In addition to storing a list of QgsField instances, it also:
* - allows quick lookups of field names to index in the list
* - keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
* \note QgsFields objects are implicitly shared.
*/
class QgsFields
{
%TypeHeaderCode
#include <qgsfield.h>
%End
public:
enum FieldOrigin
{
OriginUnknown, //!< it has not been specified where the field comes from
OriginProvider, //!< field comes from the underlying data provider of the vector layer (originIndex = index in provider's fields)
OriginJoin, //!< field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index within the join)
OriginEdit, //!< field has been temporarily added in editing mode (originIndex = index in the list of added attributes)
OriginExpression //!< field is calculated from an expression
};
/** Constructor for an empty field container
*/
QgsFields();
/** Copy constructor
*/
QgsFields( const QgsFields& other );
virtual ~QgsFields();
//! Remove all fields
void clear();
//! Append a field. The field must have unique name, otherwise it is rejected (returns false)
bool append( const QgsField& field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
//! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
bool appendExpressionField( const QgsField& field, int originIndex );
//! Remove a field with the given index
void remove( int fieldIdx );
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipCpp->remove( a0 );
}
%End
//! Extend with fields from another QgsFields container
void extend( const QgsFields& other );
//! Check whether the container is empty
bool isEmpty() const;
//! Return number of items
int count() const;
// __len__ annotation since sip 4.10.3
//int count() const /__len__/;
int __len__() const;
%MethodCode
sipRes = sipCpp->count();
%End
//! Return number of items
int size() const;
//! Return if a field index is valid
//! @param i Index of the field which needs to be checked
//! @return True if the field exists
bool exists( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
// const QgsField& operator[]( int i ) const;
QgsField& operator[](int i) /Factory/;
%MethodCode
SIP_SSIZE_T idx = sipConvertFromSequenceIndex(a0, sipCpp->count());
if (idx < 0)
sipIsErr = 1;
else
sipRes = new QgsField(sipCpp->operator[](idx));
%End
//! Get field at particular index (must be in range 0..N-1)
QgsField at( int i ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QgsField( sipCpp->at( a0 ) );
}
%End
//! Get field at particular index (must be in range 0..N-1)
QgsField field( int fieldIdx ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QgsField( sipCpp->field( a0 ) );
}
%End
//! Get field at particular index (must be in range 0..N-1)
QgsField field( const QString& name ) const /Factory/;
%MethodCode
int fieldIdx = sipCpp->indexFromName(*a0);
if (fieldIdx == -1)
{
PyErr_SetString(PyExc_KeyError, a0->toAscii());
sipIsErr = 1;
}
else
{
sipRes = new QgsField( sipCpp->field( *a0 ) );
}
%End
//! Get field's origin (value from an enumeration)
FieldOrigin fieldOrigin( int fieldIdx ) const;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = sipCpp->fieldOrigin( a0 );
}
%End
//! Get field's origin index (its meaning is specific to each type of origin)
int fieldOriginIndex( int fieldIdx ) const;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = sipCpp->fieldOriginIndex( a0 );
}
%End
//! Look up field's index from name. Returns -1 on error
int indexFromName( const QString& name ) const;
//! Look up field's index from name
//! also looks up case-insensitive if there is no match otherwise
//! @note added in 2.4
int fieldNameIndex( const QString& fieldName ) const;
//! Utility function to get list of attribute indexes
//! @note added in 2.4
QgsAttributeList allAttributesList() const;
//! Utility function to return a list of QgsField instances
QList<QgsField> toList() const;
//! @note added in 2.6
bool operator==( const QgsFields& other ) const;
//! @note added in 2.6
bool operator!=( const QgsFields& other ) const;
/** Returns an icon corresponding to a field index, based on the field's type and source
* @note added in QGIS 2.14
*/
QIcon iconForField( int fieldIdx ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QIcon( sipCpp->iconForField( a0 ) );
}
%End
//! Allows direct construction of QVariants from fields.
operator QVariant() const;
/* SIP_PYOBJECT __getitem__(int key);
%MethodCode
if (a0 = sipConvertFromSequenceIndex(a0, sipCpp->count()) < 0)
sipIsErr = 1;
else
{
qDebug("__getitem__ %d", a0);
QgsField* fld = new QgsField(sipCpp->at(a0));
sipRes = sipConvertFromType(fld, sipType_QgsField, Py_None);
}
%End*/
void __setitem__(int key, const QgsField& field);
%MethodCode
int idx = (int)sipConvertFromSequenceIndex(a0, sipCpp->count());
if (idx < 0)
sipIsErr = 1;
else
(*sipCpp)[idx] = *a1;
%End
};

239
python/core/qgsfields.sip Normal file
View File

@ -0,0 +1,239 @@
/** \class QgsFields
* \ingroup core
* Container of fields for a vector layer.
*
* In addition to storing a list of QgsField instances, it also:
* - allows quick lookups of field names to index in the list
* - keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
* \note QgsFields objects are implicitly shared.
*/
class QgsFields
{
%TypeHeaderCode
#include <qgsfield.h>
%End
public:
enum FieldOrigin
{
OriginUnknown, //!< it has not been specified where the field comes from
OriginProvider, //!< field comes from the underlying data provider of the vector layer (originIndex = index in provider's fields)
OriginJoin, //!< field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index within the join)
OriginEdit, //!< field has been temporarily added in editing mode (originIndex = index in the list of added attributes)
OriginExpression //!< field is calculated from an expression
};
/** Constructor for an empty field container
*/
QgsFields();
/** Copy constructor
*/
QgsFields( const QgsFields& other );
virtual ~QgsFields();
//! Remove all fields
void clear();
//! Append a field. The field must have unique name, otherwise it is rejected (returns false)
bool append( const QgsField& field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
//! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
bool appendExpressionField( const QgsField& field, int originIndex );
//! Remove a field with the given index
void remove( int fieldIdx );
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipCpp->remove( a0 );
}
%End
//! Extend with fields from another QgsFields container
void extend( const QgsFields& other );
//! Check whether the container is empty
bool isEmpty() const;
//! Return number of items
int count() const;
// __len__ annotation since sip 4.10.3
//int count() const /__len__/;
int __len__() const;
%MethodCode
sipRes = sipCpp->count();
%End
//! Return number of items
int size() const;
//! Return if a field index is valid
//! @param i Index of the field which needs to be checked
//! @return True if the field exists
bool exists( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
// const QgsField& operator[]( int i ) const;
QgsField& operator[](int i) /Factory/;
%MethodCode
SIP_SSIZE_T idx = sipConvertFromSequenceIndex(a0, sipCpp->count());
if (idx < 0)
sipIsErr = 1;
else
sipRes = new QgsField(sipCpp->operator[](idx));
%End
//! Get field at particular index (must be in range 0..N-1)
QgsField at( int i ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QgsField( sipCpp->at( a0 ) );
}
%End
//! Get field at particular index (must be in range 0..N-1)
QgsField field( int fieldIdx ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QgsField( sipCpp->field( a0 ) );
}
%End
//! Get field at particular index (must be in range 0..N-1)
QgsField field( const QString& name ) const /Factory/;
%MethodCode
int fieldIdx = sipCpp->indexFromName(*a0);
if (fieldIdx == -1)
{
PyErr_SetString(PyExc_KeyError, a0->toAscii());
sipIsErr = 1;
}
else
{
sipRes = new QgsField( sipCpp->field( *a0 ) );
}
%End
//! Get field's origin (value from an enumeration)
FieldOrigin fieldOrigin( int fieldIdx ) const;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = sipCpp->fieldOrigin( a0 );
}
%End
//! Get field's origin index (its meaning is specific to each type of origin)
int fieldOriginIndex( int fieldIdx ) const;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = sipCpp->fieldOriginIndex( a0 );
}
%End
/**
* Look up field's index from the field name.
* This method takes is case sensitive and only matches the data source
* name of the field.
*
* @param fieldName The name of the field.
*
* @return The field index if found or -1 in case it cannot be found.
* @see lookupField For a more tolerant alternative.
*/
int indexFromName( const QString& fieldName ) const;
/**
* Look up field's index from the field name.
* This method matches in the following order:
*
* 1. The exact field name taking case sensitivity into account
* 2. Looks for the field name by case insensitive comparison
* 3. The field alias (case insensitive)
*
* @param fieldName The name to look for.
*
* @return The field index if found or -1 in case it cannot be found.
* @see indexFromName For a more performant and precise but less tolerant alternative.
* @note added in 2.4
*/
int lookupField( const QString& fieldName ) const;
//! Utility function to get list of attribute indexes
//! @note added in 2.4
QgsAttributeList allAttributesList() const;
//! Utility function to return a list of QgsField instances
QList<QgsField> toList() const;
//! @note added in 2.6
bool operator==( const QgsFields& other ) const;
//! @note added in 2.6
bool operator!=( const QgsFields& other ) const;
/** Returns an icon corresponding to a field index, based on the field's type and source
* @note added in QGIS 2.14
*/
QIcon iconForField( int fieldIdx ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
PyErr_SetString(PyExc_KeyError, QByteArray::number(a0));
sipIsErr = 1;
}
else
{
sipRes = new QIcon( sipCpp->iconForField( a0 ) );
}
%End
//! Allows direct construction of QVariants from fields.
operator QVariant() const;
/* SIP_PYOBJECT __getitem__(int key);
%MethodCode
if (a0 = sipConvertFromSequenceIndex(a0, sipCpp->count()) < 0)
sipIsErr = 1;
else
{
qDebug("__getitem__ %d", a0);
QgsField* fld = new QgsField(sipCpp->at(a0));
sipRes = sipConvertFromType(fld, sipType_QgsField, Py_None);
}
%End*/
void __setitem__(int key, const QgsField& field);
%MethodCode
int idx = (int)sipConvertFromSequenceIndex(a0, sipCpp->count());
if (idx < 0)
sipIsErr = 1;
else
(*sipCpp)[idx] = *a1;
%End
};

View File

@ -1190,9 +1190,6 @@ class QgsVectorLayer : QgsMapLayer
/** Destroy active command and reverts all changes in it */
void destroyEditCommand();
/** Returns the index of a field name or -1 if the field does not exist */
int fieldNameIndex( const QString& fieldName ) const;
/** Editing vertex markers */
enum VertexMarkerType
{

View File

@ -18,7 +18,7 @@
#include "qgsgeometryanalyzer.h"
#include "qgsapplication.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgslogger.h"

View File

@ -19,7 +19,7 @@
#include "qgsapplication.h"
#include "qgsfeatureiterator.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeature.h"
#include "qgsgeometry.h"
#include "qgslogger.h"

View File

@ -21,7 +21,7 @@
#include <ui_qgsvectorlayersaveasdialogbase.h>
#include <QDialog>
#include "qgscontexthelp.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsvectorfilewriter.h"
class QgsVectorLayer;

View File

@ -7328,7 +7328,7 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
QgsAttributeList pkAttrList = pasteVectorLayer->pkAttributeList();
for ( int idx = 0; idx < fields.count(); ++idx )
{
int dst = pasteVectorLayer->fieldNameIndex( fields.at( idx ).name() );
int dst = pasteVectorLayer->fields().lookupField( fields.at( idx ).name() );
if ( dst < 0 )
continue;

View File

@ -38,7 +38,7 @@
#include "qgslayertreeview.h"
#include "qgsshortcutsmanager.h"
#include "qgsattributedialog.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsvectordataprovider.h"
#include "qgsfeatureaction.h"
#include "qgsactionmanager.h"

View File

@ -20,7 +20,7 @@
#include "ui_qgsaddattrdialogbase.h"
#include "qgisgui.h"
#include "qgsfield.h"
#include "qgsfields.h"
class QgsVectorLayer;

View File

@ -46,7 +46,7 @@
#include "qgsexpressionselectiondialog.h"
#include "qgsfeaturelistmodel.h"
#include "qgsrubberband.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgseditorwidgetregistry.h"
#include "qgsfieldproxymodel.h"
@ -387,7 +387,7 @@ void QgsAttributeTableDialog::columnBoxInit()
Q_FOREACH ( const QgsField& field, fields )
{
int idx = mLayer->fieldNameIndex( field.name() );
int idx = mLayer->fields().lookupField( field.name() );
if ( idx < 0 )
continue;
@ -524,7 +524,7 @@ void QgsAttributeTableDialog::filterColumnChanged( QObject* filterAction )
}
QString fieldName = mFilterButton->defaultAction()->data().toString();
// get the search widget
int fldIdx = mLayer->fieldNameIndex( fieldName );
int fldIdx = mLayer->fields().lookupField( fieldName );
if ( fldIdx < 0 )
return;
const QgsEditorWidgetSetup setup = QgsEditorWidgetRegistry::instance()->findBest( mLayer, fieldName );

View File

@ -29,7 +29,7 @@
#include "qgsclipboard.h"
#include "qgsfeature.h"
#include "qgsfeaturestore.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include "qgscoordinatereferencesystem.h"
#include "qgslogger.h"

View File

@ -22,7 +22,7 @@
#include <QMap>
#include <QObject>
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeature.h"
#include "qgscoordinatereferencesystem.h"

View File

@ -17,7 +17,7 @@
#include "qgsapplication.h"
#include "qgsdelattrdialog.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"

View File

@ -588,7 +588,7 @@ void QgsDiagramProperties::on_mFindMaximumValueButton_clicked()
}
else
{
int attributeNumber = mLayer->fields().fieldNameIndex( sizeFieldNameOrExp );
int attributeNumber = mLayer->fields().lookupField( sizeFieldNameOrExp );
maxValue = mLayer->maximumValue( attributeNumber ).toFloat();
}
@ -776,7 +776,7 @@ void QgsDiagramProperties::apply()
}
else
{
int attributeNumber = mLayer->fields().fieldNameIndex( sizeFieldNameOrExp );
int attributeNumber = mLayer->fields().lookupField( sizeFieldNameOrExp );
dr->setClassificationAttribute( attributeNumber );
}
dr->setDiagramSettings( ds );

View File

@ -91,7 +91,7 @@ void FieldSelectorDelegate::setModelData( QWidget *editor, QAbstractItemModel *m
if ( !fcb )
return;
model->setData( index, vl->fieldNameIndex( fcb->currentField() ) );
model->setData( index, vl->fields().lookupField( fcb->currentField() ) );
}
QgsVectorLayerAndAttributeModel::QgsVectorLayerAndAttributeModel( QgsLayerTreeGroup* rootNode, QObject *parent )

View File

@ -18,7 +18,7 @@
#include "ui_qgsfieldcalculatorbase.h"
#include "qgscontexthelp.h"
#include "qgsfield.h"
#include "qgsfields.h"
class QgsVectorLayer;

View File

@ -855,7 +855,7 @@ QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTr
{
case DesignerTreeItemData::Field:
{
int idx = mLayer->fieldNameIndex( itemData.name() );
int idx = mLayer->fields().lookupField( itemData.name() );
widgetDef = new QgsAttributeEditorField( itemData.name(), idx, parent );
break;
}

View File

@ -681,7 +681,7 @@ QString QgsIdentifyResultsDialog::representValue( QgsVectorLayer* vlayer, const
QgsEditorWidgetFactory* factory = QgsEditorWidgetRegistry::instance()->factory( setup.type() );
int idx = vlayer->fieldNameIndex( fieldName );
int idx = vlayer->fields().lookupField( fieldName );
if ( !factory )
return value.toString();

View File

@ -21,7 +21,7 @@
#include "ui_qgsidentifyresultsbase.h"
#include "qgscontexthelp.h"
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsmaptoolidentify.h"
#include "qgswebview.h"

View File

@ -98,7 +98,7 @@ void QgsLabelPropertyDialog::init( const QString& layerId, const QString& provid
QString labelFieldName = vlayer->customProperty( "labeling/fieldName" ).toString();
if ( !labelFieldName.isEmpty() )
{
mCurLabelField = vlayer->fieldNameIndex( labelFieldName );
mCurLabelField = vlayer->fields().lookupField( labelFieldName );
if ( mCurLabelField >= 0 )
{
mLabelTextLineEdit->setText( attributeValues.at( mCurLabelField ).toString() );
@ -373,7 +373,7 @@ void QgsLabelPropertyDialog::enableDataDefinedWidgets( QgsVectorLayer* vlayer )
continue; // can only modify attributes with an active data definition of a mapped field
}
int ddIndx = vlayer->fieldNameIndex( ddField );
int ddIndx = vlayer->fields().lookupField( ddField );
if ( ddIndx == -1 )
{
continue;

View File

@ -18,7 +18,7 @@
#include "qgsattributedialog.h"
#include "qgscsexception.h"
#include "qgscurvepolygon.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include "qgslinestring.h"
#include "qgsmultipoint.h"

View File

@ -17,7 +17,7 @@
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"

View File

@ -20,7 +20,7 @@
#include "qgsdistancearea.h"
#include "qgsfeature.h"
#include "qgsfeaturestore.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include "qgslogger.h"
#include "qgsidentifyresultsdialog.h"

View File

@ -162,7 +162,7 @@ QString QgsMapToolLabel::currentLabelText( int trunc )
QString labelField = vlayer->customProperty( "labeling/fieldName" ).toString();
if ( !labelField.isEmpty() )
{
int labelFieldId = vlayer->fieldNameIndex( labelField );
int labelFieldId = vlayer->fields().lookupField( labelField );
QgsFeature f;
if ( vlayer->getFeatures( QgsFeatureRequest().setFilterFid( mCurrentLabel.pos.featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) )
{
@ -434,7 +434,7 @@ int QgsMapToolLabel::dataDefinedColumnIndex( QgsPalLayerSettings::DataDefinedPro
{
QString fieldname = dataDefinedColumnName( p, labelSettings );
if ( !fieldname.isEmpty() )
return vlayer->fieldNameIndex( fieldname );
return vlayer->fields().lookupField( fieldname );
return -1;
}
@ -497,7 +497,7 @@ bool QgsMapToolLabel::layerIsRotatable( QgsVectorLayer* vlayer, int& rotationCol
bool QgsMapToolLabel::labelIsRotatable( QgsVectorLayer* layer, const QgsPalLayerSettings& settings, int& rotationCol ) const
{
QString rColName = dataDefinedColumnName( QgsPalLayerSettings::Rotation, settings );
rotationCol = layer->fieldNameIndex( rColName );
rotationCol = layer->fields().lookupField( rColName );
return rotationCol != -1;
}
@ -606,8 +606,8 @@ bool QgsMapToolLabel::labelMoveable( QgsVectorLayer* vlayer, const QgsPalLayerSe
QString xColName = dataDefinedColumnName( QgsPalLayerSettings::PositionX, settings );
QString yColName = dataDefinedColumnName( QgsPalLayerSettings::PositionY, settings );
//return !xColName.isEmpty() && !yColName.isEmpty();
xCol = vlayer->fieldNameIndex( xColName );
yCol = vlayer->fieldNameIndex( yColName );
xCol = vlayer->fields().lookupField( xColName );
yCol = vlayer->fields().lookupField( yColName );
return ( xCol != -1 && yCol != -1 );
}
@ -629,7 +629,7 @@ bool QgsMapToolLabel::labelCanShowHide( QgsVectorLayer* vlayer, int& showCol ) c
{
QString fieldname = dataDefinedColumnName( QgsPalLayerSettings::Show,
vlayer->labeling()->settings( vlayer, providerId ) );
showCol = vlayer->fieldNameIndex( fieldname );
showCol = vlayer->fields().lookupField( fieldname );
if ( showCol != -1 )
return true;
}

View File

@ -21,7 +21,7 @@
#include "qgsapplication.h"
#include "qgseditorwidgetwrapper.h"
#include "qgsfeatureiterator.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsmapcanvas.h"
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"

View File

@ -22,7 +22,7 @@
#include "ui_qgsmergeattributesdialogbase.h"
#include "qgsfeature.h"
#include "qgsstatisticalsummary.h"
#include "qgsfield.h"
#include "qgsfields.h"
class QgsMapCanvas;
class QgsRubberBand;

View File

@ -134,7 +134,7 @@ void QgsStatisticalSummaryDockWidget::refreshStatistics()
if ( !mFieldExpressionWidget->isExpression() )
{
QString field = mFieldExpressionWidget->currentField();
fieldType = mLayer->fields().field( mLayer->fields().fieldNameIndex( field ) ).type();
fieldType = mLayer->fields().field( mLayer->fields().lookupField( field ) ).type();
if ( fieldType == QVariant::String || fieldType == QVariant::Date || fieldType == QVariant::DateTime )
{
isNumeric = false;

View File

@ -122,6 +122,7 @@ SET(QGIS_CORE_SRCS
qgsfeaturerequest.cpp
qgsfeaturestore.cpp
qgsfield.cpp
qgsfields.cpp
qgsfontutils.cpp
qgsgeometrycache.cpp
qgsgeometrysimplifier.cpp
@ -637,6 +638,7 @@ SET(QGIS_CORE_HDRS
qgsfeatureiterator.h
qgsfeaturerequest.h
qgsfeaturestore.h
qgsfields.h
qgsfontutils.h
qgsgeometrycache.h
qgshistogram.h

View File

@ -178,7 +178,7 @@ int QgsAtlasComposition::updateFeatures()
QgsFeature feat;
mFeatureIds.clear();
mFeatureKeys.clear();
int sortIdx = mCoverageLayer->fieldNameIndex( mSortKeyAttributeName );
int sortIdx = mCoverageLayer->fields().lookupField( mSortKeyAttributeName );
while ( fit.nextFeature( feat ) )
{

View File

@ -330,7 +330,7 @@ void QgsComposerAttributeTableV2::setDisplayedFields( const QStringList& fields,
{
Q_FOREACH ( const QString& field, fields )
{
int attrIdx = layerFields.fieldNameIndex( field );
int attrIdx = layerFields.lookupField( field );
if ( attrIdx < 0 )
continue;
@ -373,7 +373,7 @@ void QgsComposerAttributeTableV2::restoreFieldAliasMap( const QMap<int, QString>
QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin();
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
{
int attrIdx = source->fieldNameIndex(( *columnIt )->attribute() );
int attrIdx = source->fields().lookupField(( *columnIt )->attribute() );
if ( map.contains( attrIdx ) )
{
( *columnIt )->setHeading( map.value( attrIdx ) );
@ -499,7 +499,7 @@ bool QgsComposerAttributeTableV2::getTableContents( QgsComposerTableContents &co
QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin();
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
{
int idx = layer->fieldNameIndex(( *columnIt )->attribute() );
int idx = layer->fields().lookupField(( *columnIt )->attribute() );
if ( idx != -1 )
{
currentRow << replaceWrapChar( f.attributes().at( idx ) );

View File

@ -56,7 +56,7 @@ QVariant QgsAggregateCalculator::calculate( QgsAggregateCalculator::Aggregate ag
QScopedPointer<QgsExpression> expression;
int attrNum = mLayer->fieldNameIndex( fieldOrExpression );
int attrNum = mLayer->fields().lookupField( fieldOrExpression );
if ( attrNum == -1 )
{

View File

@ -14,7 +14,7 @@
* *
***************************************************************************/
#include "qgsattributetableconfig.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include <QStringList>
QgsAttributeTableConfig::QgsAttributeTableConfig()
@ -65,7 +65,7 @@ void QgsAttributeTableConfig::update( const QgsFields& fields )
const ColumnConfig& column = mColumns.at( i );
if ( column.type == Field )
{
if ( fields.fieldNameIndex( column.name ) == -1 )
if ( fields.lookupField( column.name ) == -1 )
{
mColumns.remove( i );
}

View File

@ -18,7 +18,7 @@
#include "qgslogger.h"
#include "qgsexpression.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsvectorlayer.h"
QgsDataDefined::QgsDataDefined( bool active,

View File

@ -23,7 +23,7 @@
#include <QDomDocument>
#include "qgsexpressioncontext.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgscoordinatetransform.h"
#include "qgssymbol.h"

View File

@ -597,7 +597,7 @@ QgsAttributeEditorElement* QgsEditFormConfig::attributeEditorElementFromDomEleme
else if ( elem.tagName() == "attributeEditorField" )
{
QString name = elem.attribute( "name" );
int idx = d->mFields.fieldNameIndex( name );
int idx = d->mFields.lookupField( name );
newElement = new QgsAttributeEditorField( name, idx, parent );
}
else if ( elem.tagName() == "attributeEditorRelation" )

View File

@ -18,7 +18,7 @@
#include <QMap>
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgseditformconfig.h"
/// @cond PRIVATE

View File

@ -3086,7 +3086,7 @@ static QVariant fcnGetFeature( const QVariantList& values, const QgsExpressionCo
}
QString attribute = getStringValue( values.at( 1 ), parent );
int attributeId = vl->fieldNameIndex( attribute );
int attributeId = vl->fields().lookupField( attribute );
if ( attributeId == -1 )
{
return QVariant();
@ -3824,6 +3824,24 @@ QStringList QgsExpression::referencedColumns() const
return columns;
}
QSet<int> QgsExpression::referencedAttributeIndexes( const QgsFields& fields ) const
{
QStringList referencedFields = d->mRootNode->referencedColumns();
QSet<int> referencedIndexes;
Q_FOREACH ( const QString& fieldName, referencedFields )
{
if ( fieldName == QgsFeatureRequest::AllAttributes )
{
referencedIndexes = fields.allAttributesList().toSet();
break;
}
referencedIndexes << fields.lookupField( fieldName );
}
return referencedIndexes;
}
bool QgsExpression::needsGeometry() const
{
if ( !d->mRootNode )
@ -4807,7 +4825,7 @@ QVariant QgsExpression::NodeColumnRef::eval( QgsExpression *parent, const QgsExp
if ( context && context->hasVariable( QgsExpressionContext::EXPR_FIELDS ) )
{
QgsFields fields = qvariant_cast<QgsFields>( context->variable( QgsExpressionContext::EXPR_FIELDS ) );
index = fields.fieldNameIndex( mName );
index = fields.lookupField( mName );
}
}
@ -4829,7 +4847,7 @@ bool QgsExpression::NodeColumnRef::prepare( QgsExpression *parent, const QgsExpr
QgsFields fields = qvariant_cast<QgsFields>( context->variable( QgsExpressionContext::EXPR_FIELDS ) );
mIndex = fields.fieldNameIndex( mName );
mIndex = fields.lookupField( mName );
if ( mIndex >= 0 )
{
return true;

View File

@ -179,10 +179,19 @@ class CORE_EXPORT QgsExpression
* all attributes from the layer are required for evaluation of the expression.
* QgsFeatureRequest::setSubsetOfAttributes automatically handles this case.
*
* @see referencedAttributeIndexes()
*
* TODO QGIS3: Return QSet<QString>
*/
QStringList referencedColumns() const;
/**
* Return a list of field name indexes obtained from the provided fields.
*
* @note Added in QGIS 3.0
*/
QSet<int> referencedAttributeIndexes( const QgsFields& fields ) const;
//! Returns true if the expression uses feature geometry for some computation
bool needsGeometry() const;
@ -294,13 +303,13 @@ class CORE_EXPORT QgsExpression
* in the string with the result of its evaluation with the specified context
*
* Additional substitutions can be passed through the substitutionMap parameter
* @param action
* @param context expression context
* @param distanceArea optional QgsDistanceArea. If specified, the QgsDistanceArea is used for distance
* @param action The source string in which placeholders should be replaced.
* @param context Expression context
* @param distanceArea Optional QgsDistanceArea. If specified, the QgsDistanceArea is used for distance
* and area conversion
* @note added in QGIS 2.12
*/
static QString replaceExpressionText( const QString &action, const QgsExpressionContext* context,
static QString replaceExpressionText( const QString& action, const QgsExpressionContext* context,
const QgsDistanceArea* distanceArea = nullptr );
/** Attempts to evaluate a text string as an expression to a resultant double
@ -335,12 +344,12 @@ class CORE_EXPORT QgsExpression
boAnd,
// comparison
boEQ, // =
boNE, // <>
boLE, // <=
boGE, // >=
boLT, // <
boGT, // >
boEQ, //!< =
boNE, //!< <>
boLE, //!< <=
boGE, //!< >=
boLT, //!< <
boGT, //!< >
boRegexp,
boLike,
boNotLike,

View File

@ -17,7 +17,7 @@
#include "qgslogger.h"
#include "qgsexpression.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsvectorlayer.h"
#include "qgsproject.h"
#include "qgssymbollayerutils.h"

View File

@ -22,7 +22,7 @@
#include <QList>
#include <QDomNode>
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsexpression.h"
/** \ingroup core

View File

@ -15,7 +15,7 @@ email : sherman at mrcc.com
#include "qgsfeature.h"
#include "qgsfeature_p.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include "qgsrectangle.h"
@ -274,7 +274,7 @@ QVariant QgsFeature::attribute( const QString& name ) const
int QgsFeature::fieldNameIndex( const QString& fieldName ) const
{
return d->fields.fieldNameIndex( fieldName );
return d->fields.lookupField( fieldName );
}
/***************************************************************************

View File

@ -24,7 +24,7 @@ email : sherman at mrcc.com
#include <QSet>
#include <QExplicitlySharedDataPointer>
#include "qgsfield.h"
#include "qgsfields.h"
class QgsGeometry;
class QgsRectangle;

View File

@ -33,7 +33,7 @@ email : nyall dot dawson at gmail dot com
* See details in QEP #17
****************************************************************************/
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"

View File

@ -14,7 +14,7 @@
***************************************************************************/
#include "qgsfeaturerequest.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include <QStringList>
@ -208,7 +208,7 @@ QgsFeatureRequest& QgsFeatureRequest::setSubsetOfAttributes( const QStringList&
Q_FOREACH ( const QString& attrName, attrNames )
{
int attrNum = fields.fieldNameIndex( attrName );
int attrNum = fields.lookupField( attrName );
if ( attrNum != -1 && !mAttrs.contains( attrNum ) )
mAttrs.append( attrNum );
}

View File

@ -17,7 +17,7 @@
#include "qgis.h"
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgscoordinatereferencesystem.h"
#include <QList>
#include <QMetaType>

View File

@ -14,7 +14,7 @@
* *
***************************************************************************/
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfield_p.h"
#include "qgis.h"
#include "qgsapplication.h"
@ -323,331 +323,3 @@ QDataStream& operator>>( QDataStream& in, QgsField& field )
field.setSubType( static_cast< QVariant::Type >( subType ) );
return in;
}
////////////////////////////////////////////////////////////////////////////
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
QgsFields::QgsFields()
{
d = new QgsFieldsPrivate();
}
QgsFields::QgsFields( const QgsFields& other )
: d( other.d )
{
}
QgsFields& QgsFields::operator =( const QgsFields & other )
{
d = other.d;
return *this;
}
QgsFields::~QgsFields()
{
}
void QgsFields::clear()
{
d->fields.clear();
d->nameToIndex.clear();
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
bool QgsFields::append( const QgsField& field, FieldOrigin origin, int originIndex )
{
if ( d->nameToIndex.contains( field.name() ) )
return false;
if ( originIndex == -1 && origin == OriginProvider )
originIndex = d->fields.count();
d->fields.append( Field( field, origin, originIndex ) );
d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
return true;
}
bool QgsFields::appendExpressionField( const QgsField& field, int originIndex )
{
if ( d->nameToIndex.contains( field.name() ) )
return false;
d->fields.append( Field( field, OriginExpression, originIndex ) );
d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
return true;
}
void QgsFields::remove( int fieldIdx )
{
if ( !exists( fieldIdx ) )
return;
d->fields.remove( fieldIdx );
d->nameToIndex.clear();
for ( int idx = 0; idx < count(); ++idx )
{
d->nameToIndex.insert( d->fields.at( idx ).field.name(), idx );
}
}
void QgsFields::extend( const QgsFields& other )
{
for ( int i = 0; i < other.count(); ++i )
{
append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) );
}
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
bool QgsFields::isEmpty() const
{
return d->fields.isEmpty();
}
int QgsFields::count() const
{
return d->fields.count();
}
int QgsFields::size() const
{
return d->fields.count();
}
bool QgsFields::exists( int i ) const
{
return i >= 0 && i < d->fields.count();
}
QgsField &QgsFields::operator[]( int i )
{
return d->fields[i].field;
}
QgsField QgsFields::at( int i ) const
{
return d->fields[i].field;
}
QgsField QgsFields::field( int fieldIdx ) const
{
return d->fields[fieldIdx].field;
}
QgsField QgsFields::field( const QString &name ) const
{
return d->fields[ indexFromName( name )].field;
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
QgsField QgsFields::operator[]( int i ) const
{
return d->fields[i].field;
}
QgsFields::FieldOrigin QgsFields::fieldOrigin( int fieldIdx ) const
{
if ( !exists( fieldIdx ) )
return OriginUnknown;
return d->fields[fieldIdx].origin;
}
int QgsFields::fieldOriginIndex( int fieldIdx ) const
{
return d->fields[fieldIdx].originIndex;
}
int QgsFields::indexFromName( const QString &fieldName ) const
{
return d->nameToIndex.value( fieldName, -1 );
}
QList<QgsField> QgsFields::toList() const
{
QList<QgsField> lst;
for ( int i = 0; i < d->fields.count(); ++i )
lst.append( d->fields[i].field );
return lst;
}
bool QgsFields::operator==( const QgsFields &other ) const
{
return d->fields == other.d->fields;
}
QgsFields::const_iterator QgsFields::constBegin() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.first() );
}
QgsFields::const_iterator QgsFields::constEnd() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.last() + 1 );
}
QgsFields::const_iterator QgsFields::begin() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.first() );
}
QgsFields::const_iterator QgsFields::end() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.last() + 1 );
}
QgsFields::iterator QgsFields::begin()
{
if ( d->fields.isEmpty() )
return iterator();
d.detach();
return iterator( &d->fields.first() );
}
QgsFields::iterator QgsFields::end()
{
if ( d->fields.isEmpty() )
return iterator();
d.detach();
return iterator( &d->fields.last() + 1 );
}
QIcon QgsFields::iconForField( int fieldIdx ) const
{
switch ( d->fields.at( fieldIdx ).field.type() )
{
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
{
return QgsApplication::getThemeIcon( "/mIconFieldInteger.svg" );
}
case QVariant::Double:
{
return QgsApplication::getThemeIcon( "/mIconFieldFloat.svg" );
}
case QVariant::String:
{
return QgsApplication::getThemeIcon( "/mIconFieldText.svg" );
}
case QVariant::Date:
{
return QgsApplication::getThemeIcon( "/mIconFieldDate.svg" );
}
case QVariant::DateTime:
{
return QgsApplication::getThemeIcon( "/mIconFieldDateTime.svg" );
}
case QVariant::Time:
{
return QgsApplication::getThemeIcon( "/mIconFieldTime.svg" );
}
default:
return QIcon();
}
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
int QgsFields::fieldNameIndex( const QString& fieldName ) const
{
for ( int idx = 0; idx < count(); ++idx )
{
if ( d->fields[idx].field.name() == fieldName )
return idx;
}
for ( int idx = 0; idx < count(); ++idx )
{
if ( QString::compare( d->fields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
return idx;
}
for ( int idx = 0; idx < count(); ++idx )
{
if ( QString::compare( d->fields[idx].field.alias(), fieldName, Qt::CaseInsensitive ) == 0 )
return idx;
}
return -1;
}
QgsAttributeList QgsFields::allAttributesList() const
{
QgsAttributeList lst;
for ( int i = 0; i < d->fields.count(); ++i )
lst.append( i );
return lst;
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
QDataStream& operator<<( QDataStream& out, const QgsFields& fields )
{
out << static_cast< quint32 >( fields.size() );
for ( int i = 0; i < fields.size(); i++ )
{
out << fields.field( i );
}
return out;
}
QDataStream& operator>>( QDataStream& in, QgsFields& fields )
{
fields.clear();
quint32 size;
in >> size;
for ( quint32 i = 0; i < size; i++ )
{
QgsField field;
in >> field;
fields.append( field );
}
return in;
}

View File

@ -269,291 +269,4 @@ CORE_EXPORT QDataStream& operator<<( QDataStream& out, const QgsField& field );
CORE_EXPORT QDataStream& operator>>( QDataStream& in, QgsField& field );
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
/** \class QgsFields
* \ingroup core
* Container of fields for a vector layer.
*
* In addition to storing a list of QgsField instances, it also:
* - allows quick lookups of field names to index in the list
* - keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
* \note QgsFields objects are implicitly shared.
*/
class CORE_EXPORT QgsFields
{
public:
enum FieldOrigin
{
OriginUnknown, //!< it has not been specified where the field comes from
OriginProvider, //!< field comes from the underlying data provider of the vector layer (originIndex = index in provider's fields)
OriginJoin, //!< field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index within the join)
OriginEdit, //!< field has been temporarily added in editing mode (originIndex = index in the list of added attributes)
OriginExpression //!< field is calculated from an expression
};
typedef struct Field
{
Field(): origin( OriginUnknown ), originIndex( -1 ) {}
Field( const QgsField& f, FieldOrigin o, int oi ): field( f ), origin( o ), originIndex( oi ) {}
//! @note added in 2.6
bool operator==( const Field& other ) const { return field == other.field && origin == other.origin && originIndex == other.originIndex; }
//! @note added in 2.6
bool operator!=( const Field& other ) const { return !( *this == other ); }
QgsField field; //!< field
FieldOrigin origin; //!< origin of the field
int originIndex; //!< index specific to the origin
} Field;
/** Constructor for an empty field container
*/
QgsFields();
/** Copy constructor
*/
QgsFields( const QgsFields& other );
/** Assignment operator
*/
QgsFields& operator =( const QgsFields &other );
virtual ~QgsFields();
//! Remove all fields
void clear();
//! Append a field. The field must have unique name, otherwise it is rejected (returns false)
bool append( const QgsField& field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
//! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
bool appendExpressionField( const QgsField& field, int originIndex );
//! Remove a field with the given index
void remove( int fieldIdx );
//! Extend with fields from another QgsFields container
void extend( const QgsFields& other );
//! Check whether the container is empty
bool isEmpty() const;
//! Return number of items
int count() const;
//! Return number of items
int size() const;
//! Return if a field index is valid
//! @param i Index of the field which needs to be checked
//! @return True if the field exists
bool exists( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
QgsField operator[]( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
QgsField& operator[]( int i );
//! Get field at particular index (must be in range 0..N-1)
QgsField at( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
QgsField field( int fieldIdx ) const;
//! Get field with matching name
QgsField field( const QString& name ) const;
//! Get field's origin (value from an enumeration)
FieldOrigin fieldOrigin( int fieldIdx ) const;
//! Get field's origin index (its meaning is specific to each type of origin)
int fieldOriginIndex( int fieldIdx ) const;
/**
* Look up field's index from the field name.
* This method takes is case sensitive and only matches the data source
* name of the field.
*
* @param fieldName The name of the field.
*
* @return The field index if found or -1 in case it cannot be found.
* @see fieldNameIndex For a more tolerant alternative.
*/
int indexFromName( const QString& fieldName ) const;
/**
* Look up field's index from the field name.
* This method matches in the following order:
*
* 1. The exact field name taking case sensitivity into account
* 2. Looks for the field name by case insensitive comparison
* 3. The field alias (case insensitive)
*
* @param fieldName The name to look for.
*
* @return The field index if found or -1 in case it cannot be found.
* @see indexFromName For a more performant and precise but less tolerant alternative.
* @note added in 2.4
*/
int fieldNameIndex( const QString& fieldName ) const;
//! Utility function to get list of attribute indexes
//! @note added in 2.4
QgsAttributeList allAttributesList() const;
//! Utility function to return a list of QgsField instances
QList<QgsField> toList() const;
//! @note added in 2.6
bool operator==( const QgsFields& other ) const;
//! @note added in 2.6
bool operator!=( const QgsFields& other ) const { return !( *this == other ); }
/** Returns an icon corresponding to a field index, based on the field's type and source
* @note added in QGIS 2.14
*/
QIcon iconForField( int fieldIdx ) const;
//! Allows direct construction of QVariants from fields.
operator QVariant() const
{
return QVariant::fromValue( *this );
}
///@cond PRIVATE
class const_iterator;
class iterator
{
public:
QgsFields::Field* d;
typedef std::random_access_iterator_tag iterator_category;
typedef qptrdiff difference_type;
inline iterator()
: d( nullptr )
{}
inline iterator( QgsFields::Field *n )
: d( n )
{}
inline QgsField& operator*() const { return d->field; }
inline QgsField* operator->() const { return &d->field; }
inline QgsField& operator[]( difference_type j ) const { return d[j].field; }
inline bool operator==( const iterator &o ) const noexcept { return d == o.d; }
inline bool operator!=( const iterator &o ) const noexcept { return d != o.d; }
inline bool operator<( const iterator& other ) const noexcept { return d < other.d; }
inline bool operator<=( const iterator& other ) const noexcept { return d <= other.d; }
inline bool operator>( const iterator& other ) const noexcept { return d > other.d; }
inline bool operator>=( const iterator& other ) const noexcept { return d >= other.d; }
inline iterator& operator++() { ++d; return *this; }
inline iterator operator++( int ) { QgsFields::Field* n = d; ++d; return n; }
inline iterator& operator--() { d--; return *this; }
inline iterator operator--( int ) { QgsFields::Field* n = d; d--; return n; }
inline iterator& operator+=( difference_type j ) { d += j; return *this; }
inline iterator& operator-=( difference_type j ) { d -= j; return *this; }
inline iterator operator+( difference_type j ) const { return iterator( d + j ); }
inline iterator operator-( difference_type j ) const { return iterator( d -j ); }
inline int operator-( iterator j ) const { return int( d - j.d ); }
};
friend class iterator;
class const_iterator
{
public:
const QgsFields::Field* d;
typedef std::random_access_iterator_tag iterator_category;
typedef qptrdiff difference_type;
inline const_iterator()
: d( nullptr ) {}
inline const_iterator( const QgsFields::Field* f )
: d( f ) {}
inline const_iterator( const const_iterator &o )
: d( o.d ) {}
inline explicit const_iterator( const iterator &o )
: d( o.d ) {}
inline const QgsField& operator*() const { return d->field; }
inline const QgsField* operator->() const { return &d->field; }
inline const QgsField& operator[]( difference_type j ) const noexcept { return d[j].field; }
inline bool operator==( const const_iterator &o ) const noexcept { return d == o.d; }
inline bool operator!=( const const_iterator &o ) const noexcept { return d != o.d; }
inline bool operator<( const const_iterator& other ) const noexcept { return d < other.d; }
inline bool operator<=( const const_iterator& other ) const noexcept { return d <= other.d; }
inline bool operator>( const const_iterator& other ) const noexcept { return d > other.d; }
inline bool operator>=( const const_iterator& other ) const noexcept { return d >= other.d; }
inline const_iterator& operator++() { ++d; return *this; }
inline const_iterator operator++( int ) { const QgsFields::Field* n = d; ++d; return n; }
inline const_iterator& operator--() { d--; return *this; }
inline const_iterator operator--( int ) { const QgsFields::Field* n = d; --d; return n; }
inline const_iterator& operator+=( difference_type j ) { d += j; return *this; }
inline const_iterator& operator-=( difference_type j ) { d -= j; return *this; }
inline const_iterator operator+( difference_type j ) const { return const_iterator( d + j ); }
inline const_iterator operator-( difference_type j ) const { return const_iterator( d -j ); }
inline int operator-( const_iterator j ) const { return int( d - j.d ); }
};
friend class const_iterator;
///@endcond
/**
* Returns a const STL-style iterator pointing to the first item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator constBegin() const noexcept;
/**
* Returns a const STL-style iterator pointing to the imaginary item after the last item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator constEnd() const noexcept;
/**
* Returns a const STL-style iterator pointing to the first item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator begin() const noexcept;
/**
* Returns a const STL-style iterator pointing to the imaginary item after the last item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator end() const noexcept;
/**
* Returns an STL-style iterator pointing to the first item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
iterator begin();
/**
* Returns an STL-style iterator pointing to the imaginary item after the last item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
iterator end();
private:
QSharedDataPointer<QgsFieldsPrivate> d;
};
Q_DECLARE_METATYPE( QgsFields )
/** Writes the fields to stream out. QGIS version compatibility is not guaranteed. */
CORE_EXPORT QDataStream& operator<<( QDataStream& out, const QgsFields& fields );
/** Reads fields from stream in into fields. QGIS version compatibility is not guaranteed. */
CORE_EXPORT QDataStream& operator>>( QDataStream& in, QgsFields& fields );
#endif

View File

@ -30,7 +30,6 @@
#include <QString>
#include <QVariant>
#include <QSharedData>
#include "qgsfield.h"
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
@ -112,38 +111,6 @@ class QgsFieldPrivate : public QSharedData
QgsEditorWidgetSetup editorWidgetSetup;
};
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
class CORE_EXPORT QgsFieldsPrivate : public QSharedData
{
public:
QgsFieldsPrivate()
{
}
QgsFieldsPrivate( const QgsFieldsPrivate& other )
: QSharedData( other )
, fields( other.fields )
, nameToIndex( other.nameToIndex )
{
}
~QgsFieldsPrivate() {}
//! internal storage of the container
QVector<QgsFields::Field> fields;
//! map for quick resolution of name to index
QHash<QString, int> nameToIndex;
};
/// @endcond
#endif

346
src/core/qgsfields.cpp Normal file
View File

@ -0,0 +1,346 @@
/***************************************************************************
qgsfields.cpp - QgsFields
---------------------
begin : 22.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsfields.h"
#include "qgsfields_p.h"
#include "qgsapplication.h"
#include <QIcon>
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
QgsFields::QgsFields()
{
d = new QgsFieldsPrivate();
}
QgsFields::QgsFields( const QgsFields& other )
: d( other.d )
{
}
QgsFields& QgsFields::operator =( const QgsFields & other )
{
d = other.d;
return *this;
}
QgsFields::~QgsFields()
{
}
void QgsFields::clear()
{
d->fields.clear();
d->nameToIndex.clear();
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
bool QgsFields::append( const QgsField& field, FieldOrigin origin, int originIndex )
{
if ( d->nameToIndex.contains( field.name() ) )
return false;
if ( originIndex == -1 && origin == OriginProvider )
originIndex = d->fields.count();
d->fields.append( Field( field, origin, originIndex ) );
d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
return true;
}
bool QgsFields::appendExpressionField( const QgsField& field, int originIndex )
{
if ( d->nameToIndex.contains( field.name() ) )
return false;
d->fields.append( Field( field, OriginExpression, originIndex ) );
d->nameToIndex.insert( field.name(), d->fields.count() - 1 );
return true;
}
void QgsFields::remove( int fieldIdx )
{
if ( !exists( fieldIdx ) )
return;
d->fields.remove( fieldIdx );
d->nameToIndex.clear();
for ( int idx = 0; idx < count(); ++idx )
{
d->nameToIndex.insert( d->fields.at( idx ).field.name(), idx );
}
}
void QgsFields::extend( const QgsFields& other )
{
for ( int i = 0; i < other.count(); ++i )
{
append( other.at( i ), other.fieldOrigin( i ), other.fieldOriginIndex( i ) );
}
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
bool QgsFields::isEmpty() const
{
return d->fields.isEmpty();
}
int QgsFields::count() const
{
return d->fields.count();
}
int QgsFields::size() const
{
return d->fields.count();
}
bool QgsFields::exists( int i ) const
{
return i >= 0 && i < d->fields.count();
}
QgsField &QgsFields::operator[]( int i )
{
return d->fields[i].field;
}
QgsField QgsFields::at( int i ) const
{
return d->fields[i].field;
}
QgsField QgsFields::field( int fieldIdx ) const
{
return d->fields[fieldIdx].field;
}
QgsField QgsFields::field( const QString &name ) const
{
return d->fields[ indexFromName( name )].field;
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
QgsField QgsFields::operator[]( int i ) const
{
return d->fields[i].field;
}
QgsFields::FieldOrigin QgsFields::fieldOrigin( int fieldIdx ) const
{
if ( !exists( fieldIdx ) )
return OriginUnknown;
return d->fields[fieldIdx].origin;
}
int QgsFields::fieldOriginIndex( int fieldIdx ) const
{
return d->fields[fieldIdx].originIndex;
}
int QgsFields::indexFromName( const QString &fieldName ) const
{
return d->nameToIndex.value( fieldName, -1 );
}
QList<QgsField> QgsFields::toList() const
{
QList<QgsField> lst;
for ( int i = 0; i < d->fields.count(); ++i )
lst.append( d->fields[i].field );
return lst;
}
bool QgsFields::operator==( const QgsFields &other ) const
{
return d->fields == other.d->fields;
}
QgsFields::const_iterator QgsFields::constBegin() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.first() );
}
QgsFields::const_iterator QgsFields::constEnd() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.last() + 1 );
}
QgsFields::const_iterator QgsFields::begin() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.first() );
}
QgsFields::const_iterator QgsFields::end() const noexcept
{
if ( d->fields.isEmpty() )
return const_iterator();
return const_iterator( &d->fields.last() + 1 );
}
QgsFields::iterator QgsFields::begin()
{
if ( d->fields.isEmpty() )
return iterator();
d.detach();
return iterator( &d->fields.first() );
}
QgsFields::iterator QgsFields::end()
{
if ( d->fields.isEmpty() )
return iterator();
d.detach();
return iterator( &d->fields.last() + 1 );
}
QIcon QgsFields::iconForField( int fieldIdx ) const
{
switch ( d->fields.at( fieldIdx ).field.type() )
{
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
{
return QgsApplication::getThemeIcon( "/mIconFieldInteger.svg" );
}
case QVariant::Double:
{
return QgsApplication::getThemeIcon( "/mIconFieldFloat.svg" );
}
case QVariant::String:
{
return QgsApplication::getThemeIcon( "/mIconFieldText.svg" );
}
case QVariant::Date:
{
return QgsApplication::getThemeIcon( "/mIconFieldDate.svg" );
}
case QVariant::DateTime:
{
return QgsApplication::getThemeIcon( "/mIconFieldDateTime.svg" );
}
case QVariant::Time:
{
return QgsApplication::getThemeIcon( "/mIconFieldTime.svg" );
}
default:
return QIcon();
}
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
int QgsFields::lookupField( const QString& fieldName ) const
{
for ( int idx = 0; idx < count(); ++idx )
{
if ( d->fields[idx].field.name() == fieldName )
return idx;
}
for ( int idx = 0; idx < count(); ++idx )
{
if ( QString::compare( d->fields[idx].field.name(), fieldName, Qt::CaseInsensitive ) == 0 )
return idx;
}
for ( int idx = 0; idx < count(); ++idx )
{
QString alias = d->fields[idx].field.alias();
if ( !alias.isNull() && QString::compare( alias, fieldName, Qt::CaseInsensitive ) == 0 )
return idx;
}
return -1;
}
QgsAttributeList QgsFields::allAttributesList() const
{
QgsAttributeList lst;
for ( int i = 0; i < d->fields.count(); ++i )
lst.append( i );
return lst;
}
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
QDataStream& operator<<( QDataStream& out, const QgsFields& fields )
{
out << static_cast< quint32 >( fields.size() );
for ( int i = 0; i < fields.size(); i++ )
{
out << fields.field( i );
}
return out;
}
QDataStream& operator>>( QDataStream& in, QgsFields& fields )
{
fields.clear();
quint32 size;
in >> size;
for ( quint32 i = 0; i < size; i++ )
{
QgsField field;
in >> field;
fields.append( field );
}
return in;
}

314
src/core/qgsfields.h Normal file
View File

@ -0,0 +1,314 @@
/***************************************************************************
qgsfields.h - QgsFields
---------------------
begin : 22.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSFIELDS_H
#define QGSFIELDS_H
#include "qgsfield.h"
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
/** \class QgsFields
* \ingroup core
* Container of fields for a vector layer.
*
* In addition to storing a list of QgsField instances, it also:
* - allows quick lookups of field names to index in the list
* - keeps track of where the field definition comes from (vector data provider, joined layer or newly added from an editing operation)
* \note QgsFields objects are implicitly shared.
*/
class CORE_EXPORT QgsFields
{
public:
enum FieldOrigin
{
OriginUnknown, //!< it has not been specified where the field comes from
OriginProvider, //!< field comes from the underlying data provider of the vector layer (originIndex = index in provider's fields)
OriginJoin, //!< field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index within the join)
OriginEdit, //!< field has been temporarily added in editing mode (originIndex = index in the list of added attributes)
OriginExpression //!< field is calculated from an expression
};
typedef struct Field
{
Field()
: origin( OriginUnknown )
, originIndex( -1 )
{}
Field( const QgsField& f, FieldOrigin o, int oi )
: field( f )
, origin( o )
, originIndex( oi )
{}
//! @note added in 2.6
bool operator==( const Field& other ) const { return field == other.field && origin == other.origin && originIndex == other.originIndex; }
//! @note added in 2.6
bool operator!=( const Field& other ) const { return !( *this == other ); }
QgsField field; //!< field
FieldOrigin origin; //!< origin of the field
int originIndex; //!< index specific to the origin
} Field;
/** Constructor for an empty field container
*/
QgsFields();
/** Copy constructor
*/
QgsFields( const QgsFields& other );
/** Assignment operator
*/
QgsFields& operator =( const QgsFields& other );
virtual ~QgsFields();
//! Remove all fields
void clear();
//! Append a field. The field must have unique name, otherwise it is rejected (returns false)
bool append( const QgsField& field, FieldOrigin origin = OriginProvider, int originIndex = -1 );
//! Append an expression field. The field must have unique name, otherwise it is rejected (returns false)
bool appendExpressionField( const QgsField& field, int originIndex );
//! Remove a field with the given index
void remove( int fieldIdx );
//! Extend with fields from another QgsFields container
void extend( const QgsFields& other );
//! Check whether the container is empty
bool isEmpty() const;
//! Return number of items
int count() const;
//! Return number of items
int size() const;
//! Return if a field index is valid
//! @param i Index of the field which needs to be checked
//! @return True if the field exists
bool exists( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
QgsField operator[]( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
QgsField& operator[]( int i );
//! Get field at particular index (must be in range 0..N-1)
QgsField at( int i ) const;
//! Get field at particular index (must be in range 0..N-1)
QgsField field( int fieldIdx ) const;
//! Get field with matching name
QgsField field( const QString& name ) const;
//! Get field's origin (value from an enumeration)
FieldOrigin fieldOrigin( int fieldIdx ) const;
//! Get field's origin index (its meaning is specific to each type of origin)
int fieldOriginIndex( int fieldIdx ) const;
/**
* Look up field's index from the field name.
* This method takes is case sensitive and only matches the data source
* name of the field.
*
* @param fieldName The name of the field.
*
* @return The field index if found or -1 in case it cannot be found.
* @see lookupField For a more tolerant alternative.
*/
int indexFromName( const QString& fieldName ) const;
/**
* Look up field's index from the field name.
* This method matches in the following order:
*
* 1. The exact field name taking case sensitivity into account
* 2. Looks for the field name by case insensitive comparison
* 3. The field alias (case insensitive)
*
* @param fieldName The name to look for.
*
* @return The field index if found or -1 in case it cannot be found.
* @see indexFromName For a more performant and precise but less tolerant alternative.
* @note added in 2.4
*/
int lookupField( const QString& fieldName ) const;
//! Utility function to get list of attribute indexes
//! @note added in 2.4
QgsAttributeList allAttributesList() const;
//! Utility function to return a list of QgsField instances
QList<QgsField> toList() const;
//! @note added in 2.6
bool operator==( const QgsFields& other ) const;
//! @note added in 2.6
bool operator!=( const QgsFields& other ) const { return !( *this == other ); }
/** Returns an icon corresponding to a field index, based on the field's type and source
* @note added in QGIS 2.14
*/
QIcon iconForField( int fieldIdx ) const;
//! Allows direct construction of QVariants from fields.
operator QVariant() const
{
return QVariant::fromValue( *this );
}
///@cond PRIVATE
class const_iterator;
class iterator
{
public:
QgsFields::Field* d;
typedef std::random_access_iterator_tag iterator_category;
typedef qptrdiff difference_type;
inline iterator()
: d( nullptr )
{}
inline iterator( QgsFields::Field *n )
: d( n )
{}
inline QgsField& operator*() const { return d->field; }
inline QgsField* operator->() const { return &d->field; }
inline QgsField& operator[]( difference_type j ) const { return d[j].field; }
inline bool operator==( const iterator &o ) const noexcept { return d == o.d; }
inline bool operator!=( const iterator &o ) const noexcept { return d != o.d; }
inline bool operator<( const iterator& other ) const noexcept { return d < other.d; }
inline bool operator<=( const iterator& other ) const noexcept { return d <= other.d; }
inline bool operator>( const iterator& other ) const noexcept { return d > other.d; }
inline bool operator>=( const iterator& other ) const noexcept { return d >= other.d; }
inline iterator& operator++() { ++d; return *this; }
inline iterator operator++( int ) { QgsFields::Field* n = d; ++d; return n; }
inline iterator& operator--() { d--; return *this; }
inline iterator operator--( int ) { QgsFields::Field* n = d; d--; return n; }
inline iterator& operator+=( difference_type j ) { d += j; return *this; }
inline iterator& operator-=( difference_type j ) { d -= j; return *this; }
inline iterator operator+( difference_type j ) const { return iterator( d + j ); }
inline iterator operator-( difference_type j ) const { return iterator( d -j ); }
inline int operator-( iterator j ) const { return int( d - j.d ); }
};
friend class iterator;
class const_iterator
{
public:
const QgsFields::Field* d;
typedef std::random_access_iterator_tag iterator_category;
typedef qptrdiff difference_type;
inline const_iterator()
: d( nullptr ) {}
inline const_iterator( const QgsFields::Field* f )
: d( f ) {}
inline const_iterator( const const_iterator &o )
: d( o.d ) {}
inline explicit const_iterator( const iterator &o )
: d( o.d ) {}
inline const QgsField& operator*() const { return d->field; }
inline const QgsField* operator->() const { return &d->field; }
inline const QgsField& operator[]( difference_type j ) const noexcept { return d[j].field; }
inline bool operator==( const const_iterator &o ) const noexcept { return d == o.d; }
inline bool operator!=( const const_iterator &o ) const noexcept { return d != o.d; }
inline bool operator<( const const_iterator& other ) const noexcept { return d < other.d; }
inline bool operator<=( const const_iterator& other ) const noexcept { return d <= other.d; }
inline bool operator>( const const_iterator& other ) const noexcept { return d > other.d; }
inline bool operator>=( const const_iterator& other ) const noexcept { return d >= other.d; }
inline const_iterator& operator++() { ++d; return *this; }
inline const_iterator operator++( int ) { const QgsFields::Field* n = d; ++d; return n; }
inline const_iterator& operator--() { d--; return *this; }
inline const_iterator operator--( int ) { const QgsFields::Field* n = d; --d; return n; }
inline const_iterator& operator+=( difference_type j ) { d += j; return *this; }
inline const_iterator& operator-=( difference_type j ) { d -= j; return *this; }
inline const_iterator operator+( difference_type j ) const { return const_iterator( d + j ); }
inline const_iterator operator-( difference_type j ) const { return const_iterator( d -j ); }
inline int operator-( const_iterator j ) const { return int( d - j.d ); }
};
friend class const_iterator;
///@endcond
/**
* Returns a const STL-style iterator pointing to the first item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator constBegin() const noexcept;
/**
* Returns a const STL-style iterator pointing to the imaginary item after the last item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator constEnd() const noexcept;
/**
* Returns a const STL-style iterator pointing to the first item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator begin() const noexcept;
/**
* Returns a const STL-style iterator pointing to the imaginary item after the last item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
const_iterator end() const noexcept;
/**
* Returns an STL-style iterator pointing to the first item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
iterator begin();
/**
* Returns an STL-style iterator pointing to the imaginary item after the last item in the list.
*
* @note added in 2.16
* @note not available in Python bindings
*/
iterator end();
private:
QSharedDataPointer<QgsFieldsPrivate> d;
};
Q_DECLARE_METATYPE( QgsFields )
/** Writes the fields to stream out. QGIS version compatibility is not guaranteed. */
CORE_EXPORT QDataStream& operator<<( QDataStream& out, const QgsFields& fields );
/** Reads fields from stream in into fields. QGIS version compatibility is not guaranteed. */
CORE_EXPORT QDataStream& operator>>( QDataStream& in, QgsFields& fields );
#endif // QGSFIELDS_H

67
src/core/qgsfields_p.h Normal file
View File

@ -0,0 +1,67 @@
/***************************************************************************
qgsfields_p - %{Cpp:License:ClassName}
---------------------
begin : 22.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSFIELDS_P_H
#define QGSFIELDS_P_H
/// @cond PRIVATE
//
// W A R N I N G
// -------------
//
// This file is not part of the QGIS API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
#include <QSharedData>
#include "qgsfields.h"
/***************************************************************************
* This class is considered CRITICAL and any change MUST be accompanied with
* full unit tests in testqgsfields.cpp.
* See details in QEP #17
****************************************************************************/
class CORE_EXPORT QgsFieldsPrivate : public QSharedData
{
public:
QgsFieldsPrivate()
{
}
QgsFieldsPrivate( const QgsFieldsPrivate& other )
: QSharedData( other )
, fields( other.fields )
, nameToIndex( other.nameToIndex )
{
}
~QgsFieldsPrivate() {}
//! internal storage of the container
QVector<QgsFields::Field> fields;
//! map for quick resolution of name to index
QHash<QString, int> nameToIndex;
};
/// @endcond
#endif // QGSFIELDS_P_H

View File

@ -17,7 +17,7 @@
#include <expat.h>
#include "qgis.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsrectangle.h"
#include "qgswkbptr.h"
#include "qgsfeature.h"

View File

@ -18,7 +18,7 @@
#include <expat.h>
#include "qgis.h"
#include "qgserror.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include <list>
#include <set>
#include <stack>

View File

@ -19,7 +19,7 @@
#include "qgsfeature.h"
#include "qgscoordinatereferencesystem.h"
#include "qgscoordinatetransform.h"
#include "qgsfield.h"
#include "qgsfields.h"
class QTextCodec;
class QgsVectorLayer;

View File

@ -17,7 +17,7 @@
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgsgeometry.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include <QTextCodec>
#include <QUuid>

View File

@ -31,7 +31,7 @@
#include <QRectF>
#include "qgsfeature.h"
#include "qgsgeometry.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgspoint.h"
#include "qgsmapunitscale.h"
#include "qgsstringutils.h"

View File

@ -279,7 +279,7 @@ QgsAttributeList QgsRelation::referencedFields() const
Q_FOREACH ( const FieldPair& pair, mFieldPairs )
{
attrs << mReferencedLayer->fieldNameIndex( pair.second );
attrs << mReferencedLayer->fields().lookupField( pair.second );
}
return attrs;
}
@ -290,7 +290,7 @@ QgsAttributeList QgsRelation::referencingFields() const
Q_FOREACH ( const FieldPair& pair, mFieldPairs )
{
attrs << mReferencingLayer->fieldNameIndex( pair.first );
attrs << mReferencingLayer->fields().lookupField( pair.first );
}
return attrs;
@ -337,13 +337,13 @@ void QgsRelation::updateRelationStatus()
Q_FOREACH ( const FieldPair& fieldPair, mFieldPairs )
{
if ( -1 == mReferencingLayer->fieldNameIndex( fieldPair.first ) )
if ( -1 == mReferencingLayer->fields().lookupField( fieldPair.first ) )
{
QgsDebugMsg( QString( "Invalid relation: field %1 does not exist in referencing layer %2" ).arg( fieldPair.first, mReferencingLayer->name() ) );
mValid = false;
break;
}
else if ( -1 == mReferencedLayer->fieldNameIndex( fieldPair.second ) )
else if ( -1 == mReferencedLayer->fields().lookupField( fieldPair.second ) )
{
QgsDebugMsg( QString( "Invalid relation: field %1 does not exist in referencedg layer %2" ).arg( fieldPair.second, mReferencedLayer->name() ) );
mValid = false;

View File

@ -20,7 +20,7 @@
#include <QDomNode>
#include <QPair>
#include "qgsfield.h"
#include "qgsfields.h"
class QgsVectorLayer;
class QgsFeatureIterator;

View File

@ -111,7 +111,7 @@ QList<QgsRelation> QgsRelationManager::referencingRelations( const QgsVectorLaye
bool containsField = false;
Q_FOREACH ( const QgsRelation::FieldPair& fp, rel.fieldPairs() )
{
if ( fieldIdx == layer->fieldNameIndex( fp.referencingField() ) )
if ( fieldIdx == layer->fields().lookupField( fp.referencingField() ) )
{
containsField = true;
break;

View File

@ -17,7 +17,7 @@
#define QGSSQLEXPRESSIONCOMPILER_H
#include "qgsexpression.h"
#include "qgsfield.h"
#include "qgsfields.h"
/** \ingroup core
* \class QgsSqlExpressionCompiler

View File

@ -26,7 +26,7 @@
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgsfeaturerequest.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include "qgsgeometrycollection.h"
#include "qgsgeometryfactory.h"
@ -259,7 +259,7 @@ QString QgsVectorDataProvider::capabilitiesString() const
int QgsVectorDataProvider::fieldNameIndex( const QString& fieldName ) const
{
return fields().fieldNameIndex( fieldName );
return fields().lookupField( fieldName );
}
QMap<QString, int> QgsVectorDataProvider::fieldNameMap() const

View File

@ -17,7 +17,7 @@
***************************************************************************/
#include "qgsapplication.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgsgeometry.h"
@ -2866,10 +2866,10 @@ void QgsVectorFileWriter::addRendererAttributes( QgsVectorLayer* vl, QgsAttribut
QList<QString> rendererAttributes = renderer->usedAttributes();
for ( int i = 0; i < rendererAttributes.size(); ++i )
{
int index = vl->fieldNameIndex( rendererAttributes.at( i ) );
int index = vl->fields().lookupField( rendererAttributes.at( i ) );
if ( index != -1 )
{
attList.push_back( vl->fieldNameIndex( rendererAttributes.at( i ) ) );
attList.push_back( vl->fields().lookupField( rendererAttributes.at( i ) ) );
}
}
}

View File

@ -19,7 +19,7 @@
#ifndef QGSVECTORFILEWRITER_H
#define QGSVECTORFILEWRITER_H
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgssymbol.h"
#include <ogr_api.h>

View File

@ -47,7 +47,7 @@
#include "qgsexpressionfieldbuffer.h"
#include "qgsfeature.h"
#include "qgsfeaturerequest.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometrycache.h"
#include "qgsgeometry.h"
#include "qgslogger.h"
@ -726,7 +726,7 @@ bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
QgsFeatureRequest request;
if ( !mRenderer->filterNeedsGeometry() )
request.setFlags( QgsFeatureRequest::NoGeometry );
request.setSubsetOfAttributes( mRenderer->usedAttributes(), mUpdatedFields );
request.setSubsetOfAttributes( mRenderer->usedAttributes(), mFields );
QgsFeatureIterator fit = getFeatures( request );
QgsVectorLayerInterruptionCheckerDuringCountSymbolFeatures interruptionCheck( &progressDialog );
if ( showProgress )
@ -1646,7 +1646,7 @@ bool QgsVectorLayer::writeXml( QDomNode & layer_node,
//default expressions
QDomElement defaultsElem = document.createElement( "defaults" );
Q_FOREACH ( const QgsField& field, mUpdatedFields )
Q_FOREACH ( const QgsField& field, mFields )
{
QDomElement defaultElem = document.createElement( "default" );
defaultElem.setAttribute( "field", field.name() );
@ -1694,7 +1694,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
QString displayField = node.namedItem( "displayfield" ).toElement().text();
// Try to migrate pre QGIS 3.0 display field property
if ( mUpdatedFields.fieldNameIndex( displayField ) < 0 )
if ( mFields.lookupField( displayField ) < 0 )
{
// if it's not a field, it's a maptip
if ( mMapTipTemplate.isEmpty() )
@ -1904,11 +1904,11 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
//attribute aliases
QDomElement aliasElem = doc.createElement( "aliases" );
Q_FOREACH ( const QgsField& field, mUpdatedFields )
Q_FOREACH ( const QgsField& field, mFields )
{
QDomElement aliasEntryElem = doc.createElement( "alias" );
aliasEntryElem.setAttribute( "field", field.name() );
aliasEntryElem.setAttribute( "index", mUpdatedFields.indexFromName( field.name() ) );
aliasEntryElem.setAttribute( "index", mFields.indexFromName( field.name() ) );
aliasEntryElem.setAttribute( "name", field.alias() );
aliasElem.appendChild( aliasEntryElem );
}
@ -2113,12 +2113,12 @@ void QgsVectorLayer::remAttributeAlias( int attIndex )
return;
QString name = fields().at( attIndex ).name();
mUpdatedFields.at( attIndex ).setAlias( QString() );
mFields.at( attIndex ).setAlias( QString() );
if ( mAttributeAliasMap.contains( name ) )
{
mAttributeAliasMap.remove( name );
updateFields();
mEditFormConfig.setFields( mUpdatedFields );
mEditFormConfig.setFields( mFields );
emit layerModified();
}
}
@ -2139,8 +2139,8 @@ void QgsVectorLayer::addAttributeAlias( int attIndex, const QString& aliasString
QString name = fields().at( attIndex ).name();
mAttributeAliasMap.insert( name, aliasString );
mUpdatedFields[ attIndex ].setAlias( aliasString );
mEditFormConfig.setFields( mUpdatedFields );
mFields[ attIndex ].setAlias( aliasString );
mEditFormConfig.setFields( mFields );
emit layerModified(); // TODO[MD]: should have a different signal?
}
@ -2154,8 +2154,8 @@ QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
QString QgsVectorLayer::attributeDisplayName( int attributeIndex ) const
{
if ( attributeIndex >= 0 && attributeIndex < mUpdatedFields.count() )
return mUpdatedFields.at( attributeIndex ).displayName();
if ( attributeIndex >= 0 && attributeIndex < mFields.count() )
return mFields.at( attributeIndex ).displayName();
else
return QString();
}
@ -2176,7 +2176,7 @@ bool QgsVectorLayer::deleteAttribute( int index )
if ( index < 0 || index >= fields().count() )
return false;
if ( mUpdatedFields.fieldOrigin( index ) == QgsFields::OriginExpression )
if ( mFields.fieldOrigin( index ) == QgsFields::OriginExpression )
{
removeExpressionField( index );
return true;
@ -2247,10 +2247,10 @@ QgsAttributeList QgsVectorLayer::pkAttributeList() const
QgsAttributeList pkAttributesList;
QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
for ( int i = 0; i < mUpdatedFields.count(); ++i )
for ( int i = 0; i < mFields.count(); ++i )
{
if ( mUpdatedFields.fieldOrigin( i ) == QgsFields::OriginProvider &&
providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
if ( mFields.fieldOrigin( i ) == QgsFields::OriginProvider &&
providerIndexes.contains( mFields.fieldOriginIndex( i ) ) )
pkAttributesList << i;
}
@ -2627,7 +2627,7 @@ void QgsVectorLayer::setDisplayExpression( const QString& displayExpression )
QString QgsVectorLayer::displayExpression() const
{
if ( !mDisplayExpression.isEmpty() || mUpdatedFields.isEmpty() )
if ( !mDisplayExpression.isEmpty() || mFields.isEmpty() )
{
return mDisplayExpression;
}
@ -2635,7 +2635,7 @@ QString QgsVectorLayer::displayExpression() const
{
QString idxName;
Q_FOREACH ( const QgsField& field, mUpdatedFields )
Q_FOREACH ( const QgsField& field, mFields )
{
QString fldName = field.name();
@ -2666,7 +2666,7 @@ QString QgsVectorLayer::displayExpression() const
}
else
{
return QgsExpression::quotedColumnRef( mUpdatedFields.at( 0 ).name() );
return QgsExpression::quotedColumnRef( mFields.at( 0 ).name() );
}
}
}
@ -2774,11 +2774,6 @@ void QgsVectorLayer::destroyEditCommand()
}
}
int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
{
return fields().fieldNameIndex( fieldName );
}
bool QgsVectorLayer::addJoin( const QgsVectorJoinInfo& joinInfo )
{
return mJoinBuffer && mJoinBuffer->addJoin( joinInfo );
@ -2812,7 +2807,7 @@ int QgsVectorLayer::addExpressionField( const QString& exp, const QgsField& fld
emit beforeAddingExpressionField( fld.name() );
mExpressionFieldBuffer->addExpression( exp, fld );
updateFields();
int idx = mUpdatedFields.indexFromName( fld.name() );
int idx = mFields.indexFromName( fld.name() );
emit attributeAdded( idx );
return idx;
}
@ -2820,7 +2815,7 @@ int QgsVectorLayer::addExpressionField( const QString& exp, const QgsField& fld
void QgsVectorLayer::removeExpressionField( int index )
{
emit beforeRemovingExpressionField( index );
int oi = mUpdatedFields.fieldOriginIndex( index );
int oi = mFields.fieldOriginIndex( index );
mExpressionFieldBuffer->removeExpression( oi );
updateFields();
emit attributeDeleted( index );
@ -2828,7 +2823,7 @@ void QgsVectorLayer::removeExpressionField( int index )
QString QgsVectorLayer::expressionField( int index ) const
{
int oi = mUpdatedFields.fieldOriginIndex( index );
int oi = mFields.fieldOriginIndex( index );
if ( oi < 0 || oi >= mExpressionFieldBuffer->expressions().size() )
return QString();
@ -2837,7 +2832,7 @@ QString QgsVectorLayer::expressionField( int index ) const
void QgsVectorLayer::updateExpressionField( int index, const QString& exp )
{
int oi = mUpdatedFields.fieldOriginIndex( index );
int oi = mFields.fieldOriginIndex( index );
mExpressionFieldBuffer->updateExpression( oi, exp );
}
@ -2846,44 +2841,44 @@ void QgsVectorLayer::updateFields()
if ( !mDataProvider )
return;
QgsFields oldFields = mUpdatedFields;
QgsFields oldFields = mFields;
mUpdatedFields = mDataProvider->fields();
mFields = mDataProvider->fields();
// added / removed fields
if ( mEditBuffer )
mEditBuffer->updateFields( mUpdatedFields );
mEditBuffer->updateFields( mFields );
// joined fields
if ( mJoinBuffer && mJoinBuffer->containsJoins() )
mJoinBuffer->updateFields( mUpdatedFields );
mJoinBuffer->updateFields( mFields );
if ( mExpressionFieldBuffer )
mExpressionFieldBuffer->updateFields( mUpdatedFields );
mExpressionFieldBuffer->updateFields( mFields );
// set aliases and default values
QMap< QString, QString >::const_iterator aliasIt = mAttributeAliasMap.constBegin();
for ( ; aliasIt != mAttributeAliasMap.constEnd(); ++aliasIt )
{
int index = mUpdatedFields.fieldNameIndex( aliasIt.key() );
int index = mFields.lookupField( aliasIt.key() );
if ( index < 0 )
continue;
mUpdatedFields[ index ].setAlias( aliasIt.value() );
mFields[ index ].setAlias( aliasIt.value() );
}
QMap< QString, QString >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
for ( ; defaultIt != mDefaultExpressionMap.constEnd(); ++defaultIt )
{
int index = mUpdatedFields.fieldNameIndex( defaultIt.key() );
int index = mFields.lookupField( defaultIt.key() );
if ( index < 0 )
continue;
mUpdatedFields[ index ].setDefaultValueExpression( defaultIt.value() );
mFields[ index ].setDefaultValueExpression( defaultIt.value() );
}
if ( oldFields != mUpdatedFields )
if ( oldFields != mFields )
{
emit updatedFields();
mEditFormConfig.setFields( mUpdatedFields );
mEditFormConfig.setFields( mFields );
}
}
@ -2898,10 +2893,10 @@ void QgsVectorLayer::createJoinCaches() const
QVariant QgsVectorLayer::defaultValue( int index, const QgsFeature& feature, QgsExpressionContext* context ) const
{
if ( index < 0 || index >= mUpdatedFields.count() )
if ( index < 0 || index >= mFields.count() )
return QVariant();
QString expression = mUpdatedFields.at( index ).defaultValueExpression();
QString expression = mFields.at( index ).defaultValueExpression();
if ( expression.isEmpty() )
return mDataProvider->defaultValue( index );
@ -2947,26 +2942,26 @@ QVariant QgsVectorLayer::defaultValue( int index, const QgsFeature& feature, Qgs
void QgsVectorLayer::setDefaultValueExpression( int index, const QString& expression )
{
if ( index < 0 || index >= mUpdatedFields.count() )
if ( index < 0 || index >= mFields.count() )
return;
if ( expression.isEmpty() )
{
mDefaultExpressionMap.remove( mUpdatedFields.at( index ).name() );
mDefaultExpressionMap.remove( mFields.at( index ).name() );
}
else
{
mDefaultExpressionMap.insert( mUpdatedFields.at( index ).name(), expression );
mDefaultExpressionMap.insert( mFields.at( index ).name(), expression );
}
updateFields();
}
QString QgsVectorLayer::defaultValueExpression( int index ) const
{
if ( index < 0 || index >= mUpdatedFields.count() )
if ( index < 0 || index >= mFields.count() )
return QString();
else
return mUpdatedFields.at( index ).defaultValueExpression();
return mFields.at( index ).defaultValueExpression();
}
void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit ) const
@ -2977,7 +2972,7 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
return;
}
QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
QgsFields::FieldOrigin origin = mFields.fieldOrigin( index );
switch ( origin )
{
case QgsFields::OriginUnknown:
@ -3082,7 +3077,7 @@ QVariant QgsVectorLayer::minimumValue( int index ) const
return QVariant();
}
QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
QgsFields::FieldOrigin origin = mFields.fieldOrigin( index );
switch ( origin )
{
@ -3170,7 +3165,7 @@ QVariant QgsVectorLayer::maximumValue( int index ) const
return QVariant();
}
QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
QgsFields::FieldOrigin origin = mFields.fieldOrigin( index );
switch ( origin )
{
case QgsFields::OriginUnknown:
@ -3260,12 +3255,12 @@ QVariant QgsVectorLayer::aggregate( QgsAggregateCalculator::Aggregate aggregate,
}
// test if we are calculating based on a field
int attrIndex = mUpdatedFields.fieldNameIndex( fieldOrExpression );
int attrIndex = mFields.lookupField( fieldOrExpression );
if ( attrIndex >= 0 )
{
// aggregate is based on a field - if it's a provider field, we could possibly hand over the calculation
// to the provider itself
QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( attrIndex );
QgsFields::FieldOrigin origin = mFields.fieldOrigin( attrIndex );
if ( origin == QgsFields::OriginProvider )
{
bool providerOk = false;
@ -3293,7 +3288,7 @@ QList<QVariant> QgsVectorLayer::getValues( const QString &fieldOrExpression, boo
QScopedPointer<QgsExpression> expression;
QgsExpressionContext context;
int attrNum = fieldNameIndex( fieldOrExpression );
int attrNum = mFields.lookupField( fieldOrExpression );
if ( attrNum == -1 )
{
@ -3486,7 +3481,7 @@ void QgsVectorLayer::readSldLabeling( const QDomNode& node )
setCustomProperty( "labeling/fieldName", labelAttribute );
setCustomProperty( "labeling/isExpression", false );
int fieldIndex = fieldNameIndex( labelAttribute );
int fieldIndex = mFields.lookupField( labelAttribute );
if ( fieldIndex == -1 )
{
// label attribute is not in columns, check if it is an expression

View File

@ -31,7 +31,7 @@
#include "qgsfeature.h"
#include "qgsfeaturerequest.h"
#include "qgseditorwidgetconfig.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgssnapper.h"
#include "qgsvectorsimplifymethod.h"
#include "qgseditformconfig.h"
@ -1128,7 +1128,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*
* @return A list of fields
*/
inline QgsFields fields() const { return mUpdatedFields; }
inline QgsFields fields() const { return mFields; }
/**
* Returns the list of fields of this layer.
@ -1137,19 +1137,19 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*
* @return A list of fields
*/
inline QgsFields pendingFields() const { return mUpdatedFields; }
inline QgsFields pendingFields() const { return mFields; }
/**
* Returns list of attribute indexes. i.e. a list from 0 ... fieldCount()
* Alias for {@link attributeList()}
*/
inline QgsAttributeList pendingAllAttributesList() const { return mUpdatedFields.allAttributesList(); }
inline QgsAttributeList pendingAllAttributesList() const { return mFields.allAttributesList(); }
/**
* Returns list of attribute indexes. i.e. a list from 0 ... fieldCount()
* Alias for {@link attributeList()}
*/
inline QgsAttributeList attributeList() const { return mUpdatedFields.allAttributesList(); }
inline QgsAttributeList attributeList() const { return mFields.allAttributesList(); }
/**
* Returns list of attributes making up the primary key
@ -1331,9 +1331,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
/** Destroy active command and reverts all changes in it */
void destroyEditCommand();
/** Returns the index of a field name or -1 if the field does not exist */
int fieldNameIndex( const QString& fieldName ) const;
/** Editing vertex markers */
enum VertexMarkerType
{
@ -1917,7 +1914,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
QgsFeatureIds mSelectedFeatureIds;
/** Field map to commit */
QgsFields mUpdatedFields;
QgsFields mFields;
/** Map that stores the aliases for attributes. Key is the attribute name and value the alias for that attribute*/
QgsStringMap mAttributeAliasMap;

View File

@ -120,7 +120,7 @@ bool QgsVectorLayerEditBuffer::addFeature( QgsFeature& f )
{
return false;
}
if ( L->mUpdatedFields.count() != f.attributes().count() )
if ( L->mFields.count() != f.attributes().count() )
return false;
// TODO: check correct geometry type

View File

@ -19,7 +19,7 @@
#include <QSet>
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
class QgsVectorLayer;

View File

@ -105,12 +105,9 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
{
//ensure that all fields required for filter expressions are prepared
Q_FOREACH ( const QString& field, mRequest.filterExpression()->referencedColumns() )
{
int attrIdx = mSource->mFields.fieldNameIndex( field );
if ( !mRequest.subsetOfAttributes().contains( attrIdx ) )
mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() << attrIdx );
}
QSet<int> attributeIndexes = mRequest.filterExpression()->referencedAttributeIndexes( mSource->mFields );
attributeIndexes += mRequest.subsetOfAttributes().toSet();
mRequest.setSubsetOfAttributes( attributeIndexes.toList() );
}
}
@ -129,7 +126,8 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
int nPendingFields = mSource->mFields.count();
Q_FOREACH ( int attrIndex, subset )
{
if ( attrIndex < 0 || attrIndex >= nPendingFields ) continue;
if ( attrIndex < 0 || attrIndex >= nPendingFields )
continue;
if ( mSource->mFields.fieldOrigin( attrIndex ) == QgsFields::OriginProvider )
providerSubset << mSource->mFields.fieldOriginIndex( attrIndex );
}
@ -143,7 +141,7 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
{
Q_FOREACH ( const QString& attr, mProviderRequest.orderBy().usedAttributes() )
{
providerSubset << mSource->mFields.fieldNameIndex( attr );
providerSubset << mSource->mFields.lookupField( attr );
}
}
@ -154,7 +152,7 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeat
{
Q_FOREACH ( const QString& field, mProviderRequest.filterExpression()->referencedColumns() )
{
int idx = source->mFields.fieldNameIndex( field );
int idx = source->mFields.lookupField( field );
// If there are fields in the expression which are not of origin provider, the provider will not be able to filter based on them.
// In this case we disable the expression filter.
@ -538,7 +536,7 @@ void QgsVectorLayerFeatureIterator::prepareExpression( int fieldIdx )
Q_FOREACH ( const QString& col, exp->referencedColumns() )
{
int dependantFieldIdx = mSource->mFields.fieldNameIndex( col );
int dependantFieldIdx = mSource->mFields.lookupField( col );
if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
{
mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() << dependantFieldIdx );

View File

@ -16,7 +16,7 @@
#define QGSVECTORLAYERFEATUREITERATOR_H
#include "qgsfeatureiterator.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include <QSet>

View File

@ -16,7 +16,7 @@
* *
***************************************************************************/
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgsgeometry.h"

View File

@ -192,7 +192,7 @@ QVector<int> QgsVectorLayerJoinBuffer::joinSubsetIndices( QgsVectorLayer* joinLa
for ( int i = 0; i < joinFieldsSubset.count(); ++i )
{
QString joinedFieldName = joinFieldsSubset.at( i );
int index = fields.fieldNameIndex( joinedFieldName );
int index = fields.lookupField( joinedFieldName );
if ( index != -1 )
{
subsetIndices.append( index );

View File

@ -154,7 +154,7 @@ bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext& context, QStr
else
{
// If we aren't an expression, we check to see if we can find the column.
if ( mFields.fieldNameIndex( lyr.fieldName ) == -1 )
if ( mFields.lookupField( lyr.fieldName ) == -1 )
{
return false;
}
@ -218,7 +218,7 @@ bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext& context, QStr
lyr.rasterCompressFactor = context.rasterScaleFactor();
// save the pal layer to our layer context (with some additional info)
lyr.fieldIndex = mFields.fieldNameIndex( lyr.fieldName );
lyr.fieldIndex = mFields.lookupField( lyr.fieldName );
lyr.xform = &mapSettings.mapToPixel();
lyr.ct = QgsCoordinateTransform();

View File

@ -34,7 +34,7 @@ class QgsSingleSymbolRenderer;
typedef QList<int> QgsAttributeList;
#include "qgis.h"
#include "qgsfield.h" // QgsFields
#include "qgsfields.h" // QgsFields
#include "qgsfeature.h" // QgsFeatureIds
#include "qgsfeatureiterator.h"
#include "qgsvectorsimplifymethod.h"

View File

@ -22,7 +22,7 @@
#include <QSet>
#include <QList>
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeature.h"
class QgsGeometry;

View File

@ -17,8 +17,8 @@ email : hugo dot mercier at oslandia dot com
#ifndef QGSVIRTUALLAYERDEFINITION_H
#define QGSVIRTUALLAYERDEFINITION_H
#include <qgsfield.h>
#include <qgis.h>
#include "qgsfields.h"
#include "qgis.h"
/** \ingroup core
* Class to manipulate the definition of a virtual layer
@ -143,7 +143,7 @@ class CORE_EXPORT QgsVirtualLayerDefinition
void setGeometrySrid( long srid ) { mGeometrySrid = srid; }
//! Get field definitions
const QgsFields& fields() const { return mFields; }
QgsFields fields() const { return mFields; }
//! Set field definitions
void setFields( const QgsFields& fields ) { mFields = fields; }

View File

@ -39,7 +39,7 @@ QgsVirtualLayerDefinition QgsVirtualLayerDefinitionUtils::fromJoinedLayer( QgsVe
{
// find an uid name
QString uid = "uid";
while ( fields.fieldNameIndex( uid ) != -1 )
while ( fields.lookupField( uid ) != -1 )
uid += "_"; // add "_" each time this name already exists
// add a column

View File

@ -31,7 +31,7 @@
#include "qgscolorrampshader.h"
#include "qgsdataprovider.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsraster.h"
#include "qgsrasterinterface.h"
#include "qgsrasterpyramid.h"

View File

@ -395,7 +395,7 @@ void QgsCategorizedSymbolRenderer::startRender( QgsRenderContext& context, const
rebuildHash();
// find out classification attribute index from name
mAttrNum = fields.fieldNameIndex( mAttrName );
mAttrNum = fields.lookupField( mAttrName );
if ( mAttrNum == -1 )
{
mExpression.reset( new QgsExpression( mAttrName ) );
@ -494,7 +494,7 @@ void QgsCategorizedSymbolRenderer::toSld( QDomDocument &doc, QDomElement &elemen
QString QgsCategorizedSymbolRenderer::filter( const QgsFields& fields )
{
int attrNum = fields.fieldNameIndex( mAttrName );
int attrNum = fields.lookupField( mAttrName );
bool isExpression = ( attrNum == -1 );
bool hasDefault = false;

View File

@ -383,7 +383,7 @@ void QgsGraduatedSymbolRenderer::startRender( QgsRenderContext& context, const Q
mCounting = context.rendererScale() == 0.0;
// find out classification attribute index from name
mAttrNum = fields.fieldNameIndex( mAttrName );
mAttrNum = fields.lookupField( mAttrName );
if ( mAttrNum == -1 )
{
@ -804,7 +804,7 @@ QgsGraduatedSymbolRenderer* QgsGraduatedSymbolRenderer::createRenderer(
return r;
}
void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses )
void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer* vlayer, Mode mode, int nclasses )
{
if ( mAttrName.isEmpty() )
return;
@ -822,7 +822,7 @@ void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mod
double minimum;
double maximum;
int attrNum = vlayer->fieldNameIndex( mAttrName );
int attrNum = vlayer->fields().lookupField( mAttrName );
bool ok;
if ( attrNum == -1 )

View File

@ -73,7 +73,7 @@ void QgsHeatmapRenderer::startRender( QgsRenderContext& context, const QgsFields
}
// find out classification attribute index from name
mWeightAttrNum = fields.fieldNameIndex( mWeightExpressionString );
mWeightAttrNum = fields.lookupField( mWeightExpressionString );
if ( mWeightAttrNum == -1 )
{
mWeightExpression.reset( new QgsExpression( mWeightExpressionString ) );

View File

@ -20,7 +20,7 @@
#include "qgsrectangle.h"
#include "qgsrendercontext.h"
#include "qgssymbol.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeaturerequest.h"
#include <QList>

View File

@ -16,7 +16,7 @@
#ifndef QGSRULEBASEDRENDERERV2_H
#define QGSRULEBASEDRENDERERV2_H
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsfeature.h"
#include "qgis.h"

View File

@ -22,7 +22,7 @@
#include "qgsmapunitscale.h"
#include "qgspointv2.h"
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgsfields.h"
class QColor;
class QImage;

View File

@ -179,7 +179,7 @@ QVariant QgsSymbolLayer::evaluateDataDefinedProperty( const QString& property, c
}
else if ( context.feature() && !dd->field().isEmpty() && !mFields.isEmpty() )
{
int attributeIndex = mFields.fieldNameIndex( dd->field() );
int attributeIndex = mFields.lookupField( dd->field() );
if ( attributeIndex >= 0 )
{
if ( ok )

View File

@ -32,7 +32,7 @@
#include "qgssymbol.h"
#include "qgssymbollayerutils.h" // QgsStringMap
#include "qgsfield.h"
#include "qgsfields.h"
class QPainter;
class QSize;

View File

@ -213,8 +213,8 @@ void QgsVectorFieldSymbolLayer::startRender( QgsSymbolRenderContext& context )
QgsFields fields = context.fields();
if ( !fields.isEmpty() )
{
mXIndex = fields.fieldNameIndex( mXAttribute );
mYIndex = fields.fieldNameIndex( mYAttribute );
mXIndex = fields.lookupField( mXAttribute );
mYIndex = fields.lookupField( mYAttribute );
}
else
{

View File

@ -134,7 +134,7 @@ void QgsAttributeTableFilterModel::setAttributeTableConfig( const QgsAttributeTa
continue;
// The new value for the mapping (field index or -1 for action column)
int newValue = ( columnConfig.type == QgsAttributeTableConfig::Action ) ? -1 : layer()->fieldNameIndex( columnConfig.name );
int newValue = ( columnConfig.type == QgsAttributeTableConfig::Action ) ? -1 : layer()->fields().lookupField( columnConfig.name );
newColumnMapping << newValue;
}

View File

@ -23,7 +23,7 @@
#include "qgsexpression.h"
#include "qgsfeatureiterator.h"
#include "qgsconditionalstyle.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayeractionregistry.h"
@ -432,7 +432,7 @@ void QgsAttributeTableModel::fieldConditionalStyleChanged( const QString &fieldN
return;
}
int fieldIndex = mLayerCache->layer()->fieldNameIndex( fieldName );
int fieldIndex = mLayerCache->layer()->fields().lookupField( fieldName );
if ( fieldIndex == -1 )
return;
@ -788,7 +788,7 @@ void QgsAttributeTableModel::prefetchSortData( const QString& expressionString )
if ( mSortCacheExpression.isField() )
{
QString fieldName = static_cast<const QgsExpression::NodeColumnRef*>( mSortCacheExpression.rootNode() )->name();
mSortFieldIndex = mLayerCache->layer()->fieldNameIndex( fieldName );
mSortFieldIndex = mLayerCache->layer()->fields().lookupField( fieldName );
}
if ( mSortFieldIndex == -1 )
@ -797,7 +797,7 @@ void QgsAttributeTableModel::prefetchSortData( const QString& expressionString )
Q_FOREACH ( const QString& col, mSortCacheExpression.referencedColumns() )
{
mSortCacheAttributes.append( mLayerCache->layer()->fieldNameIndex( col ) );
mSortCacheAttributes.append( mLayerCache->layer()->fields().lookupField( col ) );
}
}
else

View File

@ -138,7 +138,7 @@ void QgsDualView::columnBoxInit()
Q_FOREACH ( const QgsField& field, fields )
{
int fieldIndex = mLayerCache->layer()->fieldNameIndex( field.name() );
int fieldIndex = mLayerCache->layer()->fields().lookupField( field.name() );
if ( fieldIndex == -1 )
continue;

View File

@ -36,7 +36,7 @@
#include "qgsexpressionselectiondialog.h"
#include "qgsfeaturelistmodel.h"
#include "qgsrubberband.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgseditorwidgetregistry.h"
@ -65,7 +65,7 @@ QgsOrganizeTableColumnsDialog::QgsOrganizeTableColumnsDialog( const QgsVectorLay
}
else
{
int idx = vl->fieldNameIndex( columnConfig.name );
int idx = vl->fields().lookupField( columnConfig.name );
item = new QListWidgetItem( vl->attributeDisplayName( idx ), mFieldsList );
switch ( vl->fields().fieldOrigin( idx ) )

View File

@ -31,7 +31,7 @@ class FromFactoriesPlugin: public QgsEditorWidgetAutoConfPlugin
const QMap<QString, QgsEditorWidgetFactory*> factories = QgsEditorWidgetRegistry::instance()->factories();
for ( QMap<QString, QgsEditorWidgetFactory*>::const_iterator i = factories.begin(); i != factories.end(); ++i )
{
const int index = vl->fieldNameIndex( fieldName );
const int index = vl->fields().lookupField( fieldName );
if ( index >= 0 )
{
const int score = i.value()->fieldScore( vl, index );
@ -109,4 +109,4 @@ void QgsEditorWidgetAutoConf::registerPlugin( QgsEditorWidgetAutoConfPlugin* plu
{
plugins.append( QSharedPointer<QgsEditorWidgetAutoConfPlugin>( plugin ) );
}
///@endcond
///@endcond

View File

@ -16,7 +16,7 @@
#include "qgseditorwidgetfactory.h"
#include "qgsdefaultsearchwidgetwrapper.h"
#include "qgssearchwidgetwrapper.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsvectordataprovider.h"
#include <QSettings>

View File

@ -244,7 +244,7 @@ void QgsEditorWidgetRegistry::readMapLayer( QgsMapLayer* mapLayer, const QDomEle
QString name = editTypeElement.attribute( "name" );
int idx = vectorLayer->fieldNameIndex( name );
int idx = vectorLayer->fields().lookupField( name );
if ( idx == -1 )
continue;

View File

@ -16,7 +16,7 @@
#include "qgseditorwidgetwrapper.h"
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include <QTableView>

View File

@ -16,7 +16,7 @@
#include "qgssearchwidgetwrapper.h"
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include <QWidget>

View File

@ -15,7 +15,7 @@
#include "qgscheckboxsearchwidgetwrapper.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgscheckboxwidgetfactory.h"
#include "qgsvectorlayer.h"

View File

@ -15,7 +15,7 @@
#include "qgsdatetimesearchwidgetwrapper.h"
#include "qgsfield.h"
#include "qgsfields.h"
#include "qgsdatetimeeditfactory.h"
#include "qgsvectorlayer.h"
#include "qgsdatetimeedit.h"

Some files were not shown because too many files have changed in this diff Show More