QGIS API Documentation  3.6.0-Noosa (5873452)
qgsfileutils.cpp
Go to the documentation of this file.
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 
23 QString QgsFileUtils::representFileSize( qint64 bytes )
24 {
25  QStringList list;
26  list << QObject::tr( "KB" ) << QObject::tr( "MB" ) << QObject::tr( "GB" ) << QObject::tr( "TB" );
27 
28  QStringListIterator i( list );
29  QString unit = QObject::tr( "bytes" );
30 
31  while ( bytes >= 1024.0 && i.hasNext() )
32  {
33  unit = i.next();
34  bytes /= 1024.0;
35  }
36  return QStringLiteral( "%1 %2" ).arg( QString::number( bytes ), unit );
37 }
38 
39 QStringList QgsFileUtils::extensionsFromFilter( const QString &filter )
40 {
41  const QRegularExpression rx( QStringLiteral( "\\*\\.([a-zA-Z0-9]+)" ) );
42  QStringList extensions;
43  QRegularExpressionMatchIterator matches = rx.globalMatch( filter );
44 
45  while ( matches.hasNext() )
46  {
47  const QRegularExpressionMatch match = matches.next();
48  if ( match.hasMatch() )
49  {
50  QStringList newExtensions = match.capturedTexts();
51  newExtensions.pop_front(); // remove whole match
52  extensions.append( newExtensions );
53  }
54  }
55  return extensions;
56 }
57 
58 QString QgsFileUtils::ensureFileNameHasExtension( const QString &f, const QStringList &extensions )
59 {
60  if ( extensions.empty() || f.isEmpty() )
61  return f;
62 
63  QString fileName = f;
64  bool hasExt = false;
65  for ( const QString &extension : qgis::as_const( extensions ) )
66  {
67  const QString extWithDot = extension.startsWith( '.' ) ? extension : '.' + extension;
68  if ( fileName.endsWith( extWithDot, Qt::CaseInsensitive ) )
69  {
70  hasExt = true;
71  break;
72  }
73  }
74 
75  if ( !hasExt )
76  {
77  const QString extension = extensions.at( 0 );
78  const QString extWithDot = extension.startsWith( '.' ) ? extension : '.' + extension;
79  fileName += extWithDot;
80  }
81 
82  return fileName;
83 }
84 
85 QString QgsFileUtils::addExtensionFromFilter( const QString &fileName, const QString &filter )
86 {
87  const QStringList extensions = extensionsFromFilter( filter );
88  return ensureFileNameHasExtension( fileName, extensions );
89 }
90 
91 QString QgsFileUtils::stringToSafeFilename( const QString &string )
92 {
93  QRegularExpression rx( QStringLiteral( "[/\\\\\\?%\\*\\:\\|\"<>]" ) );
94  QString s = string;
95  s.replace( rx, QStringLiteral( "_" ) );
96  return s;
97 }
98 
99 QString QgsFileUtils::findClosestExistingPath( const QString &path )
100 {
101  if ( path.isEmpty() )
102  return QString();
103 
104  QDir currentPath;
105  QFileInfo fi( path );
106  if ( fi.isFile() )
107  currentPath = fi.dir();
108  else
109  currentPath = QDir( path );
110 
111  QSet< QString > visited;
112  while ( !currentPath.exists() )
113  {
114  const QString parentPath = QDir::cleanPath( currentPath.absolutePath() + QStringLiteral( "/.." ) );
115  if ( visited.contains( parentPath ) )
116  return QString(); // break circular links
117 
118  if ( parentPath.isEmpty() || parentPath == QStringLiteral( "." ) )
119  return QString();
120  currentPath = QDir( parentPath );
121  visited << parentPath;
122  }
123 
124  const QString res = QDir::cleanPath( currentPath.absolutePath() );
125 
126  if ( res == QDir::currentPath() )
127  return QString(); // avoid default to binary folder if a filename alone is specified
128 
129  return res == QStringLiteral( "." ) ? QString() : res;
130 }
static QString findClosestExistingPath(const QString &path)
Returns the top-most existing folder from path.
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 stringToSafeFilename(const QString &string)
Converts a string to a safe filename, replacing characters which are not safe for filenames with an &#39;...
static QStringList extensionsFromFilter(const QString &filter)
Returns a list of the extensions contained within a file filter string.
static QString addExtensionFromFilter(const QString &fileName, const QString &filter)
Ensures that a fileName ends with an extension from the specified filter string.