Navigation Menu

Skip to content

Commit

Permalink
Truncate filter from middle of string
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 19, 2021
1 parent 73f9020 commit 1436a81
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 2 deletions.
11 changes: 11 additions & 0 deletions python/core/auto_generated/qgsstringutils.sip.in
Expand Up @@ -325,6 +325,17 @@ Returns an escaped string matching the behavior of QRegExp.escape.

:return: Escaped string

.. versionadded:: 3.22
%End

static QString truncateMiddleOfString( const QString &string, int maxLength );
%Docstring
Truncates a ``string`` to the specified maximum character length.

If the ``string`` exceeds the maximum character length, then the string
will be truncated by removing characters from the middle of the string
and replacing them with a horizontal ellipsis character.

.. versionadded:: 3.22
%End

Expand Down
4 changes: 2 additions & 2 deletions src/app/qgslayertreeviewfilterindicator.cpp
Expand Up @@ -23,7 +23,7 @@
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgisapp.h"

#include "qgsstringutils.h"

QgsLayerTreeViewFilterIndicatorProvider::QgsLayerTreeViewFilterIndicatorProvider( QgsLayerTreeView *view )
: QgsLayerTreeViewIndicatorProvider( view )
Expand Down Expand Up @@ -63,7 +63,7 @@ QString QgsLayerTreeViewFilterIndicatorProvider::tooltipText( QgsMapLayer *layer

if ( filter.size() > 1024 )
{
filter = filter.left( 1023 ) + QString( QChar( 0x2026 ) );
filter = QgsStringUtils::truncateMiddleOfString( filter, 1024 );
}

return QStringLiteral( "<b>%1:</b><br>%2" ).arg( tr( "Filter" ), filter.toHtmlEscaped() );
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsstringutils.cpp
Expand Up @@ -721,6 +721,18 @@ QString QgsStringUtils::qRegExpEscape( const QString &string )
return escaped;
}

QString QgsStringUtils::truncateMiddleOfString( const QString &string, int maxLength )
{
const int charactersToTruncate = string.length() - maxLength;
if ( charactersToTruncate <= 0 )
return string;

// note we actually truncate an extra character, as we'll be replacing it with the ... character
const int truncateFrom = string.length() / 2 - ( charactersToTruncate + 1 ) / 2;

return string.leftRef( truncateFrom ) + QString( QChar( 0x2026 ) ) + string.midRef( truncateFrom + charactersToTruncate + 1 );
}

QgsStringReplacement::QgsStringReplacement( const QString &match, const QString &replacement, bool caseSensitive, bool wholeWordOnly )
: mMatch( match )
, mReplacement( replacement )
Expand Down
11 changes: 11 additions & 0 deletions src/core/qgsstringutils.h
Expand Up @@ -315,6 +315,17 @@ class CORE_EXPORT QgsStringUtils
*/
static QString qRegExpEscape( const QString &string );

/**
* Truncates a \a string to the specified maximum character length.
*
* If the \a string exceeds the maximum character length, then the string
* will be truncated by removing characters from the middle of the string
* and replacing them with a horizontal ellipsis character.
*
* \since QGIS 3.22
*/
static QString truncateMiddleOfString( const QString &string, int maxLength );

};

#endif //QGSSTRINGUTILS_H
17 changes: 17 additions & 0 deletions tests/src/python/test_qgsstringutils.py
Expand Up @@ -220,6 +220,23 @@ def testfuzzyScore(self):
QgsStringUtils.fuzzyScore('abcd efg hig', 'abcd e hi')
)

def test_truncate_from_middle(self):
"""
Test QgsStringUtils.truncateMiddleOfString
"""
self.assertEqual(QgsStringUtils.truncateMiddleOfString('', 0), '')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('', 10), '')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('abcdef', 10), 'abcdef')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('abcdefghij', 10), 'abcdefghij')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('abcdefghijk', 10), 'abcd…ghijk')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('abcdefghijkl', 10), 'abcde…ijkl')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('abcdefghijklmnop', 10), 'abcde…mnop')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('this is a test', 11), 'this … test')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('this is a test', 1), '…')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('this is a test', 2), 't…')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('this is a test', 3), 't…t')
self.assertEqual(QgsStringUtils.truncateMiddleOfString('this is a test', 0), '…')


if __name__ == '__main__':
unittest.main()

0 comments on commit 1436a81

Please sign in to comment.