Add some extension and filter handling functions to QgsFileUtils

This commit is contained in:
Nyall Dawson 2017-12-18 09:05:59 +10:00
parent 48e6ec58e8
commit 128e37eaf4
4 changed files with 187 additions and 0 deletions

View File

@ -27,6 +27,45 @@ class QgsFileUtils
Return the human size from bytes
%End
static QStringList extensionsFromFilter( const QString &filter );
%Docstring
Returns a list of the extensions contained within a file ``filter`` string.
E.g. a ``filter`` of "GeoTIFF Files (*.tiff *.tif)" would return a list
containing "tiff", "tif". The initial '.' is stripped off the extension.
.. seealso:: :py:func:`ensureFileNameHasExtension()`
.. seealso:: :py:func:`addExtensionFromFilter()`
%End
static QString ensureFileNameHasExtension( const QString &fileName, const QStringList &extensions );
%Docstring
Ensures that a ``fileName`` ends with an extension from the provided list of
``extensions``.
E.g. if extensions contains "tif" and "tiff", then a ``fileName`` of
"d:/my_file" will return "d:/my_file.tif". A ``fileName`` of
"d:/my_file.TIFF" or "d:/my_file.TIF" will be returned unchanged.
.. seealso:: :py:func:`extensionsFromFilter()`
.. seealso:: :py:func:`addExtensionFromFilter()`
%End
static QString addExtensionFromFilter( const QString &fileName, const QString &filter );
%Docstring
Ensures that a ``fileName`` ends with an extension from the specified ``filter``
string.
E.g. a ``fileName`` of "d:/my_file" with a filter of "GeoTIFF Files (*.tiff *.tif)"
will return "d:/my_file.tif", where as ``fileName`` of "d:/my_file.TIFF" or "d:/my_file.TIF"
will be returned unchanged.
.. seealso:: :py:func:`extensionsFromFilter()`
.. seealso:: :py:func:`ensureFileNameHasExtension()`
%End
};
/************************************************************************

View File

@ -1,5 +1,6 @@
#include "qgsfileutils.h"
#include <QObject>
#include <QRegularExpression>
QString QgsFileUtils::representFileSize( qint64 bytes )
{
@ -16,3 +17,55 @@ QString QgsFileUtils::representFileSize( qint64 bytes )
}
return QString( "%1 %2" ).arg( QString::number( bytes ), unit );
}
QStringList QgsFileUtils::extensionsFromFilter( const QString &filter )
{
const QRegularExpression rx( QStringLiteral( "\\*\\.([a-zA-Z0-9]+)" ) );
QStringList extensions;
QRegularExpressionMatchIterator matches = rx.globalMatch( filter );
while ( matches.hasNext() )
{
const QRegularExpressionMatch match = matches.next();
if ( match.hasMatch() )
{
QStringList newExtensions = match.capturedTexts();
newExtensions.pop_front(); // remove whole match
extensions.append( newExtensions );
}
}
return extensions;
}
QString QgsFileUtils::ensureFileNameHasExtension( const QString &f, const QStringList &extensions )
{
if ( extensions.empty() || f.isEmpty() )
return f;
QString fileName = f;
bool hasExt = false;
for ( const QString &extension : qgis::as_const( extensions ) )
{
const QString extWithDot = extension.startsWith( '.' ) ? extension : '.' + extension;
if ( fileName.endsWith( extWithDot, Qt::CaseInsensitive ) )
{
hasExt = true;
break;
}
}
if ( !hasExt )
{
const QString extension = extensions.at( 0 );
const QString extWithDot = extension.startsWith( '.' ) ? extension : '.' + extension;
fileName += extWithDot;
}
return fileName;
}
QString QgsFileUtils::addExtensionFromFilter( const QString &fileName, const QString &filter )
{
const QStringList extensions = extensionsFromFilter( filter );
return ensureFileNameHasExtension( fileName, extensions );
}

View File

@ -35,6 +35,41 @@ class CORE_EXPORT QgsFileUtils
*/
static QString representFileSize( qint64 bytes );
/**
* Returns a list of the extensions contained within a file \a filter string.
* E.g. a \a filter of "GeoTIFF Files (*.tiff *.tif)" would return a list
* containing "tiff", "tif". The initial '.' is stripped off the extension.
* \see ensureFileNameHasExtension()
* \see addExtensionFromFilter()
*/
static QStringList extensionsFromFilter( const QString &filter );
/**
* Ensures that a \a fileName ends with an extension from the provided list of
* \a extensions.
*
* E.g. if extensions contains "tif" and "tiff", then a \a fileName of
* "d:/my_file" will return "d:/my_file.tif". A \a fileName of
* "d:/my_file.TIFF" or "d:/my_file.TIF" will be returned unchanged.
*
* \see extensionsFromFilter()
* \see addExtensionFromFilter()
*/
static QString ensureFileNameHasExtension( const QString &fileName, const QStringList &extensions );
/**
* Ensures that a \a fileName ends with an extension from the specified \a filter
* string.
*
* E.g. a \a fileName of "d:/my_file" with a filter of "GeoTIFF Files (*.tiff *.tif)"
* will return "d:/my_file.tif", where as \a fileName of "d:/my_file.TIFF" or "d:/my_file.TIF"
* will be returned unchanged.
*
* \see extensionsFromFilter()
* \see ensureFileNameHasExtension()
*/
static QString addExtensionFromFilter( const QString &fileName, const QString &filter );
};
#endif // QGSFILEUTILS_H

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsFileUtils.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '18/12/2017'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis # NOQA
from qgis.core import QgsFileUtils
from qgis.testing import unittest
class TestQgsFileUtils(unittest.TestCase):
def testExtensionsFromFilter(self):
self.assertEqual(QgsFileUtils.extensionsFromFilter(''), [])
self.assertEqual(QgsFileUtils.extensionsFromFilter('bad'), [])
self.assertEqual(QgsFileUtils.extensionsFromFilter('*'), [])
self.assertEqual(QgsFileUtils.extensionsFromFilter('*.'), [])
self.assertEqual(QgsFileUtils.extensionsFromFilter('Tiff files'), [])
self.assertEqual(QgsFileUtils.extensionsFromFilter('(*.)'), [])
self.assertEqual(QgsFileUtils.extensionsFromFilter('PNG Files (*.png)'), ['png'])
self.assertEqual(QgsFileUtils.extensionsFromFilter('PNG Files (*.PNG)'), ['PNG'])
self.assertEqual(QgsFileUtils.extensionsFromFilter('Geotiff Files (*.tiff *.tif)'), ['tiff', 'tif'])
def testEnsureFileNameHasExtension(self):
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('', ['']), '')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('', []), '')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test', []), 'test')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('', ['.tif']), '')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test', ['.tif']), 'test.tif')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test', ['tif']), 'test.tif')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test.tif', []), 'test.tif')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test.tif', ['bmp']), 'test.tif.bmp')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test.tif', ['tiff']), 'test.tif.tiff')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test.tif', ['tiff', 'tif']), 'test.tif')
self.assertEqual(QgsFileUtils.ensureFileNameHasExtension('test.tif', ['TIFF', 'TIF']), 'test.tif')
def testAddExtensionFromFilter(self):
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test', 'TIFF Files (*.tif)'), 'test.tif')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test', 'TIFF Files (*.tif)'), 'test.tif')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test.tif', ''), 'test.tif')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test.tif', 'BMP Files (*.bmp)'), 'test.tif.bmp')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test.tif', 'TIFF Files (*.tiff)'), 'test.tif.tiff')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test.tif', 'TIFF Files (*.tif *.tiff)'), 'test.tif')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test.tif', 'TIFF Files (*.TIF *.TIFF)'), 'test.tif')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test.tif', 'All Files (*.*)'), 'test.tif')
self.assertEqual(QgsFileUtils.addExtensionFromFilter('test', 'All Files (*.*)'), 'test')
if __name__ == '__main__':
unittest.main()