LCOV - code coverage report
Current view: top level - core - qgsfileutils.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 6 157 3.8 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :     qgsfileutils.cpp
       3                 :            :     ---------------------
       4                 :            :     begin                : November 2017
       5                 :            :     copyright            : (C) 2017 by Etienne Trimaille
       6                 :            :     email                : etienne.trimaille at gmail dot com
       7                 :            :  ***************************************************************************
       8                 :            :  *                                                                         *
       9                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      10                 :            :  *   it under the terms of the GNU General Public License as published by  *
      11                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      12                 :            :  *   (at your option) any later version.                                   *
      13                 :            :  *                                                                         *
      14                 :            :  ***************************************************************************/
      15                 :            : #include "qgsfileutils.h"
      16                 :            : #include "qgis.h"
      17                 :            : #include <QObject>
      18                 :            : #include <QRegularExpression>
      19                 :            : #include <QFileInfo>
      20                 :            : #include <QDir>
      21                 :            : #include <QSet>
      22                 :            : #include <QDirIterator>
      23                 :            : 
      24                 :          0 : QString QgsFileUtils::representFileSize( qint64 bytes )
      25                 :            : {
      26                 :          0 :   QStringList list;
      27                 :          0 :   list << QObject::tr( "KB" ) << QObject::tr( "MB" ) << QObject::tr( "GB" ) << QObject::tr( "TB" );
      28                 :            : 
      29                 :          0 :   QStringListIterator i( list );
      30                 :          0 :   QString unit = QObject::tr( "bytes" );
      31                 :            : 
      32                 :          0 :   while ( bytes >= 1024.0 && i.hasNext() )
      33                 :            :   {
      34                 :          0 :     unit = i.next();
      35                 :          0 :     bytes /= 1024.0;
      36                 :            :   }
      37                 :          0 :   return QStringLiteral( "%1 %2" ).arg( QString::number( bytes ), unit );
      38                 :          0 : }
      39                 :            : 
      40                 :          0 : QStringList QgsFileUtils::extensionsFromFilter( const QString &filter )
      41                 :            : {
      42                 :          0 :   const QRegularExpression rx( QStringLiteral( "\\*\\.([a-zA-Z0-9]+)" ) );
      43                 :          0 :   QStringList extensions;
      44                 :          0 :   QRegularExpressionMatchIterator matches = rx.globalMatch( filter );
      45                 :            : 
      46                 :          0 :   while ( matches.hasNext() )
      47                 :            :   {
      48                 :          0 :     const QRegularExpressionMatch match = matches.next();
      49                 :          0 :     if ( match.hasMatch() )
      50                 :            :     {
      51                 :          0 :       QStringList newExtensions = match.capturedTexts();
      52                 :          0 :       newExtensions.pop_front(); // remove whole match
      53                 :          0 :       extensions.append( newExtensions );
      54                 :          0 :     }
      55                 :          0 :   }
      56                 :          0 :   return extensions;
      57                 :          0 : }
      58                 :            : 
      59                 :          3 : QString QgsFileUtils::wildcardsFromFilter( const QString &filter )
      60                 :            : {
      61                 :          6 :   const QRegularExpression globPatternsRx( QStringLiteral( ".*\\((.*?)\\)$" ) );
      62                 :          3 :   const QRegularExpressionMatch matches = globPatternsRx.match( filter );
      63                 :          3 :   if ( matches.hasMatch() )
      64                 :          3 :     return matches.captured( 1 );
      65                 :            :   else
      66                 :          0 :     return QString();
      67                 :          3 : }
      68                 :            : 
      69                 :          0 : bool QgsFileUtils::fileMatchesFilter( const QString &fileName, const QString &filter )
      70                 :            : {
      71                 :          0 :   QFileInfo fi( fileName );
      72                 :          0 :   const QString name = fi.fileName();
      73                 :          0 :   const QStringList parts = filter.split( QStringLiteral( ";;" ) );
      74                 :          0 :   for ( const QString &part : parts )
      75                 :            :   {
      76                 :            : #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
      77                 :            :     const QStringList globPatterns = wildcardsFromFilter( part ).split( ' ', QString::SkipEmptyParts );
      78                 :            : #else
      79                 :          0 :     const QStringList globPatterns = wildcardsFromFilter( part ).split( ' ', Qt::SkipEmptyParts );
      80                 :            : #endif
      81                 :          0 :     for ( const QString &glob : globPatterns )
      82                 :            :     {
      83                 :          0 :       const QString re = QRegularExpression::wildcardToRegularExpression( glob );
      84                 :            : 
      85                 :          0 :       const QRegularExpression globRx( re );
      86                 :          0 :       if ( globRx.match( name ).hasMatch() )
      87                 :          0 :         return true;
      88                 :          0 :     }
      89                 :          0 :   }
      90                 :          0 :   return false;
      91                 :          0 : }
      92                 :            : 
      93                 :          0 : QString QgsFileUtils::ensureFileNameHasExtension( const QString &f, const QStringList &extensions )
      94                 :            : {
      95                 :          0 :   if ( extensions.empty() || f.isEmpty() )
      96                 :          0 :     return f;
      97                 :            : 
      98                 :          0 :   QString fileName = f;
      99                 :          0 :   bool hasExt = false;
     100                 :          0 :   for ( const QString &extension : std::as_const( extensions ) )
     101                 :            :   {
     102                 :          0 :     const QString extWithDot = extension.startsWith( '.' ) ? extension : '.' + extension;
     103                 :          0 :     if ( fileName.endsWith( extWithDot, Qt::CaseInsensitive ) )
     104                 :            :     {
     105                 :          0 :       hasExt = true;
     106                 :          0 :       break;
     107                 :            :     }
     108                 :          0 :   }
     109                 :            : 
     110                 :          0 :   if ( !hasExt )
     111                 :            :   {
     112                 :          0 :     const QString extension = extensions.at( 0 );
     113                 :          0 :     const QString extWithDot = extension.startsWith( '.' ) ? extension : '.' + extension;
     114                 :          0 :     fileName += extWithDot;
     115                 :          0 :   }
     116                 :            : 
     117                 :          0 :   return fileName;
     118                 :          0 : }
     119                 :            : 
     120                 :          0 : QString QgsFileUtils::addExtensionFromFilter( const QString &fileName, const QString &filter )
     121                 :            : {
     122                 :          0 :   const QStringList extensions = extensionsFromFilter( filter );
     123                 :          0 :   return ensureFileNameHasExtension( fileName, extensions );
     124                 :          0 : }
     125                 :            : 
     126                 :          0 : QString QgsFileUtils::stringToSafeFilename( const QString &string )
     127                 :            : {
     128                 :          0 :   QRegularExpression rx( QStringLiteral( "[/\\\\\\?%\\*\\:\\|\"<>]" ) );
     129                 :          0 :   QString s = string;
     130                 :          0 :   s.replace( rx, QStringLiteral( "_" ) );
     131                 :          0 :   return s;
     132                 :          0 : }
     133                 :            : 
     134                 :          0 : QString QgsFileUtils::findClosestExistingPath( const QString &path )
     135                 :            : {
     136                 :          0 :   if ( path.isEmpty() )
     137                 :          0 :     return QString();
     138                 :            : 
     139                 :          0 :   QDir currentPath;
     140                 :          0 :   QFileInfo fi( path );
     141                 :          0 :   if ( fi.isFile() )
     142                 :          0 :     currentPath = fi.dir();
     143                 :            :   else
     144                 :          0 :     currentPath = QDir( path );
     145                 :            : 
     146                 :          0 :   QSet< QString > visited;
     147                 :          0 :   while ( !currentPath.exists() )
     148                 :            :   {
     149                 :          0 :     const QString parentPath = QDir::cleanPath( currentPath.absolutePath() + QStringLiteral( "/.." ) );
     150                 :          0 :     if ( visited.contains( parentPath ) )
     151                 :          0 :       return QString(); // break circular links
     152                 :            : 
     153                 :          0 :     if ( parentPath.isEmpty() || parentPath == QLatin1String( "." ) )
     154                 :          0 :       return QString();
     155                 :          0 :     currentPath = QDir( parentPath );
     156                 :          0 :     visited << parentPath;
     157                 :          0 :   }
     158                 :            : 
     159                 :          0 :   const QString res = QDir::cleanPath( currentPath.absolutePath() );
     160                 :            : 
     161                 :          0 :   if ( res == QDir::currentPath() )
     162                 :          0 :     return QString(); // avoid default to binary folder if a filename alone is specified
     163                 :            : 
     164                 :          0 :   return res == QLatin1String( "." ) ? QString() : res;
     165                 :          0 : }
     166                 :            : 
     167                 :          0 : QStringList QgsFileUtils::findFile( const QString &file, const QString &basePath, int maxClimbs, int searchCeilling, const QString &currentDir )
     168                 :            : {
     169                 :          0 :   int depth = 0;
     170                 :          0 :   QString originalFolder;
     171                 :          0 :   QDir folder;
     172                 :          0 :   const QString fileName( basePath.isEmpty() ? QFileInfo( file ).fileName() : file );
     173                 :          0 :   const QString baseFolder( basePath.isEmpty() ? QFileInfo( file ).path() : basePath );
     174                 :            : 
     175                 :          0 :   if ( QFileInfo( baseFolder ).isDir() )
     176                 :            :   {
     177                 :          0 :     folder = QDir( baseFolder ) ;
     178                 :          0 :     originalFolder = folder.absolutePath();
     179                 :          0 :   }
     180                 :            :   else // invalid folder or file path
     181                 :            :   {
     182                 :          0 :     folder = QDir( QFileInfo( baseFolder ).absolutePath() );
     183                 :          0 :     originalFolder = folder.absolutePath();
     184                 :            :   }
     185                 :            : 
     186                 :          0 :   QStringList searchedFolder = QStringList();
     187                 :          0 :   QString existingBase;
     188                 :          0 :   QString backupDirectory = QDir::currentPath();
     189                 :          0 :   QStringList foundFiles;
     190                 :            : 
     191                 :          0 :   if ( !currentDir.isEmpty() && backupDirectory != currentDir && QDir( currentDir ).exists() )
     192                 :          0 :     QDir::setCurrent( currentDir );
     193                 :            : 
     194                 :            :   // find the nearest existing folder
     195                 :          0 :   while ( !folder.exists() && folder.absolutePath().count( '/' ) > searchCeilling )
     196                 :            :   {
     197                 :            : 
     198                 :          0 :     existingBase = folder.path();
     199                 :          0 :     if ( !folder.cdUp() )
     200                 :          0 :       folder = QFileInfo( existingBase ).absoluteDir(); // using fileinfo to move up one level
     201                 :            : 
     202                 :          0 :     depth += 1;
     203                 :            : 
     204                 :          0 :     if ( depth > ( maxClimbs + 4 ) ) //break early when no folders can be found
     205                 :          0 :       break;
     206                 :            :   }
     207                 :          0 :   bool folderExists = folder.exists();
     208                 :            : 
     209                 :          0 :   if ( depth > maxClimbs )
     210                 :          0 :     maxClimbs = depth;
     211                 :            : 
     212                 :          0 :   if ( folder.absolutePath().count( '/' ) < searchCeilling )
     213                 :          0 :     searchCeilling = folder.absolutePath().count( '/' ) - 1;
     214                 :            : 
     215                 :          0 :   while ( depth <= maxClimbs && folderExists && folder.absolutePath().count( '/' ) >= searchCeilling )
     216                 :            :   {
     217                 :            : 
     218                 :          0 :     QDirIterator localFinder( folder.path(), QStringList() << fileName, QDir::Files, QDirIterator::NoIteratorFlags );
     219                 :          0 :     searchedFolder.append( folder.absolutePath() );
     220                 :          0 :     if ( localFinder.hasNext() )
     221                 :            :     {
     222                 :          0 :       foundFiles << localFinder.next();
     223                 :          0 :       return foundFiles;
     224                 :            :     }
     225                 :            : 
     226                 :            : 
     227                 :          0 :     const QFileInfoList subdirs = folder.entryInfoList( QDir::AllDirs );
     228                 :          0 :     for ( const QFileInfo &subdir : subdirs )
     229                 :            :     {
     230                 :          0 :       if ( ! searchedFolder.contains( subdir.absolutePath() ) )
     231                 :            :       {
     232                 :          0 :         QDirIterator subDirFinder( subdir.path(), QStringList() << fileName, QDir::Files, QDirIterator::Subdirectories );
     233                 :          0 :         if ( subDirFinder.hasNext() )
     234                 :            :         {
     235                 :          0 :           QString possibleFile = subDirFinder.next();
     236                 :          0 :           if ( !subDirFinder.hasNext() )
     237                 :            :           {
     238                 :          0 :             foundFiles << possibleFile;
     239                 :          0 :             return foundFiles;
     240                 :            :           }
     241                 :            : 
     242                 :          0 :           foundFiles << possibleFile;
     243                 :          0 :           while ( subDirFinder.hasNext() )
     244                 :            :           {
     245                 :          0 :             foundFiles << subDirFinder.next();
     246                 :            :           }
     247                 :          0 :           return foundFiles;
     248                 :          0 :         }
     249                 :          0 :       }
     250                 :            :     }
     251                 :          0 :     depth += 1;
     252                 :            : 
     253                 :          0 :     if ( depth > maxClimbs )
     254                 :          0 :       break;
     255                 :            : 
     256                 :          0 :     folderExists = folder.cdUp();
     257                 :          0 :   }
     258                 :            : 
     259                 :          0 :   if ( QDir::currentPath() == currentDir && currentDir != backupDirectory )
     260                 :          0 :     QDir::setCurrent( backupDirectory );
     261                 :            : 
     262                 :          0 :   return foundFiles;
     263                 :          0 : }
     264                 :            : 

Generated by: LCOV version 1.14