Skip to content

Commit

Permalink
Add abstraction of project's absolute file path, base name, last modi…
Browse files Browse the repository at this point in the history
…fied
  • Loading branch information
wonder-sk committed Apr 7, 2018
1 parent 47d5b7f commit 15f7ec7
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 3 deletions.
28 changes: 28 additions & 0 deletions python/core/qgsproject.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,37 @@ representation.
%Docstring
Returns QFileInfo object for the project's associated file.

.. note::

The use of this method is discouraged since QGIS 3.2 as it only works with project files stored
in the file system. It is recommended to use absoluteFilePath(), baseName(), lastModifiedTime() as
replacements that are aware of the fact that projects may be saved in other project storages.

.. seealso:: :py:func:`fileName`

.. versionadded:: 2.9
%End

QDateTime lastModified() const;
%Docstring
Returns last modified time of the project file as returned by the file system (or other project storage).

.. versionadded:: 3.2
%End

QString absoluteFilePath() const;
%Docstring
Returns full absolute path to the project file if the project is stored in a file system - derived from fileName().
Returns empty string when the project is stored in a project storage (there is no concept of paths for custom project storages).

.. versionadded:: 3.2
%End

QString baseName() const;
%Docstring
Returns the base name of the project file without the path and without extension - derived from fileName().

.. versionadded:: 3.2
%End

QgsCoordinateReferenceSystem crs() const;
Expand Down
1 change: 1 addition & 0 deletions python/core/qgsprojectstorage.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Metadata associated with a project
#include "qgsprojectstorage.h"
%End
public:
QString name;
QDateTime lastModified;
};

Expand Down
20 changes: 17 additions & 3 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13571,14 +13571,28 @@ void QgisApp::populateProjectStorageMenu( QMenu *menu, bool saving )
QAction *action = menu->addAction( name );
if ( saving )
{
connect( action, &QAction::triggered, [storage]
connect( action, &QAction::triggered, [this, storage]
{
QString uri = storage->showSaveGui();
if ( !uri.isEmpty() )
{
// TODO: merge with QgisApp::fileSaveAs()
QgsProject::instance()->setFileName( uri );
QgsProject::instance()->write();
if ( QgsProject::instance()->write() )
{
setTitleBarText_( *this ); // update title bar
mStatusBar->showMessage( tr( "Saved project to: %1" ).arg( uri ), 5000 );
// add this to the list of recently used project files
saveRecentProjectPath( uri );
mProjectLastModified = QgsProject::instance()->lastModified();
}
else
{
QMessageBox::critical( this,
tr( "Unable to save project %1" ).arg( uri ),
QgsProject::instance()->error(),
QMessageBox::Ok,
Qt::NoButton );
}
}
} );
}
Expand Down
39 changes: 39 additions & 0 deletions src/core/qgsproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,45 @@ QFileInfo QgsProject::fileInfo() const
return QFileInfo( mFile );
}

QDateTime QgsProject::lastModified() const
{
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromUri( mFile.fileName() );
if ( storage )
{
QgsProjectStorage::Metadata metadata;
storage->readProjectMetadata( mFile.fileName(), metadata );
return metadata.lastModified;
}
else
{
return QFileInfo( mFile.fileName() ).lastModified();
}
}

QString QgsProject::absoluteFilePath() const
{
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromUri( mFile.fileName() );
if ( storage )
return QString();

return QFileInfo( mFile.fileName() ).absoluteFilePath();
}

QString QgsProject::baseName() const
{
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromUri( mFile.fileName() );
if ( storage )
{
QgsProjectStorage::Metadata metadata;
storage->readProjectMetadata( mFile.fileName(), metadata );
return metadata.name;
}
else
{
return QFileInfo( mFile.fileName() ).baseName();
}
}

QgsCoordinateReferenceSystem QgsProject::crs() const
{
return mCrs;
Expand Down
24 changes: 24 additions & 0 deletions src/core/qgsproject.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,35 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera

/**
* Returns QFileInfo object for the project's associated file.
*
* \note The use of this method is discouraged since QGIS 3.2 as it only works with project files stored
* in the file system. It is recommended to use absoluteFilePath(), baseName(), lastModifiedTime() as
* replacements that are aware of the fact that projects may be saved in other project storages.
*
* \see fileName()
* \since QGIS 2.9
*/
QFileInfo fileInfo() const;

/**
* Returns last modified time of the project file as returned by the file system (or other project storage).
* \since QGIS 3.2
*/
QDateTime lastModified() const;

/**
* Returns full absolute path to the project file if the project is stored in a file system - derived from fileName().
* Returns empty string when the project is stored in a project storage (there is no concept of paths for custom project storages).
* \since QGIS 3.2
*/
QString absoluteFilePath() const;

/**
* Returns the base name of the project file without the path and without extension - derived from fileName().
* \since QGIS 3.2
*/
QString baseName() const;

/**
* Returns the project's native coordinate reference system.
* \since QGIS 3.0
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsprojectstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class CORE_EXPORT QgsProjectStorage
class Metadata
{
public:
//! Name of the project - equivalent to a file's base name (i.e. without path and extension).
QString name;
//! Date and local time when the file was last modified.
QDateTime lastModified;
};

Expand Down
1 change: 1 addition & 0 deletions src/providers/postgres/qgspostgresprojectstorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ bool QgsPostgresProjectStorage::readProjectMetadata( const QString &uri, QgsProj
{
if ( result.PQntuples() == 1 )
{
metadata.name = projectUri.projectName;
QString metadataStr = result.PQgetvalue( 0, 0 );
QJsonDocument doc( QJsonDocument::fromJson( metadataStr.toUtf8() ) );
ok = _parseMetadataDocument( doc, metadata );
Expand Down
37 changes: 37 additions & 0 deletions tests/src/core/testqgsprojectstorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ class MemoryStorage : public QgsProjectStorage
QString projectName = lst[1];

mProjects[projectName] = ioDevice->readAll();

QgsProjectStorage::Metadata meta;
meta.name = projectName;
meta.lastModified = QDateTime::currentDateTime();
mProjectsMetadata[projectName] = meta;
return true;
}

Expand All @@ -119,11 +124,25 @@ class MemoryStorage : public QgsProjectStorage
return false;

mProjects.remove( projectName );
mProjectsMetadata.remove( projectName );
return true;
}

virtual bool readProjectMetadata( const QString &uri, QgsProjectStorage::Metadata &metadata ) override
{
QStringList lst = uri.split( ":" );
Q_ASSERT( lst.count() == 2 );
QString projectName = lst[1];
if ( !mProjects.contains( projectName ) )
return false;

metadata = mProjectsMetadata[projectName];
return true;
}

private:
QHash<QString, QByteArray> mProjects;
QHash<QString, QgsProjectStorage::Metadata> mProjectsMetadata;
};


Expand Down Expand Up @@ -151,6 +170,12 @@ void TestQgsProjectStorage::testMemoryStorage()
QVERIFY( writeOk );
QCOMPARE( memStorage->listProjects( QString() ).count(), 1 );

QVERIFY( prj1.absoluteFilePath().isEmpty() );
QCOMPARE( prj1.baseName(), QString( "project1" ) );
QVERIFY( prj1.lastModified().secsTo( QDateTime::currentDateTime() ) < 1 );

// read the project back

QgsProject prj2;
prj2.setFileName( "memory:project1" );
bool readOk = prj2.read();
Expand All @@ -166,6 +191,18 @@ void TestQgsProjectStorage::testMemoryStorage()
bool readInvalidOk = prj3.read();
QVERIFY( !readInvalidOk );

// test metadata access

QgsProjectStorage::Metadata meta1;
bool readMetaOk = memStorage->readProjectMetadata( "memory:project1", meta1 );
QVERIFY( readMetaOk );
QCOMPARE( meta1.name, QString( "project1" ) );
QVERIFY( meta1.lastModified.secsTo( QDateTime::currentDateTime() ) < 1 );

QgsProjectStorage::Metadata metaX;
bool readMetaInvalidOk = memStorage->readProjectMetadata( "memory:projectXYZ", metaX );
QVERIFY( !readMetaInvalidOk );

// test removal

bool removeInvalidOk = memStorage->removeProject( "memory:projectXYZ" );
Expand Down
5 changes: 5 additions & 0 deletions tests/src/python/test_project_storage_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,15 @@ def testSaveLoadProject(self):

self.assertEqual(len(prj2.mapLayers()), 1)

self.assertEqual(prj2.baseName(), "abc")
self.assertEqual(prj2.absoluteFilePath(), "") # path not supported for project storages
self.assertTrue(abs(prj2.lastModified().secsTo(QDateTime.currentDateTime())) < 10)

# try to see project's metadata

res, metadata = prj_storage.readProjectMetadata(project_uri)
self.assertTrue(res)
self.assertEqual(metadata.name, "abc")
time_project = metadata.lastModified
time_now = QDateTime.currentDateTime()
time_diff = time_now.secsTo(time_project)
Expand Down

0 comments on commit 15f7ec7

Please sign in to comment.