Skip to content

Commit 15f7ec7

Browse files
committedApr 7, 2018
Add abstraction of project's absolute file path, base name, last modified
1 parent 47d5b7f commit 15f7ec7

File tree

9 files changed

+155
-3
lines changed

9 files changed

+155
-3
lines changed
 

‎python/core/qgsproject.sip.in

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,37 @@ representation.
101101
%Docstring
102102
Returns QFileInfo object for the project's associated file.
103103

104+
.. note::
105+
106+
The use of this method is discouraged since QGIS 3.2 as it only works with project files stored
107+
in the file system. It is recommended to use absoluteFilePath(), baseName(), lastModifiedTime() as
108+
replacements that are aware of the fact that projects may be saved in other project storages.
109+
104110
.. seealso:: :py:func:`fileName`
105111

106112
.. versionadded:: 2.9
113+
%End
114+
115+
QDateTime lastModified() const;
116+
%Docstring
117+
Returns last modified time of the project file as returned by the file system (or other project storage).
118+
119+
.. versionadded:: 3.2
120+
%End
121+
122+
QString absoluteFilePath() const;
123+
%Docstring
124+
Returns full absolute path to the project file if the project is stored in a file system - derived from fileName().
125+
Returns empty string when the project is stored in a project storage (there is no concept of paths for custom project storages).
126+
127+
.. versionadded:: 3.2
128+
%End
129+
130+
QString baseName() const;
131+
%Docstring
132+
Returns the base name of the project file without the path and without extension - derived from fileName().
133+
134+
.. versionadded:: 3.2
107135
%End
108136

109137
QgsCoordinateReferenceSystem crs() const;

‎python/core/qgsprojectstorage.sip.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Metadata associated with a project
3535
#include "qgsprojectstorage.h"
3636
%End
3737
public:
38+
QString name;
3839
QDateTime lastModified;
3940
};
4041

‎src/app/qgisapp.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13571,14 +13571,28 @@ void QgisApp::populateProjectStorageMenu( QMenu *menu, bool saving )
1357113571
QAction *action = menu->addAction( name );
1357213572
if ( saving )
1357313573
{
13574-
connect( action, &QAction::triggered, [storage]
13574+
connect( action, &QAction::triggered, [this, storage]
1357513575
{
1357613576
QString uri = storage->showSaveGui();
1357713577
if ( !uri.isEmpty() )
1357813578
{
13579-
// TODO: merge with QgisApp::fileSaveAs()
1358013579
QgsProject::instance()->setFileName( uri );
13581-
QgsProject::instance()->write();
13580+
if ( QgsProject::instance()->write() )
13581+
{
13582+
setTitleBarText_( *this ); // update title bar
13583+
mStatusBar->showMessage( tr( "Saved project to: %1" ).arg( uri ), 5000 );
13584+
// add this to the list of recently used project files
13585+
saveRecentProjectPath( uri );
13586+
mProjectLastModified = QgsProject::instance()->lastModified();
13587+
}
13588+
else
13589+
{
13590+
QMessageBox::critical( this,
13591+
tr( "Unable to save project %1" ).arg( uri ),
13592+
QgsProject::instance()->error(),
13593+
QMessageBox::Ok,
13594+
Qt::NoButton );
13595+
}
1358213596
}
1358313597
} );
1358413598
}

‎src/core/qgsproject.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,45 @@ QFileInfo QgsProject::fileInfo() const
462462
return QFileInfo( mFile );
463463
}
464464

465+
QDateTime QgsProject::lastModified() const
466+
{
467+
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromUri( mFile.fileName() );
468+
if ( storage )
469+
{
470+
QgsProjectStorage::Metadata metadata;
471+
storage->readProjectMetadata( mFile.fileName(), metadata );
472+
return metadata.lastModified;
473+
}
474+
else
475+
{
476+
return QFileInfo( mFile.fileName() ).lastModified();
477+
}
478+
}
479+
480+
QString QgsProject::absoluteFilePath() const
481+
{
482+
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromUri( mFile.fileName() );
483+
if ( storage )
484+
return QString();
485+
486+
return QFileInfo( mFile.fileName() ).absoluteFilePath();
487+
}
488+
489+
QString QgsProject::baseName() const
490+
{
491+
QgsProjectStorage *storage = QgsApplication::projectStorageRegistry()->projectStorageFromUri( mFile.fileName() );
492+
if ( storage )
493+
{
494+
QgsProjectStorage::Metadata metadata;
495+
storage->readProjectMetadata( mFile.fileName(), metadata );
496+
return metadata.name;
497+
}
498+
else
499+
{
500+
return QFileInfo( mFile.fileName() ).baseName();
501+
}
502+
}
503+
465504
QgsCoordinateReferenceSystem QgsProject::crs() const
466505
{
467506
return mCrs;

‎src/core/qgsproject.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,35 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
151151

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

164+
/**
165+
* Returns last modified time of the project file as returned by the file system (or other project storage).
166+
* \since QGIS 3.2
167+
*/
168+
QDateTime lastModified() const;
169+
170+
/**
171+
* Returns full absolute path to the project file if the project is stored in a file system - derived from fileName().
172+
* Returns empty string when the project is stored in a project storage (there is no concept of paths for custom project storages).
173+
* \since QGIS 3.2
174+
*/
175+
QString absoluteFilePath() const;
176+
177+
/**
178+
* Returns the base name of the project file without the path and without extension - derived from fileName().
179+
* \since QGIS 3.2
180+
*/
181+
QString baseName() const;
182+
159183
/**
160184
* Returns the project's native coordinate reference system.
161185
* \since QGIS 3.0

‎src/core/qgsprojectstorage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class CORE_EXPORT QgsProjectStorage
4141
class Metadata
4242
{
4343
public:
44+
//! Name of the project - equivalent to a file's base name (i.e. without path and extension).
45+
QString name;
46+
//! Date and local time when the file was last modified.
4447
QDateTime lastModified;
4548
};
4649

‎src/providers/postgres/qgspostgresprojectstorage.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ bool QgsPostgresProjectStorage::readProjectMetadata( const QString &uri, QgsProj
208208
{
209209
if ( result.PQntuples() == 1 )
210210
{
211+
metadata.name = projectUri.projectName;
211212
QString metadataStr = result.PQgetvalue( 0, 0 );
212213
QJsonDocument doc( QJsonDocument::fromJson( metadataStr.toUtf8() ) );
213214
ok = _parseMetadataDocument( doc, metadata );

‎tests/src/core/testqgsprojectstorage.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ class MemoryStorage : public QgsProjectStorage
106106
QString projectName = lst[1];
107107

108108
mProjects[projectName] = ioDevice->readAll();
109+
110+
QgsProjectStorage::Metadata meta;
111+
meta.name = projectName;
112+
meta.lastModified = QDateTime::currentDateTime();
113+
mProjectsMetadata[projectName] = meta;
109114
return true;
110115
}
111116

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

121126
mProjects.remove( projectName );
127+
mProjectsMetadata.remove( projectName );
128+
return true;
129+
}
130+
131+
virtual bool readProjectMetadata( const QString &uri, QgsProjectStorage::Metadata &metadata ) override
132+
{
133+
QStringList lst = uri.split( ":" );
134+
Q_ASSERT( lst.count() == 2 );
135+
QString projectName = lst[1];
136+
if ( !mProjects.contains( projectName ) )
137+
return false;
138+
139+
metadata = mProjectsMetadata[projectName];
122140
return true;
123141
}
124142

125143
private:
126144
QHash<QString, QByteArray> mProjects;
145+
QHash<QString, QgsProjectStorage::Metadata> mProjectsMetadata;
127146
};
128147

129148

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

173+
QVERIFY( prj1.absoluteFilePath().isEmpty() );
174+
QCOMPARE( prj1.baseName(), QString( "project1" ) );
175+
QVERIFY( prj1.lastModified().secsTo( QDateTime::currentDateTime() ) < 1 );
176+
177+
// read the project back
178+
154179
QgsProject prj2;
155180
prj2.setFileName( "memory:project1" );
156181
bool readOk = prj2.read();
@@ -166,6 +191,18 @@ void TestQgsProjectStorage::testMemoryStorage()
166191
bool readInvalidOk = prj3.read();
167192
QVERIFY( !readInvalidOk );
168193

194+
// test metadata access
195+
196+
QgsProjectStorage::Metadata meta1;
197+
bool readMetaOk = memStorage->readProjectMetadata( "memory:project1", meta1 );
198+
QVERIFY( readMetaOk );
199+
QCOMPARE( meta1.name, QString( "project1" ) );
200+
QVERIFY( meta1.lastModified.secsTo( QDateTime::currentDateTime() ) < 1 );
201+
202+
QgsProjectStorage::Metadata metaX;
203+
bool readMetaInvalidOk = memStorage->readProjectMetadata( "memory:projectXYZ", metaX );
204+
QVERIFY( !readMetaInvalidOk );
205+
169206
// test removal
170207

171208
bool removeInvalidOk = memStorage->removeProject( "memory:projectXYZ" );

‎tests/src/python/test_project_storage_postgres.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,15 @@ def testSaveLoadProject(self):
102102

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

105+
self.assertEqual(prj2.baseName(), "abc")
106+
self.assertEqual(prj2.absoluteFilePath(), "") # path not supported for project storages
107+
self.assertTrue(abs(prj2.lastModified().secsTo(QDateTime.currentDateTime())) < 10)
108+
105109
# try to see project's metadata
106110

107111
res, metadata = prj_storage.readProjectMetadata(project_uri)
108112
self.assertTrue(res)
113+
self.assertEqual(metadata.name, "abc")
109114
time_project = metadata.lastModified
110115
time_now = QDateTime.currentDateTime()
111116
time_diff = time_now.secsTo(time_project)

0 commit comments

Comments
 (0)
Please sign in to comment.