Skip to content
Permalink
Browse files

Merge pull request #3351 from nyalldawson/feature_geom

QgsFields cleanup
  • Loading branch information
nyalldawson committed Aug 4, 2016
2 parents 23909a1 + c40d6d3 commit 00a8fea13b622342710761dc34541365cf12b6e9
Showing with 298 additions and 307 deletions.
  1. +29 −0 doc/api_break.dox
  2. +0 −3 python/core/diagram/qgsdiagram.sip
  3. +1 −2 python/core/qgsfeature.sip
  4. +3 −3 python/core/qgsfield.sip
  5. +0 −8 python/core/symbology-ng/qgssymbollayerv2.sip
  6. +19 −4 python/core/symbology-ng/qgssymbolv2.sip
  7. +1 −1 src/analysis/vector/qgsoverlayanalyzer.cpp
  8. +1 −1 src/app/ogr/qgsvectorlayersaveasdialog.cpp
  9. +1 −1 src/app/qgisapp.cpp
  10. +2 −2 src/app/qgsdecorationgrid.cpp
  11. +1 −1 src/app/qgsdelattrdialog.cpp
  12. +4 −4 src/app/qgsdiagramproperties.cpp
  13. +1 −1 src/app/qgsfieldcalculator.cpp
  14. +1 −1 src/app/qgsfieldsproperties.cpp
  15. +7 −7 src/app/qgsidentifyresultsdialog.cpp
  16. +1 −1 src/app/qgslabelpropertydialog.cpp
  17. +1 −1 src/app/qgsmergeattributesdialog.cpp
  18. +2 −2 src/core/composer/qgscomposerattributetable.cpp
  19. +1 −1 src/core/composer/qgscomposerattributetablev2.cpp
  20. +0 −13 src/core/diagram/qgsdiagram.cpp
  21. +0 −3 src/core/diagram/qgsdiagram.h
  22. +4 −4 src/core/diagram/qgshistogramdiagram.cpp
  23. +4 −4 src/core/diagram/qgspiediagram.cpp
  24. +4 −4 src/core/diagram/qgstextdiagram.cpp
  25. +2 −2 src/core/qgsactionmanager.cpp
  26. +2 −2 src/core/qgsfeature.cpp
  27. +1 −2 src/core/qgsfeature.h
  28. +4 −4 src/core/qgsfield.cpp
  29. +5 −5 src/core/qgsfield.h
  30. +4 −4 src/core/qgsgml.cpp
  31. +6 −6 src/core/qgsjsonutils.cpp
  32. +5 −5 src/core/qgsvectorfilewriter.cpp
  33. +1 −1 src/core/qgsvectorlayer.cpp
  34. +2 −2 src/core/qgsvectorlayereditbuffer.cpp
  35. +1 −1 src/core/symbology-ng/qgs25drenderer.cpp
  36. +2 −2 src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
  37. +2 −2 src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
  38. +1 −1 src/core/symbology-ng/qgspointdisplacementrenderer.cpp
  39. +1 −1 src/core/symbology-ng/qgsrulebasedrendererv2.cpp
  40. +2 −2 src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
  41. +2 −34 src/core/symbology-ng/qgssymbollayerv2.cpp
  42. +0 −8 src/core/symbology-ng/qgssymbollayerv2.h
  43. +2 −2 src/core/symbology-ng/qgssymbollayerv2utils.cpp
  44. +6 −6 src/core/symbology-ng/qgssymbolv2.cpp
  45. +21 −5 src/core/symbology-ng/qgssymbolv2.h
  46. +4 −4 src/core/symbology-ng/qgsvectorfieldsymbollayer.cpp
  47. +1 −1 src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp
  48. +2 −2 src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp
  49. +1 −1 src/gui/qgsattributeform.cpp
  50. +1 −1 src/gui/qgsquerybuilder.cpp
  51. +1 −1 src/gui/qgssearchquerybuilder.cpp
  52. +1 −1 src/providers/db2/qgsdb2featureiterator.cpp
  53. +3 −3 src/providers/db2/qgsdb2provider.cpp
  54. +1 −1 src/providers/grass/qgsgrassprovider.cpp
  55. +6 −6 src/providers/grass/qgsgrassvectormaplayer.cpp
  56. +1 −1 src/providers/memory/qgsmemoryprovider.cpp
  57. +1 −1 src/providers/mssql/qgsmssqlfeatureiterator.cpp
  58. +4 −4 src/providers/mssql/qgsmssqlprovider.cpp
  59. +3 −3 src/providers/ogr/qgsogrprovider.cpp
  60. +5 −5 src/providers/oracle/qgsoraclefeatureiterator.cpp
  61. +25 −25 src/providers/oracle/qgsoracleprovider.cpp
  62. +1 −1 src/providers/oracle/qgsoracleprovider.h
  63. +1 −1 src/providers/postgres/qgspostgresfeatureiterator.cpp
  64. +19 −19 src/providers/postgres/qgspostgresprovider.cpp
  65. +1 −1 src/providers/postgres/qgspostgresprovider.h
  66. +10 −10 src/providers/spatialite/qgsspatialiteprovider.cpp
  67. +1 −1 src/providers/spatialite/qgsspatialiteprovider.h
  68. +3 −3 src/providers/wfs/qgswfsfeatureiterator.cpp
  69. +4 −4 src/providers/wfs/qgswfsprovider.cpp
  70. +1 −1 src/server/qgsserverprojectparser.cpp
  71. +1 −1 src/server/qgswfsprojectparser.cpp
  72. +11 −11 src/server/qgswfsserver.cpp
  73. +5 −5 src/server/qgswmsserver.cpp
  74. +9 −9 tests/src/core/testqgsfeature.cpp
  75. +2 −2 tests/src/gui/testqgsdualview.cpp
  76. +9 −9 tests/src/providers/grass/testqgsgrassprovider.cpp
@@ -233,6 +233,13 @@ instead.</li>
be returned in place of a null pointer.</li>
</ul>

\subsection qgis_api_break_3_0_QgsDiagram QgsDiagram

<ul>
<li>The deprecated getExpression( const QString& expression, const QgsFields* fields ) method has been removed.
Use the variant which accepts an expression context instead.</li>
</ul>

\subsection qgis_api_break_3_0_QgsDiagramLayerSettings QgsDiagramLayerSettings

<ul>
@@ -255,6 +262,7 @@ a feature has a geometry is now done using the new hasGeometry() method. Any cod
None will need to be modified, as the method will return an empty geometry if the feature has no geometry.</b></li>
<li>The temporary constGeometry() method has been removed. Use geometry() instead.</li>
<li>setFields( const QgsFields*, bool ) has been removed, use setFields( const QgsFields&, bool ) instead.</li>
<li>fields() no longer returns a pointer, but instead a QgsFields value.</li>
</ul>

\subsection qgis_api_break_3_0_QgsFeatureRendererV2 QgsFeatureRendererV2
@@ -263,6 +271,12 @@ None will need to be modified, as the method will return an empty geometry if th
<li>The method capabilities() returns QgsFeatureRendererV2::Capabilities flags instead of an integer. The two are binary compatible.
</ul>

\subsection qgis_api_break_3_0_QgsFields QgsFields

<ul>
<li>All const methods which return a field from QgsFields now return a QgsField value, not a reference.</li>
</ul>

\subsection qgis_api_break_3_0_QgsGeometry QgsGeometry

<ul>
@@ -523,6 +537,21 @@ be returned instead of a null pointer if no transformation is required.</li>
<li>The OutputUnit enum, including QgsSymbolV2::MM, QgsSymbolV2::MapUnit, QgsSymbolV2::Mixed, QgsSymbolV2::Pixel and QgsSymbolV2::Percentage has been moved to QgsUnitTypes
and renamed to RenderUnit. QgsSymbolV2::OutputUnitList was renamed to QgsUnitTypes::RenderUnitList. All methods which previously accepted QgsSymbolV2::OutputUnit
parameters or QgsSymbolV2::OutputUnitList parameters now take QgsUnitTypes::RenderUnit or QgsUnitTypes::RenderUnitList parameters respectively.</li>
<li>startRender() now accepts a QgsFields reference, not a pointer.</li>
</ul>

\subsection qgis_api_break_3_0_QgsSymbolLayerV2 QgsSymbolLayerV2

<ul>
<li>The deprecated prepareExpressions( const QgsFields* fields, double scale = -1.0 ) method has been removed. Use
the variant which takes QgsSymbolV2RenderContext instead.</li>
</ul>

\subsection qgis_api_break_3_0_QgsSymbolV2RenderContext QgsSymbolV2RenderContext

<ul>
<li>The constructor now accepts a QgsFields reference, not a pointer.</li>
<li>fields() now returns a QgsFields value, not a pointer.</li>
</ul>

\subsection qgis_api_break_3_0_QgsSymbolLayerV2Utils QgsSymbolLayerV2Utils
@@ -11,9 +11,6 @@ class QgsDiagram

void clearCache();

//! @deprecated use QgsExpressionContext variant instead
QgsExpression* getExpression( const QString& expression, const QgsFields* fields ) /Deprecated/;

/** Returns a prepared expression for the specified context.
* @param expression expression string
* @param context expression context
@@ -361,9 +361,8 @@ class QgsFeature

/** Returns the field map associated with the feature.
* @see setFields
* TODO: QGIS 3 - return value, not pointer
*/
const QgsFields* fields() const;
QgsFields fields() const;

/** Insert a value into attribute. Returns false if attribute name could not be converted to index.
* Field map must be associated using @link setFields @endlink before this method can be used.
@@ -262,7 +262,7 @@ class QgsFields
%End

//! Get field at particular index (must be in range 0..N-1)
const QgsField& at( int i ) const /Factory/;
QgsField at( int i ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
@@ -276,7 +276,7 @@ class QgsFields
%End

//! Get field at particular index (must be in range 0..N-1)
const QgsField& field( int fieldIdx ) const /Factory/;
QgsField field( int fieldIdx ) const /Factory/;
%MethodCode
if ( a0 < 0 || a0 >= sipCpp->count() )
{
@@ -290,7 +290,7 @@ class QgsFields
%End

//! Get field at particular index (must be in range 0..N-1)
const QgsField& field( const QString& name ) const /Factory/;
QgsField field( const QString& name ) const /Factory/;
%MethodCode
int fieldIdx = sipCpp->indexFromName(*a0);
if (fieldIdx == -1)
@@ -301,14 +301,6 @@ class QgsSymbolLayerV2
protected:
QgsSymbolLayerV2( QgsSymbolV2::SymbolType type, bool locked = false );

/** Prepares all data defined property expressions for evaluation. This should
* be called prior to evaluating data defined properties.
* @param fields associated layer fields
* @param scale map scale
* @deprecated use variant which takes QgsSymbolV2RenderContext instead
*/
virtual void prepareExpressions( const QgsFields* fields, double scale = -1.0 ) /Deprecated/;

/** Prepares all data defined property expressions for evaluation. This should
* be called prior to evaluating data defined properties.
* @param context symbol render context
@@ -110,7 +110,21 @@ class QgsSymbolV2
//! delete layer at specified index and set a new one
bool changeSymbolLayer( int index, QgsSymbolLayerV2 *layer /Transfer/ );

void startRender( QgsRenderContext& context, const QgsFields* fields = 0 );
/** Begins the rendering process for the symbol. This must be called before renderFeature(),
* and should be followed by a call to stopRender().
* @param context render context which symbol will be drawn using
* @param fields fields for features to be rendered (usually the associated
* vector layer's fields). Required for correct calculation of data defined
* overrides.
* @see stopRender()
*/
void startRender( QgsRenderContext& context, const QgsFields& fields = QgsFields() );

/** Ends the rendering process. This should be called after rendering all desired features.
* @param context render context, must match the context specified when startRender()
* was called.
* @see startRender()
*/
void stopRender( QgsRenderContext& context );

void setColor( const QColor& color );
@@ -205,7 +219,8 @@ class QgsSymbolV2
const QgsVectorLayer* layer() const;

/**
* Render a feature.
* Render a feature. Before calling this the startRender() method should be called to initialise
* the rendering process. After rendering all features stopRender() must be called.
*/
void renderFeature( const QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false, int currentVertexMarkerType = 0, int currentVertexMarkerSize = 0 );

@@ -292,7 +307,7 @@ class QgsSymbolV2RenderContext
* @param fields
* @param mapUnitScale
*/
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsUnitTypes::RenderUnit u, qreal alpha = 1.0, bool selected = false, int renderHints = 0, const QgsFeature* f = 0, const QgsFields* fields = 0, const QgsMapUnitScale& mapUnitScale = QgsMapUnitScale() );
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsUnitTypes::RenderUnit u, qreal alpha = 1.0, bool selected = false, int renderHints = 0, const QgsFeature* f = 0, const QgsFields& fields = QgsFields(), const QgsMapUnitScale& mapUnitScale = QgsMapUnitScale() );
~QgsSymbolV2RenderContext();

QgsRenderContext& renderContext();
@@ -333,7 +348,7 @@ class QgsSymbolV2RenderContext
//! to allow symbols with data-defined properties prepare the expressions
//! (other times fields() returns null)
//! @note added in 2.4
const QgsFields* fields() const;
QgsFields fields() const;

/** Part count of current geometry
* @note added in QGIS 2.16
@@ -192,7 +192,7 @@ void QgsOverlayAnalyzer::combineFieldLists( QgsFields& fieldListA, const QgsFiel

for ( int idx = 0; idx < fieldListB.count(); ++idx )
{
QgsField field = fieldListB[idx];
QgsField field = fieldListB.at( idx );
int count = 0;
while ( names.contains( field.name() ) )
{
@@ -271,7 +271,7 @@ void QgsVectorLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( int idx

for ( int i = 0; i < mLayer->fields().size(); ++i )
{
const QgsField &fld = mLayer->fields().at( i );
QgsField fld = mLayer->fields().at( i );
Qt::ItemFlags flags = mLayer->providerType() != "oracle" || !fld.typeName().contains( "SDO_GEOMETRY" ) ? Qt::ItemIsEnabled : Qt::NoItemFlags;
QTableWidgetItem *item;
item = new QTableWidgetItem( fld.name() );
@@ -6848,7 +6848,7 @@ void QgisApp::mergeAttributesOfSelectedFeatures()
continue;

QVariant val = merged.at( i );
const QgsField &fld( vl->fields().at( i ) );
QgsField fld( vl->fields().at( i ) );
bool isDefaultValue = vl->fields().fieldOrigin( i ) == QgsFields::OriginProvider &&
vl->dataProvider() &&
vl->dataProvider()->defaultValue( vl->fields().fieldOriginIndex( i ) ) == val;
@@ -232,7 +232,7 @@ void QgsDecorationGrid::render( QPainter * p )

QgsRenderContext context = QgsRenderContext::fromMapSettings( QgisApp::instance()->mapCanvas()->mapSettings() );
context.setPainter( p );
mLineSymbol->startRender( context, nullptr );
mLineSymbol->startRender( context );

for ( ; vIt != verticalLines.constEnd(); ++vIt )
{
@@ -310,7 +310,7 @@ void QgsDecorationGrid::render( QPainter * p )

QgsRenderContext context = QgsRenderContext::fromMapSettings( QgisApp::instance()->mapCanvas()->mapSettings() );
context.setPainter( p );
mMarkerSymbol->startRender( context, nullptr );
mMarkerSymbol->startRender( context );

QPointF intersectionPoint;
for ( ; vIt != verticalLines.constEnd(); ++vIt )
@@ -34,7 +34,7 @@ QgsDelAttrDialog::QgsDelAttrDialog( const QgsVectorLayer* vl )
const QgsFields& layerAttributes = vl->fields();
for ( int idx = 0; idx < layerAttributes.count(); ++idx )
{
QListWidgetItem* item = new QListWidgetItem( layerAttributes[idx].name(), listBox2 );
QListWidgetItem* item = new QListWidgetItem( layerAttributes.at( idx ).name(), listBox2 );
switch ( vl->fields().fieldOrigin( idx ) )
{
case QgsFields::OriginExpression:
@@ -184,14 +184,14 @@ QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer,
for ( int idx = 0; idx < layerFields.count(); ++idx )
{
QTreeWidgetItem *newItem = new QTreeWidgetItem( mAttributesTreeWidget );
QString name = QString( "\"%1\"" ).arg( layerFields[idx].name() );
QString name = QString( "\"%1\"" ).arg( layerFields.at( idx ).name() );
newItem->setText( 0, name );
newItem->setData( 0, Qt::UserRole, name );
newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled );

mDataDefinedXComboBox->addItem( layerFields[idx].name(), idx );
mDataDefinedYComboBox->addItem( layerFields[idx].name(), idx );
mDataDefinedVisibilityComboBox->addItem( layerFields[idx].name(), idx );
mDataDefinedXComboBox->addItem( layerFields.at( idx ).name(), idx );
mDataDefinedYComboBox->addItem( layerFields.at( idx ).name(), idx );
mDataDefinedVisibilityComboBox->addItem( layerFields.at( idx ).name(), idx );
}

const QgsDiagramRendererV2* dr = layer->diagramRenderer();
@@ -234,7 +234,7 @@ void QgsFieldCalculator::accept()

for ( int idx = 0; idx < fields.count(); ++idx )
{
if ( fields[idx].name() == mOutputFieldNameLineEdit->text() )
if ( fields.at( idx ).name() == mOutputFieldNameLineEdit->text() )
{
mAttributeId = idx;
break;
@@ -576,7 +576,7 @@ void QgsFieldsProperties::attributeAdded( int idx )
const QgsFields &fields = mLayer->fields();
int row = mFieldsList->rowCount();
mFieldsList->insertRow( row );
setRow( row, idx, fields[idx] );
setRow( row, idx, fields.at( idx ) );
mFieldsList->setCurrentCell( row, idx );

for ( int i = idx + 1; i < mIndexedWidgets.count(); i++ )
@@ -493,7 +493,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
featItem->addChild( attrItem );

attrItem->setData( 0, Qt::DisplayRole, vlayer->attributeDisplayName( i ) );
attrItem->setData( 0, Qt::UserRole, fields[i].name() );
attrItem->setData( 0, Qt::UserRole, fields.at( i ).name() );
attrItem->setData( 0, Qt::UserRole + 1, i );

attrItem->setData( 1, Qt::UserRole, value );
@@ -515,7 +515,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
attrItem->treeWidget()->setItemWidget( attrItem, 1, nullptr );
}

if ( fields[i].name() == vlayer->displayField() )
if ( fields.at( i ).name() == vlayer->displayField() )
{
featItem->setText( 0, attrItem->text( 0 ) );
featItem->setText( 1, attrItem->text( 1 ) );
@@ -560,11 +560,11 @@ void QgsIdentifyResultsDialog::addFeature( QgsVectorLayer *vlayer, const QgsFeat
tblResults->setItem( j, 1, item );

item = new QTableWidgetItem( QString::number( i ) );
if ( fields[i].name() == vlayer->displayField() )
if ( fields.at( i ).name() == vlayer->displayField() )
item->setData( Qt::DisplayRole, vlayer->attributeDisplayName( i ) + " *" );
else
item->setData( Qt::DisplayRole, vlayer->attributeDisplayName( i ) );
item->setData( Qt::UserRole, fields[i].name() );
item->setData( Qt::UserRole, fields.at( i ).name() );
item->setData( Qt::UserRole + 1, i );
tblResults->setItem( j, 2, item );

@@ -765,7 +765,7 @@ void QgsIdentifyResultsDialog::addFeature( QgsRasterLayer *layer,

QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << QString::number( i ) << attrs.at( i ).toString() );

attrItem->setData( 0, Qt::DisplayRole, fields[i].name() );
attrItem->setData( 0, Qt::DisplayRole, fields.at( i ).name() );

QVariant value = attrs.at( i );
attrItem->setData( 1, Qt::DisplayRole, value );
@@ -1188,7 +1188,7 @@ void QgsIdentifyResultsDialog::doAction( QTreeWidgetItem *item, int action )
const QgsFields& fields = layer->fields();
for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx )
{
if ( fields[fldIdx].name() == fieldName )
if ( fields.at( fldIdx ).name() == fieldName )
{
idx = fldIdx;
break;
@@ -1741,7 +1741,7 @@ void QgsIdentifyResultsDialog::copyFeatureAttributes()
if ( attrIdx < 0 || attrIdx >= fields.count() )
continue;

text += QString( "%1: %2\n" ).arg( fields[attrIdx].name(), it.value().toString() );
text += QString( "%1: %2\n" ).arg( fields.at( attrIdx ).name(), it.value().toString() );
}
}
else if ( rlayer )
@@ -103,7 +103,7 @@ void QgsLabelPropertyDialog::init( const QString& layerId, const QString& provid
{
mLabelTextLineEdit->setText( attributeValues.at( mCurLabelField ).toString() );
const QgsFields& layerFields = vlayer->fields();
switch ( layerFields[mCurLabelField].type() )
switch ( layerFields.at( mCurLabelField ).type() )
{
case QVariant::Double:
mLabelTextLineEdit->setValidator( new QDoubleValidator( this ) );
@@ -358,7 +358,7 @@ QVariant QgsMergeAttributesDialog::calcStatistic( int col, QgsStatisticalSummary

if ( values.isEmpty() )
{
return QVariant( mVectorLayer->fields()[col].type() );
return QVariant( mVectorLayer->fields().at( col ).type() );
}

summary.calculate( values );
@@ -241,7 +241,7 @@ void QgsComposerAttributeTable::setDisplayAttributes( const QSet<int>& attr, boo
}
QString currentAlias = mVectorLayer->attributeDisplayName( attrIdx );
QgsComposerTableColumn* col = new QgsComposerTableColumn;
col->setAttribute( fields[attrIdx].name() );
col->setAttribute( fields.at( attrIdx ).name() );
col->setHeading( currentAlias );
mColumns.append( col );
}
@@ -652,7 +652,7 @@ bool QgsComposerAttributeTable::readXml( const QDomElement& itemElem, const QDom
//find corresponding column
Q_FOREACH ( QgsComposerTableColumn* column, mColumns )
{
if ( column->attribute() == fields[attribute].name() )
if ( column->attribute() == fields.at( attribute ).name() )
{
column->setSortByRank( i + 1 );
column->setSortOrder( order );
@@ -338,7 +338,7 @@ void QgsComposerAttributeTableV2::setDisplayAttributes( const QSet<int>& attr, b
}
QString currentAlias = source->attributeDisplayName( attrIdx );
QgsComposerTableColumn* col = new QgsComposerTableColumn;
col->setAttribute( fields[attrIdx].name() );
col->setAttribute( fields.at( attrIdx ).name() );
col->setHeading( currentAlias );
mColumns.append( col );
}
@@ -45,19 +45,6 @@ void QgsDiagram::clearCache()
mExpressions.clear();
}

QgsExpression* QgsDiagram::getExpression( const QString& expression, const QgsFields* fields )
{
Q_NOWARN_DEPRECATED_PUSH
if ( !mExpressions.contains( expression ) )
{
QgsExpression* expr = new QgsExpression( expression );
expr->prepare( *fields );
mExpressions[expression] = expr;
}
return mExpressions[expression];
Q_NOWARN_DEPRECATED_POP
}

QgsExpression *QgsDiagram::getExpression( const QString &expression, const QgsExpressionContext &context )
{
if ( !mExpressions.contains( expression ) )
@@ -42,9 +42,6 @@ class CORE_EXPORT QgsDiagram

void clearCache();

//! @deprecated use QgsExpressionContext variant instead
Q_DECL_DEPRECATED QgsExpression* getExpression( const QString& expression, const QgsFields* fields );

/** Returns a prepared expression for the specified context.
* @param expression expression string
* @param context expression context

0 comments on commit 00a8fea

Please sign in to comment.
You can’t perform that action at this time.