File indexing completed on 2024-05-05 05:50:39
0001 /* 0002 SPDX-FileCopyrightText: 2016 Vladyslav Batyrenko <mvlabat@gmail.com> 0003 0004 SPDX-License-Identifier: BSD-2-Clause 0005 */ 0006 0007 #include "archiveentry.h" 0008 0009 #include <QMimeDatabase> 0010 0011 #include "util.h" 0012 0013 namespace Kerfuffle 0014 { 0015 Archive::Entry::Entry(QObject *parent, const QString &fullPath, const QString &rootNode) 0016 : QObject(parent) 0017 , rootNode(rootNode) 0018 , compressedSizeIsSet(true) 0019 , m_parent(qobject_cast<Entry *>(parent)) 0020 , m_size(0) 0021 , m_compressedSize(0) 0022 , m_sparseSize(0) 0023 , m_isDirectory(false) 0024 , m_isExecutable(false) 0025 , m_isPasswordProtected(false) 0026 , m_isSparse(false) 0027 { 0028 if (!fullPath.isEmpty()) 0029 setFullPath(fullPath); 0030 } 0031 0032 Archive::Entry::~Entry() 0033 { 0034 } 0035 0036 qulonglong Archive::Entry::size() const 0037 { 0038 return m_size; 0039 } 0040 0041 qulonglong Archive::Entry::sparseSize() const 0042 { 0043 return m_sparseSize; 0044 } 0045 0046 bool Archive::Entry::isSparse() const 0047 { 0048 return m_isSparse; 0049 } 0050 0051 void Archive::Entry::copyMetaData(const Archive::Entry *sourceEntry) 0052 { 0053 setProperty("fullPath", sourceEntry->property("fullPath")); 0054 setProperty("permissions", sourceEntry->property("permissions")); 0055 setProperty("owner", sourceEntry->property("owner")); 0056 setProperty("group", sourceEntry->property("group")); 0057 setProperty("size", sourceEntry->property("size")); 0058 setProperty("compressedSize", sourceEntry->property("compressedSize")); 0059 setProperty("sparseSize", sourceEntry->property("sparseSize")); 0060 setProperty("link", sourceEntry->property("link")); 0061 setProperty("ratio", sourceEntry->property("ratio")); 0062 setProperty("CRC", sourceEntry->property("CRC")); 0063 setProperty("BLAKE2", sourceEntry->property("BLAKE2")); 0064 setProperty("method", sourceEntry->property("method")); 0065 setProperty("version", sourceEntry->property("version")); 0066 setProperty("timestamp", sourceEntry->property("timestamp").toDateTime()); 0067 setProperty("isDirectory", sourceEntry->property("isDirectory")); 0068 setProperty("isPasswordProtected", sourceEntry->property("isPasswordProtected")); 0069 } 0070 0071 QVector<Archive::Entry *> Archive::Entry::entries() 0072 { 0073 Q_ASSERT(isDir()); 0074 return m_entries; 0075 } 0076 0077 const QVector<Archive::Entry *> Archive::Entry::entries() const 0078 { 0079 Q_ASSERT(isDir()); 0080 return m_entries; 0081 } 0082 0083 void Archive::Entry::setEntryAt(int index, Entry *value) 0084 { 0085 Q_ASSERT(isDir()); 0086 Q_ASSERT(index < m_entries.count()); 0087 m_entries[index] = value; 0088 } 0089 0090 void Archive::Entry::appendEntry(Entry *entry) 0091 { 0092 Q_ASSERT(isDir()); 0093 m_entries.append(entry); 0094 } 0095 0096 void Archive::Entry::removeEntryAt(int index) 0097 { 0098 Q_ASSERT(isDir()); 0099 Q_ASSERT(index < m_entries.count()); 0100 m_entries.remove(index); 0101 } 0102 0103 Archive::Entry *Archive::Entry::getParent() const 0104 { 0105 return m_parent; 0106 } 0107 0108 void Archive::Entry::setParent(Archive::Entry *parent) 0109 { 0110 m_parent = parent; 0111 } 0112 0113 void Archive::Entry::setFullPath(const QString &fullPath) 0114 { 0115 m_fullPath = fullPath; 0116 0117 m_name = Kerfuffle::Util::lastPathSegment(m_fullPath); 0118 } 0119 0120 QString Archive::Entry::fullPath(PathFormat format) const 0121 { 0122 if (format == NoTrailingSlash && m_fullPath.endsWith(QLatin1Char('/'))) { 0123 return m_fullPath.left(m_fullPath.size() - 1); 0124 } else { 0125 return m_fullPath; 0126 } 0127 } 0128 0129 QString Archive::Entry::displayName() const 0130 { 0131 if (m_displayName.isEmpty()) { 0132 return m_name; 0133 } 0134 0135 return m_displayName; 0136 } 0137 0138 QString Archive::Entry::name() const 0139 { 0140 return m_name; 0141 } 0142 0143 QStringView Archive::Entry::nameView() const 0144 { 0145 return m_name; 0146 } 0147 0148 void Archive::Entry::setDisplayName(const QString &displayName) 0149 { 0150 m_displayName = displayName; 0151 } 0152 0153 void Archive::Entry::setIsDirectory(const bool isDirectory) 0154 { 0155 m_isDirectory = isDirectory; 0156 } 0157 0158 bool Archive::Entry::isDir() const 0159 { 0160 return m_isDirectory; 0161 } 0162 0163 void Archive::Entry::setIsExecutable(const bool isExecutable) 0164 { 0165 m_isExecutable = isExecutable; 0166 } 0167 0168 bool Archive::Entry::isExecutable() const 0169 { 0170 return m_isExecutable; 0171 } 0172 0173 int Archive::Entry::row() const 0174 { 0175 if (getParent()) { 0176 return getParent()->entries().indexOf(const_cast<Archive::Entry *>(this)); 0177 } 0178 return 0; 0179 } 0180 0181 Archive::Entry *Archive::Entry::find(QStringView name) const 0182 { 0183 for (Entry *entry : std::as_const(m_entries)) { 0184 if (entry && (entry->nameView() == name)) { 0185 return entry; 0186 } 0187 } 0188 return nullptr; 0189 } 0190 0191 Archive::Entry *Archive::Entry::findByPath(const QStringList &pieces, int index) const 0192 { 0193 if (index == pieces.count()) { 0194 return nullptr; 0195 } 0196 0197 Entry *next = find(pieces.at(index)); 0198 if (index == pieces.count() - 1) { 0199 return next; 0200 } 0201 if (next && next->isDir()) { 0202 return next->findByPath(pieces, index + 1); 0203 } 0204 return nullptr; 0205 } 0206 0207 void Archive::Entry::countChildren(uint &dirs, uint &files) const 0208 { 0209 dirs = files = 0; 0210 if (!isDir()) { 0211 return; 0212 } 0213 0214 const auto archiveEntries = entries(); 0215 for (auto entry : archiveEntries) { 0216 if (entry->isDir()) { 0217 dirs++; 0218 } else { 0219 files++; 0220 } 0221 } 0222 } 0223 0224 QIcon Archive::Entry::icon() const 0225 { 0226 if (m_icon.isNull()) { 0227 QMimeDatabase db; 0228 0229 if (m_isDirectory) { 0230 static QIcon directoryIcon = QIcon::fromTheme(db.mimeTypeForName(QStringLiteral("inode/directory")).iconName()); 0231 m_icon = directoryIcon; 0232 } else { 0233 m_icon = QIcon::fromTheme(db.mimeTypeForFile(displayName(), QMimeDatabase::MatchMode::MatchExtension).iconName()); 0234 } 0235 } 0236 0237 return m_icon; 0238 } 0239 0240 bool Archive::Entry::operator==(const Archive::Entry &right) const 0241 { 0242 return m_fullPath == right.m_fullPath; 0243 } 0244 0245 QDebug operator<<(QDebug d, const Kerfuffle::Archive::Entry &entry) 0246 { 0247 d.nospace() << "Entry(" << entry.property("fullPath"); 0248 if (!entry.rootNode.isEmpty()) { 0249 d.nospace() << "," << entry.rootNode; 0250 } 0251 d.nospace() << ")"; 0252 return d.space(); 0253 } 0254 0255 QDebug operator<<(QDebug d, const Kerfuffle::Archive::Entry *entry) 0256 { 0257 d.nospace() << "Entry(" << entry->property("fullPath"); 0258 if (!entry->rootNode.isEmpty()) { 0259 d.nospace() << "," << entry->rootNode; 0260 } 0261 d.nospace() << ")"; 0262 return d.space(); 0263 } 0264 0265 } 0266 0267 #include "moc_archiveentry.cpp"