LCOV - code coverage report
Current view: top level - core - qgsfield.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 18 323 5.6 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :        qgsfield.cpp - Describes a field in a layer or table
       3                 :            :         --------------------------------------
       4                 :            :        Date                 : 01-Jan-2004
       5                 :            :        Copyright            : (C) 2004 by Gary E.Sherman
       6                 :            :        email                : sherman at mrcc.com
       7                 :            : 
       8                 :            :  ***************************************************************************
       9                 :            :  *                                                                         *
      10                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      11                 :            :  *   it under the terms of the GNU General Public License as published by  *
      12                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      13                 :            :  *   (at your option) any later version.                                   *
      14                 :            :  *                                                                         *
      15                 :            :  ***************************************************************************/
      16                 :            : 
      17                 :            : #include "qgsfields.h"
      18                 :            : #include "qgsfield_p.h"
      19                 :            : #include "qgis.h"
      20                 :            : #include "qgsapplication.h"
      21                 :            : #include "qgssettings.h"
      22                 :            : 
      23                 :            : #include <QDataStream>
      24                 :            : #include <QIcon>
      25                 :            : #include <QLocale>
      26                 :            : #include <QJsonDocument>
      27                 :            : 
      28                 :            : /***************************************************************************
      29                 :            :  * This class is considered CRITICAL and any change MUST be accompanied with
      30                 :            :  * full unit tests in testqgsfield.cpp.
      31                 :            :  * See details in QEP #17
      32                 :            :  ****************************************************************************/
      33                 :            : 
      34                 :            : #if 0
      35                 :            : QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
      36                 :            :                     QString comment )
      37                 :            :   : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
      38                 :            :   , mComment( comment )
      39                 :            : {
      40                 :            :   // This function used to lower case the field name since some stores
      41                 :            :   // use upper case (e.g., shapefiles), but that caused problems with
      42                 :            :   // attribute actions getting confused between uppercase and
      43                 :            :   // lowercase versions of the attribute names, so just leave the
      44                 :            :   // names how they are now.
      45                 :            : }
      46                 :            : #endif
      47                 :        246 : QgsField::QgsField( const QString &name, QVariant::Type type,
      48                 :            :                     const QString &typeName, int len, int prec, const QString &comment, QVariant::Type subType )
      49                 :        246 : {
      50                 :        246 :   d = new QgsFieldPrivate( name, type, subType, typeName, len, prec, comment );
      51                 :        246 : }
      52                 :            : 
      53                 :       2895 : QgsField::QgsField( const QgsField &other ) //NOLINT
      54                 :       2895 :   : d( other.d )
      55                 :       2895 : {
      56                 :            : 
      57                 :       2895 : }
      58                 :            : 
      59                 :       3129 : QgsField::~QgsField() = default;
      60                 :            : 
      61                 :            : /***************************************************************************
      62                 :            :  * This class is considered CRITICAL and any change MUST be accompanied with
      63                 :            :  * full unit tests in testqgsfield.cpp.
      64                 :            :  * See details in QEP #17
      65                 :            :  ****************************************************************************/
      66                 :            : 
      67                 :          0 : QgsField &QgsField::operator =( const QgsField &other )  //NOLINT
      68                 :            : {
      69                 :          0 :   d = other.d;
      70                 :          0 :   return *this;
      71                 :            : }
      72                 :            : 
      73                 :          0 : bool QgsField::operator==( const QgsField &other ) const
      74                 :            : {
      75                 :          0 :   return *( other.d ) == *d;
      76                 :            : }
      77                 :            : 
      78                 :          0 : bool QgsField::operator!=( const QgsField &other ) const
      79                 :            : {
      80                 :          0 :   return !( *this == other );
      81                 :            : }
      82                 :            : 
      83                 :       1012 : QString QgsField::name() const
      84                 :            : {
      85                 :       1012 :   return d->name;
      86                 :            : }
      87                 :            : 
      88                 :          0 : QString QgsField::displayName() const
      89                 :            : {
      90                 :          0 :   if ( !d->alias.isEmpty() )
      91                 :          0 :     return d->alias;
      92                 :            :   else
      93                 :          0 :     return d->name;
      94                 :          0 : }
      95                 :            : 
      96                 :          0 : QString QgsField::displayNameWithAlias() const
      97                 :            : {
      98                 :          0 :   if ( alias().isEmpty() )
      99                 :            :   {
     100                 :          0 :     return name();
     101                 :            :   }
     102                 :          0 :   return QStringLiteral( "%1 (%2)" ).arg( name() ).arg( alias() );
     103                 :          0 : }
     104                 :            : 
     105                 :          0 : QString QgsField::displayType( const bool showConstraints ) const
     106                 :            : {
     107                 :          0 :   QString typeStr = typeName();
     108                 :            : 
     109                 :          0 :   if ( length() > 0 && precision() > 0 )
     110                 :          0 :     typeStr += QStringLiteral( "(%1, %2)" ).arg( length() ).arg( precision() );
     111                 :          0 :   else if ( length() > 0 )
     112                 :          0 :     typeStr += QStringLiteral( "(%1)" ).arg( length() );
     113                 :            : 
     114                 :          0 :   if ( showConstraints )
     115                 :            :   {
     116                 :          0 :     typeStr += ( constraints().constraints() & QgsFieldConstraints::ConstraintNotNull )
     117                 :          0 :                ? QStringLiteral( " NOT NULL" )
     118                 :          0 :                : QStringLiteral( " NULL" );
     119                 :            : 
     120                 :          0 :     typeStr += ( constraints().constraints() & QgsFieldConstraints::ConstraintUnique )
     121                 :          0 :                ? QStringLiteral( " UNIQUE" )
     122                 :          0 :                : QString();
     123                 :          0 :   }
     124                 :            : 
     125                 :          0 :   return typeStr;
     126                 :          0 : }
     127                 :            : 
     128                 :       1900 : QVariant::Type QgsField::type() const
     129                 :            : {
     130                 :       1900 :   return d->type;
     131                 :            : }
     132                 :            : 
     133                 :          0 : QVariant::Type QgsField::subType() const
     134                 :            : {
     135                 :          0 :   return d->subType;
     136                 :            : }
     137                 :            : 
     138                 :          0 : QString QgsField::typeName() const
     139                 :            : {
     140                 :          0 :   return d->typeName;
     141                 :            : }
     142                 :            : 
     143                 :          0 : int QgsField::length() const
     144                 :            : {
     145                 :          0 :   return d->length;
     146                 :            : }
     147                 :            : 
     148                 :          0 : int QgsField::precision() const
     149                 :            : {
     150                 :          0 :   return d->precision;
     151                 :            : }
     152                 :            : 
     153                 :          0 : QString QgsField::comment() const
     154                 :            : {
     155                 :          0 :   return d->comment;
     156                 :            : }
     157                 :            : 
     158                 :          0 : bool QgsField::isNumeric() const
     159                 :            : {
     160                 :          0 :   return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
     161                 :            : }
     162                 :            : 
     163                 :          0 : bool QgsField::isDateOrTime() const
     164                 :            : {
     165                 :          0 :   return d->type == QVariant::Date || d->type == QVariant::Time || d->type == QVariant::DateTime;
     166                 :            : }
     167                 :            : 
     168                 :            : /***************************************************************************
     169                 :            :  * This class is considered CRITICAL and any change MUST be accompanied with
     170                 :            :  * full unit tests in testqgsfield.cpp.
     171                 :            :  * See details in QEP #17
     172                 :            :  ****************************************************************************/
     173                 :            : 
     174                 :          0 : void QgsField::setName( const QString &name )
     175                 :            : {
     176                 :          0 :   d->name = name;
     177                 :          0 : }
     178                 :            : 
     179                 :          0 : void QgsField::setType( QVariant::Type type )
     180                 :            : {
     181                 :          0 :   d->type = type;
     182                 :          0 : }
     183                 :            : 
     184                 :          0 : void QgsField::setSubType( QVariant::Type subType )
     185                 :            : {
     186                 :          0 :   d->subType = subType;
     187                 :          0 : }
     188                 :            : 
     189                 :          0 : void QgsField::setTypeName( const QString &typeName )
     190                 :            : {
     191                 :          0 :   d->typeName = typeName;
     192                 :          0 : }
     193                 :            : 
     194                 :          0 : void QgsField::setLength( int len )
     195                 :            : {
     196                 :          0 :   d->length = len;
     197                 :          0 : }
     198                 :          0 : void QgsField::setPrecision( int precision )
     199                 :            : {
     200                 :          0 :   d->precision = precision;
     201                 :          0 : }
     202                 :            : 
     203                 :          0 : void QgsField::setComment( const QString &comment )
     204                 :            : {
     205                 :          0 :   d->comment = comment;
     206                 :          0 : }
     207                 :            : 
     208                 :          0 : QgsDefaultValue QgsField::defaultValueDefinition() const
     209                 :            : {
     210                 :          0 :   return d->defaultValueDefinition;
     211                 :            : }
     212                 :            : 
     213                 :          0 : void QgsField::setDefaultValueDefinition( const QgsDefaultValue &defaultValueDefinition )
     214                 :            : {
     215                 :          0 :   d->defaultValueDefinition = defaultValueDefinition;
     216                 :          0 : }
     217                 :            : 
     218                 :          1 : void QgsField::setConstraints( const QgsFieldConstraints &constraints )
     219                 :            : {
     220                 :          1 :   d->constraints = constraints;
     221                 :          1 : }
     222                 :            : 
     223                 :          1 : const QgsFieldConstraints &QgsField::constraints() const
     224                 :            : {
     225                 :          1 :   return d->constraints;
     226                 :            : }
     227                 :            : 
     228                 :          0 : QString QgsField::alias() const
     229                 :            : {
     230                 :          0 :   return d->alias;
     231                 :            : }
     232                 :            : 
     233                 :          0 : void QgsField::setAlias( const QString &alias )
     234                 :            : {
     235                 :          0 :   d->alias = alias;
     236                 :          0 : }
     237                 :            : 
     238                 :          0 : QgsField::ConfigurationFlags QgsField::configurationFlags() const
     239                 :            : {
     240                 :          0 :   return d->flags;
     241                 :            : }
     242                 :            : 
     243                 :          0 : void QgsField::setConfigurationFlags( QgsField::ConfigurationFlags flags )
     244                 :            : {
     245                 :          0 :   d->flags = flags;
     246                 :          0 : }
     247                 :            : 
     248                 :            : /***************************************************************************
     249                 :            :  * This class is considered CRITICAL and any change MUST be accompanied with
     250                 :            :  * full unit tests in testqgsfield.cpp.
     251                 :            :  * See details in QEP #17
     252                 :            :  ****************************************************************************/
     253                 :            : 
     254                 :          0 : QString QgsField::displayString( const QVariant &v ) const
     255                 :            : {
     256                 :          0 :   if ( v.isNull() )
     257                 :            :   {
     258                 :          0 :     return QgsApplication::nullRepresentation();
     259                 :            :   }
     260                 :            : 
     261                 :            :   // Special treatment for numeric types if group separator is set or decimalPoint is not a dot
     262                 :          0 :   if ( d->type == QVariant::Double )
     263                 :            :   {
     264                 :            :     // if value doesn't contain a double (a default value expression for instance),
     265                 :            :     // apply no transformation
     266                 :            :     bool ok;
     267                 :          0 :     v.toDouble( &ok );
     268                 :          0 :     if ( !ok )
     269                 :          0 :       return v.toString();
     270                 :            : 
     271                 :            :     // Locales with decimal point != '.' or that require group separator: use QLocale
     272                 :          0 :     if ( QLocale().decimalPoint() != '.' ||
     273                 :          0 :          !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
     274                 :            :     {
     275                 :          0 :       if ( d->precision > 0 )
     276                 :            :       {
     277                 :          0 :         if ( -1 < v.toDouble() && v.toDouble() < 1 )
     278                 :            :         {
     279                 :          0 :           return QLocale().toString( v.toDouble(), 'g', d->precision );
     280                 :            :         }
     281                 :            :         else
     282                 :            :         {
     283                 :          0 :           return QLocale().toString( v.toDouble(), 'f', d->precision );
     284                 :            :         }
     285                 :            :       }
     286                 :            :       else
     287                 :            :       {
     288                 :            :         // Precision is not set, let's guess it from the
     289                 :            :         // standard conversion to string
     290                 :          0 :         QString s( v.toString() );
     291                 :          0 :         int dotPosition( s.indexOf( '.' ) );
     292                 :            :         int precision;
     293                 :          0 :         if ( dotPosition < 0 && s.indexOf( 'e' ) < 0 )
     294                 :            :         {
     295                 :          0 :           precision = 0;
     296                 :          0 :           return QLocale().toString( v.toDouble(), 'f', precision );
     297                 :            :         }
     298                 :            :         else
     299                 :            :         {
     300                 :          0 :           if ( dotPosition < 0 ) precision = 0;
     301                 :          0 :           else precision = s.length() - dotPosition - 1;
     302                 :            : 
     303                 :          0 :           if ( -1 < v.toDouble() && v.toDouble() < 1 )
     304                 :            :           {
     305                 :          0 :             return QLocale().toString( v.toDouble(), 'g', precision );
     306                 :            :           }
     307                 :            :           else
     308                 :            :           {
     309                 :          0 :             return QLocale().toString( v.toDouble(), 'f', precision );
     310                 :            :           }
     311                 :            :         }
     312                 :          0 :       }
     313                 :            :     }
     314                 :            :     // Default for doubles with precision
     315                 :          0 :     else if ( d->type == QVariant::Double && d->precision > 0 )
     316                 :            :     {
     317                 :          0 :       if ( -1 < v.toDouble() && v.toDouble() < 1 )
     318                 :            :       {
     319                 :          0 :         return QString::number( v.toDouble(), 'g', d->precision );
     320                 :            :       }
     321                 :            :       else
     322                 :            :       {
     323                 :          0 :         return QString::number( v.toDouble(), 'f', d->precision );
     324                 :            :       }
     325                 :            :     }
     326                 :          0 :   }
     327                 :            :   // Other numeric types than doubles
     328                 :          0 :   else if ( isNumeric() &&
     329                 :          0 :             !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
     330                 :            :   {
     331                 :            :     bool ok;
     332                 :          0 :     qlonglong converted( v.toLongLong( &ok ) );
     333                 :          0 :     if ( ok )
     334                 :          0 :       return QLocale().toString( converted );
     335                 :          0 :   }
     336                 :          0 :   else if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String( "jsonb" ) )
     337                 :            :   {
     338                 :          0 :     QJsonDocument doc = QJsonDocument::fromVariant( v );
     339                 :          0 :     return QString::fromUtf8( doc.toJson().data() );
     340                 :          0 :   }
     341                 :          0 :   else if ( d->type == QVariant::ByteArray )
     342                 :            :   {
     343                 :          0 :     return QObject::tr( "BLOB" );
     344                 :            :   }
     345                 :            :   // Fallback if special rules do not apply
     346                 :          0 :   return v.toString();
     347                 :          0 : }
     348                 :            : 
     349                 :          0 : QString QgsField::readableConfigurationFlag( QgsField::ConfigurationFlag flag )
     350                 :            : {
     351                 :          0 :   switch ( flag )
     352                 :            :   {
     353                 :            :     case ConfigurationFlag::None:
     354                 :          0 :       return QObject::tr( "None" );
     355                 :            :     case ConfigurationFlag::NotSearchable:
     356                 :          0 :       return QObject::tr( "Not searchable" );
     357                 :            :     case ConfigurationFlag::HideFromWms:
     358                 :          0 :       return QStringLiteral( "Do not expose via WMS" );
     359                 :            :     case ConfigurationFlag::HideFromWfs:
     360                 :          0 :       return QStringLiteral( "Do not expose via WFS" );
     361                 :            :   }
     362                 :          0 :   return QString();
     363                 :          0 : }
     364                 :            : 
     365                 :            : /***************************************************************************
     366                 :            :  * This class is considered CRITICAL and any change MUST be accompanied with
     367                 :            :  * full unit tests in testqgsfield.cpp.
     368                 :            :  * See details in QEP #17
     369                 :            :  ****************************************************************************/
     370                 :            : 
     371                 :          0 : bool QgsField::convertCompatible( QVariant &v, QString *errorMessage ) const
     372                 :            : {
     373                 :          0 :   const QVariant original = v;
     374                 :          0 :   if ( errorMessage )
     375                 :          0 :     errorMessage->clear();
     376                 :            : 
     377                 :          0 :   if ( v.isNull() )
     378                 :            :   {
     379                 :          0 :     v.convert( d->type );
     380                 :          0 :     return true;
     381                 :            :   }
     382                 :            : 
     383                 :          0 :   if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
     384                 :            :   {
     385                 :          0 :     v = QVariant( d->type );
     386                 :          0 :     if ( errorMessage )
     387                 :          0 :       *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
     388                 :          0 :     return false;
     389                 :            :   }
     390                 :            : 
     391                 :            :   // Give it a chance to convert to double since for not '.' locales
     392                 :            :   // we accept both comma and dot as decimal point
     393                 :          0 :   if ( d->type == QVariant::Double && v.type() == QVariant::String )
     394                 :            :   {
     395                 :          0 :     QVariant tmp( v );
     396                 :          0 :     if ( !tmp.convert( d->type ) )
     397                 :            :     {
     398                 :            :       // This might be a string with thousand separator: use locale to convert
     399                 :          0 :       bool ok = false;
     400                 :          0 :       double d = qgsPermissiveToDouble( v.toString(), ok );
     401                 :          0 :       if ( ok )
     402                 :            :       {
     403                 :          0 :         v = QVariant( d );
     404                 :          0 :         return true;
     405                 :            :       }
     406                 :            :       // For not 'dot' locales, we also want to accept '.'
     407                 :          0 :       if ( QLocale().decimalPoint() != '.' )
     408                 :            :       {
     409                 :          0 :         d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
     410                 :          0 :         if ( ok )
     411                 :            :         {
     412                 :          0 :           v = QVariant( d );
     413                 :          0 :           return true;
     414                 :            :         }
     415                 :          0 :       }
     416                 :          0 :     }
     417                 :          0 :   }
     418                 :            : 
     419                 :            :   // For string representation of an int we also might have thousand separator
     420                 :          0 :   if ( d->type == QVariant::Int && v.type() == QVariant::String )
     421                 :            :   {
     422                 :          0 :     QVariant tmp( v );
     423                 :          0 :     if ( !tmp.convert( d->type ) )
     424                 :            :     {
     425                 :            :       // This might be a string with thousand separator: use locale to convert
     426                 :            :       bool ok;
     427                 :          0 :       int i = qgsPermissiveToInt( v.toString(), ok );
     428                 :          0 :       if ( ok )
     429                 :            :       {
     430                 :          0 :         v = QVariant( i );
     431                 :          0 :         return true;
     432                 :            :       }
     433                 :          0 :     }
     434                 :          0 :   }
     435                 :            : 
     436                 :            :   // For string representation of a long we also might have thousand separator
     437                 :          0 :   if ( d->type == QVariant::LongLong && v.type() == QVariant::String )
     438                 :            :   {
     439                 :          0 :     QVariant tmp( v );
     440                 :          0 :     if ( !tmp.convert( d->type ) )
     441                 :            :     {
     442                 :            :       // This might be a string with thousand separator: use locale to convert
     443                 :            :       bool ok;
     444                 :          0 :       qlonglong l = qgsPermissiveToLongLong( v.toString(), ok );
     445                 :          0 :       if ( ok )
     446                 :            :       {
     447                 :          0 :         v = QVariant( l );
     448                 :          0 :         return true;
     449                 :            :       }
     450                 :          0 :     }
     451                 :          0 :   }
     452                 :            : 
     453                 :            :   //String representations of doubles in QVariant will return false to convert( QVariant::Int )
     454                 :            :   //work around this by first converting to double, and then checking whether the double is convertible to int
     455                 :          0 :   if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
     456                 :            :   {
     457                 :          0 :     bool ok = false;
     458                 :          0 :     double dbl = v.toDouble( &ok );
     459                 :          0 :     if ( !ok )
     460                 :            :     {
     461                 :            :       //couldn't convert to number
     462                 :          0 :       v = QVariant( d->type );
     463                 :            : 
     464                 :          0 :       if ( errorMessage )
     465                 :          0 :         *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
     466                 :            : 
     467                 :          0 :       return false;
     468                 :            :     }
     469                 :            : 
     470                 :          0 :     double round = std::round( dbl );
     471                 :          0 :     if ( round  > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
     472                 :            :     {
     473                 :            :       //double too large to fit in int
     474                 :          0 :       v = QVariant( d->type );
     475                 :            : 
     476                 :          0 :       if ( errorMessage )
     477                 :          0 :         *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
     478                 :            : 
     479                 :          0 :       return false;
     480                 :            :     }
     481                 :          0 :     v = QVariant( static_cast< int >( std::round( dbl ) ) );
     482                 :          0 :     return true;
     483                 :            :   }
     484                 :            : 
     485                 :            :   //String representations of doubles in QVariant will return false to convert( QVariant::LongLong )
     486                 :            :   //work around this by first converting to double, and then checking whether the double is convertible to longlong
     487                 :          0 :   if ( d->type == QVariant::LongLong && v.canConvert( QVariant::Double ) )
     488                 :            :   {
     489                 :            :     //firstly test the conversion to longlong because conversion to double will rounded the value
     490                 :          0 :     QVariant tmp( v );
     491                 :          0 :     if ( !tmp.convert( d->type ) )
     492                 :            :     {
     493                 :          0 :       bool ok = false;
     494                 :          0 :       double dbl = v.toDouble( &ok );
     495                 :          0 :       if ( !ok )
     496                 :            :       {
     497                 :            :         //couldn't convert to number
     498                 :          0 :         v = QVariant( d->type );
     499                 :            : 
     500                 :          0 :         if ( errorMessage )
     501                 :          0 :           *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
     502                 :            : 
     503                 :          0 :         return false;
     504                 :            :       }
     505                 :            : 
     506                 :          0 :       double round = std::round( dbl );
     507                 :          0 :       if ( round  > static_cast<double>( std::numeric_limits<long long>::max() ) || round < static_cast<double>( -std::numeric_limits<long long>::max() ) )
     508                 :            :       {
     509                 :            :         //double too large to fit in longlong
     510                 :          0 :         v = QVariant( d->type );
     511                 :            : 
     512                 :          0 :         if ( errorMessage )
     513                 :          0 :           *errorMessage = QObject::tr( "Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
     514                 :            : 
     515                 :          0 :         return false;
     516                 :            :       }
     517                 :          0 :       v = QVariant( static_cast< long long >( std::round( dbl ) ) );
     518                 :          0 :       return true;
     519                 :            :     }
     520                 :          0 :   }
     521                 :            : 
     522                 :          0 :   if ( !v.convert( d->type ) )
     523                 :            :   {
     524                 :          0 :     v = QVariant( d->type );
     525                 :            : 
     526                 :          0 :     if ( errorMessage )
     527                 :          0 :       *errorMessage = QObject::tr( "Could not convert value \"%1\" to target type" ).arg( original.toString() );
     528                 :            : 
     529                 :          0 :     return false;
     530                 :            :   }
     531                 :            : 
     532                 :          0 :   if ( d->type == QVariant::Double && d->precision > 0 )
     533                 :            :   {
     534                 :          0 :     double s = std::pow( 10, d->precision );
     535                 :          0 :     double d = v.toDouble() * s;
     536                 :          0 :     v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
     537                 :          0 :     return true;
     538                 :            :   }
     539                 :            : 
     540                 :          0 :   if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
     541                 :            :   {
     542                 :          0 :     const int length = v.toString().length();
     543                 :          0 :     v = v.toString().left( d->length );
     544                 :            : 
     545                 :          0 :     if ( errorMessage )
     546                 :          0 :       *errorMessage = QObject::tr( "String of length %1 exceeds maximum field length (%2)" ).arg( length ).arg( d->length );
     547                 :            : 
     548                 :          0 :     return false;
     549                 :            :   }
     550                 :            : 
     551                 :          0 :   return true;
     552                 :          0 : }
     553                 :            : 
     554                 :          0 : void QgsField::setEditorWidgetSetup( const QgsEditorWidgetSetup &v )
     555                 :            : {
     556                 :          0 :   d->editorWidgetSetup = v;
     557                 :          0 : }
     558                 :            : 
     559                 :          0 : QgsEditorWidgetSetup QgsField::editorWidgetSetup() const
     560                 :            : {
     561                 :          0 :   return d->editorWidgetSetup;
     562                 :            : }
     563                 :            : 
     564                 :          0 : void QgsField::setReadOnly( bool readOnly )
     565                 :            : {
     566                 :          0 :   d->isReadOnly = readOnly;
     567                 :          0 : }
     568                 :            : 
     569                 :          0 : bool QgsField::isReadOnly() const
     570                 :            : {
     571                 :          0 :   return d->isReadOnly;
     572                 :            : }
     573                 :            : 
     574                 :            : 
     575                 :            : /***************************************************************************
     576                 :            :  * This class is considered CRITICAL and any change MUST be accompanied with
     577                 :            :  * full unit tests in testqgsfield.cpp.
     578                 :            :  * See details in QEP #17
     579                 :            :  ****************************************************************************/
     580                 :            : 
     581                 :          0 : QDataStream &operator<<( QDataStream &out, const QgsField &field )
     582                 :            : {
     583                 :          0 :   out << field.name();
     584                 :          0 :   out << static_cast< quint32 >( field.type() );
     585                 :          0 :   out << field.typeName();
     586                 :          0 :   out << field.length();
     587                 :          0 :   out << field.precision();
     588                 :          0 :   out << field.comment();
     589                 :          0 :   out << field.alias();
     590                 :          0 :   out << field.defaultValueDefinition().expression();
     591                 :          0 :   out << field.defaultValueDefinition().applyOnUpdate();
     592                 :          0 :   out << field.constraints().constraints();
     593                 :          0 :   out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) );
     594                 :          0 :   out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintUnique ) );
     595                 :          0 :   out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintExpression ) );
     596                 :          0 :   out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintNotNull ) );
     597                 :          0 :   out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintUnique ) );
     598                 :          0 :   out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintExpression ) );
     599                 :          0 :   out << field.constraints().constraintExpression();
     600                 :          0 :   out << field.constraints().constraintDescription();
     601                 :          0 :   out << static_cast< quint32 >( field.subType() );
     602                 :          0 :   return out;
     603                 :          0 : }
     604                 :            : 
     605                 :          0 : QDataStream &operator>>( QDataStream &in, QgsField &field )
     606                 :            : {
     607                 :            :   quint32 type;
     608                 :            :   quint32 subType;
     609                 :            :   quint32 length;
     610                 :            :   quint32 precision;
     611                 :            :   quint32 constraints;
     612                 :            :   quint32 originNotNull;
     613                 :            :   quint32 originUnique;
     614                 :            :   quint32 originExpression;
     615                 :            :   quint32 strengthNotNull;
     616                 :            :   quint32 strengthUnique;
     617                 :            :   quint32 strengthExpression;
     618                 :            : 
     619                 :            :   bool applyOnUpdate;
     620                 :            : 
     621                 :          0 :   QString name;
     622                 :          0 :   QString typeName;
     623                 :          0 :   QString comment;
     624                 :          0 :   QString alias;
     625                 :          0 :   QString defaultValueExpression;
     626                 :          0 :   QString constraintExpression;
     627                 :          0 :   QString constraintDescription;
     628                 :            : 
     629                 :          0 :   in >> name >> type >> typeName >> length >> precision >> comment >> alias
     630                 :          0 :      >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
     631                 :          0 :      constraintExpression >> constraintDescription >> subType;
     632                 :          0 :   field.setName( name );
     633                 :          0 :   field.setType( static_cast< QVariant::Type >( type ) );
     634                 :          0 :   field.setTypeName( typeName );
     635                 :          0 :   field.setLength( static_cast< int >( length ) );
     636                 :          0 :   field.setPrecision( static_cast< int >( precision ) );
     637                 :          0 :   field.setComment( comment );
     638                 :          0 :   field.setAlias( alias );
     639                 :          0 :   field.setDefaultValueDefinition( QgsDefaultValue( defaultValueExpression, applyOnUpdate ) );
     640                 :          0 :   QgsFieldConstraints fieldConstraints;
     641                 :          0 :   if ( constraints & QgsFieldConstraints::ConstraintNotNull )
     642                 :            :   {
     643                 :          0 :     fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintOrigin>( originNotNull ) );
     644                 :          0 :     fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthNotNull ) );
     645                 :          0 :   }
     646                 :            :   else
     647                 :          0 :     fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintNotNull );
     648                 :          0 :   if ( constraints & QgsFieldConstraints::ConstraintUnique )
     649                 :            :   {
     650                 :          0 :     fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintOrigin>( originUnique ) );
     651                 :          0 :     fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthUnique ) );
     652                 :          0 :   }
     653                 :            :   else
     654                 :          0 :     fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintUnique );
     655                 :          0 :   if ( constraints & QgsFieldConstraints::ConstraintExpression )
     656                 :            :   {
     657                 :          0 :     fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintOrigin>( originExpression ) );
     658                 :          0 :     fieldConstraints.setConstraintStrength( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintStrength>( strengthExpression ) );
     659                 :          0 :   }
     660                 :            :   else
     661                 :          0 :     fieldConstraints.removeConstraint( QgsFieldConstraints::ConstraintExpression );
     662                 :          0 :   fieldConstraints.setConstraintExpression( constraintExpression, constraintDescription );
     663                 :          0 :   field.setConstraints( fieldConstraints );
     664                 :          0 :   field.setSubType( static_cast< QVariant::Type >( subType ) );
     665                 :          0 :   return in;
     666                 :          0 : }

Generated by: LCOV version 1.14