Add QgsMapLayer::isTemporary to test whether a map layer is temporary

These include memory layer provider layers, or layers physically
stored inside a user's temporary folder (e.g. /tmp)
This commit is contained in:
Nyall Dawson 2019-11-08 11:02:58 +10:00
parent 9e30319be7
commit 377848e2ad
4 changed files with 92 additions and 0 deletions

View File

@ -511,6 +511,16 @@ Returns ``True`` if the layer can be edited.
Returns ``True`` if the layer is considered a spatial layer, ie it has some form of geometry associated with it.
.. versionadded:: 2.16
%End
virtual bool isTemporary() const;
%Docstring
Returns ``True`` if the layer is considered a temporary layer.
These include memory-only layers such as those created by the "memory" data provider, or layers
stored inside a local temporary folder (such as the "/tmp" folder on Linux).
.. versionadded:: 3.10.1
%End
enum ReadFlag

View File

@ -1727,6 +1727,31 @@ bool QgsMapLayer::isSpatial() const
return true;
}
bool QgsMapLayer::isTemporary() const
{
// invalid layers are temporary? -- who knows?!
if ( !isValid() )
return false;
if ( mProviderKey == QLatin1String( "memory" ) )
return true;
const QVariantMap sourceParts = QgsProviderRegistry::instance()->decodeUri( mProviderKey, mDataSource );
const QString path = sourceParts.value( QStringLiteral( "path" ) ).toString();
if ( path.isEmpty() )
return false;
// check if layer path is inside one of the standard temporary file locations for this platform
const QStringList tempPaths = QStandardPaths::standardLocations( QStandardPaths::TempLocation );
for ( const QString &tempPath : tempPaths )
{
if ( path.startsWith( tempPath ) )
return true;
}
return false;
}
void QgsMapLayer::setValid( bool valid )
{
mValid = valid;

View File

@ -522,6 +522,16 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
virtual bool isSpatial() const;
/**
* Returns TRUE if the layer is considered a temporary layer.
*
* These include memory-only layers such as those created by the "memory" data provider, or layers
* stored inside a local temporary folder (such as the "/tmp" folder on Linux).
*
* \since QGIS 3.10.1
*/
virtual bool isTemporary() const;
/**
* Flags which control project read behavior.
* \since QGIS 3.10

View File

@ -13,9 +13,12 @@ __copyright__ = 'Copyright 2017, The QGIS Project'
import os
import qgis # NOQA
import tempfile
import glob
import shutil
from qgis.core import (QgsReadWriteContext,
QgsVectorLayer,
QgsRasterLayer,
QgsProject)
from qgis.testing import start_app, unittest
from qgis.PyQt.QtXml import QDomDocument
@ -138,6 +141,50 @@ class TestQgsMapLayer(unittest.TestCase):
uri = layer.styleURI()
self.assertEqual(uri, os.path.join(TEST_DATA_DIR, 'delimitedtext', 'test.qml'))
def testIsTemporary(self):
# test if a layer is correctly marked as temporary
dir = QTemporaryDir()
dir_path = dir.path()
for file in glob.glob(os.path.join(TEST_DATA_DIR, 'france_parts.*')):
shutil.copy(os.path.join(TEST_DATA_DIR, file), dir_path)
not_temp_source = os.path.join(TEST_DATA_DIR, 'france_parts.*')
temp_source = os.path.join(dir_path, 'france_parts.shp')
vl = QgsVectorLayer('invalid', 'test')
self.assertFalse(vl.isValid())
self.assertFalse(vl.isTemporary())
vl = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'france_parts.shp'), 'test')
self.assertTrue(vl.isValid())
self.assertFalse(vl.isTemporary())
vl = QgsVectorLayer(temp_source, 'test')
self.assertTrue(vl.isValid())
self.assertTrue(vl.isTemporary())
# memory layers are temp
layer = QgsVectorLayer("Point?field=fldtxt:string",
"layer", "memory")
self.assertTrue(vl.isValid())
self.assertTrue(vl.isTemporary())
rl = QgsRasterLayer('invalid', 'test')
self.assertFalse(rl.isValid())
self.assertFalse(rl.isTemporary())
not_temp_source = os.path.join(TEST_DATA_DIR, 'float1-16.tif')
shutil.copy(not_temp_source, dir_path)
temp_source = os.path.join(dir_path, 'float1-16.tif')
rl = QgsRasterLayer(not_temp_source, 'test')
self.assertTrue(rl.isValid())
self.assertFalse(rl.isTemporary())
rl = QgsRasterLayer(temp_source, 'test')
self.assertTrue(rl.isValid())
self.assertTrue(rl.isTemporary())
if __name__ == '__main__':
unittest.main()