Skip to content

Commit a63ddd2

Browse files
committed
expression interval fixes:
* allow more than two translated forms (fixes #8453) * support signed floating point values * allow non-ascii characters in translation strings
1 parent c25e358 commit a63ddd2

File tree

1 file changed

+29
-30
lines changed

1 file changed

+29
-30
lines changed

src/core/qgsexpression.cpp

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ QgsExpression::Interval QgsExpression::Interval::invalidInterVal()
5151
QgsExpression::Interval QgsExpression::Interval::fromString( QString string )
5252
{
5353
int seconds = 0;
54-
QRegExp rx( "(\\d?\\.?\\d+\\s+[a-z]+)", Qt::CaseInsensitive );
54+
QRegExp rx( "([-+]?\\d?\\.?\\d+\\s+\\S+)", Qt::CaseInsensitive );
5555
QStringList list;
5656
int pos = 0;
5757

@@ -61,44 +61,43 @@ QgsExpression::Interval QgsExpression::Interval::fromString( QString string )
6161
pos += rx.matchedLength();
6262
}
6363

64+
QMap<int, QStringList> map;
65+
map.insert( 1, QStringList() << "second" << "seconds" << QObject::tr( "second|seconds", "list of words separated by | which reference years" ).split( "|" ) );
66+
map.insert( 0 + MINUTE, QStringList() << "minute" << "minutes" << QObject::tr( "minute|minutes", "list of words separated by | which reference minutes" ).split( "|" ) );
67+
map.insert( 0 + HOUR, QStringList() << "hour" << "hours" << QObject::tr( "hour|hours", "list of words separated by | which reference minutes hours" ).split( "|" ) );
68+
map.insert( 0 + DAY, QStringList() << "day" << "days" << QObject::tr( "day|days", "list of words separated by | which reference days" ).split( "|" ) );
69+
map.insert( 0 + WEEKS, QStringList() << "week" << "weeks" << QObject::tr( "week|weeks", "wordlist separated by | which reference weeks" ).split( "|" ) );
70+
map.insert( 0 + MONTHS, QStringList() << "month" << "months" << QObject::tr( "month|months", "list of words separated by | which reference months" ).split( "|" ) );
71+
map.insert( 0 + YEARS, QStringList() << "year" << "years" << QObject::tr( "year|years", "list of words separated by | which reference years" ).split( "|" ) );
72+
6473
foreach ( QString match, list )
6574
{
6675
QStringList split = match.split( QRegExp( "\\s+" ) );
6776
bool ok;
68-
int value = split.at( 0 ).toInt( &ok );
77+
double value = split.at( 0 ).toDouble( &ok );
6978
if ( !ok )
7079
{
7180
continue;
7281
}
7382

74-
if ( match.contains( "day", Qt::CaseInsensitive ) ||
75-
match.contains( QObject::tr( "day", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
76-
match.contains( QObject::tr( "days", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
77-
seconds += value * QgsExpression::Interval::DAY;
78-
if ( match.contains( "week", Qt::CaseInsensitive ) ||
79-
match.contains( QObject::tr( "week", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
80-
match.contains( QObject::tr( "weeks", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
81-
seconds += value * QgsExpression::Interval::WEEKS;
82-
if ( match.contains( "month", Qt::CaseInsensitive ) ||
83-
match.contains( QObject::tr( "month", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
84-
match.contains( QObject::tr( "months", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
85-
seconds += value * QgsExpression::Interval::MONTHS;
86-
if ( match.contains( "year", Qt::CaseInsensitive ) ||
87-
match.contains( QObject::tr( "year", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
88-
match.contains( QObject::tr( "years", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
89-
seconds += value * QgsExpression::Interval::YEARS;
90-
if ( match.contains( "second", Qt::CaseInsensitive ) ||
91-
match.contains( QObject::tr( "second", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
92-
match.contains( QObject::tr( "seconds", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
93-
seconds += value;
94-
if ( match.contains( "minute", Qt::CaseInsensitive ) ||
95-
match.contains( QObject::tr( "minute", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
96-
match.contains( QObject::tr( "minutes", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
97-
seconds += value * QgsExpression::Interval::MINUTE;
98-
if ( match.contains( "hour", Qt::CaseInsensitive ) ||
99-
match.contains( QObject::tr( "hour", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) ||
100-
match.contains( QObject::tr( "hours", "Note: Word is part matched in code" ), Qt::CaseInsensitive ) )
101-
seconds += value * QgsExpression::Interval::HOUR;
83+
bool matched = false;
84+
foreach ( int duration, map.keys() )
85+
{
86+
foreach ( QString name, map[duration] )
87+
{
88+
if ( match.contains( name, Qt::CaseInsensitive ) )
89+
{
90+
matched = true;
91+
break;
92+
}
93+
}
94+
95+
if ( matched )
96+
{
97+
seconds += value * duration;
98+
break;
99+
}
100+
}
102101
}
103102

104103
// If we can't parse the string at all then we just return invalid

0 commit comments

Comments
 (0)