Skip to content

Commit

Permalink
Merge branch 'jb36842-extration-roles' into 'master'
Browse files Browse the repository at this point in the history
[nemo-filemanager] Add extected and extrected target path roles. Contributes to JB#36842

See merge request !11
  • Loading branch information
rainemak committed Mar 13, 2018
2 parents acbc9a3 + 2ae2a0f commit a0bf9e8
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/daemon/daemon.pro
Expand Up @@ -5,6 +5,7 @@ QT += dbus
CONFIG += c++11

CONFIG += link_pkgconfig link_prl
QMAKE_CXXFLAGS += -Wparentheses -Werror -Wfatal-errors

packagesExist(qt5-boostable) {
DEFINES += HAS_BOOSTER
Expand Down
83 changes: 71 additions & 12 deletions src/plugin/archivemodel.cpp
Expand Up @@ -71,6 +71,8 @@ enum {
CreatedRole,
IsDirRole,
IsLinkRole,
ExtractedRole,
ExtractedTargetPathRole,
SymLinkTargetRole,
IsSelectedRole,
ExtensionRole,
Expand Down Expand Up @@ -239,7 +241,7 @@ void ArchiveModelPrivate::scheduleExtract(const QString &entryName, const QStrin
connect(extractionWatcher, &QFutureWatcher<FileExtractionResult>::finished, this, [this, mode]() {
FileExtractionResult result = extractionWatcher->result();
ArchiveModel::ErrorState state = result.first;
QString entry = result.second;
ExtractionInfo extractionInfo = result.second;

if (state == ArchiveModel::NoError) {
setStatus(ArchiveModel::Ready, state);
Expand All @@ -251,33 +253,49 @@ void ArchiveModelPrivate::scheduleExtract(const QString &entryName, const QStrin
emit q->extractingChanged();

if (state == ArchiveModel::NoError) {
QFileInfo entryInfo(entry);
QString absolutePath = extractionInfo.absolutePath;
QFileInfo entryInfo(absolutePath);
bool isDir = entryInfo.isDir();
QStringList entries;
QStringList extractedFiles;
if (mode == ExtractionMode::SingleFile && !isDir) {
entries << entry;
extractedFiles << absolutePath;
} else {
QDir d(entry, QString(), QDir::Name | QDir::DirsFirst, QDir::NoDotAndDotDot | QDir::AllEntries);
QDir d(absolutePath, QString(), QDir::Name | QDir::DirsFirst, QDir::NoDotAndDotDot | QDir::AllEntries);
QDirIterator dirIterator(d, QDirIterator::Subdirectories);
while (dirIterator.hasNext()) {
QString f = dirIterator.next();
entries << f;
extractedFiles << f;
}
}

QDir entryDir(entry);
QDir entryDir(absolutePath);
QString name;
if (entries.count() == 1) {
entryInfo.setFile(entries.at(0));
if (extractedFiles.count() == 1) {
entryInfo.setFile(extractedFiles.at(0));
name = entryInfo.fileName();
} else {
name = entryDir.dirName();
}

if (mode == ExtractionMode::SingleFile) {
int i = findIndex(extractionInfo.entry);
if (i >= 0) {
if (!extractedEntries.contains(extractionInfo.entry)) {
extractedEntries.insert(extractionInfo.entry, extractionInfo);
QModelIndex index = q->index(i, 0);
emit q->dataChanged(index, index, QVector<int>() << ExtractedRole << ExtractedTargetPathRole);
} else {
qCWarning(lcArchiveLog) << extractionInfo.entry << "is already extracted.";
}
} else {
qCWarning(lcArchiveLog) << extractionInfo.entry << "is not part of this archive directory. Source of bug!";
}
}

// When extracting an archive entryInfo is a directory. Thus, checking that we're extracting a single file
// from an archive that is a directory.
emit q->filesExtracted(entryDir.absolutePath(), (mode == ExtractionMode::SingleFile && entryInfo.isDir()),
name, entries);
name, extractedFiles);
}
extractionWatcher->deleteLater();
extractionWatcher = nullptr;
Expand All @@ -300,6 +318,15 @@ void ArchiveModelPrivate::scheduleExtract(const QString &entryName, const QStrin
}
}

int ArchiveModelPrivate::findIndex(const QString &entryName)
{
for (int i = 0; i < entryList.count(); ++i) {
if (entryList.at(i)->name() == entryName)
return i;
}
return -1;
}

FileExtractionResult ArchiveModelPrivate::doExtractFile(const QString &entryName, const QString &targetPath)
{
QMutexLocker lock(&extractionMutex);
Expand Down Expand Up @@ -329,7 +356,7 @@ FileExtractionResult ArchiveModelPrivate::doExtractFile(const QString &entryName

if (extracted) {
result.first = ArchiveModel::NoError;
result.second = out;
result.second = ExtractionInfo(entryName, out);
} else {
result.first = ArchiveModel::ErrorArchiveExtractFailed;
}
Expand All @@ -352,7 +379,7 @@ FileExtractionResult ArchiveModelPrivate::doExtractAllFiles(const QString &targe
QString out;
if (dir->copyTo(targetPath, true, true, &out)) {
result.first = ArchiveModel::NoError;
result.second = out;
result.second = ExtractionInfo("", out);
qCDebug(lcArchiveLog) << "Extracted archive to:" << out;
} else {
result.first = ArchiveModel::ErrorArchiveExtractFailed;
Expand Down Expand Up @@ -420,6 +447,16 @@ QVariant ArchiveModel::data(const QModelIndex &index, int role) const
}
return 0;

case ExtractedRole:
return d->extractedEntries.contains(entry->name());

case ExtractedTargetPathRole:
if (d->extractedEntries.contains(entry->name())) {
const ExtractionInfo &extrationInfo = d->extractedEntries.value(entry->name());
return extrationInfo.absolutePath;
}
return QString();

case CreatedRole:
return entry->date();

Expand Down Expand Up @@ -461,6 +498,8 @@ QHash<int, QByteArray> ArchiveModel::roleNames() const
roles.insert(MimeTypeRole, QByteArray("mimeType"));
roles.insert(SizeRole, QByteArray("size"));
roles.insert(CreatedRole, QByteArray("created"));
roles.insert(ExtractedRole, QByteArray("extracted"));
roles.insert(ExtractedTargetPathRole, QByteArray("extractedTargetPath"));
roles.insert(IsDirRole, QByteArray("isDir"));
roles.insert(IsLinkRole, QByteArray("isLink"));
roles.insert(SymLinkTargetRole, QByteArray("symLinkTarget"));
Expand Down Expand Up @@ -680,4 +719,24 @@ bool ArchiveModel::extractFile(const QString &entryName, const QString &targetPa
return true;
}

bool ArchiveModel::cleanExtractedEntry(const QString &entry)
{
if (d->extracting) {
qmlInfo(this) << "Extracting, wait for extraction to complete.";
d->setStatus(Extracting, ErrorExtractingInProgress);
return false;
}

int entryIndex = d->findIndex(entry);
if (d->extractedEntries.contains(entry) && entryIndex >= 0) {
d->extractedEntries.remove(entry);
QModelIndex index = this->index(entryIndex, 0);
emit dataChanged(index, index, QVector<int>() << ExtractedRole << ExtractedTargetPathRole);
} else {
qmlInfo(this) << "Entry:" << entry << "is not extracted.";
}

return true;
}

}
3 changes: 3 additions & 0 deletions src/plugin/archivemodel.h
Expand Up @@ -116,6 +116,9 @@ class ArchiveModel : public QAbstractListModel
Q_INVOKABLE bool extractAllFiles(const QString &targetPath);
Q_INVOKABLE bool extractFile(const QString &entryName, const QString &targetPath);

// If component user deletes the file from outside, clean state for the extracted.
Q_INVOKABLE bool cleanExtractedEntry(const QString &entry);

signals:
void pathChanged();
void statusChanged();
Expand Down
19 changes: 18 additions & 1 deletion src/plugin/archivemodel_p.h
Expand Up @@ -50,7 +50,21 @@ enum ExtractionMode {
// There could be selected files
};

typedef QPair<ArchiveModel::ErrorState, QString> FileExtractionResult;
struct ExtractionInfo
{
ExtractionInfo() {}

ExtractionInfo(QString entry, QString absolutePath)
: entry(entry)
, absolutePath(absolutePath)
{
}

QString entry;
QString absolutePath;
};

typedef QPair<ArchiveModel::ErrorState, ExtractionInfo> FileExtractionResult;

class ArchiveModelPrivate : public QObject
{
Expand All @@ -67,9 +81,12 @@ class ArchiveModelPrivate : public QObject

void scheduleExtract(const QString &entryName, const QString &targetPath, ExtractionMode mode);

int findIndex(const QString &entryName);

ArchiveModel *q;
ArchiveModel::Status status;
ArchiveModel::ErrorState errorState;
QMap<QString, ExtractionInfo> extractedEntries;
qint64 requiredSpace;
QString path;
QString errorString;
Expand Down
2 changes: 2 additions & 0 deletions src/plugin/plugin.pro
Expand Up @@ -13,6 +13,8 @@ contains(CONFIG, desktop) {
PKGCONFIG += contactcache-qt5
}

QMAKE_CXXFLAGS += -Wparentheses -Werror -Wfatal-errors

PKGCONFIG += KF5Archive

# Drop any library linkage we dont actually need (such as contactcache-qt5)
Expand Down

0 comments on commit a0bf9e8

Please sign in to comment.