QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
qgsarchive.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsarchive.cpp
3 ----------------
4
5 begin : July 07, 2017
6 copyright : (C) 2017 by Paul Blottiere
8 ***************************************************************************/
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#include "qgsarchive.h"
20#include "qgsziputils.h"
21#include "qgsmessagelog.h"
22#include "qgsauxiliarystorage.h"
23
24
25#ifdef Q_OS_WIN
26#include <windows.h>
27#endif
28
29#include <QStandardPaths>
30#include <QUuid>
31
33 : mDir( new QTemporaryDir() )
34{
35}
36
38 : mFiles( other.mFiles )
39 , mDir( new QTemporaryDir() )
40{
41}
42
44{
45 if ( this != &other )
46 {
47 mFiles = other.mFiles;
48 mDir.reset( new QTemporaryDir() );
49 }
50
51 return *this;
52}
53
54QString QgsArchive::dir() const
55{
56 return mDir->path();
57}
58
60{
61 mDir.reset( new QTemporaryDir() );
62 mFiles.clear();
63}
64
65bool QgsArchive::zip( const QString &filename )
66{
67 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
68 const QString uuid = QUuid::createUuid().toString();
69 QFile tmpFile( tempPath + QDir::separator() + uuid );
70
71 // zip content
72 if ( ! QgsZipUtils::zip( tmpFile.fileName(), mFiles ) )
73 {
74 const QString err = QObject::tr( "Unable to zip content" );
75 QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
76 return false;
77 }
78
79 // remove existing zip file
80 if ( QFile::exists( filename ) )
81 QFile::remove( filename );
82
83#ifdef Q_OS_WIN
84 // Clear temporary flag (see GH #32118)
85 DWORD dwAttrs;
86#ifdef UNICODE
87 dwAttrs = GetFileAttributes( qUtf16Printable( tmpFile.fileName() ) );
88 SetFileAttributes( qUtf16Printable( tmpFile.fileName() ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
89#else
90 dwAttrs = GetFileAttributes( tmpFile.fileName().toLocal8Bit( ).data( ) );
91 SetFileAttributes( tmpFile.fileName().toLocal8Bit( ).data( ), dwAttrs & ~ FILE_ATTRIBUTE_TEMPORARY );
92#endif
93
94#endif // Q_OS_WIN
95
96 // save zip archive
97 if ( ! tmpFile.rename( filename ) )
98 {
99 const QString err = QObject::tr( "Unable to save zip file '%1'" ).arg( filename );
100 QgsMessageLog::logMessage( err, QStringLiteral( "QgsArchive" ) );
101 return false;
102 }
103
104 return true;
105}
106
107bool QgsArchive::unzip( const QString &filename )
108{
109 clear();
110 return QgsZipUtils::unzip( filename, mDir->path(), mFiles );
111}
112
113void QgsArchive::addFile( const QString &file )
114{
115 mFiles.append( file );
116}
117
118bool QgsArchive::removeFile( const QString &file )
119{
120 bool rc = false;
121
122 if ( !file.isEmpty() && mFiles.contains( file ) && QFile::exists( file ) )
123 rc = QFile::remove( file );
124
125 mFiles.removeOne( file );
126
127 return rc;
128}
129
130QStringList QgsArchive::files() const
131{
132 return mFiles;
133}
134
136{
137 return QFileInfo::exists( mDir->path() );
138}
139
141{
142 const auto constFiles = files();
143 for ( const QString &file : constFiles )
144 {
145 const QFileInfo fileInfo( file );
146 if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 )
147 return file;
148 }
149
150 return QString();
151}
152
153bool QgsProjectArchive::unzip( const QString &filename )
154{
155 if ( QgsArchive::unzip( filename ) )
156 return ! projectFile().isEmpty();
157 else
158 return false;
159}
160
162{
163 return removeFile( projectFile() );
164}
165
167{
168 const QString extension = QgsAuxiliaryStorage::extension();
169
170 const QStringList fileList = files();
171 for ( const QString &file : fileList )
172 {
173 const QFileInfo fileInfo( file );
174 if ( fileInfo.suffix().compare( extension, Qt::CaseInsensitive ) == 0 )
175 return file;
176 }
177
178 return QString();
179}
Class allowing to manage the zip/unzip actions.
Definition: qgsarchive.h:36
QgsArchive()
Constructor.
Definition: qgsarchive.cpp:32
QgsArchive & operator=(const QgsArchive &other)
Definition: qgsarchive.cpp:43
virtual bool unzip(const QString &zipFilename)
Clear the current content of this archive and unzip.
Definition: qgsarchive.cpp:107
bool zip(const QString &zipFilename)
Zip the content of this archive.
Definition: qgsarchive.cpp:65
void clear()
Clear the current content of this archive and create a new temporary directory.
Definition: qgsarchive.cpp:59
bool exists() const
Returns true if the archive exists on the filesystem, false otherwise.
Definition: qgsarchive.cpp:135
void addFile(const QString &filename)
Add a new file to this archive.
Definition: qgsarchive.cpp:113
bool removeFile(const QString &filename)
Remove a file from this archive and from the filesystem.
Definition: qgsarchive.cpp:118
QString dir() const
Returns the current temporary directory.
Definition: qgsarchive.cpp:54
QStringList files() const
Returns the list of files within this archive.
Definition: qgsarchive.cpp:130
static QString extension()
Returns the extension used for auxiliary databases.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QString projectFile() const
Returns the current .qgs project file or an empty string if there's none.
Definition: qgsarchive.cpp:140
QString auxiliaryStorageFile() const
Returns the current .qgd auxiliary storage file or an empty string if there's none.
Definition: qgsarchive.cpp:166
bool clearProjectFile()
Remove the current .qgs project file from the temporary directory.
Definition: qgsarchive.cpp:161
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
Definition: qgsarchive.cpp:153
CORE_EXPORT bool unzip(const QString &zip, const QString &dir, QStringList &files)
Unzip a zip file in an output directory.
Definition: qgsziputils.cpp:37
CORE_EXPORT bool zip(const QString &zip, const QStringList &files)
Zip the list of files in the zip file.