18 #include <QRegularExpression>
22 #include <QDirIterator>
27 list << QObject::tr(
"KB" ) << QObject::tr(
"MB" ) << QObject::tr(
"GB" ) << QObject::tr(
"TB" );
29 QStringListIterator i( list );
30 QString unit = QObject::tr(
"bytes" );
32 while ( bytes >= 1024.0 && i.hasNext() )
37 return QStringLiteral(
"%1 %2" ).arg( QString::number( bytes ), unit );
42 const QRegularExpression rx( QStringLiteral(
"\\*\\.([a-zA-Z0-9]+)" ) );
43 QStringList extensions;
44 QRegularExpressionMatchIterator matches = rx.globalMatch( filter );
46 while ( matches.hasNext() )
48 const QRegularExpressionMatch match = matches.next();
49 if ( match.hasMatch() )
51 QStringList newExtensions = match.capturedTexts();
52 newExtensions.pop_front();
53 extensions.append( newExtensions );
61 const QRegularExpression globPatternsRx( QStringLiteral(
".*\\((.*?)\\)$" ) );
62 const QRegularExpressionMatch matches = globPatternsRx.match( filter );
63 if ( matches.hasMatch() )
64 return matches.captured( 1 );
71 QFileInfo fi( fileName );
72 const QString name = fi.fileName();
73 const QStringList parts = filter.split( QStringLiteral(
";;" ) );
74 for (
const QString &part : parts )
76 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
77 const QStringList globPatterns =
wildcardsFromFilter( part ).split(
' ', QString::SkipEmptyParts );
79 const QStringList globPatterns =
wildcardsFromFilter( part ).split(
' ', Qt::SkipEmptyParts );
81 for (
const QString &glob : globPatterns )
83 #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
84 const QString re = QRegularExpression::wildcardToRegularExpression( glob );
86 const QRegularExpression globRx( re );
87 if ( globRx.match( name ).hasMatch() )
91 rx.setPatternSyntax( QRegExp::Wildcard );
92 if ( rx.indexIn( name ) != -1 )
102 if ( extensions.empty() || f.isEmpty() )
105 QString fileName = f;
107 for (
const QString &extension : qgis::as_const( extensions ) )
109 const QString extWithDot = extension.startsWith(
'.' ) ? extension :
'.' + extension;
110 if ( fileName.endsWith( extWithDot, Qt::CaseInsensitive ) )
119 const QString extension = extensions.at( 0 );
120 const QString extWithDot = extension.startsWith(
'.' ) ? extension :
'.' + extension;
121 fileName += extWithDot;
135 QRegularExpression rx( QStringLiteral(
"[/\\\\\\?%\\*\\:\\|\"<>]" ) );
137 s.replace( rx, QStringLiteral(
"_" ) );
143 if ( path.isEmpty() )
147 QFileInfo fi( path );
149 currentPath = fi.dir();
151 currentPath = QDir( path );
153 QSet< QString > visited;
154 while ( !currentPath.exists() )
156 const QString parentPath = QDir::cleanPath( currentPath.absolutePath() + QStringLiteral(
"/.." ) );
157 if ( visited.contains( parentPath ) )
160 if ( parentPath.isEmpty() || parentPath == QLatin1String(
"." ) )
162 currentPath = QDir( parentPath );
163 visited << parentPath;
166 const QString res = QDir::cleanPath( currentPath.absolutePath() );
168 if ( res == QDir::currentPath() )
171 return res == QLatin1String(
"." ) ? QString() : res;
174 QStringList
QgsFileUtils::findFile(
const QString &file,
const QString &basePath,
int maxClimbs,
int searchCeilling,
const QString ¤tDir )
177 QString originalFolder;
179 const QString fileName( basePath.isEmpty() ? QFileInfo( file ).fileName() : file );
180 const QString baseFolder( basePath.isEmpty() ? QFileInfo( file ).path() : basePath );
182 if ( QFileInfo( baseFolder ).isDir() )
184 folder = QDir( baseFolder ) ;
185 originalFolder = folder.absolutePath();
189 folder = QDir( QFileInfo( baseFolder ).absolutePath() );
190 originalFolder = folder.absolutePath();
193 QStringList searchedFolder = QStringList();
194 QString existingBase;
195 QString backupDirectory = QDir::currentPath();
196 QStringList foundFiles;
198 if ( !currentDir.isEmpty() && backupDirectory != currentDir && QDir( currentDir ).exists() )
199 QDir::setCurrent( currentDir );
202 while ( !folder.exists() && folder.absolutePath().count(
'/' ) > searchCeilling )
205 existingBase = folder.path();
206 if ( !folder.cdUp() )
207 folder = QFileInfo( existingBase ).absoluteDir();
211 if ( depth > ( maxClimbs + 4 ) )
214 bool folderExists = folder.exists();
216 if ( depth > maxClimbs )
219 if ( folder.absolutePath().count(
'/' ) < searchCeilling )
220 searchCeilling = folder.absolutePath().count(
'/' ) - 1;
222 while ( depth <= maxClimbs && folderExists && folder.absolutePath().count(
'/' ) >= searchCeilling )
225 QDirIterator localFinder( folder.path(), QStringList() << fileName, QDir::Files, QDirIterator::NoIteratorFlags );
226 searchedFolder.append( folder.absolutePath() );
227 if ( localFinder.hasNext() )
229 foundFiles << localFinder.next();
234 const QFileInfoList subdirs = folder.entryInfoList( QDir::AllDirs );
235 for (
const QFileInfo &subdir : subdirs )
237 if ( ! searchedFolder.contains( subdir.absolutePath() ) )
239 QDirIterator subDirFinder( subdir.path(), QStringList() << fileName, QDir::Files, QDirIterator::Subdirectories );
240 if ( subDirFinder.hasNext() )
242 QString possibleFile = subDirFinder.next();
243 if ( !subDirFinder.hasNext() )
245 foundFiles << possibleFile;
249 foundFiles << possibleFile;
250 while ( subDirFinder.hasNext() )
252 foundFiles << subDirFinder.next();
260 if ( depth > maxClimbs )
263 folderExists = folder.cdUp();
266 if ( QDir::currentPath() == currentDir && currentDir != backupDirectory )
267 QDir::setCurrent( backupDirectory );
static QString stringToSafeFilename(const QString &string)
Converts a string to a safe filename, replacing characters which are not safe for filenames with an '...
static QStringList findFile(const QString &file, const QString &basepath=QString(), int maxClimbs=4, int searchCeiling=4, const QString ¤tDir=QString())
Will check basepath in an outward spiral up to maxClimbs levels to check if file exists.
static QString wildcardsFromFilter(const QString &filter)
Given a filter string like "GeoTIFF Files (*.tiff *.tif)", extracts the wildcard portion of this filt...
static bool fileMatchesFilter(const QString &fileName, const QString &filter)
Returns true if the given fileName matches a file filter string.
static QString ensureFileNameHasExtension(const QString &fileName, const QStringList &extensions)
Ensures that a fileName ends with an extension from the provided list of extensions.
static QString representFileSize(qint64 bytes)
Returns the human size from bytes.
static QString addExtensionFromFilter(const QString &fileName, const QString &filter)
Ensures that a fileName ends with an extension from the specified filter string.
static QString findClosestExistingPath(const QString &path)
Returns the top-most existing folder from path.
static QStringList extensionsFromFilter(const QString &filter)
Returns a list of the extensions contained within a file filter string.