22
22
23
23
#include < QDataStream>
24
24
#include < QIcon>
25
+ #include < QLocale>
25
26
26
27
/* **************************************************************************
27
28
* This class is considered CRITICAL and any change MUST be accompanied with
@@ -208,9 +209,51 @@ QString QgsField::displayString( const QVariant &v ) const
208
209
return QgsApplication::nullRepresentation ();
209
210
}
210
211
211
- if ( d->type == QVariant::Double && d->precision > 0 )
212
- return QString::number ( v.toDouble (), ' f' , d->precision );
213
-
212
+ // Special treatment for numeric types if group separator is set or decimalPoint is not a dot
213
+ if ( d->type == QVariant::Double )
214
+ {
215
+ // Locales with decimal point != '.' or that require group separator: use QLocale
216
+ if ( QLocale ().decimalPoint () != ' .' ||
217
+ !( QLocale ().numberOptions () & QLocale::NumberOption::OmitGroupSeparator ) )
218
+ {
219
+ if ( d->precision > 0 )
220
+ {
221
+ return QLocale ().toString ( v.toDouble (), ' f' , d->precision );
222
+ }
223
+ else
224
+ {
225
+ // Precision is not set, let's guess it from the
226
+ // standard conversion to string
227
+ QString s ( v.toString () );
228
+ int dotPosition ( s.indexOf ( ' .' ) );
229
+ int precision;
230
+ if ( dotPosition < 0 )
231
+ {
232
+ precision = 0 ;
233
+ }
234
+ else
235
+ {
236
+ precision = s.length () - dotPosition - 1 ;
237
+ }
238
+ return QLocale ().toString ( v.toDouble (), ' f' , precision );
239
+ }
240
+ }
241
+ // Default for doubles with precision
242
+ else if ( d->type == QVariant::Double && d->precision > 0 )
243
+ {
244
+ return QString::number ( v.toDouble (), ' f' , d->precision );
245
+ }
246
+ }
247
+ // Other numeric types than doubles
248
+ else if ( isNumeric () &&
249
+ ! QLocale ().numberOptions () & QLocale::NumberOption::OmitGroupSeparator )
250
+ {
251
+ bool ok;
252
+ qlonglong converted ( v.toLongLong ( &ok ) );
253
+ if ( ok )
254
+ return QLocale ().toString ( converted );
255
+ }
256
+ // Fallback if special rules do not apply
214
257
return v.toString ();
215
258
}
216
259
@@ -234,6 +277,68 @@ bool QgsField::convertCompatible( QVariant &v ) const
234
277
return false ;
235
278
}
236
279
280
+ // Give it a chance to convert to double since for not '.' locales
281
+ // we accept both comma and dot as decimal point
282
+ if ( d->type == QVariant::Double && v.type () == QVariant::String )
283
+ {
284
+ QVariant tmp ( v );
285
+ if ( !tmp.convert ( d->type ) )
286
+ {
287
+ // This might be a string with thousand separator: use locale to convert
288
+ bool ok;
289
+ double d = QLocale ().toDouble ( v.toString (), &ok );
290
+ if ( ok )
291
+ {
292
+ v = QVariant ( d );
293
+ return true ;
294
+ }
295
+ // For not 'dot' locales, we also want to accept '.'
296
+ if ( QLocale ().decimalPoint () != ' .' )
297
+ {
298
+ d = QLocale ( QLocale::English ).toDouble ( v.toString (), &ok );
299
+ if ( ok )
300
+ {
301
+ v = QVariant ( d );
302
+ return true ;
303
+ }
304
+ }
305
+ }
306
+ }
307
+
308
+ // For string representation of an int we also might have thousand separator
309
+ if ( d->type == QVariant::Int && v.type () == QVariant::String )
310
+ {
311
+ QVariant tmp ( v );
312
+ if ( !tmp.convert ( d->type ) )
313
+ {
314
+ // This might be a string with thousand separator: use locale to convert
315
+ bool ok;
316
+ int i = QLocale ().toInt ( v.toString (), &ok );
317
+ if ( ok )
318
+ {
319
+ v = QVariant ( i );
320
+ return true ;
321
+ }
322
+ }
323
+ }
324
+
325
+ // For string representation of a long we also might have thousand separator
326
+ if ( d->type == QVariant::LongLong && v.type () == QVariant::String )
327
+ {
328
+ QVariant tmp ( v );
329
+ if ( !tmp.convert ( d->type ) )
330
+ {
331
+ // This might be a string with thousand separator: use locale to convert
332
+ bool ok;
333
+ qlonglong l = QLocale ().toLongLong ( v.toString (), &ok );
334
+ if ( ok )
335
+ {
336
+ v = QVariant ( l );
337
+ return true ;
338
+ }
339
+ }
340
+ }
341
+
237
342
// String representations of doubles in QVariant will return false to convert( QVariant::Int )
238
343
// work around this by first converting to double, and then checking whether the double is convertible to int
239
344
if ( d->type == QVariant::Int && v.canConvert ( QVariant::Double ) )
@@ -258,6 +363,7 @@ bool QgsField::convertCompatible( QVariant &v ) const
258
363
return true ;
259
364
}
260
365
366
+
261
367
if ( !v.convert ( d->type ) )
262
368
{
263
369
v = QVariant ( d->type );
0 commit comments