Skip to content
Permalink
Browse files
Add method to determine the drive type for a file path
Supported on Windows builds only
  • Loading branch information
nyalldawson committed May 20, 2021
1 parent ac6732d commit e3061a8f513c1928783e8ef8910f77dd373c067a
Showing with 118 additions and 0 deletions.
  1. +20 −0 python/core/auto_generated/qgsfileutils.sip.in
  2. +73 −0 src/core/qgsfileutils.cpp
  3. +25 −0 src/core/qgsfileutils.h
@@ -116,6 +116,26 @@ Will check ``basepath`` in an outward spiral up to ``maxClimbs`` levels to check
:return: List of strings of the first matching path in unix format.

.. versionadded:: 3.12
%End

enum DriveType
{
Unknown,
Invalid,
Removable,
Fixed,
Remote,
CdRom,
RamDisk,
};

static DriveType driveType( const QString &path ) throw( QgsNotSupportedException );
%Docstring
Returns the drive type for the given ``path``.

:raises :: py:class:`QgsNotSupportedException` if determining the drive type is not supported on the current platform.

.. versionadded:: 3.20
%End

};
@@ -14,13 +14,20 @@
***************************************************************************/
#include "qgsfileutils.h"
#include "qgis.h"
#include "qgsexception.h"
#include <QObject>
#include <QRegularExpression>
#include <QFileInfo>
#include <QDir>
#include <QSet>
#include <QDirIterator>

#ifdef Q_OS_WIN
#include <Windows.h>
#include <ShlObj.h>
#pragma comment(lib,"Shell32.lib")
#endif

QString QgsFileUtils::representFileSize( qint64 bytes )
{
QStringList list;
@@ -262,3 +269,69 @@ QStringList QgsFileUtils::findFile( const QString &file, const QString &basePath
return foundFiles;
}

#ifdef Q_OS_WIN
std::unique_ptr< wchar_t[] > pathToWChar( const QString &path )
{
const QString nativePath = QDir::toNativeSeparators( path );

std::unique_ptr< wchar_t[] > pathArray( new wchar_t[static_cast< uint>( nativePath.length() + 1 )] );
nativePath.toWCharArray( pathArray.get() );
pathArray[static_cast< size_t >( nativePath.length() )] = 0;
return pathArray;
}
#endif

QgsFileUtils::DriveType QgsFileUtils::driveType( const QString &path )
{
#ifdef Q_OS_WIN
auto pathType = [ = ]( const QString & path ) -> DriveType
{
std::unique_ptr< wchar_t[] > pathArray = pathToWChar( path );
const UINT type = GetDriveTypeW( pathArray.get() );
switch ( type )
{
case DRIVE_UNKNOWN:
return Unknown;

case DRIVE_NO_ROOT_DIR:
return Invalid;

case DRIVE_REMOVABLE:
return Removable;

case DRIVE_FIXED:
return Fixed;

case DRIVE_REMOTE:
return Remote;

case DRIVE_CDROM:
return CdRom;

case DRIVE_RAMDISK:
return RamDisk;
}

return Unknown;

};

const QString originalPath = QDir::cleanPath( path );
QString currentPath = originalPath;
QString prevPath;
while ( currentPath != prevPath )
{
prevPath = currentPath;
currentPath = QFileInfo( currentPath ).path();
const DriveType type = pathType( currentPath );
if ( type != Unknown && type != Invalid )
return type;
}
return Unknown;

#else
( void )path;
throw QgsNotSupportedException( QStringLiteral( "Determining drive type is not supported on this platform" ) );
#endif
}

@@ -19,6 +19,7 @@
#define QGSFILEUTILS_H

#include "qgis_core.h"
#include "qgis_sip.h"
#include <QString>

/**
@@ -118,6 +119,30 @@ class CORE_EXPORT QgsFileUtils
*/
static QStringList findFile( const QString &file, const QString &basepath = QString(), int maxClimbs = 4, int searchCeiling = 4, const QString &currentDir = QString() );

/**
* Drive types
* \since QGIS 3.20
*/
enum DriveType
{
Unknown, //!< Unknown type
Invalid, //!< Invalid path
Removable, //!< Removable drive
Fixed, //!< Fixed drive
Remote, //!< Remote drive
CdRom, //!< CD-ROM
RamDisk, //!< RAM disk
};

/**
* Returns the drive type for the given \a path.
*
* \throws QgsNotSupportedException if determining the drive type is not supported on the current platform.
*
* \since QGIS 3.20
*/
static DriveType driveType( const QString &path ) SIP_THROW( QgsNotSupportedException );

};

#endif // QGSFILEUTILS_H

0 comments on commit e3061a8

Please sign in to comment.