Skip to content

Commit ee141a1

Browse files
committedJul 2, 2021
Add enum Qgis::FilePathType and add proper stable api for setting
whether QgsProject uses absolute or relative paths for file storage
1 parent 6031e75 commit ee141a1

File tree

11 files changed

+137
-45
lines changed

11 files changed

+137
-45
lines changed
 

‎python/core/auto_additions/qgis.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@
384384
Qgis.MeshEditingErrorType.FlatFace.__doc__ = "A flat face is present"
385385
Qgis.MeshEditingErrorType.UniqueSharedVertex.__doc__ = "A least two faces share only one vertices"
386386
Qgis.MeshEditingErrorType.InvalidVertex.__doc__ = "An error occurs due to an invalid vertex (for example, vertex index is out of range the available vertex)"
387-
Qgis.MeshEditingErrorType.__doc__ = 'Type of error that can occur during mesh frame editing\n\n.. versionadded:: 3.22\n\n' + '* ``NoError``: ' + Qgis.MeshEditingErrorType.NoError.__doc__ + '\n' + '* ``InvalidFace``: ' + Qgis.MeshEditingErrorType.InvalidFace.__doc__ + '\n' + '* ``FlatFace``: ' + Qgis.MeshEditingErrorType.FlatFace.__doc__ + '\n' + '* ``UniqueSharedVertex``: ' + Qgis.MeshEditingErrorType.UniqueSharedVertex.__doc__ + '\n' + '* ``InvalidVertex``: ' + Qgis.MeshEditingErrorType.InvalidVertex.__doc__
387+
Qgis.MeshEditingErrorType.__doc__ = 'Type of error that can occur during mesh frame editing.\n\n.. versionadded:: 3.22\n\n' + '* ``NoError``: ' + Qgis.MeshEditingErrorType.NoError.__doc__ + '\n' + '* ``InvalidFace``: ' + Qgis.MeshEditingErrorType.InvalidFace.__doc__ + '\n' + '* ``FlatFace``: ' + Qgis.MeshEditingErrorType.FlatFace.__doc__ + '\n' + '* ``UniqueSharedVertex``: ' + Qgis.MeshEditingErrorType.UniqueSharedVertex.__doc__ + '\n' + '* ``InvalidVertex``: ' + Qgis.MeshEditingErrorType.InvalidVertex.__doc__
388388
# --
389389
Qgis.MeshEditingErrorType.baseClass = Qgis
390+
# monkey patching scoped based enum
391+
Qgis.FilePathType.Absolute.__doc__ = "Absolute path"
392+
Qgis.FilePathType.Relative.__doc__ = "Relative path"
393+
Qgis.FilePathType.__doc__ = 'File path types.\n\n.. versionadded:: 3.22\n\n' + '* ``Absolute``: ' + Qgis.FilePathType.Absolute.__doc__ + '\n' + '* ``Relative``: ' + Qgis.FilePathType.Relative.__doc__
394+
# --
395+
Qgis.FilePathType.baseClass = Qgis

‎python/core/auto_generated/project/qgsproject.sip.in

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616

1717

18+
1819
class QgsProject : QObject, QgsExpressionContextGenerator, QgsExpressionContextScopeGenerator, QgsProjectTranslator
1920
{
2021
%Docstring(signature="appended")
@@ -262,6 +263,24 @@ Returns empty string when the project is stored in a project storage (there is n
262263
Returns the base name of the project file without the path and without extension - derived from :py:func:`~QgsProject.fileName`.
263264

264265
.. versionadded:: 3.2
266+
%End
267+
268+
Qgis::FilePathType filePathStorage() const;
269+
%Docstring
270+
Returns the type of paths used when storing file paths in a QGS/QGZ project file.
271+
272+
.. seealso:: :py:func:`setFilePathStorage`
273+
274+
.. versionadded:: 3.22
275+
%End
276+
277+
void setFilePathStorage( Qgis::FilePathType type );
278+
%Docstring
279+
Sets the ``type`` of paths used when storing file paths in a QGS/QGZ project file.
280+
281+
.. seealso:: :py:func:`filePathStorage`
282+
283+
.. versionadded:: 3.22
265284
%End
266285

267286
QgsCoordinateReferenceSystem crs() const;

‎python/core/auto_generated/qgis.sip.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ The development version
281281
InvalidVertex,
282282
};
283283

284+
enum class FilePathType
285+
{
286+
Absolute,
287+
Relative,
288+
};
289+
284290
static const double DEFAULT_SEARCH_RADIUS_MM;
285291

286292
static const float DEFAULT_MAPTOPIXEL_THRESHOLD;

‎src/app/options/qgsoptions.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,14 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
826826
Qgis::PythonMacroMode pyMacroMode = mSettings->enumValue( QStringLiteral( "/qgis/enableMacros" ), Qgis::PythonMacroMode::Ask );
827827
mEnableMacrosComboBox->setCurrentIndex( mEnableMacrosComboBox->findData( QVariant::fromValue( pyMacroMode ) ) );
828828

829-
mDefaultPathsComboBox->setCurrentIndex( mSettings->value( QStringLiteral( "/qgis/defaultProjectPathsRelative" ), QVariant( true ) ).toBool() ? 0 : 1 );
829+
mDefaultPathsComboBox->addItem( tr( "Absolute" ), static_cast< int >( Qgis::FilePathType::Absolute ) );
830+
mDefaultPathsComboBox->addItem( tr( "Relative" ), static_cast< int >( Qgis::FilePathType::Relative ) );
831+
mDefaultPathsComboBox->setCurrentIndex(
832+
mDefaultPathsComboBox->findData(
833+
static_cast< int >(
834+
mSettings->value( QStringLiteral( "/qgis/defaultProjectPathsRelative" ), QVariant( true ) ).toBool() ? Qgis::FilePathType::Relative : Qgis::FilePathType::Absolute )
835+
)
836+
);
830837

831838
QgsProject::FileFormat defaultProjectFileFormat = mSettings->enumValue( QStringLiteral( "/qgis/defaultProjectFileFormat" ), QgsProject::FileFormat::Qgz );
832839
mFileFormatQgzButton->setChecked( defaultProjectFileFormat == QgsProject::FileFormat::Qgz );
@@ -1655,7 +1662,8 @@ void QgsOptions::saveOptions()
16551662
}
16561663
mSettings->setEnumValue( QStringLiteral( "/qgis/enableMacros" ), mEnableMacrosComboBox->currentData().value<Qgis::PythonMacroMode>() );
16571664

1658-
mSettings->setValue( QStringLiteral( "/qgis/defaultProjectPathsRelative" ), mDefaultPathsComboBox->currentIndex() == 0 );
1665+
mSettings->setValue( QStringLiteral( "/qgis/defaultProjectPathsRelative" ),
1666+
static_cast< Qgis::FilePathType >( mDefaultPathsComboBox->currentData().toInt() ) == Qgis::FilePathType::Relative );
16591667

16601668
mSettings->setEnumValue( QStringLiteral( "/qgis/defaultProjectFileFormat" ), mFileFormatQgsButton->isChecked() ? QgsProject::FileFormat::Qgs : QgsProject::FileFormat::Qgz );
16611669

‎src/app/qgsprojectproperties.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,9 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
326326
int dp = QgsProject::instance()->readNumEntry( QStringLiteral( "PositionPrecision" ), QStringLiteral( "/DecimalPlaces" ) );
327327
spinBoxDP->setValue( dp );
328328

329-
cbxAbsolutePath->setCurrentIndex( QgsProject::instance()->readBoolEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), true ) ? 0 : 1 );
329+
cbxAbsolutePath->addItem( tr( "Absolute" ), static_cast< int >( Qgis::FilePathType::Absolute ) );
330+
cbxAbsolutePath->addItem( tr( "Relative" ), static_cast< int >( Qgis::FilePathType::Relative ) );
331+
cbxAbsolutePath->setCurrentIndex( cbxAbsolutePath->findData( static_cast< int >( QgsProject::instance()->filePathStorage() ) ) );
330332

331333
// populate combo box with ellipsoids
332334
// selection of the ellipsoid from settings is deferred to a later point, because it would
@@ -1124,7 +1126,7 @@ void QgsProjectProperties::apply()
11241126
QgsUnitTypes::AreaUnit areaUnits = static_cast< QgsUnitTypes::AreaUnit >( mAreaUnitsCombo->currentData().toInt() );
11251127
QgsProject::instance()->setAreaUnits( areaUnits );
11261128

1127-
QgsProject::instance()->writeEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), cbxAbsolutePath->currentIndex() == 0 );
1129+
QgsProject::instance()->setFilePathStorage( static_cast< Qgis::FilePathType >( cbxAbsolutePath->currentData().toInt() ) );
11281130

11291131
if ( mEllipsoidList.at( mEllipsoidIndex ).acronym.startsWith( QLatin1String( "PARAMETER" ) ) )
11301132
{

‎src/core/project/qgsproject.cpp

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,25 @@ QString QgsProject::baseName() const
720720
}
721721
}
722722

723+
Qgis::FilePathType QgsProject::filePathStorage() const
724+
{
725+
const bool absolutePaths = readBoolEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), false );
726+
return absolutePaths ? Qgis::FilePathType::Absolute : Qgis::FilePathType::Relative;
727+
}
728+
729+
void QgsProject::setFilePathStorage( Qgis::FilePathType type )
730+
{
731+
switch ( type )
732+
{
733+
case Qgis::FilePathType::Absolute:
734+
writeEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), true );
735+
break;
736+
case Qgis::FilePathType::Relative:
737+
writeEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), false );
738+
break;
739+
}
740+
}
741+
723742
QgsCoordinateReferenceSystem QgsProject::crs() const
724743
{
725744
return mCrs;
@@ -845,7 +864,7 @@ void QgsProject::clear()
845864
writeEntry( QStringLiteral( "PositionPrecision" ), QStringLiteral( "/DecimalPlaces" ), 2 );
846865

847866
bool defaultRelativePaths = mSettings.value( QStringLiteral( "/qgis/defaultProjectPathsRelative" ), true ).toBool();
848-
writeEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), !defaultRelativePaths );
867+
setFilePathStorage( defaultRelativePaths ? Qgis::FilePathType::Relative : Qgis::FilePathType::Absolute );
849868

850869
//copy default units to project
851870
writeEntry( QStringLiteral( "Measurement" ), QStringLiteral( "/DistanceUnits" ), mSettings.value( QStringLiteral( "/qgis/measure/displayunits" ) ).toString() );
@@ -2128,7 +2147,7 @@ bool QgsProject::write()
21282147
QString storageFilePath { storage->filePath( mFile.fileName() ) };
21292148
if ( storageFilePath.isEmpty() )
21302149
{
2131-
writeEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), true );
2150+
setFilePathStorage( Qgis::FilePathType::Absolute );
21322151
}
21332152
context.setPathResolver( pathResolver() );
21342153

@@ -2739,22 +2758,29 @@ void QgsProject::dumpProperties() const
27392758

27402759
QgsPathResolver QgsProject::pathResolver() const
27412760
{
2742-
bool absolutePaths = readBoolEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), false );
27432761
QString filePath;
2744-
if ( ! absolutePaths )
2762+
switch ( filePathStorage() )
27452763
{
2746-
// for projects stored in a custom storage, we need to ask to the
2747-
// storage for the path, if the storage returns an empty path
2748-
// relative paths are not supported
2749-
if ( QgsProjectStorage *storage = projectStorage() )
2750-
{
2751-
filePath = storage->filePath( mFile.fileName() );
2752-
}
2753-
else
2764+
case Qgis::FilePathType::Absolute:
2765+
break;
2766+
2767+
case Qgis::FilePathType::Relative:
27542768
{
2755-
filePath = fileName();
2769+
// for projects stored in a custom storage, we need to ask to the
2770+
// storage for the path, if the storage returns an empty path
2771+
// relative paths are not supported
2772+
if ( QgsProjectStorage *storage = projectStorage() )
2773+
{
2774+
filePath = storage->filePath( mFile.fileName() );
2775+
}
2776+
else
2777+
{
2778+
filePath = fileName();
2779+
}
2780+
break;
27562781
}
27572782
}
2783+
27582784
return QgsPathResolver( filePath, mArchive->dir() );
27592785
}
27602786

‎src/core/project/qgsproject.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
#include "qgis_core.h"
2525
#include "qgis_sip.h"
26+
#include "qgis.h"
27+
2628
#include <memory>
2729
#include <QHash>
2830
#include <QList>
@@ -334,6 +336,22 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
334336
*/
335337
QString baseName() const;
336338

339+
/**
340+
* Returns the type of paths used when storing file paths in a QGS/QGZ project file.
341+
*
342+
* \see setFilePathStorage()
343+
* \since QGIS 3.22
344+
*/
345+
Qgis::FilePathType filePathStorage() const;
346+
347+
/**
348+
* Sets the \a type of paths used when storing file paths in a QGS/QGZ project file.
349+
*
350+
* \see filePathStorage()
351+
* \since QGIS 3.22
352+
*/
353+
void setFilePathStorage( Qgis::FilePathType type );
354+
337355
/**
338356
* Returns the project's native coordinate reference system.
339357
* \see setCrs()

‎src/core/qgis.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,8 @@ class CORE_EXPORT Qgis
404404
Q_ENUM( RasterResamplingStage )
405405

406406
/**
407-
* Type of error that can occur during mesh frame editing
407+
* Type of error that can occur during mesh frame editing.
408+
*
408409
* \since QGIS 3.22
409410
*/
410411
enum class MeshEditingErrorType : int
@@ -417,6 +418,18 @@ class CORE_EXPORT Qgis
417418
};
418419
Q_ENUM( MeshEditingErrorType )
419420

421+
/**
422+
* File path types.
423+
*
424+
* \since QGIS 3.22
425+
*/
426+
enum class FilePathType : int
427+
{
428+
Absolute, //!< Absolute path
429+
Relative, //!< Relative path
430+
};
431+
Q_ENUM( FilePathType )
432+
420433
/**
421434
* Identify search radius in mm
422435
* \since QGIS 2.3

‎src/ui/qgsoptionsbase.ui

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,18 +1047,7 @@
10471047
</widget>
10481048
</item>
10491049
<item>
1050-
<widget class="QComboBox" name="mDefaultPathsComboBox">
1051-
<item>
1052-
<property name="text">
1053-
<string>Relative</string>
1054-
</property>
1055-
</item>
1056-
<item>
1057-
<property name="text">
1058-
<string>Absolute</string>
1059-
</property>
1060-
</item>
1061-
</widget>
1050+
<widget class="QComboBox" name="mDefaultPathsComboBox"/>
10621051
</item>
10631052
<item>
10641053
<spacer name="horizontalSpacer_24">

‎src/ui/qgsprojectpropertiesbase.ui

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -452,18 +452,7 @@
452452
</layout>
453453
</item>
454454
<item row="4" column="1">
455-
<widget class="QComboBox" name="cbxAbsolutePath">
456-
<item>
457-
<property name="text">
458-
<string>Absolute</string>
459-
</property>
460-
</item>
461-
<item>
462-
<property name="text">
463-
<string>Relative</string>
464-
</property>
465-
</item>
466-
</widget>
455+
<widget class="QComboBox" name="cbxAbsolutePath"/>
467456
</item>
468457
<item row="1" column="0">
469458
<widget class="QLabel" name="label_30">

‎tests/src/core/testqgsproject.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class TestQgsProject : public QObject
5454
void projectSaveUser();
5555
void testCrsExpressions();
5656
void testCrsValidAfterReadingProjectFile();
57+
void testFilePathType();
5758
void testDefaultRelativePaths();
5859
void testAttachmentsQgs();
5960
void testAttachmentsQgz();
@@ -660,6 +661,16 @@ void TestQgsProject::testCrsValidAfterReadingProjectFile()
660661
QCOMPARE( crsChangedSpy.count(), 2 );
661662
}
662663

664+
void TestQgsProject::testFilePathType()
665+
{
666+
QgsProject p;
667+
p.setFilePathStorage( Qgis::FilePathType::Absolute );
668+
QCOMPARE( p.filePathStorage(), Qgis::FilePathType::Absolute );
669+
670+
p.setFilePathStorage( Qgis::FilePathType::Relative );
671+
QCOMPARE( p.filePathStorage(), Qgis::FilePathType::Relative );
672+
}
673+
663674
void TestQgsProject::testCrsExpressions()
664675
{
665676
QgsProject p;
@@ -709,15 +720,20 @@ void TestQgsProject::testDefaultRelativePaths()
709720

710721
s.setValue( QStringLiteral( "/qgis/defaultProjectPathsRelative" ), true );
711722
QgsProject p1;
712-
bool p1PathsAbsolute = p1.readBoolEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), false );
723+
const bool p1PathsAbsolute = p1.readBoolEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), false );
724+
const Qgis::FilePathType p1Type = p1.filePathStorage();
725+
713726
s.setValue( QStringLiteral( "/qgis/defaultProjectPathsRelative" ), false );
714727
p1.clear();
715-
bool p1PathsAbsolute_2 = p1.readBoolEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), false );
728+
const bool p1PathsAbsolute_2 = p1.readBoolEntry( QStringLiteral( "Paths" ), QStringLiteral( "/Absolute" ), false );
729+
const Qgis::FilePathType p2Type = p1.filePathStorage();
716730

717731
s.setValue( QStringLiteral( "/qgis/defaultProjectPathsRelative" ), bk_defaultRelativePaths );
718732

719733
QCOMPARE( p1PathsAbsolute, false );
720734
QCOMPARE( p1PathsAbsolute_2, true );
735+
QCOMPARE( p1Type, Qgis::FilePathType::Relative );
736+
QCOMPARE( p2Type, Qgis::FilePathType::Absolute );
721737
}
722738

723739
void TestQgsProject::testAttachmentsQgs()

0 commit comments

Comments
 (0)
Please sign in to comment.