mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[FEATURE] Add the possibility to save/open a project in .qgz
This commit is contained in:
parent
15ed34c894
commit
f155030e63
@ -630,6 +630,23 @@ Returns the number of registered layers.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool zip();
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QString zipFileName() const;
|
||||
%Docstring
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
void setZipFileName( const QString &filename );
|
||||
|
||||
bool unzipped() const;
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
|
||||
QList<QgsMapLayer *> addMapLayers( const QList<QgsMapLayer *> &mapLayers /Transfer/,
|
||||
bool addToLegend = true);
|
||||
|
@ -5235,10 +5235,12 @@ void QgisApp::fileOpen()
|
||||
// Retrieve last used project dir from persistent settings
|
||||
QgsSettings settings;
|
||||
QString lastUsedDir = settings.value( QStringLiteral( "UI/lastProjectDir" ), QDir::homePath() ).toString();
|
||||
const QString qgs_ext = tr( "QGIS files" ) + " (*.qgs *.QGS)";
|
||||
const QString zip_ext = tr( "QGZ files" ) + " (*.qgz)";
|
||||
QString fullPath = QFileDialog::getOpenFileName( this,
|
||||
tr( "Choose a QGIS project file to open" ),
|
||||
lastUsedDir,
|
||||
tr( "QGIS files" ) + " (*.qgs *.QGS)" );
|
||||
qgs_ext + ";;" + zip_ext );
|
||||
if ( fullPath.isNull() )
|
||||
{
|
||||
return;
|
||||
@ -5271,6 +5273,8 @@ void QgisApp::enableProjectMacros()
|
||||
*/
|
||||
bool QgisApp::addProject( const QString &projectFile )
|
||||
{
|
||||
bool zip = ( QFileInfo( projectFile ).suffix() == "qgz" ) ? true : false;
|
||||
|
||||
// close the previous opened project if any
|
||||
closeProject();
|
||||
|
||||
@ -5283,7 +5287,17 @@ bool QgisApp::addProject( const QString &projectFile )
|
||||
bool autoSetupOnFirstLayer = mLayerTreeCanvasBridge->autoSetupOnFirstLayer();
|
||||
mLayerTreeCanvasBridge->setAutoSetupOnFirstLayer( false );
|
||||
|
||||
if ( !QgsProject::instance()->read( projectFile ) )
|
||||
bool readOk = false;
|
||||
if ( zip )
|
||||
{
|
||||
readOk = QgsProject::instance()->unzip( projectFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
readOk = QgsProject::instance()->read( projectFile );
|
||||
}
|
||||
|
||||
if ( !readOk && !zip )
|
||||
{
|
||||
QString backupFile = projectFile + "~";
|
||||
QString loadBackupPrompt;
|
||||
@ -5417,34 +5431,47 @@ bool QgisApp::fileSave()
|
||||
// that the project file name is reset to null in fileNew()
|
||||
QFileInfo fullPath;
|
||||
|
||||
if ( QgsProject::instance()->fileName().isNull() )
|
||||
if ( QgsProject::instance()->fileName().isNull() && QgsProject::instance()->zipFileName().isNull() )
|
||||
{
|
||||
// Retrieve last used project dir from persistent settings
|
||||
QgsSettings settings;
|
||||
QString lastUsedDir = settings.value( QStringLiteral( "UI/lastProjectDir" ), QDir::homePath() ).toString();
|
||||
|
||||
const QString qgs_ext = tr( "QGIS files" ) + " (*.qgs)";
|
||||
const QString zip_ext = tr( "QGZ files" ) + " (*.qgz)";
|
||||
QString filter;
|
||||
QString path = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
tr( "Choose a QGIS project file" ),
|
||||
lastUsedDir + '/' + QgsProject::instance()->title(),
|
||||
tr( "QGIS files" ) + " (*.qgs *.QGS)" );
|
||||
qgs_ext + ";;" + zip_ext, &filter );
|
||||
if ( path.isEmpty() )
|
||||
return false;
|
||||
|
||||
fullPath.setFile( path );
|
||||
|
||||
// make sure we have the .qgs extension in the file name
|
||||
if ( "qgs" != fullPath.suffix().toLower() )
|
||||
if ( filter == zip_ext )
|
||||
{
|
||||
fullPath.setFile( fullPath.filePath() + ".qgs" );
|
||||
if ( "qgz" != fullPath.suffix().toLower() )
|
||||
fullPath.setFile( fullPath.filePath() + ".qgz" );
|
||||
|
||||
QgsProject::instance()->setZipFileName( fullPath.filePath() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( "qgs" != fullPath.suffix().toLower() )
|
||||
fullPath.setFile( fullPath.filePath() + ".qgs" );
|
||||
|
||||
|
||||
QgsProject::instance()->setFileName( fullPath.filePath() );
|
||||
QgsProject::instance()->setFileName( fullPath.filePath() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QFileInfo fi( QgsProject::instance()->fileName() );
|
||||
if ( QgsProject::instance()->unzipped() )
|
||||
fi.setFile( QgsProject::instance()->zipFileName() );
|
||||
|
||||
fullPath = fi.absoluteFilePath();
|
||||
if ( fi.exists() && !mProjectLastModified.isNull() && mProjectLastModified != fi.lastModified() )
|
||||
{
|
||||
@ -5468,20 +5495,34 @@ bool QgisApp::fileSave()
|
||||
}
|
||||
}
|
||||
|
||||
if ( QgsProject::instance()->write() )
|
||||
bool writeOk = false;
|
||||
QString writtenFileName;
|
||||
|
||||
if ( QgsProject::instance()->unzipped() )
|
||||
{
|
||||
writeOk = QgsProject::instance()->zip();
|
||||
writtenFileName = QgsProject::instance()->zipFileName();
|
||||
}
|
||||
else
|
||||
{
|
||||
writeOk = QgsProject::instance()->write();
|
||||
writtenFileName = QgsProject::instance()->fileName();
|
||||
}
|
||||
|
||||
if ( writeOk )
|
||||
{
|
||||
setTitleBarText_( *this ); // update title bar
|
||||
mStatusBar->showMessage( tr( "Saved project to: %1" ).arg( QDir::toNativeSeparators( QgsProject::instance()->fileName() ) ), 5000 );
|
||||
mStatusBar->showMessage( tr( "Saved project to: %1" ).arg( QDir::toNativeSeparators( writtenFileName ) ), 5000 );
|
||||
|
||||
saveRecentProjectPath( fullPath.filePath() );
|
||||
|
||||
QFileInfo fi( QgsProject::instance()->fileName() );
|
||||
QFileInfo fi( writtenFileName );
|
||||
mProjectLastModified = fi.lastModified();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical( this,
|
||||
tr( "Unable to save project %1" ).arg( QDir::toNativeSeparators( QgsProject::instance()->fileName() ) ),
|
||||
tr( "Unable to save project %1" ).arg( QDir::toNativeSeparators( writtenFileName ) ),
|
||||
QgsProject::instance()->error() );
|
||||
return false;
|
||||
}
|
||||
@ -5501,10 +5542,13 @@ void QgisApp::fileSaveAs()
|
||||
QgsSettings settings;
|
||||
QString lastUsedDir = settings.value( QStringLiteral( "UI/lastProjectDir" ), QDir::homePath() ).toString();
|
||||
|
||||
const QString qgs_ext = tr( "QGIS files" ) + " (*.qgs *.QGS)";
|
||||
const QString zip_ext = tr( "QGZ files" ) + " (*.qgz)";
|
||||
QString filter;
|
||||
QString path = QFileDialog::getSaveFileName( this,
|
||||
tr( "Choose a file name to save the QGIS project file as" ),
|
||||
lastUsedDir + '/' + QgsProject::instance()->title(),
|
||||
tr( "QGIS files" ) + " (*.qgs *.QGS)" );
|
||||
qgs_ext + ";;" + zip_ext, &filter );
|
||||
if ( path.isEmpty() )
|
||||
return;
|
||||
|
||||
@ -5512,18 +5556,27 @@ void QgisApp::fileSaveAs()
|
||||
|
||||
settings.setValue( QStringLiteral( "UI/lastProjectDir" ), fullPath.path() );
|
||||
|
||||
// make sure the .qgs extension is included in the path name. if not, add it...
|
||||
if ( "qgs" != fullPath.suffix().toLower() )
|
||||
bool writeOk = false;
|
||||
if ( filter == zip_ext )
|
||||
{
|
||||
fullPath.setFile( fullPath.filePath() + ".qgs" );
|
||||
if ( "qgz" != fullPath.suffix().toLower() )
|
||||
fullPath.setFile( fullPath.filePath() + ".qgz" );
|
||||
|
||||
writeOk = QgsProject::instance()->zip( fullPath.filePath() );
|
||||
}
|
||||
else // .qgs
|
||||
{
|
||||
if ( "qgs" != fullPath.suffix().toLower() )
|
||||
fullPath.setFile( fullPath.filePath() + ".qgs" );
|
||||
|
||||
QgsProject::instance()->setFileName( fullPath.filePath() );
|
||||
writeOk = QgsProject::instance()->write();
|
||||
}
|
||||
|
||||
QgsProject::instance()->setFileName( fullPath.filePath() );
|
||||
|
||||
if ( QgsProject::instance()->write() )
|
||||
if ( writeOk )
|
||||
{
|
||||
setTitleBarText_( *this ); // update title bar
|
||||
mStatusBar->showMessage( tr( "Saved project to: %1" ).arg( QDir::toNativeSeparators( QgsProject::instance()->fileName() ) ), 5000 );
|
||||
mStatusBar->showMessage( tr( "Saved project to: %1" ).arg( QDir::toNativeSeparators( fullPath.filePath() ) ), 5000 );
|
||||
// add this to the list of recently used project files
|
||||
saveRecentProjectPath( fullPath.filePath() );
|
||||
mProjectLastModified = fullPath.lastModified();
|
||||
|
@ -95,6 +95,11 @@ QString QgsArchive::filename() const
|
||||
return mFilename;
|
||||
}
|
||||
|
||||
void QgsArchive::setFileName( const QString &filename )
|
||||
{
|
||||
mFilename = filename;
|
||||
}
|
||||
|
||||
QString QgsArchive::projectFile() const
|
||||
{
|
||||
Q_FOREACH ( const QString &file, mFiles )
|
||||
|
@ -49,6 +49,8 @@ class CORE_EXPORT QgsArchive
|
||||
|
||||
void addFile( const QString &filename );
|
||||
|
||||
void setFileName( const QString &filename );
|
||||
|
||||
QString filename() const;
|
||||
|
||||
QString projectFile() const;
|
||||
|
@ -425,6 +425,8 @@ void QgsProject::setFileName( const QString &name )
|
||||
if ( newHomePath != oldHomePath )
|
||||
emit homePathChanged();
|
||||
|
||||
mArchive->clear();
|
||||
|
||||
setDirty( true );
|
||||
}
|
||||
|
||||
@ -763,6 +765,9 @@ bool QgsProject::read()
|
||||
{
|
||||
clearError();
|
||||
|
||||
if ( ! mUnzipping )
|
||||
mArchive->clear();
|
||||
|
||||
std::unique_ptr<QDomDocument> doc( new QDomDocument( QStringLiteral( "qgis" ) ) );
|
||||
|
||||
if ( !mFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
|
||||
@ -2085,27 +2090,38 @@ bool QgsProject::unzip( const QString &filename )
|
||||
}
|
||||
|
||||
// read the project file
|
||||
mUnzipping = true;
|
||||
if ( ! read( archive->projectFile() ) )
|
||||
{
|
||||
mUnzipping = false;
|
||||
setError( tr( "Cannot read unzipped qgs project file" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// keep the archive
|
||||
mUnzipping = false;
|
||||
mArchive.reset( archive.release() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsProject::zip()
|
||||
{
|
||||
if ( unzipped() )
|
||||
return zip( mArchive->filename() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsProject::zip( const QString &filename )
|
||||
{
|
||||
clearError();
|
||||
|
||||
// save the current project in a temporary .qgs file
|
||||
QgsArchive archive;
|
||||
std::unique_ptr<QgsArchive> archive( new QgsArchive() );
|
||||
const QString baseName = QFileInfo( filename ).baseName();
|
||||
const QString qgsFileName = QString( "%1.qgs" ).arg( baseName );
|
||||
QFile qgsFile( QDir( archive.dir() ).filePath( qgsFileName ) );
|
||||
QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
|
||||
|
||||
bool writeOk;
|
||||
if ( qgsFile.open( QIODevice::WriteOnly ) )
|
||||
@ -2127,19 +2143,38 @@ bool QgsProject::zip( const QString &filename )
|
||||
}
|
||||
|
||||
// create the archive
|
||||
archive.addFile( qgsFile.fileName() );
|
||||
archive->addFile( qgsFile.fileName() );
|
||||
|
||||
// zip
|
||||
QString errMsg;
|
||||
if ( !archive.zip( filename ) )
|
||||
if ( !archive->zip( filename ) )
|
||||
{
|
||||
setError( tr( "Unable to perform zip" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// keep the archive
|
||||
mArchive.reset( archive.release() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsProject::unzipped() const
|
||||
{
|
||||
return !mArchive->filename().isEmpty();
|
||||
}
|
||||
|
||||
QString QgsProject::zipFileName() const
|
||||
{
|
||||
return mArchive->filename();
|
||||
}
|
||||
|
||||
void QgsProject::setZipFileName( const QString &filename )
|
||||
{
|
||||
mArchive.reset( new QgsArchive() );
|
||||
mArchive->setFileName( filename );
|
||||
}
|
||||
|
||||
QList<QgsMapLayer *> QgsProject::addMapLayers(
|
||||
const QList<QgsMapLayer *> &layers,
|
||||
bool addToLegend,
|
||||
|
@ -592,6 +592,14 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
*/
|
||||
bool zip( const QString &filename );
|
||||
|
||||
bool zip();
|
||||
|
||||
QString zipFileName() const;
|
||||
|
||||
void setZipFileName( const QString &filename );
|
||||
|
||||
bool unzipped() const;
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
/** Returns a list of registered map layers with a specified layer type.
|
||||
@ -1066,6 +1074,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
|
||||
QVariantMap mCustomVariables;
|
||||
|
||||
std::unique_ptr<QgsArchive> mArchive;
|
||||
bool mUnzipping;
|
||||
|
||||
QFile mFile; // current physical project file
|
||||
mutable QgsProjectPropertyKey mProperties; // property hierarchy, TODO: this shouldn't be mutable
|
||||
|
Loading…
x
Reference in New Issue
Block a user