summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladyslav Batyrenko <mvlabat@gmail.com>2016-05-24 19:48:53 (GMT)
committerVladyslav Batyrenko <mvlabat@gmail.com>2016-06-21 19:15:42 (GMT)
commita530116b619aed62d519188adc44e7588cada063 (patch)
tree6fb0e922f3936432f9a7700f7acc509f9c50de7b
parent88ad5a0ebf4585c0fe788f2a0902c5c204f1ecd0 (diff)
[GSoC] Refactor ArchiveNode and ArchiveDirNode classesrefs/backups/branch-gsoc2016/refactor-archiveentry-1475667581
Refactor ArchiveNode and ArchiveDirNode classes to Archive::Entry class and move its declaration to kerfuffle/archiveentry.h file. Make Archive::Entry store meta data in Q_PROPERTY members. Move EntryMetaDataType to part/archivemodel.cpp. Delete duplicated directory entries while reading from 7z archives. See: https://phabricator.kde.org/T2704
-rw-r--r--autotests/kerfuffle/data/archive-deepsinglehierarchy.json16
-rw-r--r--autotests/kerfuffle/data/archive-emptysinglefolder.json4
-rw-r--r--autotests/kerfuffle/data/archive-multiplefolders.json12
-rw-r--r--autotests/kerfuffle/data/archive-nodir-manyfiles.json4
-rw-r--r--autotests/kerfuffle/data/archive-onetopfolder.json6
-rw-r--r--autotests/kerfuffle/data/archive-password.json10
-rw-r--r--autotests/kerfuffle/data/archive-singlefile.json2
-rw-r--r--autotests/kerfuffle/data/archive-unorderedsinglefolder.json12
-rw-r--r--autotests/kerfuffle/data/archive001.json10
-rw-r--r--autotests/kerfuffle/data/archive002.json16
-rw-r--r--autotests/kerfuffle/jobstest.cpp16
-rw-r--r--autotests/kerfuffle/jsonarchiveinterface.cpp5
-rw-r--r--autotests/kerfuffle/jsonparser.cpp46
-rw-r--r--autotests/kerfuffle/jsonparser.h2
-rw-r--r--autotests/plugins/cli7zplugin/cli7ztest.cpp14
-rw-r--r--autotests/plugins/cli7zplugin/cli7ztest.h2
-rw-r--r--autotests/plugins/clirarplugin/clirartest.cpp19
-rw-r--r--autotests/plugins/clirarplugin/clirartest.h2
-rw-r--r--autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp17
-rw-r--r--autotests/plugins/cliunarchiverplugin/cliunarchivertest.h2
-rw-r--r--kerfuffle/CMakeLists.txt2
-rw-r--r--kerfuffle/archive_kerfuffle.cpp7
-rw-r--r--kerfuffle/archive_kerfuffle.h36
-rw-r--r--kerfuffle/archiveentry.cpp156
-rw-r--r--kerfuffle/archiveentry.h100
-rw-r--r--kerfuffle/archiveinterface.h3
-rw-r--r--kerfuffle/jobs.cpp15
-rw-r--r--kerfuffle/jobs.h6
-rw-r--r--part/archivemodel.cpp539
-rw-r--r--part/archivemodel.h26
-rw-r--r--part/infopanel.cpp49
-rw-r--r--part/part.cpp37
-rw-r--r--plugins/cli7zplugin/cliplugin.cpp45
-rw-r--r--plugins/cli7zplugin/cliplugin.h4
-rw-r--r--plugins/cliplugin-example/cliplugin.cpp37
-rw-r--r--plugins/cliplugin-example/cliplugin.h2
-rw-r--r--plugins/clirarplugin/cliplugin.cpp69
-rw-r--r--plugins/cliunarchiverplugin/cliplugin.cpp19
-rw-r--r--plugins/cliunarchiverplugin/cliplugin.h3
-rw-r--r--plugins/clizipplugin/cliplugin.cpp17
-rw-r--r--plugins/libarchive/libarchiveplugin.cpp21
-rw-r--r--plugins/libsinglefileplugin/singlefileplugin.cpp13
42 files changed, 741 insertions, 682 deletions
diff --git a/autotests/kerfuffle/data/archive-deepsinglehierarchy.json b/autotests/kerfuffle/data/archive-deepsinglehierarchy.json
index d673c7c..9aa8c0c 100644
--- a/autotests/kerfuffle/data/archive-deepsinglehierarchy.json
+++ b/autotests/kerfuffle/data/archive-deepsinglehierarchy.json
@@ -1,20 +1,20 @@
[
{
- "FileName": "aDir/",
- "IsDirectory": true
+ "fileName": "aDir/",
+ "isDirectory": true
},
{
- "FileName": "aDir/b.txt"
+ "fileName": "aDir/b.txt"
},
{
- "FileName": "aDir/aDirInside/",
- "IsDirectory": true
+ "fileName": "aDir/aDirInside/",
+ "isDirectory": true
},
{
- "FileName": "aDir/aDirInside/anotherDir/",
- "IsDirectory": true
+ "fileName": "aDir/aDirInside/anotherDir/",
+ "isDirectory": true
},
{
- "FileName": "aDir/aDirInside/anotherDir/file.txt"
+ "fileName": "aDir/aDirInside/anotherDir/file.txt"
}
]
diff --git a/autotests/kerfuffle/data/archive-emptysinglefolder.json b/autotests/kerfuffle/data/archive-emptysinglefolder.json
index 98f110b..e6c95a2 100644
--- a/autotests/kerfuffle/data/archive-emptysinglefolder.json
+++ b/autotests/kerfuffle/data/archive-emptysinglefolder.json
@@ -1,6 +1,6 @@
[
{
- "FileName": "aDir/",
- "IsDirectory": true
+ "fileName": "aDir/",
+ "isDirectory": true
}
]
diff --git a/autotests/kerfuffle/data/archive-multiplefolders.json b/autotests/kerfuffle/data/archive-multiplefolders.json
index 92e9224..47b0caf 100644
--- a/autotests/kerfuffle/data/archive-multiplefolders.json
+++ b/autotests/kerfuffle/data/archive-multiplefolders.json
@@ -1,16 +1,16 @@
[
{
- "FileName": "aDir/",
- "IsDirectory": true
+ "fileName": "aDir/",
+ "isDirectory": true
},
{
- "FileName": "aDir/b.txt"
+ "fileName": "aDir/b.txt"
},
{
- "FileName": "anotherDir/",
- "IsDirectory": true
+ "fileName": "anotherDir/",
+ "isDirectory": true
},
{
- "FileName": "anotherDir/file.txt"
+ "fileName": "anotherDir/file.txt"
}
]
diff --git a/autotests/kerfuffle/data/archive-nodir-manyfiles.json b/autotests/kerfuffle/data/archive-nodir-manyfiles.json
index 945c616..9f89f94 100644
--- a/autotests/kerfuffle/data/archive-nodir-manyfiles.json
+++ b/autotests/kerfuffle/data/archive-nodir-manyfiles.json
@@ -1,8 +1,8 @@
[
{
- "FileName": "a.txt"
+ "fileName": "a.txt"
},
{
- "FileName": "file.txt"
+ "fileName": "file.txt"
}
]
diff --git a/autotests/kerfuffle/data/archive-onetopfolder.json b/autotests/kerfuffle/data/archive-onetopfolder.json
index ec1e2ef..ca025e9 100644
--- a/autotests/kerfuffle/data/archive-onetopfolder.json
+++ b/autotests/kerfuffle/data/archive-onetopfolder.json
@@ -1,9 +1,9 @@
[
{
- "FileName": "aDir/",
- "IsDirectory": true
+ "fileName": "aDir/",
+ "isDirectory": true
},
{
- "FileName": "aDir/b.txt"
+ "fileName": "aDir/b.txt"
}
]
diff --git a/autotests/kerfuffle/data/archive-password.json b/autotests/kerfuffle/data/archive-password.json
index a6abd9b..73fd1c1 100644
--- a/autotests/kerfuffle/data/archive-password.json
+++ b/autotests/kerfuffle/data/archive-password.json
@@ -1,13 +1,13 @@
[
{
- "FileName": "foo.txt",
- "IsPasswordProtected": true
+ "fileName": "foo.txt",
+ "isPasswordProtected": true
},
{
- "FileName": "bar.txt"
+ "fileName": "bar.txt"
},
{
- "FileName": "aDirectory/",
- "IsDirectory": true
+ "fileName": "aDirectory/",
+ "isDirectory": true
}
]
diff --git a/autotests/kerfuffle/data/archive-singlefile.json b/autotests/kerfuffle/data/archive-singlefile.json
index 21d49f7..8573c43 100644
--- a/autotests/kerfuffle/data/archive-singlefile.json
+++ b/autotests/kerfuffle/data/archive-singlefile.json
@@ -1,5 +1,5 @@
[
{
- "FileName": "a.txt"
+ "fileName": "a.txt"
}
] \ No newline at end of file
diff --git a/autotests/kerfuffle/data/archive-unorderedsinglefolder.json b/autotests/kerfuffle/data/archive-unorderedsinglefolder.json
index 28db1cf..60ce54d 100644
--- a/autotests/kerfuffle/data/archive-unorderedsinglefolder.json
+++ b/autotests/kerfuffle/data/archive-unorderedsinglefolder.json
@@ -1,16 +1,16 @@
[
{
- "FileName": "aDir/anotherDir/bar.txt"
+ "fileName": "aDir/anotherDir/bar.txt"
},
{
- "FileName": "aDir/foo.txt"
+ "fileName": "aDir/foo.txt"
},
{
- "FileName": "aDir/anotherDir/",
- "IsDirectory": true
+ "fileName": "aDir/anotherDir/",
+ "isDirectory": true
},
{
- "FileName": "aDir/",
- "IsDirectory": true
+ "fileName": "aDir/",
+ "isDirectory": true
}
]
diff --git a/autotests/kerfuffle/data/archive001.json b/autotests/kerfuffle/data/archive001.json
index 01a7860..3efc558 100644
--- a/autotests/kerfuffle/data/archive001.json
+++ b/autotests/kerfuffle/data/archive001.json
@@ -1,15 +1,15 @@
[
{
- "FileName": "a.txt"
+ "fileName": "a.txt"
},
{
- "FileName": "aDir/",
- "IsDirectory": true
+ "fileName": "aDir/",
+ "isDirectory": true
},
{
- "FileName": "aDir/b.txt"
+ "fileName": "aDir/b.txt"
},
{
- "FileName": "c.txt"
+ "fileName": "c.txt"
}
]
diff --git a/autotests/kerfuffle/data/archive002.json b/autotests/kerfuffle/data/archive002.json
index 5aa50b6..c401919 100644
--- a/autotests/kerfuffle/data/archive002.json
+++ b/autotests/kerfuffle/data/archive002.json
@@ -1,18 +1,18 @@
[
{
- "FileName": "a.txt",
- "Size": 5
+ "fileName": "a.txt",
+ "size": 5
},
{
- "FileName": "aDir/",
- "IsDirectory": true
+ "fileName": "aDir/",
+ "isDirectory": true
},
{
- "FileName": "aDir/b.txt",
- "Size": 954
+ "fileName": "aDir/b.txt",
+ "size": 954
},
{
- "FileName": "c.txt",
- "Size": 45000
+ "fileName": "c.txt",
+ "size": 45000
}
]
diff --git a/autotests/kerfuffle/jobstest.cpp b/autotests/kerfuffle/jobstest.cpp
index 8effddc..d9dd0c9 100644
--- a/autotests/kerfuffle/jobstest.cpp
+++ b/autotests/kerfuffle/jobstest.cpp
@@ -26,6 +26,7 @@
#include "jsonarchiveinterface.h"
#include "kerfuffle/jobs.h"
+#include "kerfuffle/archiveentry.h"
#include <QDebug>
#include <QEventLoop>
@@ -42,7 +43,7 @@ public:
protected Q_SLOTS:
void init();
- void slotNewEntry(const ArchiveEntry& entry);
+ void slotNewEntry(Archive::Entry *entry);
private Q_SLOTS:
// ListJob-related tests
@@ -63,10 +64,10 @@ private Q_SLOTS:
private:
JSONArchiveInterface *createArchiveInterface(const QString& filePath);
- QList<ArchiveEntry> listEntries(JSONArchiveInterface *iface);
+ QList<Archive::Entry*> listEntries(JSONArchiveInterface *iface);
void startAndWaitForResult(KJob *job);
- QList<ArchiveEntry> m_entries;
+ QList<Archive::Entry*> m_entries;
QEventLoop m_eventLoop;
};
@@ -76,7 +77,6 @@ JobsTest::JobsTest()
: QObject(Q_NULLPTR)
, m_eventLoop(this)
{
- qRegisterMetaType<ArchiveEntry>("ArchiveEntry");
}
void JobsTest::init()
@@ -84,7 +84,7 @@ void JobsTest::init()
m_entries.clear();
}
-void JobsTest::slotNewEntry(const ArchiveEntry& entry)
+void JobsTest::slotNewEntry(Archive::Entry *entry)
{
m_entries.append(entry);
}
@@ -100,7 +100,7 @@ JSONArchiveInterface *JobsTest::createArchiveInterface(const QString& filePath)
return iface;
}
-QList<ArchiveEntry> JobsTest::listEntries(JSONArchiveInterface *iface)
+QList<Archive::Entry*> JobsTest::listEntries(JSONArchiveInterface *iface)
{
m_entries.clear();
@@ -209,7 +209,7 @@ void JobsTest::testListJob()
QCOMPARE(archiveEntries.size(), expectedEntryNames.size());
for (int i = 0; i < archiveEntries.size(); i++) {
- QCOMPARE(archiveEntries.at(i)[FileName].toString(), expectedEntryNames.at(i));
+ QCOMPARE(archiveEntries.at(i)->property("fileName").toString(), expectedEntryNames.at(i));
}
listJob->deleteLater();
@@ -310,7 +310,7 @@ void JobsTest::testRemoveEntries()
QCOMPARE(remainingEntries.size(), expectedRemainingEntries.size());
for (int i = 0; i < remainingEntries.size(); i++) {
- QCOMPARE(remainingEntries.at(i)[FileName].toString(), expectedRemainingEntries.at(i));
+ QCOMPARE(remainingEntries.at(i)->property("fileName").toString(), expectedRemainingEntries.at(i));
}
iface->deleteLater();
diff --git a/autotests/kerfuffle/jsonarchiveinterface.cpp b/autotests/kerfuffle/jsonarchiveinterface.cpp
index c135dbb..07b6d1c 100644
--- a/autotests/kerfuffle/jsonarchiveinterface.cpp
+++ b/autotests/kerfuffle/jsonarchiveinterface.cpp
@@ -26,6 +26,7 @@
#include "jsonarchiveinterface.h"
#include <qfile.h>
+#include "kerfuffle/archiveentry.h"
JSONArchiveInterface::JSONArchiveInterface(QObject *parent, const QVariantList& args)
: Kerfuffle::ReadWriteArchiveInterface(parent, args)
@@ -72,8 +73,8 @@ bool JSONArchiveInterface::addFiles(const QStringList& files, const Kerfuffle::C
return false;
}
- Kerfuffle::ArchiveEntry e;
- e[Kerfuffle::FileName] = file;
+ Kerfuffle::Archive::Entry *e = new Kerfuffle::Archive::Entry(NULL);
+ e->setProperty("fileName", file);
m_archive[file] = e;
}
diff --git a/autotests/kerfuffle/jsonparser.cpp b/autotests/kerfuffle/jsonparser.cpp
index 8719b11..f9e5751 100644
--- a/autotests/kerfuffle/jsonparser.cpp
+++ b/autotests/kerfuffle/jsonparser.cpp
@@ -25,41 +25,12 @@
#include "jsonparser.h"
#include "kerfuffle/archiveinterface.h"
+#include "kerfuffle/archiveentry.h"
#include <QDebug>
#include <QJsonDocument>
#include <QLatin1String>
-typedef QMap<QString, Kerfuffle::EntryMetaDataType> ArchiveProperties;
-
-static ArchiveProperties archiveProperties()
-{
- static ArchiveProperties properties;
-
- if (!properties.isEmpty()) {
- return properties;
- }
-
- properties[QStringLiteral("FileName")] = Kerfuffle::FileName;
- properties[QStringLiteral("InternalID")] = Kerfuffle::InternalID;
- properties[QStringLiteral("Permissions")] = Kerfuffle::Permissions;
- properties[QStringLiteral("Owner")] = Kerfuffle::Owner;
- properties[QStringLiteral("Group")] = Kerfuffle::Group;
- properties[QStringLiteral("Size")] = Kerfuffle::Size;
- properties[QStringLiteral("CompressedSize")] = Kerfuffle::CompressedSize;
- properties[QStringLiteral("Link")] = Kerfuffle::Link;
- properties[QStringLiteral("Ratio")] = Kerfuffle::Ratio;
- properties[QStringLiteral("CRC")] = Kerfuffle::CRC;
- properties[QStringLiteral("Method")] = Kerfuffle::Method;
- properties[QStringLiteral("Version")] = Kerfuffle::Version;
- properties[QStringLiteral("Timestamp")] = Kerfuffle::Timestamp;
- properties[QStringLiteral("IsDirectory")] = Kerfuffle::IsDirectory;
- properties[QStringLiteral("Comment")] = Kerfuffle::Comment;
- properties[QStringLiteral("IsPasswordProtected")] = Kerfuffle::IsPasswordProtected;
-
- return properties;
-}
-
JSONParser::JSONParser()
{
}
@@ -83,30 +54,29 @@ JSONParser::JSONArchive JSONParser::parse(QIODevice *json)
JSONParser::JSONArchive JSONParser::createJSONArchive(const QVariant &json)
{
- static const ArchiveProperties properties = archiveProperties();
-
JSONParser::JSONArchive archive;
foreach (const QVariant &entry, json.toList()) {
const QVariantMap entryMap = entry.toMap();
- if (!entryMap.contains(QStringLiteral("FileName"))) {
+ if (!entryMap.contains(QStringLiteral("fileName"))) {
continue;
}
- Kerfuffle::ArchiveEntry archiveEntry;
+ Kerfuffle::Archive::Entry *e = new Kerfuffle::Archive::Entry(Q_NULLPTR);
QVariantMap::const_iterator entryIterator = entryMap.constBegin();
for (; entryIterator != entryMap.constEnd(); ++entryIterator) {
- if (properties.contains(entryIterator.key())) {
- archiveEntry[properties[entryIterator.key()]] = entryIterator.value();
+ const char *key = entryIterator.key().toStdString().c_str();
+ if (e->property(key).isValid()) {
+ e->setProperty(key, entryIterator.value());
} else {
qDebug() << entryIterator.key() << "is not a valid entry key";
}
}
- const QString fileName = entryMap[QStringLiteral("FileName")].toString();
- archive[fileName] = archiveEntry;
+ const QString fileName = entryMap[QStringLiteral("fileName")].toString();
+ archive[fileName] = e;
}
return archive;
diff --git a/autotests/kerfuffle/jsonparser.h b/autotests/kerfuffle/jsonparser.h
index d52368c..8f02ff8 100644
--- a/autotests/kerfuffle/jsonparser.h
+++ b/autotests/kerfuffle/jsonparser.h
@@ -55,7 +55,7 @@
class JSONParser
{
public:
- typedef QMap<QString, Kerfuffle::ArchiveEntry> JSONArchive;
+ typedef QMap<QString, Kerfuffle::Archive::Entry*> JSONArchive;
~JSONParser();
diff --git a/autotests/plugins/cli7zplugin/cli7ztest.cpp b/autotests/plugins/cli7zplugin/cli7ztest.cpp
index 77dad77..4c9ecab 100644
--- a/autotests/plugins/cli7zplugin/cli7ztest.cpp
+++ b/autotests/plugins/cli7zplugin/cli7ztest.cpp
@@ -38,8 +38,6 @@ using namespace Kerfuffle;
void Cli7zTest::initTestCase()
{
- qRegisterMetaType<ArchiveEntry>();
-
m_plugin = new Plugin(this);
foreach (Plugin *plugin, m_pluginManger.availablePlugins()) {
if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_cli7z")) {
@@ -161,22 +159,22 @@ void Cli7zTest::testList()
QFETCH(int, someEntryIndex);
QVERIFY(someEntryIndex < signalSpy.count());
- ArchiveEntry entry = qvariant_cast<ArchiveEntry>(signalSpy.at(someEntryIndex).at(0));
+ Archive::Entry *entry = signalSpy.at(someEntryIndex).at(0).value<Archive::Entry *>();
QFETCH(QString, expectedName);
- QCOMPARE(entry[FileName].toString(), expectedName);
+ QCOMPARE(entry->property("fileName").toString(), expectedName);
QFETCH(bool, isDirectory);
- QCOMPARE(entry[IsDirectory].toBool(), isDirectory);
+ QCOMPARE(entry->isDir(), isDirectory);
QFETCH(bool, isPasswordProtected);
- QCOMPARE(entry[IsPasswordProtected].toBool(), isPasswordProtected);
+ QCOMPARE(entry->property("isPasswordProtected").toBool(), isPasswordProtected);
QFETCH(qulonglong, expectedSize);
- QCOMPARE(entry[Size].toULongLong(), expectedSize);
+ QCOMPARE(entry->property("size").toULongLong(), expectedSize);
QFETCH(QString, expectedTimestamp);
- QCOMPARE(entry[Timestamp].toString(), expectedTimestamp);
+ QCOMPARE(entry->property("timestamp").toString(), expectedTimestamp);
plugin->deleteLater();
}
diff --git a/autotests/plugins/cli7zplugin/cli7ztest.h b/autotests/plugins/cli7zplugin/cli7ztest.h
index c44ac46..1e55abf 100644
--- a/autotests/plugins/cli7zplugin/cli7ztest.h
+++ b/autotests/plugins/cli7zplugin/cli7ztest.h
@@ -53,6 +53,4 @@ private:
Plugin *m_plugin;
};
-Q_DECLARE_METATYPE(ArchiveEntry)
-
#endif
diff --git a/autotests/plugins/clirarplugin/clirartest.cpp b/autotests/plugins/clirarplugin/clirartest.cpp
index b069392..47b78c0 100644
--- a/autotests/plugins/clirarplugin/clirartest.cpp
+++ b/autotests/plugins/clirarplugin/clirartest.cpp
@@ -25,6 +25,7 @@
*/
#include "clirartest.h"
+#include "kerfuffle/archiveentry.h"
#include <QFile>
#include <QSignalSpy>
@@ -39,8 +40,6 @@ using namespace Kerfuffle;
void CliRarTest::initTestCase()
{
- qRegisterMetaType<ArchiveEntry>();
-
m_plugin = new Plugin(this);
foreach (Plugin *plugin, m_pluginManger.availablePlugins()) {
if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_clirar")) {
@@ -189,28 +188,28 @@ void CliRarTest::testList()
QFETCH(int, someEntryIndex);
QVERIFY(someEntryIndex < signalSpy.count());
- ArchiveEntry entry = qvariant_cast<ArchiveEntry>(signalSpy.at(someEntryIndex).at(0));
+ Archive::Entry *entry = signalSpy.at(someEntryIndex).at(0).value<Archive::Entry *>();
QFETCH(QString, expectedName);
- QCOMPARE(entry[FileName].toString(), expectedName);
+ QCOMPARE(entry->property("fileName").toString(), expectedName);
QFETCH(bool, isDirectory);
- QCOMPARE(entry[IsDirectory].toBool(), isDirectory);
+ QCOMPARE(entry->isDir(), isDirectory);
QFETCH(bool, isPasswordProtected);
- QCOMPARE(entry[IsPasswordProtected].toBool(), isPasswordProtected);
+ QCOMPARE(entry->property("isPasswordProtected").toBool(), isPasswordProtected);
QFETCH(QString, symlinkTarget);
- QCOMPARE(entry[Link].toString(), symlinkTarget);
+ QCOMPARE(entry->property("link").toString(), symlinkTarget);
QFETCH(qulonglong, expectedSize);
- QCOMPARE(entry[Size].toULongLong(), expectedSize);
+ QCOMPARE(entry->property("size").toULongLong(), expectedSize);
QFETCH(qulonglong, expectedCompressedSize);
- QCOMPARE(entry[CompressedSize].toULongLong(), expectedCompressedSize);
+ QCOMPARE(entry->property("compressedSize").toULongLong(), expectedCompressedSize);
QFETCH(QString, expectedTimestamp);
- QCOMPARE(entry[Timestamp].toString(), expectedTimestamp);
+ QCOMPARE(entry->property("timestamp").toString(), expectedTimestamp);
rarPlugin->deleteLater();
}
diff --git a/autotests/plugins/clirarplugin/clirartest.h b/autotests/plugins/clirarplugin/clirartest.h
index 7e545d3..8e53831 100644
--- a/autotests/plugins/clirarplugin/clirartest.h
+++ b/autotests/plugins/clirarplugin/clirartest.h
@@ -54,6 +54,4 @@ private:
Plugin *m_plugin;
};
-Q_DECLARE_METATYPE(ArchiveEntry)
-
#endif
diff --git a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp
index 9bc3672..a913b1a 100644
--- a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp
+++ b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.cpp
@@ -19,6 +19,7 @@
#include "cliunarchivertest.h"
#include "jobs.h"
+#include "kerfuffle/archiveentry.h"
#include <QDirIterator>
#include <QFile>
@@ -34,8 +35,6 @@ using namespace Kerfuffle;
void CliUnarchiverTest::initTestCase()
{
- qRegisterMetaType<ArchiveEntry>();
-
m_plugin = new Plugin(this);
foreach (Plugin *plugin, m_pluginManger.availablePlugins()) {
if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_cliunarchiver")) {
@@ -153,25 +152,25 @@ void CliUnarchiverTest::testList()
QFETCH(int, someEntryIndex);
QVERIFY(someEntryIndex < signalSpy.count());
- ArchiveEntry entry = qvariant_cast<ArchiveEntry>(signalSpy.at(someEntryIndex).at(0));
+ Archive::Entry *entry = signalSpy.at(someEntryIndex).at(0).value<Archive::Entry *>();
QFETCH(QString, expectedName);
- QCOMPARE(entry[FileName].toString(), expectedName);
+ QCOMPARE(entry->property("fileName").toString(), expectedName);
QFETCH(bool, isDirectory);
- QCOMPARE(entry[IsDirectory].toBool(), isDirectory);
+ QCOMPARE(entry->isDir(), isDirectory);
QFETCH(bool, isPasswordProtected);
- QCOMPARE(entry[IsPasswordProtected].toBool(), isPasswordProtected);
+ QCOMPARE(entry->property("isPasswordProtected").toBool(), isPasswordProtected);
QFETCH(qulonglong, expectedSize);
- QCOMPARE(entry[Size].toULongLong(), expectedSize);
+ QCOMPARE(entry->property("size").toULongLong(), expectedSize);
QFETCH(qulonglong, expectedCompressedSize);
- QCOMPARE(entry[CompressedSize].toULongLong(), expectedCompressedSize);
+ QCOMPARE(entry->property("compressedSize").toULongLong(), expectedCompressedSize);
QFETCH(QString, expectedTimestamp);
- QCOMPARE(entry[Timestamp].toString(), expectedTimestamp);
+ QCOMPARE(entry->property("timestamp").toString(), expectedTimestamp);
unarPlugin->deleteLater();
}
diff --git a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h
index 50ceb4a..8b36d2f 100644
--- a/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h
+++ b/autotests/plugins/cliunarchiverplugin/cliunarchivertest.h
@@ -49,6 +49,4 @@ private:
Plugin *m_plugin;
};
-Q_DECLARE_METATYPE(ArchiveEntry)
-
#endif
diff --git a/kerfuffle/CMakeLists.txt b/kerfuffle/CMakeLists.txt
index 4eaabaa..938f6e8 100644
--- a/kerfuffle/CMakeLists.txt
+++ b/kerfuffle/CMakeLists.txt
@@ -17,6 +17,8 @@ set(kerfuffle_SRCS
mimetypes.cpp
plugin.cpp
pluginmanager.cpp
+ archiveentry.cpp
+ archiveentry.h
)
kconfig_add_kcfg_files(kerfuffle_SRCS settings.kcfgc)
diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp
index fbb5a29..47cdb16 100644
--- a/kerfuffle/archive_kerfuffle.cpp
+++ b/kerfuffle/archive_kerfuffle.cpp
@@ -26,6 +26,7 @@
*/
#include "archive_kerfuffle.h"
+#include "archiveentry.h"
#include "ark_debug.h"
#include "archiveinterface.h"
#include "jobs.h"
@@ -60,8 +61,6 @@ Archive *Archive::create(const QString &fileName, const QString &fixedMimeType,
{
qCDebug(ARK) << "Going to create archive" << fileName;
- qRegisterMetaType<ArchiveEntry>("ArchiveEntry");
-
PluginManager pluginManager;
const QMimeType mimeType = fixedMimeType.isEmpty() ? determineMimeType(fileName) : QMimeDatabase().mimeTypeForName(fixedMimeType);
@@ -271,9 +270,9 @@ QString Archive::subfolderName()
return m_subfolderName;
}
-void Archive::onNewEntry(const ArchiveEntry &entry)
+void Archive::onNewEntry(const Archive::Entry *entry)
{
- if (!entry[IsDirectory].toBool()) {
+ if (!entry->isDir()) {
m_numberOfFiles++;
}
}
diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h
index 3cdacf3..112d638 100644
--- a/kerfuffle/archive_kerfuffle.h
+++ b/kerfuffle/archive_kerfuffle.h
@@ -54,44 +54,12 @@ class PreviewJob;
class Query;
class ReadOnlyArchiveInterface;
-/**
- * Meta data related to one entry in a compressed archive.
- *
- * When creating a plugin, information about every single entry in
- * an archive is contained in an ArchiveEntry, and metadata
- * is set with the entries in this enum.
- *
- * Please notice that not all archive formats support all the properties
- * below, so set those that are available.
- */
-enum EntryMetaDataType {
- FileName = 0, /**< The entry's file name */
- InternalID, /**< The entry's ID for Ark's internal manipulation */
- Permissions, /**< The entry's permissions */
- Owner, /**< The user the entry belongs to */
- Group, /**< The user group the entry belongs to */
- Size, /**< The entry's original size */
- CompressedSize, /**< The compressed size for the entry */
- Link, /**< The entry is a symbolic link */
- Ratio, /**< The compression ratio for the entry */
- CRC, /**< The entry's CRC */
- Method, /**< The compression method used on the entry */
- Version, /**< The archiver version needed to extract the entry */
- Timestamp, /**< The timestamp for the current entry */
- IsDirectory, /**< The entry is a directory */
- Comment,
- IsPasswordProtected, /**< The entry is password-protected */
- Custom = 1048576
-};
-
enum ArchiveError {
NoError = 0,
NoPlugin,
FailedPlugin
};
-typedef QHash<int, QVariant> ArchiveEntry;
-
/**
These are the extra options for doing the compression. Naming convention
is CamelCase with either Global, or the compression type (such as Zip,
@@ -166,6 +134,8 @@ public:
HeaderEncrypted
};
+ class Entry;
+
QString completeBaseName() const;
QString fileName() const;
QString comment() const;
@@ -236,7 +206,7 @@ private slots:
void onListFinished(KJob*);
void onAddFinished(KJob*);
void onUserQuery(Kerfuffle::Query*);
- void onNewEntry(const ArchiveEntry &entry);
+ void onNewEntry(const Archive::Entry *entry);
private:
Archive(ReadOnlyArchiveInterface *archiveInterface, bool isReadOnly, QObject *parent = 0);
diff --git a/kerfuffle/archiveentry.cpp b/kerfuffle/archiveentry.cpp
new file mode 100644
index 0000000..5a7ef15
--- /dev/null
+++ b/kerfuffle/archiveentry.cpp
@@ -0,0 +1,156 @@
+//
+// Created by mvlabat on 5/27/16.
+//
+
+#include "archiveentry.h"
+
+namespace Kerfuffle {
+Archive::Entry::Entry(Entry *parent)
+ : compressedSizeIsSet(true)
+ , m_parent(parent)
+{
+ clearMetaData();
+}
+
+Archive::Entry::~Entry()
+{
+ clear();
+}
+
+QList<Archive::Entry*> Archive::Entry::entries()
+{
+ Q_ASSERT(isDir());
+ return m_entries;
+}
+
+void Archive::Entry::setEntryAt(int index, Entry *value)
+{
+ Q_ASSERT(isDir());
+ m_entries[index] = value;
+}
+
+void Archive::Entry::appendEntry(Entry *entry)
+{
+ Q_ASSERT(isDir());
+ m_entries.append(entry);
+}
+
+void Archive::Entry::removeEntryAt(int index)
+{
+ Q_ASSERT(isDir());
+ delete m_entries.takeAt(index);
+}
+
+Archive::Entry *Archive::Entry::getParent() const
+{
+ return m_parent;
+}
+
+void Archive::Entry::setParent(Archive::Entry *parent)
+{
+ m_parent = parent;
+}
+
+int Archive::Entry::row() const
+{
+ if (getParent()) {
+ return getParent()->entries().indexOf(const_cast<Archive::Entry*>(this));
+ }
+ return 0;
+}
+
+bool Archive::Entry::isDir() const
+{
+ return m_isDirectory;
+}
+
+void Archive::Entry::processNameAndIcon()
+{
+ const QStringList pieces = m_fileName.split(QLatin1Char( '/' ), QString::SkipEmptyParts);
+ m_name = pieces.isEmpty() ? QString() : pieces.last();
+
+ QMimeDatabase db;
+ if (isDir()) {
+ m_icon = QIcon::fromTheme(db.mimeTypeForName(QStringLiteral("inode/directory")).iconName()).pixmap(IconSize(KIconLoader::Small),
+ IconSize(KIconLoader::Small));
+ } else {
+ m_icon = QIcon::fromTheme(db.mimeTypeForFile(m_fileName).iconName()).pixmap(IconSize(KIconLoader::Small),
+ IconSize(KIconLoader::Small));
+ }
+}
+
+QPixmap Archive::Entry::icon() const
+{
+ return m_icon;
+}
+
+QString Archive::Entry::name() const
+{
+ return m_name;
+}
+
+Archive::Entry *Archive::Entry::find(const QString & name)
+{
+ foreach(Entry *entry, m_entries) {
+ if (entry && (entry->name() == name)) {
+ return entry;
+ }
+ }
+ return 0;
+}
+
+Archive::Entry *Archive::Entry::findByPath(const QStringList & pieces, int index)
+{
+ if (index == pieces.count()) {
+ return 0;
+ }
+
+ Entry *next = find(pieces.at(index));
+
+ if (index == pieces.count() - 1) {
+ return next;
+ }
+ if (next && next->isDir()) {
+ return next->findByPath(pieces, index + 1);
+ }
+ return 0;
+}
+
+void Archive::Entry::clearMetaData()
+{
+ m_fileName.clear();
+ m_permissions.clear();
+ m_owner.clear();
+ m_group.clear();
+ m_size = 0;
+ m_compressedSize = 0;
+ m_link.clear();
+ m_ratio.clear();
+ m_CRC.clear();
+ m_method.clear();
+ m_version.clear();
+ m_timestamp = QDateTime();
+ m_isDirectory = false;
+ m_comment.clear();
+ m_isPasswordProtected = false;
+}
+
+void Archive::Entry::returnDirEntries(QList<Entry *> *store)
+{
+ foreach(Entry *entry, m_entries) {
+ if (entry->isDir()) {
+ store->prepend(entry);
+ entry->returnDirEntries(store);
+ }
+ }
+}
+
+void Archive::Entry::clear()
+{
+ if (isDir()) {
+ qDeleteAll(m_entries);
+ m_entries.clear();
+ }
+}
+
+}
diff --git a/kerfuffle/archiveentry.h b/kerfuffle/archiveentry.h
new file mode 100644
index 0000000..d6a7a4f
--- /dev/null
+++ b/kerfuffle/archiveentry.h
@@ -0,0 +1,100 @@
+//
+// Created by mvlabat on 5/27/16.
+//
+
+#ifndef ARK_ENTRY_H
+#define ARK_ENTRY_H
+
+#include "archive_kerfuffle.h"
+#include "app/ark_debug.h"
+
+#include <QtGui/QPixmap>
+#include <QtCore/QMimeDatabase>
+#include <QtCore/QDateTime>
+#include <QtGui/QIcon>
+
+#include <KIconLoader>
+
+namespace Kerfuffle {
+class Archive::Entry : public QObject
+{
+ Q_OBJECT
+
+ /**
+ * Meta data related to one entry in a compressed archive.
+ *
+ * When creating a plugin, information about every single entry in
+ * an archive is contained in an ArchiveEntry, and metadata
+ * is set with the entries in this enum.
+ *
+ * Please notice that not all archive formats support all the properties
+ * below, so set those that are available.
+ */
+ Q_PROPERTY(QString fileName MEMBER m_fileName)
+ Q_PROPERTY(QString permissions MEMBER m_permissions)
+ Q_PROPERTY(QString owner MEMBER m_owner)
+ Q_PROPERTY(QString group MEMBER m_group)
+ Q_PROPERTY(qulonglong size MEMBER m_size)
+ Q_PROPERTY(qulonglong compressedSize MEMBER m_compressedSize)
+ Q_PROPERTY(QString link MEMBER m_link)
+ Q_PROPERTY(QString ratio MEMBER m_ratio)
+ Q_PROPERTY(QString CRC MEMBER m_CRC)
+ Q_PROPERTY(QString method MEMBER m_method)
+ Q_PROPERTY(QString version MEMBER m_version)
+ Q_PROPERTY(QDateTime timestamp MEMBER m_timestamp)
+ Q_PROPERTY(bool isDirectory MEMBER m_isDirectory)
+ Q_PROPERTY(QString comment MEMBER m_comment)
+ Q_PROPERTY(bool isPasswordProtected MEMBER m_isPasswordProtected)
+
+public:
+
+ Entry(Entry *parent);
+ ~Entry();
+
+ QList<Entry*> entries();
+ void setEntryAt(int index, Entry *value);
+ void appendEntry(Entry *entry);
+ void removeEntryAt(int index);
+ Entry *getParent() const;
+ void setParent(Entry *parent);
+ int row() const;
+ bool isDir() const;
+ void processNameAndIcon();
+ QPixmap icon() const;
+ QString name() const;
+ Entry *find(const QString & name);
+ Entry *findByPath(const QStringList & pieces, int index = 0);
+ void clearMetaData();
+ void returnDirEntries(QList<Entry *> *store);
+ void clear();
+
+public:
+ bool compressedSizeIsSet;
+
+private:
+ QList<Entry*> m_entries;
+ QPixmap m_icon;
+ QString m_name;
+ Entry *m_parent;
+
+ QString m_fileName;
+ QString m_permissions;
+ QString m_owner;
+ QString m_group;
+ qulonglong m_size;
+ qulonglong m_compressedSize;
+ QString m_link;
+ QString m_ratio;
+ QString m_CRC;
+ QString m_method;
+ QString m_version;
+ QDateTime m_timestamp;
+ bool m_isDirectory;
+ QString m_comment;
+ bool m_isPasswordProtected;
+};
+
+}
+
+
+#endif //ARK_ENTRY_H
diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h
index ec20537..0afffa6 100644
--- a/kerfuffle/archiveinterface.h
+++ b/kerfuffle/archiveinterface.h
@@ -29,6 +29,7 @@
#define ARCHIVEINTERFACE_H
#include "archive_kerfuffle.h"
+#include "archive_entry.h"
#include "kerfuffle_export.h"
#include <QObject>
@@ -107,7 +108,7 @@ public:
signals:
void cancelled();
void error(const QString &message, const QString &details = QString());
- void entry(const ArchiveEntry &archiveEntry);
+ void entry(Archive::Entry *archiveEntry);
void entryRemoved(const QString &path);
void progress(double progress);
void info(const QString &info);
diff --git a/kerfuffle/jobs.cpp b/kerfuffle/jobs.cpp
index c14e514..33427f1 100644
--- a/kerfuffle/jobs.cpp
+++ b/kerfuffle/jobs.cpp
@@ -26,6 +26,7 @@
*/
#include "jobs.h"
+#include "archiveentry.h"
#include "ark_debug.h"
#include <QDir>
@@ -151,9 +152,9 @@ void Job::onError(const QString & message, const QString & details)
setErrorText(message);
}
-void Job::onEntry(const ArchiveEntry & archiveEntry)
+void Job::onEntry(Archive::Entry *entry)
{
- emit newEntry(archiveEntry);
+ emit newEntry(entry);
}
void Job::onProgress(double value)
@@ -234,12 +235,12 @@ bool ListJob::isSingleFolderArchive() const
return m_isSingleFolderArchive;
}
-void ListJob::onNewEntry(const ArchiveEntry& entry)
+void ListJob::onNewEntry(const Archive::Entry *entry)
{
- m_extractedFilesSize += entry[ Size ].toLongLong();
- m_isPasswordProtected |= entry [ IsPasswordProtected ].toBool();
+ m_extractedFilesSize += entry->property("size").toLongLong();
+ m_isPasswordProtected |= entry->property("isPasswordProtected").toBool();
- if (entry[IsDirectory].toBool()) {
+ if (entry->isDir()) {
m_dirCount++;
} else {
m_filesCount++;
@@ -247,7 +248,7 @@ void ListJob::onNewEntry(const ArchiveEntry& entry)
if (m_isSingleFolderArchive) {
// RPM filenames have the ./ prefix, and "." would be detected as the subfolder name, so we remove it.
- const QString fileName = entry[FileName].toString().replace(QRegularExpression(QStringLiteral("^\\./")), QString());
+ const QString fileName = entry->property("fileName").toString().replace(QRegularExpression(QStringLiteral("^\\./")), QString());
const QString basePath = fileName.split(QLatin1Char('/')).at(0);
if (m_basePath.isEmpty()) {
diff --git a/kerfuffle/jobs.h b/kerfuffle/jobs.h
index 8633b87..67a75d1 100644
--- a/kerfuffle/jobs.h
+++ b/kerfuffle/jobs.h
@@ -67,7 +67,7 @@ protected slots:
virtual void onCancelled();
virtual void onError(const QString &message, const QString &details);
virtual void onInfo(const QString &info);
- virtual void onEntry(const ArchiveEntry &archiveEntry);
+ virtual void onEntry(Archive::Entry *entry);
virtual void onProgress(double progress);
virtual void onEntryRemoved(const QString &path);
virtual void onFinished(bool result);
@@ -76,7 +76,7 @@ protected slots:
signals:
void entryRemoved(const QString & entry);
void error(const QString& errorMessage, const QString& details);
- void newEntry(const ArchiveEntry &);
+ void newEntry(Archive::Entry*);
void userQuery(Kerfuffle::Query*);
private:
@@ -114,7 +114,7 @@ private:
qlonglong m_filesCount;
private slots:
- void onNewEntry(const ArchiveEntry&);
+ void onNewEntry(const Archive::Entry*);
};
class KERFUFFLE_EXPORT ExtractJob : public Job
diff --git a/part/archivemodel.cpp b/part/archivemodel.cpp
index b8aec0e..b7c9e12 100644
--- a/part/archivemodel.cpp
+++ b/part/archivemodel.cpp
@@ -23,188 +23,64 @@
#include "archivemodel.h"
#include "ark_debug.h"
-#include "kerfuffle/archive_kerfuffle.h"
+#include "kerfuffle/archiveentry.h"
#include "kerfuffle/jobs.h"
-#include <KIconLoader>
#include <KLocalizedString>
#include <kio/global.h>
-#include <QDateTime>
#include <QDBusConnection>
#include <QMimeData>
-#include <QMimeDatabase>
-#include <QPersistentModelIndex>
#include <QRegularExpression>
#include <QUrl>
using namespace Kerfuffle;
-class ArchiveDirNode;
-
//used to speed up the loading of large archives
-static ArchiveNode* s_previousMatch = Q_NULLPTR;
+static Archive::Entry *s_previousMatch = Q_NULLPTR;
Q_GLOBAL_STATIC(QStringList, s_previousPieces)
-
-// TODO: This class hierarchy needs some love.
-// Having a parent take a child class as a parameter in the constructor
-// should trigger one's spider-sense (TM).
-class ArchiveNode
-{
-public:
- ArchiveNode(ArchiveDirNode *parent, const ArchiveEntry & entry)
- : m_parent(parent)
- {
- setEntry(entry);
- }
-
- virtual ~ArchiveNode()
- {
- }
-
- const ArchiveEntry &entry() const
- {
- return m_entry;
- }
-
- void setEntry(const ArchiveEntry& entry)
- {
- m_entry = entry;
-
- const QStringList pieces = entry[FileName].toString().split(QLatin1Char( '/' ), QString::SkipEmptyParts);
- m_name = pieces.isEmpty() ? QString() : pieces.last();
-
- QMimeDatabase db;
- if (entry[IsDirectory].toBool()) {
- m_icon = QIcon::fromTheme(db.mimeTypeForName(QStringLiteral("inode/directory")).iconName()).pixmap(IconSize(KIconLoader::Small),
- IconSize(KIconLoader::Small));
- } else {
- m_icon = QIcon::fromTheme(db.mimeTypeForFile(m_entry[FileName].toString()).iconName()).pixmap(IconSize(KIconLoader::Small),
- IconSize(KIconLoader::Small));
- }
- }
-
- ArchiveDirNode *parent() const
- {
- return m_parent;
- }
-
- int row() const;
-
- virtual bool isDir() const
- {
- return false;
- }
-
- QPixmap icon() const
- {
- return m_icon;
- }
-
- QString name() const
- {
- return m_name;
- }
-
-protected:
- void setIcon(const QPixmap &icon)
- {
- m_icon = icon;
- }
-
-private:
- ArchiveEntry m_entry;
- QPixmap m_icon;
- QString m_name;
- ArchiveDirNode *m_parent;
+/**
+ * Meta data related to one entry in a compressed archive.
+ *
+ * This is used for indexing entry properties as numbers
+ * and for determining data displaying order in part's view.
+ */
+enum EntryMetaDataType {
+ FileName, /**< The entry's file name */
+ Size, /**< The entry's original size */
+ CompressedSize, /**< The compressed size for the entry */
+ Permissions, /**< The entry's permissions */
+ Owner, /**< The user the entry belongs to */
+ Group, /**< The user group the entry belongs to */
+ Ratio, /**< The compression ratio for the entry */
+ CRC, /**< The entry's CRC */
+ Method, /**< The compression method used on the entry */
+ Version, /**< The archiver version needed to extract the entry */
+ Timestamp, /**< The timestamp for the current entry */
+ Comment,
};
-
-class ArchiveDirNode: public ArchiveNode
-{
-public:
- ArchiveDirNode(ArchiveDirNode *parent, const ArchiveEntry & entry)
- : ArchiveNode(parent, entry)
- {
- }
-
- ~ArchiveDirNode()
- {
- clear();
- }
-
- QList<ArchiveNode*> entries()
- {
- return m_entries;
- }
-
- void setEntryAt(int index, ArchiveNode* value)
- {
- m_entries[index] = value;
- }
-
- void appendEntry(ArchiveNode* entry)
- {
- m_entries.append(entry);
- }
-
- void removeEntryAt(int index)
- {
- delete m_entries.takeAt(index);
- }
-
- virtual bool isDir() const
- {
- return true;
- }
-
- ArchiveNode* find(const QString & name)
- {
- foreach(ArchiveNode *node, m_entries) {
- if (node && (node->name() == name)) {
- return node;
- }
- }
- return 0;
- }
-
- ArchiveNode* findByPath(const QStringList & pieces, int index = 0)
- {
- if (index == pieces.count()) {
- return 0;
- }
-
- ArchiveNode *next = find(pieces.at(index));
-
- if (index == pieces.count() - 1) {
- return next;
- }
- if (next && next->isDir()) {
- return static_cast<ArchiveDirNode*>(next)->findByPath(pieces, index + 1);
- }
- return 0;
- }
-
- void returnDirNodes(QList<ArchiveDirNode*> *store)
- {
- foreach(ArchiveNode *node, m_entries) {
- if (node->isDir()) {
- store->prepend(static_cast<ArchiveDirNode*>(node));
- static_cast<ArchiveDirNode*>(node)->returnDirNodes(store);
- }
- }
- }
-
- void clear()
- {
- qDeleteAll(m_entries);
- m_entries.clear();
- }
-
-private:
- QList<ArchiveNode*> m_entries;
-};
+/**
+ * Mappings between column indexes and entry properties.
+ */
+static QMap<int, QString> initializePropertiesList() {
+ QMap<int, QString> propertiesList = QMap<int, QString>();
+ propertiesList.insert(FileName, QStringLiteral("fileName"));
+ propertiesList.insert(Size, QStringLiteral("size"));
+ propertiesList.insert(CompressedSize, QStringLiteral("compressedSize"));
+ propertiesList.insert(Permissions, QStringLiteral("permissions"));
+ propertiesList.insert(Owner, QStringLiteral("owner"));
+ propertiesList.insert(Group, QStringLiteral("group"));
+ propertiesList.insert(Ratio, QStringLiteral("ratio"));
+ propertiesList.insert(CRC, QStringLiteral("CRC"));
+ propertiesList.insert(Method, QStringLiteral("method"));
+ propertiesList.insert(Version, QStringLiteral("version"));
+ propertiesList.insert(Timestamp, QStringLiteral("timestamp"));
+ propertiesList.insert(Comment, QStringLiteral("comment"));
+ return propertiesList;
+}
+static const QMap<int, QString> propertiesList = initializePropertiesList();
/**
* Helper functor used by qStableSort.
@@ -226,7 +102,7 @@ public:
{
}
- inline bool operator()(const QPair<ArchiveNode*, int> &left, const QPair<ArchiveNode*, int> &right) const
+ inline bool operator()(const QPair<Archive::Entry*, int> &left, const QPair<Archive::Entry*, int> &right) const
{
if (m_sortOrder == Qt::AscendingOrder) {
return lessThan(left, right);
@@ -236,29 +112,30 @@ public:
}
protected:
- bool lessThan(const QPair<ArchiveNode*, int> &left, const QPair<ArchiveNode*, int> &right) const
+ bool lessThan(const QPair<Archive::Entry*, int> &left, const QPair<Archive::Entry*, int> &right) const
{
- const ArchiveNode * const leftNode = left.first;
- const ArchiveNode * const rightNode = right.first;
+ const Archive::Entry * const leftEntry = left.first;
+ const Archive::Entry * const rightEntry = right.first;
// #234373: sort folders before files
- if ((leftNode->isDir()) && (!rightNode->isDir())) {
+ if ((leftEntry->isDir()) && (!rightEntry->isDir())) {
return (m_sortOrder == Qt::AscendingOrder);
- } else if ((!leftNode->isDir()) && (rightNode->isDir())) {
+ } else if ((!leftEntry->isDir()) && (rightEntry->isDir())) {
return !(m_sortOrder == Qt::AscendingOrder);
}
- const QVariant &leftEntry = leftNode->entry()[m_sortColumn];
- const QVariant &rightEntry = rightNode->entry()[m_sortColumn];
+ EntryMetaDataType column = static_cast<EntryMetaDataType>(m_sortColumn);
+ const QVariant &leftEntryMetaData = leftEntry->property(propertiesList[column].toStdString().c_str());
+ const QVariant &rightEntryMetaData = rightEntry->property(propertiesList[column].toStdString().c_str());
switch (m_sortColumn) {
case FileName:
- return leftNode->name() < rightNode->name();
+ return leftEntry->name() < rightEntry->name();
case Size:
case CompressedSize:
- return leftEntry.toInt() < rightEntry.toInt();
+ return leftEntryMetaData.toInt() < rightEntryMetaData.toInt();
default:
- return leftEntry.toString() < rightEntry.toString();
+ return leftEntryMetaData.toString() < rightEntryMetaData.toString();
}
// We should not get here.
@@ -271,66 +148,59 @@ private:
Qt::SortOrder m_sortOrder;
};
-int ArchiveNode::row() const
-{
- if (parent()) {
- return parent()->entries().indexOf(const_cast<ArchiveNode*>(this));
- }
- return 0;
-}
-
ArchiveModel::ArchiveModel(const QString &dbusPathName, QObject *parent)
: QAbstractItemModel(parent)
- , m_rootNode(new ArchiveDirNode(0, ArchiveEntry()))
+ , m_rootEntry(new Archive::Entry(Q_NULLPTR))
, m_dbusPathName(dbusPathName)
{
+ m_rootEntry->setProperty("isDirectory", true);
}
ArchiveModel::~ArchiveModel()
{
- delete m_rootNode;
- m_rootNode = 0;
+ delete m_rootEntry;
+ m_rootEntry = 0;
}
QVariant ArchiveModel::data(const QModelIndex &index, int role) const
{
if (index.isValid()) {
- ArchiveNode *node = static_cast<ArchiveNode*>(index.internalPointer());
+ Archive::Entry *entry = static_cast<Archive::Entry*>(index.internalPointer());
switch (role) {
case Qt::DisplayRole: {
//TODO: complete the columns
- int columnId = m_showColumns.at(index.column());
- switch (columnId) {
+ int column = m_showColumns.at(index.column());
+ switch (column) {
case FileName:
- return node->name();
+ return entry->name();
case Size:
- if (node->isDir()) {
+ if (entry->isDir()) {
int dirs;
int files;
const int children = childCount(index, dirs, files);
return KIO::itemsSummaryString(children, files, dirs, 0, false);
- } else if (node->entry().contains(Link)) {
+ } else if (!entry->property("link").toString().isEmpty()) {
return QVariant();
} else {
- return KIO::convertSize(node->entry()[ Size ].toULongLong());
+ return KIO::convertSize(entry->property("size").toULongLong());
}
case CompressedSize:
- if (node->isDir() || node->entry().contains(Link)) {
+ if (entry->isDir() || !entry->property("link").toString().isEmpty()) {
return QVariant();
} else {
- qulonglong compressedSize = node->entry()[ CompressedSize ].toULongLong();
+ qulonglong compressedSize = entry->property("compressedSize").toULongLong();
if (compressedSize != 0) {
return KIO::convertSize(compressedSize);
} else {
return QVariant();
}
}
- case Ratio: // TODO: Use node->entry()[Ratio] when available
- if (node->isDir() || node->entry().contains(Link)) {
+ case Ratio: // TODO: Use entry->metaData()[Ratio] when available
+ if (entry->isDir() || !entry->property("link").toString().isEmpty()) {
return QVariant();
} else {
- qulonglong compressedSize = node->entry()[ CompressedSize ].toULongLong();
- qulonglong size = node->entry()[ Size ].toULongLong();
+ qulonglong compressedSize = entry->property("compressedSize").toULongLong();
+ qulonglong size = entry->property("size").toULongLong();
if (compressedSize == 0 || size == 0) {
return QVariant();
} else {
@@ -340,23 +210,22 @@ QVariant ArchiveModel::data(const QModelIndex &index, int role) const
}
case Timestamp: {
- const QDateTime timeStamp = node->entry().value(Timestamp).toDateTime();
+ const QDateTime timeStamp = entry->property("timestamp").toDateTime();
return QLocale().toString(timeStamp, QLocale::ShortFormat);
}
default:
- return node->entry().value(columnId);
+ return entry->property(propertiesList[column].toStdString().c_str());
}
- break;
}
case Qt::DecorationRole:
if (index.column() == 0) {
- return node->icon();
+ return entry->icon();
}
return QVariant();
case Qt::FontRole: {
QFont f;
- f.setItalic(node->entry()[ IsPasswordProtected ].toBool());
+ f.setItalic(entry->property("isPasswordProtected").toBool());
return f;
}
default:
@@ -425,11 +294,11 @@ QVariant ArchiveModel::headerData(int section, Qt::Orientation, int role) const
QModelIndex ArchiveModel::index(int row, int column, const QModelIndex &parent) const
{
if (hasIndex(row, column, parent)) {
- ArchiveDirNode *parentNode = parent.isValid() ? static_cast<ArchiveDirNode*>(parent.internalPointer()) : m_rootNode;
+ Archive::Entry *parentEntry = parent.isValid() ? static_cast<Archive::Entry*>(parent.internalPointer()) : m_rootEntry;
- Q_ASSERT(parentNode->isDir());
+ Q_ASSERT(parentEntry->isDir());
- ArchiveNode *item = parentNode->entries().value(row, 0);
+ Archive::Entry *item = parentEntry->entries().value(row, 0);
if (item) {
return createIndex(row, column, item);
}
@@ -441,35 +310,35 @@ QModelIndex ArchiveModel::index(int row, int column, const QModelIndex &parent)
QModelIndex ArchiveModel::parent(const QModelIndex &index) const
{
if (index.isValid()) {
- ArchiveNode *item = static_cast<ArchiveNode*>(index.internalPointer());
+ Archive::Entry *item = static_cast<Archive::Entry*>(index.internalPointer());
Q_ASSERT(item);
- if (item->parent() && (item->parent() != m_rootNode)) {
- return createIndex(item->parent()->row(), 0, item->parent());
+ if (item->getParent() && (item->getParent() != m_rootEntry)) {
+ return createIndex(item->getParent()->row(), 0, item->getParent());
}
}
return QModelIndex();
}
-ArchiveEntry ArchiveModel::entryForIndex(const QModelIndex &index)
+Archive::Entry *ArchiveModel::entryForIndex(const QModelIndex &index)
{
if (index.isValid()) {
- ArchiveNode *item = static_cast<ArchiveNode*>(index.internalPointer());
+ Archive::Entry *item = static_cast<Archive::Entry*>(index.internalPointer());
Q_ASSERT(item);
- return item->entry();
+ return item;
}
- return ArchiveEntry();
+ return Q_NULLPTR;
}
int ArchiveModel::childCount(const QModelIndex &index, int &dirs, int &files) const
{
if (index.isValid()) {
dirs = files = 0;
- ArchiveNode *item = static_cast<ArchiveNode*>(index.internalPointer());
+ Archive::Entry *item = static_cast<Archive::Entry*>(index.internalPointer());
Q_ASSERT(item);
if (item->isDir()) {
- const QList<ArchiveNode*> entries = static_cast<ArchiveDirNode*>(item)->entries();
- foreach(const ArchiveNode *node, entries) {
- if (node->isDir()) {
+ const QList<Archive::Entry*> entries = static_cast<Archive::Entry*>(item)->entries();
+ foreach(const Archive::Entry *entry, entries) {
+ if (entry->isDir()) {
dirs++;
} else {
files++;
@@ -485,10 +354,10 @@ int ArchiveModel::childCount(const QModelIndex &index, int &dirs, int &files) co
int ArchiveModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() <= 0) {
- ArchiveNode *parentNode = parent.isValid() ? static_cast<ArchiveNode*>(parent.internalPointer()) : m_rootNode;
+ Archive::Entry *parentEntry = parent.isValid() ? static_cast<Archive::Entry*>(parent.internalPointer()) : m_rootEntry;
- if (parentNode && parentNode->isDir()) {
- return static_cast<ArchiveDirNode*>(parentNode)->entries().count();
+ if (parentEntry && parentEntry->isDir()) {
+ return static_cast<Archive::Entry*>(parentEntry)->entries().count();
}
}
return 0;
@@ -507,16 +376,16 @@ void ArchiveModel::sort(int column, Qt::SortOrder order)
emit layoutAboutToBeChanged();
- QList<ArchiveDirNode*> dirNodes;
- m_rootNode->returnDirNodes(&dirNodes);
- dirNodes.append(m_rootNode);
+ QList<Archive::Entry*> dirEntries;
+ m_rootEntry->returnDirEntries(&dirEntries);
+ dirEntries.append(m_rootEntry);
const ArchiveModelSorter modelSorter(m_showColumns.at(column), order);
- foreach(ArchiveDirNode* dir, dirNodes) {
- QVector < QPair<ArchiveNode*,int> > sorting(dir->entries().count());
+ foreach(Archive::Entry *dir, dirEntries) {
+ QVector < QPair<Archive::Entry*,int> > sorting(dir->entries().count());
for (int i = 0; i < dir->entries().count(); ++i) {
- ArchiveNode *item = dir->entries().at(i);
+ Archive::Entry *item = dir->entries().at(i);
sorting[i].first = item;
sorting[i].second = i;
}
@@ -526,7 +395,7 @@ void ArchiveModel::sort(int column, Qt::SortOrder order)
QModelIndexList fromIndexes;
QModelIndexList toIndexes;
for (int r = 0; r < sorting.count(); ++r) {
- ArchiveNode *item = sorting.at(r).first;
+ Archive::Entry *item = sorting.at(r).first;
toIndexes.append(createIndex(r, 0, item));
fromIndexes.append(createIndex(sorting.at(r).second, 0, sorting.at(r).first));
dir->setEntryAt(r, sorting.at(r).first);
@@ -535,8 +404,8 @@ void ArchiveModel::sort(int column, Qt::SortOrder order)
changePersistentIndexList(fromIndexes, toIndexes);
emit dataChanged(
- index(0, 0, indexForNode(dir)),
- index(dir->entries().size() - 1, 0, indexForNode(dir)));
+ index(0, 0, indexForEntry(dir)),
+ index(dir->entries().size() - 1, 0, indexForEntry(dir)));
}
emit layoutChanged();
@@ -598,11 +467,12 @@ bool ArchiveModel::dropMimeData(const QMimeData * data, Qt::DropAction action, i
#if 0
if (parent.isValid()) {
QModelIndex droppedOnto = index(row, column, parent);
- if (entryForIndex(droppedOnto).value(IsDirectory).toBool()) {
+ Archive::Entry *entry = entryForIndex(droppedOnto);
+ if (entry->isDir()) {
qCDebug(ARK) << "Using entry";
- path = entryForIndex(droppedOnto).value(FileName).toString();
+ path = entry->fileName.toString();
} else {
- path = entryForIndex(parent).value(FileName).toString();
+ path = entryForIndex(parent)->fileName.toString();
}
}
@@ -632,9 +502,9 @@ QString ArchiveModel::cleanFileName(const QString& fileName)
return fileName;
}
-ArchiveDirNode* ArchiveModel::parentFor(const ArchiveEntry& entry)
+Archive::Entry *ArchiveModel::parentFor(const Archive::Entry *entry)
{
- QStringList pieces = entry[ FileName ].toString().split(QLatin1Char( '/' ), QString::SkipEmptyParts);
+ QStringList pieces = entry->property("fileName").toString().split(QLatin1Char( '/' ), QString::SkipEmptyParts);
if (pieces.isEmpty()) {
return Q_NULLPTR;
}
@@ -656,32 +526,37 @@ ArchiveDirNode* ArchiveModel::parentFor(const ArchiveEntry& entry)
//if match return it
if (equal) {
- return static_cast<ArchiveDirNode*>(s_previousMatch);
+ return s_previousMatch;
}
}
}
- ArchiveDirNode *parent = m_rootNode;
+ Archive::Entry *parent = m_rootEntry;
foreach(const QString &piece, pieces) {
- ArchiveNode *node = parent->find(piece);
- if (!node) {
- ArchiveEntry e;
- e[ FileName ] = (parent == m_rootNode) ?
- piece : parent->entry()[ FileName ].toString() + QLatin1Char( '/' ) + piece;
- e[ InternalID ] = e.value(FileName);
- e[ IsDirectory ] = true;
- node = new ArchiveDirNode(parent, e);
- insertNode(node);
+ Archive::Entry *entry = parent->find(piece);
+ if (!entry) {
+ // Directory entry will be traversed later (that happens for some archive formats, 7z for instance).
+ // We have to create one before, in order to construct tree from its children,
+ // and then delete the existing one (see ArchiveModel::newEntry).
+ entry = new Archive::Entry(parent);
+
+ entry->setProperty("fileName", (parent == m_rootEntry)
+ ? piece
+ : parent->property("fileName").toString() + QLatin1Char( '/' ) + piece);
+ entry->setProperty("isDirectory", true);
+ entry->processNameAndIcon();
+ insertEntry(entry);
}
- if (!node->isDir()) {
- ArchiveEntry e(node->entry());
- node = new ArchiveDirNode(parent, e);
- //Maybe we have both a file and a directory of the same name
- // We avoid removing previous entries unless necessary
- insertNode(node);
+ if (!entry->isDir()) {
+ Archive::Entry *e = new Archive::Entry(parent);
+ copyEntryMetaData(e, entry);
+ e->processNameAndIcon();
+ // Maybe we have both a file and a directory of the same name.
+ // We avoid removing previous entries unless necessary.
+ insertEntry(e);
}
- parent = static_cast<ArchiveDirNode*>(node);
+ parent = entry;
}
s_previousMatch = parent;
@@ -689,13 +564,14 @@ ArchiveDirNode* ArchiveModel::parentFor(const ArchiveEntry& entry)
return parent;
}
-QModelIndex ArchiveModel::indexForNode(ArchiveNode *node)
+
+QModelIndex ArchiveModel::indexForEntry(Archive::Entry *entry)
{
- Q_ASSERT(node);
- if (node != m_rootNode) {
- Q_ASSERT(node->parent());
- Q_ASSERT(node->parent()->isDir());
- return createIndex(node->row(), 0, node);
+ Q_ASSERT(entry);
+ if (entry != m_rootEntry) {
+ Q_ASSERT(entry->getParent());
+ Q_ASSERT(entry->getParent()->isDir());
+ return createIndex(entry->row(), 0, entry);
}
return QModelIndex();
}
@@ -707,16 +583,16 @@ void ArchiveModel::slotEntryRemoved(const QString & path)
return;
}
- ArchiveNode *entry = m_rootNode->findByPath(entryFileName.split(QLatin1Char( '/' ), QString::SkipEmptyParts));
+ Archive::Entry *entry = m_rootEntry->findByPath(entryFileName.split(QLatin1Char( '/' ), QString::SkipEmptyParts));
if (entry) {
- ArchiveDirNode *parent = entry->parent();
- QModelIndex index = indexForNode(entry);
+ Archive::Entry *parent = entry->getParent();
+ QModelIndex index = indexForEntry(entry);
Q_UNUSED(index);
- beginRemoveRows(indexForNode(parent), entry->row(), entry->row());
+ beginRemoveRows(indexForEntry(parent), entry->row(), entry->row());
- //delete parent->entries()[ entry->row() ];
- //parent->entries()[ entry->row() ] = 0;
+ //delete parent->entries()[ metaData->row() ];
+ //parent->entries()[ metaData->row() ] = 0;
parent->removeEntryAt(entry->row());
endRemoveRows();
@@ -728,7 +604,7 @@ void ArchiveModel::slotUserQuery(Kerfuffle::Query *query)
query->execute();
}
-void ArchiveModel::slotNewEntryFromSetArchive(const ArchiveEntry& entry)
+void ArchiveModel::slotNewEntryFromSetArchive(Archive::Entry *entry)
{
// we cache all entries that appear when opening a new archive
// so we can all them together once it's done, this is a huge
@@ -737,14 +613,14 @@ void ArchiveModel::slotNewEntryFromSetArchive(const ArchiveEntry& entry)
m_newArchiveEntries.push_back(entry);
}
-void ArchiveModel::slotNewEntry(const ArchiveEntry& entry)
+void ArchiveModel::slotNewEntry(Archive::Entry *entry)
{
newEntry(entry, NotifyViews);
}
-void ArchiveModel::newEntry(const ArchiveEntry& receivedEntry, InsertBehaviour behaviour)
+void ArchiveModel::newEntry(Archive::Entry *receivedEntry, InsertBehaviour behaviour)
{
- if (receivedEntry[FileName].toString().isEmpty()) {
+ if (receivedEntry->property("fileName").toString().isEmpty()) {
qCDebug(ARK) << "Weird, received empty entry (no filename) - skipping";
return;
}
@@ -752,28 +628,16 @@ void ArchiveModel::newEntry(const ArchiveEntry& receivedEntry, InsertBehaviour b
//if there are no addidional columns registered, then have a look at the
//entry and populate some
if (m_showColumns.isEmpty()) {
- //these are the columns we are interested in showing in the display
- static const QList<int> columnsForDisplay =
- QList<int>()
- << FileName
- << Size
- << CompressedSize
- << Permissions
- << Owner
- << Group
- << Ratio
- << CRC
- << Method
- << Version
- << Timestamp
- << Comment;
-
QList<int> toInsert;
- foreach(int column, columnsForDisplay) {
- if (receivedEntry.contains(column)) {
- toInsert << column;
+ QMap<int, QString>::const_iterator i = propertiesList.begin();
+ while (i != propertiesList.end()) {
+ if (!receivedEntry->property(i.value().toStdString().c_str()).toString().isEmpty()) {
+ if (i.key() != CompressedSize || receivedEntry->compressedSizeIsSet) {
+ toInsert << i.key();
+ }
}
+ ++i;
}
beginInsertColumns(QModelIndex(), 0, toInsert.size() - 1);
m_showColumns << toInsert;
@@ -782,58 +646,54 @@ void ArchiveModel::newEntry(const ArchiveEntry& receivedEntry, InsertBehaviour b
qCDebug(ARK) << "Showing columns: " << m_showColumns;
}
- //make a copy
- ArchiveEntry entry = receivedEntry;
-
//#194241: Filenames such as "./file" should be displayed as "file"
//#241967: Entries called "/" should be ignored
//#355839: Entries called "//" should be ignored
- QString entryFileName = cleanFileName(entry[FileName].toString());
+ QString entryFileName = cleanFileName(receivedEntry->property("fileName").toString());
if (entryFileName.isEmpty()) { // The entry contains only "." or "./"
return;
}
- entry[FileName] = entryFileName;
+ receivedEntry->setProperty("fileName", entryFileName);
- /// 1. Skip already created nodes
- if (m_rootNode) {
- ArchiveNode *existing = m_rootNode->findByPath(entry[ FileName ].toString().split(QLatin1Char( '/' )));
+ /// 1. Skip already created entries
+ if (m_rootEntry) {
+ Archive::Entry *existing = m_rootEntry->findByPath(entryFileName.split(QLatin1Char( '/' )));
if (existing) {
- qCDebug(ARK) << "Refreshing entry for" << entry[FileName].toString();
+ qCDebug(ARK) << "Refreshing entry for" << entryFileName;
+ existing->setProperty("fileName", entryFileName);
// Multi-volume files are repeated at least in RAR archives.
// In that case, we need to sum the compressed size for each volume
- qulonglong currentCompressedSize = existing->entry()[CompressedSize].toULongLong();
- entry[CompressedSize] = currentCompressedSize + entry[CompressedSize].toULongLong();
-
- //TODO: benchmark whether it's a bad idea to reset the entry here.
- existing->setEntry(entry);
+ qulonglong currentCompressedSize = existing->property("compressedSize").toULongLong();
+ existing->setProperty("compressedSize", currentCompressedSize + receivedEntry->property("compressedSize").toULongLong());
+ existing->processNameAndIcon();
return;
}
}
- /// 2. Find Parent Node, creating missing ArchiveDirNodes in the process
- ArchiveDirNode *parent = parentFor(entry);
+ /// 2. Find Parent Entry, creating missing direcotry ArchiveEntries in the process
+ Archive::Entry *parent = parentFor(receivedEntry);
- /// 3. Create an ArchiveNode
- const QStringList path = entry[FileName].toString().split(QLatin1Char('/'), QString::SkipEmptyParts);
+ /// 3. Create an Archive::Entry
+ const QStringList path = entryFileName.split(QLatin1Char('/'), QString::SkipEmptyParts);
const QString name = path.last();
- ArchiveNode *node = parent->find(name);
- if (node) {
- node->setEntry(entry);
+ Archive::Entry *entry = parent->find(name);
+ if (entry) {
+ copyEntryMetaData(entry, receivedEntry);
+ entry->setProperty("fileName", entryFileName);
+ entry->processNameAndIcon();
+ delete receivedEntry;
} else {
- if (entry[ FileName ].toString().endsWith(QLatin1Char( '/' )) || (entry.contains(IsDirectory) && entry[ IsDirectory ].toBool())) {
- node = new ArchiveDirNode(parent, entry);
- } else {
- node = new ArchiveNode(parent, entry);
- }
- insertNode(node, behaviour);
+ receivedEntry->setParent(parent);
+ receivedEntry->processNameAndIcon();
+ insertEntry(receivedEntry, behaviour);
}
}
void ArchiveModel::slotLoadingFinished(KJob *job)
{
int i = 0;
- foreach(const ArchiveEntry &entry, m_newArchiveEntries) {
+ foreach(Archive::Entry *entry, m_newArchiveEntries) {
newEntry(entry, DoNotNotifyViews);
i++;
}
@@ -846,15 +706,34 @@ void ArchiveModel::slotLoadingFinished(KJob *job)
emit loadingFinished(job);
}
-void ArchiveModel::insertNode(ArchiveNode *node, InsertBehaviour behaviour)
+void ArchiveModel::copyEntryMetaData(Archive::Entry *destinationEntry, const Archive::Entry *sourceEntry)
{
- Q_ASSERT(node);
- ArchiveDirNode *parent = node->parent();
+ destinationEntry->setProperty("fileName", sourceEntry->property("fileName"));
+ destinationEntry->setProperty("permissions", sourceEntry->property("permissions"));
+ destinationEntry->setProperty("owner", sourceEntry->property("owner"));
+ destinationEntry->setProperty("group", sourceEntry->property("group"));
+ destinationEntry->setProperty("size", sourceEntry->property("size"));
+ destinationEntry->setProperty("compressedSize", sourceEntry->property("compressedSize"));
+ destinationEntry->setProperty("link", sourceEntry->property("link"));
+ destinationEntry->setProperty("ratio", sourceEntry->property("ratio"));
+ destinationEntry->setProperty("CRC", sourceEntry->property("CRC"));
+ destinationEntry->setProperty("method", sourceEntry->property("method"));
+ destinationEntry->setProperty("version", sourceEntry->property("version"));
+ destinationEntry->setProperty("timestamp", sourceEntry->property("timestamp").toDateTime());
+ destinationEntry->setProperty("isDirectory", sourceEntry->property("isDirectory"));
+ destinationEntry->setProperty("comment", sourceEntry->property("comment"));
+ destinationEntry->setProperty("isPasswordProtected", sourceEntry->property("isPasswordProtected"));
+}
+
+void ArchiveModel::insertEntry(Archive::Entry *entry, InsertBehaviour behaviour)
+{
+ Q_ASSERT(entry);
+ Archive::Entry *parent = entry->getParent();
Q_ASSERT(parent);
if (behaviour == NotifyViews) {
- beginInsertRows(indexForNode(parent), parent->entries().count(), parent->entries().count());
+ beginInsertRows(indexForEntry(parent), parent->entries().count(), parent->entries().count());
}
- parent->appendEntry(node);
+ parent->appendEntry(entry);
if (behaviour == NotifyViews) {
endInsertRows();
}
@@ -869,7 +748,7 @@ KJob* ArchiveModel::setArchive(Kerfuffle::Archive *archive)
{
m_archive.reset(archive);
- m_rootNode->clear();
+ m_rootEntry->clear();
s_previousMatch = Q_NULLPTR;
s_previousPieces->clear();
@@ -987,10 +866,10 @@ void ArchiveModel::slotCleanupEmptyDirs()
//breadth-first traverse
while (!queue.isEmpty()) {
QPersistentModelIndex node = queue.takeFirst();
- ArchiveEntry entry = entryForIndex(node);
+ Archive::Entry *entry = entryForIndex(node);
if (!hasChildren(node)) {
- if (!entry.contains(InternalID)) {
+ if (!entry->property("fileName").toString().isEmpty()) {
nodesToDelete << node;
}
} else {
@@ -1001,12 +880,10 @@ void ArchiveModel::slotCleanupEmptyDirs()
}
foreach(const QPersistentModelIndex& node, nodesToDelete) {
- ArchiveNode *rawNode = static_cast<ArchiveNode*>(node.internalPointer());
- qCDebug(ARK) << "Delete with parent entries " << rawNode->parent()->entries() << " and row " << rawNode->row();
- beginRemoveRows(parent(node), rawNode->row(), rawNode->row());
- rawNode->parent()->removeEntryAt(rawNode->row());
+ Archive::Entry *rawEntry = static_cast<Archive::Entry*>(node.internalPointer());
+ qCDebug(ARK) << "Delete with parent entries " << rawEntry->getParent()->entries() << " and row " << rawEntry->row();
+ beginRemoveRows(parent(node), rawEntry->row(), rawEntry->row());
+ rawEntry->getParent()->removeEntryAt(rawEntry->row());
endRemoveRows();
}
}
-
-
diff --git a/part/archivemodel.h b/part/archivemodel.h
index 9a2b551..a922731 100644
--- a/part/archivemodel.h
+++ b/part/archivemodel.h
@@ -28,16 +28,13 @@
#include <kjobtrackerinterface.h>
#include "kerfuffle/archive_kerfuffle.h"
-using Kerfuffle::ArchiveEntry;
+using Kerfuffle::Archive;
namespace Kerfuffle
{
class Query;
}
-class ArchiveNode;
-class ArchiveDirNode;
-
class ArchiveModel: public QAbstractItemModel
{
Q_OBJECT
@@ -60,13 +57,13 @@ public:
//drag and drop related
Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE;
QStringList mimeTypes() const Q_DECL_OVERRIDE;
- QMimeData * mimeData(const QModelIndexList & indexes) const Q_DECL_OVERRIDE;
+ QMimeData *mimeData(const QModelIndexList & indexes) const Q_DECL_OVERRIDE;
bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) Q_DECL_OVERRIDE;
KJob* setArchive(Kerfuffle::Archive *archive);
Kerfuffle::Archive *archive() const;
- Kerfuffle::ArchiveEntry entryForIndex(const QModelIndex &index);
+ Archive::Entry *entryForIndex(const QModelIndex &index);
int childCount(const QModelIndex &index, int &dirs, int &files) const;
Kerfuffle::ExtractJob* extractFile(const QVariant& fileName, const QString& destinationDir, const Kerfuffle::ExtractionOptions& options = Kerfuffle::ExtractionOptions()) const;
@@ -93,8 +90,8 @@ signals:
void droppedFiles(const QStringList& files, const QString& path = QString());
private slots:
- void slotNewEntryFromSetArchive(const ArchiveEntry& entry);
- void slotNewEntry(const ArchiveEntry& entry);
+ void slotNewEntryFromSetArchive(Archive::Entry *entry);
+ void slotNewEntry(Archive::Entry *entry);
void slotLoadingFinished(KJob *job);
void slotEntryRemoved(const QString & path);
void slotUserQuery(Kerfuffle::Query *query);
@@ -112,8 +109,8 @@ private:
*/
QString cleanFileName(const QString& fileName);
- ArchiveDirNode* parentFor(const Kerfuffle::ArchiveEntry& entry);
- QModelIndex indexForNode(ArchiveNode *node);
+ Archive::Entry *parentFor(const Kerfuffle::Archive::Entry *entry);
+ QModelIndex indexForEntry(Archive::Entry *entry);
static bool compareAscending(const QModelIndex& a, const QModelIndex& b);
static bool compareDescending(const QModelIndex& a, const QModelIndex& b);
/**
@@ -121,13 +118,14 @@ private:
* of the change.
*/
enum InsertBehaviour { NotifyViews, DoNotNotifyViews };
- void insertNode(ArchiveNode *node, InsertBehaviour behaviour = NotifyViews);
- void newEntry(const Kerfuffle::ArchiveEntry& entry, InsertBehaviour behaviour);
+ void copyEntryMetaData(Archive::Entry *destinationEntry, const Archive::Entry *sourceEntry);
+ void insertEntry(Archive::Entry *entry, InsertBehaviour behaviour = NotifyViews);
+ void newEntry(Kerfuffle::Archive::Entry *receivedEntry, InsertBehaviour behaviour);
- QList<Kerfuffle::ArchiveEntry> m_newArchiveEntries; // holds entries from opening a new archive until it's totally open
+ QList<Kerfuffle::Archive::Entry*> m_newArchiveEntries; // holds entries from opening a new archive until it's totally open
QList<int> m_showColumns;
QScopedPointer<Kerfuffle::Archive> m_archive;
- ArchiveDirNode *m_rootNode;
+ Archive::Entry *m_rootEntry;
QString m_dbusPathName;
};
diff --git a/part/infopanel.cpp b/part/infopanel.cpp
index d93a0b3..55a8a56 100644
--- a/part/infopanel.cpp
+++ b/part/infopanel.cpp
@@ -20,16 +20,11 @@
*/
#include "infopanel.h"
-#include "ark_debug.h"
-#include "kerfuffle/archive_kerfuffle.h"
+#include "kerfuffle/archiveentry.h"
-#include <QLabel>
-#include <QVBoxLayout>
#include <QFileInfo>
-#include <QMimeDatabase>
#include <KLocalizedString>
-#include <KIconLoader>
#include <kio/global.h>
using namespace Kerfuffle;
@@ -98,35 +93,35 @@ void InfoPanel::setIndex(const QModelIndex& index)
if (!index.isValid()) {
updateWithDefaults();
} else {
- const ArchiveEntry& entry = m_model->entryForIndex(index);
+ const Archive::Entry *entry = m_model->entryForIndex(index);
QMimeDatabase db;
QMimeType mimeType;
- if (entry[ IsDirectory ].toBool()) {
+ if (entry->isDir()) {
mimeType = db.mimeTypeForName(QStringLiteral("inode/directory"));
} else {
- mimeType = db.mimeTypeForFile(entry[ FileName ].toString(), QMimeDatabase::MatchExtension);
+ mimeType = db.mimeTypeForFile(entry->property("fileName").toString(), QMimeDatabase::MatchExtension);
}
iconLabel->setPixmap(getDesktopIconForName(mimeType.iconName()));
- if (entry[ IsDirectory ].toBool()) {
+ if (entry->isDir()) {
int dirs;
int files;
const int children = m_model->childCount(index, dirs, files);
additionalInfo->setText(KIO::itemsSummaryString(children, files, dirs, 0, false));
- } else if (entry.contains(Link)) {
+ } else if (!entry->property("link").toString().isEmpty()) {
additionalInfo->setText(i18n("Symbolic Link"));
} else {
- if (entry.contains(Size)) {
- additionalInfo->setText(KIO::convertSize(entry[ Size ].toULongLong()));
+ if (entry->property("size") != 0) {
+ additionalInfo->setText(KIO::convertSize(entry->property("size").toULongLong()));
} else {
additionalInfo->setText(i18n("Unknown size"));
}
}
- const QStringList nameParts = entry[ FileName ].toString().split(QLatin1Char( '/' ), QString::SkipEmptyParts);
- const QString name = (nameParts.count() > 0) ? nameParts.last() : entry[ FileName ].toString();
+ const QStringList nameParts = entry->property("fileName").toString().split(QLatin1Char( '/' ), QString::SkipEmptyParts);
+ const QString name = (nameParts.count() > 0) ? nameParts.last() : entry->property("fileName").toString();
fileName->setText(name);
showMetaDataFor(index);
@@ -144,8 +139,8 @@ void InfoPanel::setIndexes(const QModelIndexList &list)
fileName->setText(i18np("One file selected", "%1 files selected", list.size()));
quint64 totalSize = 0;
foreach(const QModelIndex& index, list) {
- const ArchiveEntry& entry = m_model->entryForIndex(index);
- totalSize += entry[ Size ].toULongLong();
+ const Archive::Entry *entry = m_model->entryForIndex(index);
+ totalSize += entry->property("size").toULongLong();
}
additionalInfo->setText(KIO::convertSize(totalSize));
hideMetaData();
@@ -168,41 +163,41 @@ void InfoPanel::showMetaDataFor(const QModelIndex &index)
{
showMetaData();
- const ArchiveEntry& entry = m_model->entryForIndex(index);
+ const Archive::Entry *entry = m_model->entryForIndex(index);
QMimeDatabase db;
QMimeType mimeType;
- if (entry[ IsDirectory ].toBool()) {
+ if (entry->isDir()) {
mimeType = db.mimeTypeForName(QStringLiteral("inode/directory"));
} else {
- mimeType = db.mimeTypeForFile(entry[FileName].toString(), QMimeDatabase::MatchExtension);
+ mimeType = db.mimeTypeForFile(entry->property("fileName").toString(), QMimeDatabase::MatchExtension);
}
m_typeLabel->setText(i18n("<b>Type:</b> %1", mimeType.comment()));
- if (entry.contains(Owner)) {
+ if (!entry->property("owner").toString().isEmpty()) {
m_ownerLabel->show();
- m_ownerLabel->setText(i18n("<b>Owner:</b> %1", entry[Owner].toString()));
+ m_ownerLabel->setText(i18n("<b>Owner:</b> %1", entry->property("owner").toString()));
} else {
m_ownerLabel->hide();
}
- if (entry.contains(Group)) {
+ if (!entry->property("group").toString().isEmpty()) {
m_groupLabel->show();
- m_groupLabel->setText(i18n("<b>Group:</b> %1", entry[Group].toString()));
+ m_groupLabel->setText(i18n("<b>Group:</b> %1", entry->property("group").toString()));
} else {
m_groupLabel->hide();
}
- if (entry.contains(Link)) {
+ if (!entry->property("link").toString().isEmpty()) {
m_targetLabel->show();
- m_targetLabel->setText(i18n("<b>Target:</b> %1", entry[Link].toString()));
+ m_targetLabel->setText(i18n("<b>Target:</b> %1", entry->property("link").toString()));
} else {
m_targetLabel->hide();
}
- if (entry.contains(IsPasswordProtected) && entry[ IsPasswordProtected ].toBool()) {
+ if (entry->property("isPasswordProtected").toBool()) {
m_passwordLabel->show();
m_passwordLabel->setText(i18n("<b>Password protected:</b> Yes"));
} else {
diff --git a/part/part.cpp b/part/part.cpp
index abd6e8f..fb486f0 100644
--- a/part/part.cpp
+++ b/part/part.cpp
@@ -30,7 +30,7 @@
#include "dnddbusinterfaceadaptor.h"
#include "infopanel.h"
#include "jobtracker.h"
-#include "kerfuffle/archive_kerfuffle.h"
+#include "kerfuffle/archiveentry.h"
#include "kerfuffle/extractiondialog.h"
#include "kerfuffle/extractionsettingspage.h"
#include "kerfuffle/jobs.h"
@@ -408,18 +408,17 @@ void Part::setupActions()
void Part::updateActions()
{
bool isWritable = m_model->archive() && !m_model->archive()->isReadOnly();
- bool isDirectory = m_model->entryForIndex(m_view->selectionModel()->currentIndex())[IsDirectory].toBool();
+ const Archive::Entry *entry = m_model->entryForIndex(m_view->selectionModel()->currentIndex());
int selectedEntriesCount = m_view->selectionModel()->selectedRows().count();
// Figure out if entry size is larger than preview size limit.
const int maxPreviewSize = ArkSettings::previewFileSizeLimit() * 1024 * 1024;
const bool limit = ArkSettings::limitPreviewFileSize();
- const qlonglong size = m_model->entryForIndex(m_view->selectionModel()->currentIndex())[Size].toLongLong();
- bool isPreviewable = (!limit || (limit && size < maxPreviewSize));
+ bool isPreviewable = (!limit || (limit && entry != Q_NULLPTR && entry->property("size").toLongLong() < maxPreviewSize));
m_previewAction->setEnabled(!isBusy() &&
isPreviewable &&
- !isDirectory &&
+ !entry->isDir() &&
(selectedEntriesCount == 1));
m_extractArchiveAction->setEnabled(!isBusy() &&
(m_model->rowCount() > 0));
@@ -436,11 +435,11 @@ void Part::updateActions()
(selectedEntriesCount > 0));
m_openFileAction->setEnabled(!isBusy() &&
isPreviewable &&
- !isDirectory &&
+ !entry->isDir() &&
(selectedEntriesCount == 1));
m_openFileWithAction->setEnabled(!isBusy() &&
isPreviewable &&
- !isDirectory &&
+ !entry->isDir() &&
(selectedEntriesCount == 1));
m_propertiesAction->setEnabled(!isBusy() &&
m_model->archive());
@@ -794,7 +793,7 @@ void Part::slotLoadingFinished(KJob *job)
displayMsgWidget(KMessageWidget::Warning, xi18nc("@info", "The archive is empty or Ark could not open its content."));
} else if (m_model->rowCount() == 1) {
if (m_model->archive()->mimeType().inherits(QStringLiteral("application/x-cd-image")) &&
- m_model->entryForIndex(m_model->index(0, 0))[FileName].toString() == QLatin1String("README.TXT")) {
+ m_model->entryForIndex(m_model->index(0, 0))->property("fileName").toString() == QLatin1String("README.TXT")) {
qCWarning(ARK) << "Detected ISO image with UDF filesystem";
displayMsgWidget(KMessageWidget::Warning, xi18nc("@info", "Ark does not currently support ISO files with UDF filesystem."));
}
@@ -842,30 +841,30 @@ void Part::slotOpenEntry(int mode)
qCDebug(ARK) << "Opening with mode" << mode;
QModelIndex index = m_view->selectionModel()->currentIndex();
- const ArchiveEntry& entry = m_model->entryForIndex(index);
+ const Archive::Entry *entry = m_model->entryForIndex(index);
// Don't open directories.
- if (entry[IsDirectory].toBool()) {
+ if (entry->isDir()) {
return;
}
// We don't support opening symlinks.
- if (entry[Link].toBool()) {
+ if (!entry->property("link").toString().isEmpty()) {
displayMsgWidget(KMessageWidget::Information, i18n("Ark cannot open symlinks."));
return;
}
// Extract the entry.
- if (!entry.isEmpty()) {
+ if (!entry->property("fileName").toString().isEmpty()) {
m_openFileMode = static_cast<OpenFileMode>(mode);
KJob *job = Q_NULLPTR;
if (m_openFileMode == Preview) {
- job = m_model->preview(entry[InternalID].toString());
+ job = m_model->preview(entry->property("fileName").toString());
connect(job, &KJob::result, this, &Part::slotPreviewExtractedEntry);
} else {
- const QString file = entry[InternalID].toString();
+ const QString file = entry->property("fileName").toString();
job = (m_openFileMode == OpenFile) ? m_model->open(file) : m_model->openWith(file);
connect(job, &KJob::result, this, &Part::slotOpenExtractedEntry);
}
@@ -1084,8 +1083,8 @@ QList<QVariant> Part::filesForIndexes(const QModelIndexList& list) const
QVariantList ret;
foreach(const QModelIndex& index, list) {
- const ArchiveEntry& entry = m_model->entryForIndex(index);
- ret << entry[InternalID].toString();
+ const Archive::Entry *entry = m_model->entryForIndex(index);
+ ret << entry->property("fileName").toString();
}
return ret;
@@ -1109,14 +1108,14 @@ QList<QVariant> Part::filesAndRootNodesForIndexes(const QModelIndexList& list) c
}
// Fetch the root node for the unselected parent.
- const QString rootInternalID =
- m_model->entryForIndex(selectionRoot).value(InternalID).toString();
+ const QString rootFileName =
+ m_model->entryForIndex(selectionRoot)->property("fileName").toString();
// Append index with root node to fileList.
QModelIndexList alist = QModelIndexList() << index;
foreach (const QVariant &file, filesForIndexes(alist)) {
- QVariant v = QVariant::fromValue(fileRootNodePair(file.toString(), rootInternalID));
+ QVariant v = QVariant::fromValue(fileRootNodePair(file.toString(), rootFileName));
if (!fileList.contains(v)) {
fileList.append(v);
}
diff --git a/plugins/cli7zplugin/cliplugin.cpp b/plugins/cli7zplugin/cliplugin.cpp
index 788890e..cbb794a 100644
--- a/plugins/cli7zplugin/cliplugin.cpp
+++ b/plugins/cli7zplugin/cliplugin.cpp
@@ -40,6 +40,7 @@ CliPlugin::CliPlugin(QObject *parent, const QVariantList & args)
, m_archiveType(ArchiveType7z)
, m_parseState(ParseStateTitle)
, m_linesComment(0)
+ , m_isFirstInformationEntry(true)
{
qCDebug(ARK) << "Loaded cli_7z plugin";
}
@@ -185,54 +186,60 @@ bool CliPlugin::readListLine(const QString& line)
} else if (m_parseState == ParseStateEntryInformation) {
+ if (m_isFirstInformationEntry) {
+ m_isFirstInformationEntry = false;
+ m_currentArchiveEntry = new Archive::Entry(Q_NULLPTR);
+ m_currentArchiveEntry->compressedSizeIsSet = false;
+ }
if (line.startsWith(QStringLiteral("Path = "))) {
const QString entryFilename =
QDir::fromNativeSeparators(line.mid(7).trimmed());
- m_currentArchiveEntry.clear();
- m_currentArchiveEntry[FileName] = entryFilename;
- m_currentArchiveEntry[InternalID] = entryFilename;
+ m_currentArchiveEntry->setProperty("fileName", entryFilename);
} else if (line.startsWith(QStringLiteral("Size = "))) {
- m_currentArchiveEntry[ Size ] = line.mid(7).trimmed();
+ m_currentArchiveEntry->setProperty("size", line.mid(7).trimmed());
} else if (line.startsWith(QStringLiteral("Packed Size = "))) {
// #236696: 7z files only show a single Packed Size value
// corresponding to the whole archive.
if (m_archiveType != ArchiveType7z) {
- m_currentArchiveEntry[CompressedSize] = line.mid(14).trimmed();
+ m_currentArchiveEntry->compressedSizeIsSet = true;
+ m_currentArchiveEntry->setProperty("compressedSize", line.mid(14).trimmed());
}
} else if (line.startsWith(QStringLiteral("Modified = "))) {
- m_currentArchiveEntry[ Timestamp ] =
- QDateTime::fromString(line.mid(11).trimmed(),
- QStringLiteral("yyyy-MM-dd hh:mm:ss"));
+ m_currentArchiveEntry->setProperty("timestamp", QDateTime::fromString(line.mid(11).trimmed(),
+ QStringLiteral("yyyy-MM-dd hh:mm:ss")));
} else if (line.startsWith(QStringLiteral("Attributes = "))) {
const QString attributes = line.mid(13).trimmed();
const bool isDirectory = attributes.startsWith(QLatin1Char('D'));
- m_currentArchiveEntry[ IsDirectory ] = isDirectory;
+ m_currentArchiveEntry->setProperty("isDirectory", isDirectory);
if (isDirectory) {
const QString directoryName =
- m_currentArchiveEntry[FileName].toString();
+ m_currentArchiveEntry->property("fileName").toString();
if (!directoryName.endsWith(QLatin1Char('/'))) {
const bool isPasswordProtected = (line.at(12) == QLatin1Char('+'));
- m_currentArchiveEntry[FileName] =
- m_currentArchiveEntry[InternalID] = QString(directoryName + QLatin1Char('/'));
- m_currentArchiveEntry[ IsPasswordProtected ] =
- isPasswordProtected;
+ m_currentArchiveEntry->setProperty("fileName", QString(directoryName + QLatin1Char('/')));
+ m_currentArchiveEntry->setProperty("isPasswordProtected", isPasswordProtected);
}
}
- m_currentArchiveEntry[ Permissions ] = attributes.mid(1);
+ m_currentArchiveEntry->setProperty("permissions", attributes.mid(1));
} else if (line.startsWith(QStringLiteral("CRC = "))) {
- m_currentArchiveEntry[ CRC ] = line.mid(6).trimmed();
+ m_currentArchiveEntry->setProperty("CRC", line.mid(6).trimmed());
} else if (line.startsWith(QStringLiteral("Method = "))) {
- m_currentArchiveEntry[ Method ] = line.mid(9).trimmed();
+ m_currentArchiveEntry->setProperty("method", line.mid(9).trimmed());
} else if (line.startsWith(QStringLiteral("Encrypted = ")) &&
line.size() >= 13) {
- m_currentArchiveEntry[ IsPasswordProtected ] = (line.at(12) == QLatin1Char('+'));
+ m_currentArchiveEntry->setProperty("isPasswordProtected", line.at(12) == QLatin1Char('+'));
} else if (line.startsWith(QStringLiteral("Block = ")) ||
line.startsWith(QStringLiteral("Version = "))) {
- if (m_currentArchiveEntry.contains(FileName)) {
+ m_isFirstInformationEntry = true;
+ if (!m_currentArchiveEntry->property("fileName").toString().isEmpty()) {
emit entry(m_currentArchiveEntry);
}
+ else {
+ delete m_currentArchiveEntry;
+ }
+ m_currentArchiveEntry = Q_NULLPTR;
}
}
diff --git a/plugins/cli7zplugin/cliplugin.h b/plugins/cli7zplugin/cliplugin.h
index 9a332bf..806c647 100644
--- a/plugins/cli7zplugin/cliplugin.h
+++ b/plugins/cli7zplugin/cliplugin.h
@@ -25,6 +25,7 @@
#define CLIPLUGIN_H
#include "kerfuffle/cliinterface.h"
+#include "kerfuffle/archiveentry.h"
class CliPlugin : public Kerfuffle::CliInterface
{
@@ -63,7 +64,8 @@ private:
} m_parseState;
int m_linesComment;
- Kerfuffle::ArchiveEntry m_currentArchiveEntry;
+ Kerfuffle::Archive::Entry *m_currentArchiveEntry;
+ bool m_isFirstInformationEntry;
};
#endif // CLIPLUGIN_H
diff --git a/plugins/cliplugin-example/cliplugin.cpp b/plugins/cliplugin-example/cliplugin.cpp
index b0701e4..fa21fbb 100644
--- a/plugins/cliplugin-example/cliplugin.cpp
+++ b/plugins/cliplugin-example/cliplugin.cpp
@@ -22,6 +22,7 @@
#include "cliplugin.h"
#include "ark_debug.h"
+#include "kerfuffle/archiveentry.h"
#include "kerfuffle/kerfuffle_export.h"
#include <QDebug>
@@ -97,11 +98,11 @@ bool CliPlugin::readListLine(const QString &line)
// rar gives one line for the filename and a line after it with some file properties
if (m_isFirstLine) {
- m_internalId = line.trimmed();
+ m_entryFilename = line.trimmed();
//m_entryFilename.chop(1); // handle newline
- if (!m_internalId.isEmpty() && m_internalId.at(0) == QLatin1Char('*')) {
+ if (!m_entryFilename.isEmpty() && m_entryFilename.at(0) == QLatin1Char('*')) {
m_isPasswordProtected = true;
- m_internalId.remove(0, 1); // and the spaces in front
+ m_entryFilename.remove(0, 1); // and the spaces in front
} else
m_isPasswordProtected = false;
@@ -110,7 +111,7 @@ bool CliPlugin::readListLine(const QString &line)
}
QStringList fileprops = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
- m_internalId = QDir::fromNativeSeparators(m_internalId);
+ m_entryFilename = QDir::fromNativeSeparators(m_entryFilename);
bool isDirectory = (bool)(fileprops[ 5 ].contains(QLatin1Char('d'), Qt::CaseInsensitive));
QDateTime ts(QDate::fromString(fileprops[ 3 ], QLatin1String("dd-MM-yy")),
@@ -121,25 +122,23 @@ bool CliPlugin::readListLine(const QString &line)
ts = ts.addYears(100);
}
- m_entryFilename = m_internalId;
- if (isDirectory && !m_internalId.endsWith(QLatin1Char('/'))) {
+ if (isDirectory && !m_entryFilename.endsWith(QLatin1Char('/'))) {
m_entryFilename += QLatin1Char('/');
}
qCDebug(ARK) << m_entryFilename << " : " << fileprops;
- ArchiveEntry e;
- e[ FileName ] = m_entryFilename;
- e[ InternalID ] = m_internalId;
- e[ Size ] = fileprops[ 0 ];
- e[ CompressedSize] = fileprops[ 1 ];
- e[ Ratio ] = fileprops[ 2 ];
- e[ Timestamp ] = ts;
- e[ IsDirectory ] = isDirectory;
- e[ Permissions ] = fileprops[ 5 ].remove(0, 1);
- e[ CRC ] = fileprops[ 6 ];
- e[ Method ] = fileprops[ 7 ];
- e[ Version ] = fileprops[ 8 ];
- e[ IsPasswordProtected] = m_isPasswordProtected;
+ Archive::Entry *e = new Archive::Entry(Q_NULLPTR);
+ e->setProperty("fileName", m_entryFilename);
+ e->setProperty("size", fileprops[ 0 ]);
+ e->setProperty("compressedSize", fileprops[ 1 ]);
+ e->setProperty("ratio", fileprops[ 2 ]);
+ e->setProperty("timestamp", ts);
+ e->setProperty("isDirectory", isDirectory);
+ e->setProperty("permissions", fileprops[ 5 ].remove(0, 1));
+ e->setProperty("CRC", fileprops[ 6 ]);
+ e->setProperty("method", fileprops[ 7 ]);
+ e->setProperty("version", fileprops[ 8 ]);
+ e->setProperty("ssPasswordProtected", m_isPasswordProtected);
qCDebug(ARK) << "Added entry: " << e;
emit entry(e);
diff --git a/plugins/cliplugin-example/cliplugin.h b/plugins/cliplugin-example/cliplugin.h
index 21e935d..cd4770d 100644
--- a/plugins/cliplugin-example/cliplugin.h
+++ b/plugins/cliplugin-example/cliplugin.h
@@ -38,7 +38,7 @@ public:
private:
bool m_isFirstLine, m_incontent, m_isPasswordProtected;
- QString m_entryFilename, m_internalId;
+ QString m_entryFilename;
};
diff --git a/plugins/clirarplugin/cliplugin.cpp b/plugins/clirarplugin/cliplugin.cpp
index ab31ffb..545bed0 100644
--- a/plugins/clirarplugin/cliplugin.cpp
+++ b/plugins/clirarplugin/cliplugin.cpp
@@ -22,14 +22,13 @@
#include "cliplugin.h"
#include "ark_debug.h"
-#include "kerfuffle/kerfuffle_export.h"
+#include "kerfuffle/archiveentry.h"
#include <QDateTime>
-#include <QRegularExpression>
#include <KPluginFactory>
-using namespace Kerfuffle;
+ using namespace Kerfuffle;
K_PLUGIN_FACTORY_WITH_JSON(CliPluginFactory, "kerfuffle_clirar.json", registerPlugin<CliPlugin>();)
@@ -251,18 +250,18 @@ void CliPlugin::handleUnrar5Line(const QString &line) {
void CliPlugin::handleUnrar5Entry() {
- ArchiveEntry e;
+ Archive::Entry *e = new Archive::Entry(Q_NULLPTR);
QString compressionRatio = m_unrar5Details.value(QStringLiteral("ratio"));
compressionRatio.chop(1); // Remove the '%'
- e[Ratio] = compressionRatio;
+ e->setProperty("ratio", compressionRatio);
QString time = m_unrar5Details.value(QStringLiteral("mtime"));
QDateTime ts = QDateTime::fromString(time, QStringLiteral("yyyy-MM-dd HH:mm:ss,zzz"));
- e[Timestamp] = ts;
+ e->setProperty("timestamp", ts);
bool isDirectory = (m_unrar5Details.value(QStringLiteral("type")) == QLatin1String("Directory"));
- e[IsDirectory] = isDirectory;
+ e->setProperty("isDirectory", isDirectory);
if (isDirectory && !m_unrar5Details.value(QStringLiteral("name")).endsWith(QLatin1Char('/'))) {
m_unrar5Details[QStringLiteral("name")] += QLatin1Char('/');
@@ -271,26 +270,25 @@ void CliPlugin::handleUnrar5Entry() {
QString compression = m_unrar5Details.value(QStringLiteral("compression"));
int optionPos = compression.indexOf(QLatin1Char('-'));
if (optionPos != -1) {
- e[Method] = compression.mid(optionPos);
- e[Version] = compression.left(optionPos).trimmed();
+ e->setProperty("method", compression.mid(optionPos));
+ e->setProperty("version", compression.left(optionPos).trimmed());
} else {
// No method specified.
- e[Method].clear();
- e[Version] = compression;
+ e->setProperty("method", QStringLiteral(""));
+ e->setProperty("version", compression);
}
m_isPasswordProtected = m_unrar5Details.value(QStringLiteral("flags")).contains(QStringLiteral("encrypted"));
- e[IsPasswordProtected] = m_isPasswordProtected;
+ e->setProperty("isPasswordProtected", m_isPasswordProtected);
- e[FileName] = m_unrar5Details.value(QStringLiteral("name"));
- e[InternalID] = m_unrar5Details.value(QStringLiteral("name"));
- e[Size] = m_unrar5Details.value(QStringLiteral("size"));
- e[CompressedSize] = m_unrar5Details.value(QStringLiteral("packed size"));
- e[Permissions] = m_unrar5Details.value(QStringLiteral("attributes"));
- e[CRC] = m_unrar5Details.value(QStringLiteral("crc32"));
+ e->setProperty("fileName", m_unrar5Details.value(QStringLiteral("name")));
+ e->setProperty("size", m_unrar5Details.value(QStringLiteral("size")));
+ e->setProperty("compressedSize", m_unrar5Details.value(QStringLiteral("packed size")));
+ e->setProperty("permissions", m_unrar5Details.value(QStringLiteral("attributes")));
+ e->setProperty("CRC", m_unrar5Details.value(QStringLiteral("crc32")));
- if (e[Permissions].toString().startsWith(QLatin1Char('l'))) {
- e[Link] = m_unrar5Details.value(QStringLiteral("target"));
+ if (e->property("permissions").toString().startsWith(QLatin1Char('l'))) {
+ e->setProperty("link", m_unrar5Details.value(QStringLiteral("target")));
}
m_unrar5Details.clear();
@@ -454,7 +452,7 @@ void CliPlugin::handleUnrar4Line(const QString &line) {
void CliPlugin::handleUnrar4Entry() {
- ArchiveEntry e;
+ Archive::Entry *e = new Archive::Entry(NULL);
QDateTime ts = QDateTime::fromString(QString(m_unrar4Details.at(4) + QLatin1Char(' ') + m_unrar4Details.at(5)),
QStringLiteral("dd-MM-yy hh:mm"));
@@ -463,11 +461,11 @@ void CliPlugin::handleUnrar4Entry() {
if (ts.date().year() < 1950) {
ts = ts.addYears(100);
}
- e[Timestamp] = ts;
+ e->setProperty("timestamp", ts);
bool isDirectory = ((m_unrar4Details.at(6).at(0) == QLatin1Char('d')) ||
(m_unrar4Details.at(6).at(1) == QLatin1Char('D')));
- e[IsDirectory] = isDirectory;
+ e->setProperty("isDirectory", isDirectory);
if (isDirectory && !m_unrar4Details.at(0).endsWith(QLatin1Char('/'))) {
m_unrar4Details[0] += QLatin1Char('/');
@@ -486,23 +484,22 @@ void CliPlugin::handleUnrar4Entry() {
} else {
compressionRatio.chop(1); // Remove the '%'
}
- e[Ratio] = compressionRatio;
+ e->setProperty("ratio", compressionRatio);
// TODO:
// - Permissions differ depending on the system the entry was added
// to the archive.
- e[FileName] = m_unrar4Details.at(0);
- e[InternalID] = m_unrar4Details.at(0);
- e[Size] = m_unrar4Details.at(1);
- e[CompressedSize] = m_unrar4Details.at(2);
- e[Permissions] = m_unrar4Details.at(6);
- e[CRC] = m_unrar4Details.at(7);
- e[Method] = m_unrar4Details.at(8);
- e[Version] = m_unrar4Details.at(9);
- e[IsPasswordProtected] = m_isPasswordProtected;
-
- if (e[Permissions].toString().startsWith(QLatin1Char('l'))) {
- e[Link] = m_unrar4Details.at(10);
+ e->setProperty("fileName", m_unrar4Details.at(0));
+ e->setProperty("size", m_unrar4Details.at(1));
+ e->setProperty("compressedSize", m_unrar4Details.at(2));
+ e->setProperty("permissions", m_unrar4Details.at(6));
+ e->setProperty("CRC", m_unrar4Details.at(7));
+ e->setProperty("method", m_unrar4Details.at(8));
+ e->setProperty("version", m_unrar4Details.at(9));
+ e->setProperty("isPasswordProtected", m_isPasswordProtected);
+
+ if (e->property("permissions").toString().startsWith(QLatin1Char('l'))) {
+ e->setProperty("link", m_unrar4Details.at(10));
}
m_unrar4Details.clear();
diff --git a/plugins/cliunarchiverplugin/cliplugin.cpp b/plugins/cliunarchiverplugin/cliplugin.cpp
index 71ac4a0..7e3e4ff 100644
--- a/plugins/cliunarchiverplugin/cliplugin.cpp
+++ b/plugins/cliunarchiverplugin/cliplugin.cpp
@@ -189,24 +189,23 @@ void CliPlugin::readJsonOutput()
foreach (const QJsonValue& value, entries) {
const QJsonObject currentEntry = value.toObject();
- m_currentEntry.clear();
+ m_currentEntry->clearMetaData();
QString filename = currentEntry.value(QStringLiteral("XADFileName")).toString();
- m_currentEntry[IsDirectory] = !currentEntry.value(QStringLiteral("XADIsDirectory")).isUndefined();
- if (m_currentEntry[IsDirectory].toBool()) {
+ m_currentEntry->setProperty("isDirectory", !currentEntry.value(QStringLiteral("XADIsDirectory")).isUndefined());
+ if (m_currentEntry->isDir()) {
filename += QLatin1Char('/');
}
- m_currentEntry[FileName] = filename;
- m_currentEntry[InternalID] = filename;
+ m_currentEntry->setProperty("fileName", filename);
// FIXME: archives created from OSX (i.e. with the __MACOSX folder) list each entry twice, the 2nd time with size 0
- m_currentEntry[Size] = currentEntry.value(QStringLiteral("XADFileSize"));
- m_currentEntry[CompressedSize] = currentEntry.value(QStringLiteral("XADCompressedSize"));
- m_currentEntry[Timestamp] = currentEntry.value(QStringLiteral("XADLastModificationDate")).toVariant();
- m_currentEntry[Size] = currentEntry.value(QStringLiteral("XADFileSize"));
- m_currentEntry[IsPasswordProtected] = (currentEntry.value(QStringLiteral("XADIsEncrypted")).toInt() == 1);
+ m_currentEntry->setProperty("size", currentEntry.value(QStringLiteral("XADFileSize")));
+ m_currentEntry->setProperty("compressedSize", currentEntry.value(QStringLiteral("XADCompressedSize")));
+ m_currentEntry->setProperty("timestamp", currentEntry.value(QStringLiteral("XADLastModificationDate")).toVariant());
+ m_currentEntry->setProperty("size", currentEntry.value(QStringLiteral("XADFileSize")));
+ m_currentEntry->setProperty("isPasswordProtected", (currentEntry.value(QStringLiteral("XADIsEncrypted")).toInt() == 1));
// TODO: missing fields
emit entry(m_currentEntry);
diff --git a/plugins/cliunarchiverplugin/cliplugin.h b/plugins/cliunarchiverplugin/cliplugin.h
index ac7b5d6..0923c48 100644
--- a/plugins/cliunarchiverplugin/cliplugin.h
+++ b/plugins/cliunarchiverplugin/cliplugin.h
@@ -23,6 +23,7 @@
#ifndef CLIPLUGIN_H
#define CLIPLUGIN_H
+#include "kerfuffle/archiveentry.h"
#include "kerfuffle/cliinterface.h"
class CliPlugin : public Kerfuffle::CliInterface
@@ -56,7 +57,7 @@ private:
void readJsonOutput();
- Kerfuffle::ArchiveEntry m_currentEntry;
+ Kerfuffle::Archive::Entry *m_currentEntry;
QString m_jsonOutput;
};
diff --git a/plugins/clizipplugin/cliplugin.cpp b/plugins/clizipplugin/cliplugin.cpp
index ea2f6d2..bf61f94 100644
--- a/plugins/clizipplugin/cliplugin.cpp
+++ b/plugins/clizipplugin/cliplugin.cpp
@@ -23,6 +23,7 @@
#include "ark_debug.h"
#include "kerfuffle/cliinterface.h"
#include "kerfuffle/kerfuffle_export.h"
+#include "kerfuffle/archiveentry.h"
#include <KPluginFactory>
@@ -161,25 +162,25 @@ bool CliPlugin::readListLine(const QString &line)
case ParseStateEntry:
QRegularExpressionMatch rxMatch = entryPattern.match(line);
if (rxMatch.hasMatch()) {
- ArchiveEntry e;
- e[Permissions] = rxMatch.captured(1);
+ Archive::Entry *e = new Archive::Entry(Q_NULLPTR);
+ e->setProperty("permissions", rxMatch.captured(1));
// #280354: infozip may not show the right attributes for a given directory, so an entry
// ending with '/' is actually more reliable than 'd' bein in the attributes.
- e[IsDirectory] = rxMatch.captured(10).endsWith(QLatin1Char('/'));
+ e->setProperty("isDirectory", rxMatch.captured(10).endsWith(QLatin1Char('/')));
- e[Size] = rxMatch.captured(4);
+ e->setProperty("size", rxMatch.captured(4));
QString status = rxMatch.captured(5);
if (status[0].isUpper()) {
- e[IsPasswordProtected] = true;
+ e->setProperty("isPasswordProtected", true);
}
- e[CompressedSize] = rxMatch.captured(6).toInt();
+ e->setProperty("compressedSize", rxMatch.captured(6).toInt());
const QDateTime ts(QDate::fromString(rxMatch.captured(8), QStringLiteral("yyyyMMdd")),
QTime::fromString(rxMatch.captured(9), QStringLiteral("hhmmss")));
- e[Timestamp] = ts;
+ e->setProperty("timestamp", ts);
- e[FileName] = e[InternalID] = rxMatch.captured(10);
+ e->setProperty("fileName", rxMatch.captured(10));
emit entry(e);
}
break;
diff --git a/plugins/libarchive/libarchiveplugin.cpp b/plugins/libarchive/libarchiveplugin.cpp
index 934e5a2..ad7685c 100644
--- a/plugins/libarchive/libarchiveplugin.cpp
+++ b/plugins/libarchive/libarchiveplugin.cpp
@@ -28,6 +28,7 @@
#include "libarchiveplugin.h"
#include "ark_debug.h"
#include "kerfuffle/kerfuffle_export.h"
+#include "kerfuffle/archiveentry.h"
#include "kerfuffle/queries.h"
#include <archive_entry.h>
@@ -415,33 +416,33 @@ bool LibarchivePlugin::copyFiles(const QVariantList& files, const QString& desti
void LibarchivePlugin::emitEntryFromArchiveEntry(struct archive_entry *aentry)
{
- ArchiveEntry e;
+ Archive::Entry *e = new Archive::Entry(NULL);
#ifdef _MSC_VER
- e[FileName] = QDir::fromNativeSeparators(QString::fromUtf16((ushort*)archive_entry_pathname_w(aentry)));
+ e->fileName = QDir::fromNativeSeparators(QString::fromUtf16((ushort*)archive_entry_pathname_w(aentry)));
#else
- e[FileName] = QDir::fromNativeSeparators(QString::fromWCharArray(archive_entry_pathname_w(aentry)));
+ e->setProperty("fileName", QDir::fromNativeSeparators(QString::fromWCharArray(archive_entry_pathname_w(aentry))));
#endif
- e[InternalID] = e[FileName];
const QString owner = QString::fromLatin1(archive_entry_uname(aentry));
if (!owner.isEmpty()) {
- e[Owner] = owner;
+ e->setProperty("owner", owner);
}
const QString group = QString::fromLatin1(archive_entry_gname(aentry));
if (!group.isEmpty()) {
- e[Group] = group;
+ e->setProperty("group", group);
}
- e[Size] = (qlonglong)archive_entry_size(aentry);
- e[IsDirectory] = S_ISDIR(archive_entry_mode(aentry));
+ e->compressedSizeIsSet = false;
+ e->setProperty("size", (qlonglong)archive_entry_size(aentry));
+ e->setProperty("isDirectory", S_ISDIR(archive_entry_mode(aentry)));
if (archive_entry_symlink(aentry)) {
- e[Link] = QLatin1String( archive_entry_symlink(aentry) );
+ e->setProperty("link", QLatin1String( archive_entry_symlink(aentry) ));
}
- e[Timestamp] = QDateTime::fromTime_t(archive_entry_mtime(aentry));
+ e->setProperty("timestamp", QDateTime::fromTime_t(archive_entry_mtime(aentry)));
emit entry(e);
}
diff --git a/plugins/libsinglefileplugin/singlefileplugin.cpp b/plugins/libsinglefileplugin/singlefileplugin.cpp
index c09a72e..2c1eb04 100644
--- a/plugins/libsinglefileplugin/singlefileplugin.cpp
+++ b/plugins/libsinglefileplugin/singlefileplugin.cpp
@@ -25,13 +25,11 @@
#include "singlefileplugin.h"
#include "ark_debug.h"
-#include "kerfuffle/kerfuffle_export.h"
+#include "kerfuffle/archiveentry.h"
#include "kerfuffle/queries.h"
-#include <QByteArray>
#include <QFile>
#include <QFileInfo>
-#include <QString>
#include <KFilterDev>
#include <KLocalizedString>
@@ -107,13 +105,8 @@ bool LibSingleFileInterface::list()
{
qCDebug(ARK) << "Listing archive contents";
- const QString filename = uncompressedFileName();
-
- Kerfuffle::ArchiveEntry e;
-
- e[Kerfuffle::FileName] = filename;
- e[Kerfuffle::InternalID] = filename;
-
+ Kerfuffle::Archive::Entry *e = new Kerfuffle::Archive::Entry(Q_NULLPTR);
+ e->setProperty("fileName", uncompressedFileName());
emit entry(e);
return true;