Skip to content

Commit

Permalink
[expression] made wordwrap delimiter string an optional 3rd argument
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed Feb 21, 2014
1 parent d1c61a0 commit 1c5228c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 46 deletions.
8 changes: 4 additions & 4 deletions resources/function_help/wordwrap
@@ -1,14 +1,14 @@
<h3>wordwrap() function</h3>
Returns a string wrapped to a minimum number of characters.
Returns a string wrapped to a maximum/minimum number of characters.

<p><h4>Syntax</h4>
replace(<i>string,delimiter_string,wrap_characters</i>)</p>
replace(<i>string,wrap_length[,delimiter_string]</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> string</i> &rarr; is string. The string to be wrapped.<br>
<i> delimiter_string</i> &rarr; is string. The delimiter character(s) to break to a new line.<br>
<i> wrap_characters</i> &rarr; is number. IF positive, the number represents the ideal maximum number of characters to wrap; if negative, the number represents the minimum number of characters to wrap.<br></p>
<i> wrap_length</i> &rarr; is number. If positive, the number represents the ideal maximum number of characters to wrap; if negative, the number represents the minimum number of characters to wrap.<br>
<i> delimiter_string</i> &rarr; is string. The delimiter string to wrap to a new line (<u>optional</u>).<br></p>

<p><h4>Example</h4>
<!-- Show example of function.-->
Expand Down
88 changes: 49 additions & 39 deletions src/core/qgsexpression.cpp
Expand Up @@ -633,52 +633,62 @@ static QVariant fcnTrim( const QVariantList& values, const QgsFeature* , QgsExpr

static QVariant fcnWordwrap( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
{
QString str = getStringValue( values.at( 0 ), parent );
QString newstr;

QString delimiterstr = getStringValue ( values.at(1), parent );
int delimiterlength = delimiterstr.length();

//if wrap value is positive, wrap is (mostly) the maximum width before wrap on delimiter
//if wrap value is negative, wrap is the minimum width before permitting wrap delimiter
int wrap = getIntValue( values.at(2), parent );

QStringList lines = str.split( "\n" );
int strlength, strcurrent, strhit, lasthit;

for ( int i = 0; i < lines.size(); i++ )
if (values.length() > 1)
{
strlength = lines[i].length();
strcurrent = 0;
strhit = 0;
lasthit = 0;
QString str = getStringValue( values.at( 0 ), parent );
int wrap = getIntValue( values.at(1), parent );

while (strcurrent < strlength)
if (!str.isEmpty() && wrap != 0)
{
if (wrap > 0)
QString newstr;
QString delimiterstr;
if (values.length() == 3) delimiterstr = getStringValue ( values.at(2), parent );
if (delimiterstr.isEmpty()) delimiterstr = " ";
int delimiterlength = delimiterstr.length();

QStringList lines = str.split( "\n" );
int strlength, strcurrent, strhit, lasthit;

for ( int i = 0; i < lines.size(); i++ )
{
//first try to locate delimiter backwards
strhit = lines[i].lastIndexOf( delimiterstr, strcurrent + wrap);
if (strhit == lasthit || strhit == -1) {
//if no new backward delimiter found, try to locate forward
strhit = lines[i].indexOf( delimiterstr, strcurrent + qAbs(wrap) );
strlength = lines[i].length();
strcurrent = 0;
strhit = 0;
lasthit = 0;

while (strcurrent < strlength)
{
// positive wrap value = desired maximum line width to wrap
// negative wrap value = desired minimum line width before wrap
if (wrap > 0)
{
//first try to locate delimiter backwards
strhit = lines[i].lastIndexOf( delimiterstr, strcurrent + wrap);
if (strhit == lasthit || strhit == -1) {
//if no new backward delimiter found, try to locate forward
strhit = lines[i].indexOf( delimiterstr, strcurrent + qAbs(wrap) );
}
lasthit = strhit;
} else {
strhit = lines[i].indexOf( delimiterstr, strcurrent + qAbs(wrap) );
}
if (strhit > -1) {
newstr.append( lines[i].midRef( strcurrent , strhit - strcurrent ) );
newstr.append( "\n" );
strcurrent = strhit + delimiterlength;
} else {
newstr.append( lines[i].midRef( strcurrent ) );
strcurrent = strlength;
}
}
lasthit = strhit;
} else {
strhit = lines[i].indexOf( delimiterstr, strcurrent + qAbs(wrap) );
}
if (strhit > -1) {
newstr.append( lines[i].midRef( strcurrent , strhit - strcurrent ) );
newstr.append( "\n" );
strcurrent = strhit + delimiterlength;
} else {
newstr.append( lines[i].midRef( strcurrent ) );
strcurrent = strlength;
if (i < lines.size() - 1) newstr.append( "\n" );
}

return QVariant( newstr );
}
if (i < lines.size() - 1) newstr.append( "\n" );
}
return QVariant( newstr );

return QVariant();
}

static QVariant fcnLength( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
Expand Down Expand Up @@ -1534,7 +1544,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "upper", 1, fcnUpper, "String" )
<< new StaticFunction( "title", 1, fcnTitle, "String" )
<< new StaticFunction( "trim", 1, fcnTrim, "String" )
<< new StaticFunction( "wordwrap", 3, fcnWordwrap, "String" )
<< new StaticFunction( "wordwrap", -1, fcnWordwrap, "String" )
<< new StaticFunction( "length", 1, fcnLength, "String" )
<< new StaticFunction( "replace", 3, fcnReplace, "String" )
<< new StaticFunction( "regexp_replace", 3, fcnRegexpReplace, "String" )
Expand Down
8 changes: 5 additions & 3 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -315,9 +315,11 @@ class TestQgsExpression: public QObject
QTest::newRow( "title" ) << "title(' HeLlO WORLD ')" << false << QVariant( " Hello World " );
QTest::newRow( "trim" ) << "trim(' Test String ')" << false << QVariant( "Test String" );
QTest::newRow( "trim empty string" ) << "trim('')" << false << QVariant( "" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis',' ',13)" << false << QVariant( "university of\nqgis" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis',' ',-3)" << false << QVariant( "university\nof qgis" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis\nsupports many multiline',' ',-5)" << false << QVariant( "university\nof qgis\nsupports\nmany multiline" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis',13)" << false << QVariant( "university of\nqgis" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis',13,' ')" << false << QVariant( "university of\nqgis" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis',-3)" << false << QVariant( "university\nof qgis" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis',-3,' ')" << false << QVariant( "university\nof qgis" );
QTest::newRow( "wordwrap" ) << "wordwrap('university of qgis\nsupports many multiline',-5,' ')" << false << QVariant( "university\nof qgis\nsupports\nmany multiline" );
QTest::newRow( "format" ) << "format('%1 %2 %3 %1', 'One', 'Two', 'Three')" << false << QVariant( "One Two Three One" );

// implicit conversions
Expand Down

0 comments on commit 1c5228c

Please sign in to comment.