46 KArchive *KArchiveInterface::archive()
49 KMimeType::Ptr mimeType = KMimeType::findByPath(
filename());
51 if (mimeType->is(QLatin1String(
"application/zip"))) {
64 if (!archive()->isOpen() && !archive()->
open(QIODevice::ReadOnly)) {
65 emit
error(i18nc(
"@info",
"Could not open the archive <filename>%1</filename> for reading",
filename()));
68 return browseArchive(archive());
72 void KArchiveInterface::getAllEntries(
const KArchiveDirectory *dir,
const QString &prefix, QList< QVariant > &list)
74 foreach(
const QString &entryName, dir->entries()) {
75 const KArchiveEntry *
entry = dir->entry(entryName);
76 if (entry->isDirectory()) {
77 QString newPrefix = (prefix.isEmpty() ? prefix : prefix + QLatin1Char(
'/')) + entryName;
78 getAllEntries(static_cast<const KArchiveDirectory*>(entry), newPrefix, list);
81 list.append(prefix + QLatin1Char(
'/') + entryName);
88 const bool preservePaths = options.value(QLatin1String(
"PreservePaths")).toBool();
89 const KArchiveDirectory *dir = archive()->directory();
91 if (!archive()->isOpen() && !archive()->
open(QIODevice::ReadOnly)) {
92 emit
error(i18nc(
"@info",
"Could not open the archive <filename>%1</filename> for reading",
filename()));
96 QList<QVariant> extrFiles = files;
97 if (extrFiles.isEmpty()) {
98 getAllEntries(dir, QString(), extrFiles);
101 bool overwriteAllSelected =
false;
102 bool autoSkipSelected =
false;
103 QSet<QString> dirCache;
104 foreach(
const QVariant &file, extrFiles) {
105 QString realDestination = destinationDirectory;
106 const KArchiveEntry *archiveEntry = dir->entry(file.toString());
108 emit
error(i18nc(
"@info",
"File <filename>%1</filename> not found in the archive" , file.toString()));
113 QFileInfo fi(file.toString());
114 QDir dest(destinationDirectory);
115 QString filepath = archiveEntry->isDirectory() ? fi.filePath() : fi.path();
116 if (!dirCache.contains(filepath)) {
117 if (!dest.mkpath(filepath)) {
118 emit
error(i18nc(
"@info",
"Error creating directory <filename>%1</filename>", filepath));
121 dirCache << filepath;
123 realDestination = dest.absolutePath() + QLatin1Char(
'/') + filepath;
127 if (!archiveEntry->isDirectory()) {
128 if (QFile::exists(realDestination + QLatin1Char(
'/') + archiveEntry->name()) && !overwriteAllSelected) {
129 if (autoSkipSelected) {
133 int response = handleFileExistsMessage(realDestination, archiveEntry->name());
135 if (response == OverwriteCancel) {
138 if (response == OverwriteYes || response == OverwriteAll) {
139 static_cast<const KArchiveFile*
>(archiveEntry)->copyTo(realDestination);
140 if (response == OverwriteAll) {
141 overwriteAllSelected =
true;
144 if (response == OverwriteAutoSkip) {
145 autoSkipSelected =
true;
149 static_cast<const KArchiveFile*
>(archiveEntry)->copyTo(realDestination);
157 int KArchiveInterface::handleFileExistsMessage(
const QString &dir,
const QString &fileName)
160 query.setNoRenameMode(
true);
162 query.waitForResponse();
164 if (query.responseOverwrite()) {
166 }
else if (query.responseSkip()) {
167 return OverwriteSkip;
168 }
else if (query.responseOverwriteAll()) {
170 }
else if (query.responseAutoSkip()) {
171 return OverwriteAutoSkip;
174 return OverwriteCancel;
177 bool KArchiveInterface::browseArchive(KArchive *archive)
179 return processDir(archive->directory());
182 bool KArchiveInterface::processDir(
const KArchiveDirectory *dir,
const QString & prefix)
184 foreach(
const QString& entryName, dir->entries()) {
185 const KArchiveEntry *entry = dir->entry(entryName);
186 createEntryFor(entry, prefix);
187 if (entry->isDirectory()) {
188 QString newPrefix = (prefix.isEmpty() ? prefix : prefix + QLatin1Char(
'/')) + entryName;
189 processDir(static_cast<const KArchiveDirectory*>(entry), newPrefix);
195 void KArchiveInterface::createEntryFor(
const KArchiveEntry *aentry,
const QString& prefix)
198 QString fileName = prefix.isEmpty() ? aentry->name() : prefix + QLatin1Char(
'/') + aentry->name();
200 if (aentry->isDirectory() && !fileName.endsWith(QLatin1Char(
'/')))
201 fileName += QLatin1Char(
'/');
205 e[
Permissions ] = permissionsString(aentry->permissions());
206 e[
Owner ] = aentry->user();
207 e[
Group ] = aentry->group();
210 if (!aentry->symLinkTarget().isEmpty()) {
211 e[
Link ] = aentry->symLinkTarget();
213 if (aentry->isFile()) {
214 e[
Size ] =
static_cast<const KArchiveFile*
>(aentry)->size();
225 kDebug() <<
"Starting...";
228 if (archive()->isOpen()) {
231 if (!archive()->
open(QIODevice::ReadWrite)) {
232 emit
error(i18nc(
"@info",
"Could not open the archive <filename>%1</filename> for writing.",
filename()));
236 kDebug() <<
"Archive opened for writing...";
237 kDebug() <<
"Will add " << files.count() <<
" files";
238 foreach(
const QString &path, files) {
239 kDebug() <<
"Adding " << path;
241 Q_ASSERT(fi.exists());
244 if (archive()->addLocalDirectory(path, fi.fileName())) {
245 const KArchiveEntry *entry = archive()->directory()->entry(fi.fileName());
246 createEntryFor(entry, QString());
247 processDir((KArchiveDirectory*) archive()->directory()->
entry(fi.fileName()), fi.fileName());
249 emit
error(i18nc(
"@info",
"Could not add the directory <filename>%1</filename> to the archive", path));
253 if (archive()->addLocalFile(path, fi.fileName())) {
254 const KArchiveEntry *entry = archive()->directory()->entry(fi.fileName());
255 createEntryFor(entry, QString());
257 emit
error(i18nc(
"@info",
"Could not add the file <filename>%1</filename> to the archive.", path));
262 kDebug() <<
"Closing the archive";
275 QString KArchiveInterface::permissionsString(mode_t perm)
277 static char buffer[ 12 ];
279 char uxbit,gxbit,oxbit;
281 if ( (perm & (S_IXUSR|S_ISUID)) == (S_IXUSR|S_ISUID) )
283 else if ( (perm & (S_IXUSR|S_ISUID)) == S_ISUID )
285 else if ( (perm & (S_IXUSR|S_ISUID)) == S_IXUSR )
290 if ( (perm & (S_IXGRP|S_ISGID)) == (S_IXGRP|S_ISGID) )
292 else if ( (perm & (S_IXGRP|S_ISGID)) == S_ISGID )
294 else if ( (perm & (S_IXGRP|S_ISGID)) == S_IXGRP )
299 if ( (perm & (S_IXOTH|S_ISVTX)) == (S_IXOTH|S_ISVTX) )
301 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_ISVTX )
303 else if ( (perm & (S_IXOTH|S_ISVTX)) == S_IXOTH )
312 else if (S_ISLNK(perm))
317 buffer[1] = ((( perm & S_IRUSR ) == S_IRUSR ) ?
'r' :
'-' );
318 buffer[2] = ((( perm & S_IWUSR ) == S_IWUSR ) ?
'w' :
'-' );
320 buffer[4] = ((( perm & S_IRGRP ) == S_IRGRP ) ?
'r' :
'-' );
321 buffer[5] = ((( perm & S_IWGRP ) == S_IWGRP ) ?
'w' :
'-' );
323 buffer[7] = ((( perm & S_IROTH ) == S_IROTH ) ?
'r' :
'-' );
324 buffer[8] = ((( perm & S_IWOTH ) == S_IWOTH ) ?
'w' :
'-' );
328 return QString::fromLatin1(buffer);
The user the entry belongs to.
The entry is a directory.
void userQuery(Query *query)
QString filename() const
Returns the filename of the archive currently being handled.
bool deleteFiles(const QList< QVariant > &files)
The entry is a symbolic link.
void entry(const ArchiveEntry &archiveEntry)
QHash< int, QVariant > ArchiveEntry
bool list()
List archive contents.
QHash< QString, QVariant > CompressionOptions
These are the extra options for doing the compression.
The timestamp for the current entry.
KArchiveInterface(QObject *parent=0, const QVariantList &args=QVariantList())
QHash< QString, QVariant > ExtractionOptions
void error(const QString &message, const QString &details=QString())
The entry's original size.
bool addFiles(const QStringList &files, const CompressionOptions &options)
#define KERFUFFLE_EXPORT_PLUGIN(p)
The user group the entry belongs to.
The entry's ID for Ark's internal manipulation.
bool copyFiles(const QList< QVariant > &files, const QString &destinationDirectory, ExtractionOptions options)
Extract files from archive.