コード例 #1
0
ファイル: archivemodel.cpp プロジェクト: aelog/ark
QModelIndex ArchiveModel::parent(const QModelIndex &index) const
{
    if (index.isValid()) {
        Archive::Entry *item = static_cast<Archive::Entry*>(index.internalPointer());
        Q_ASSERT(item);
        if (item->getParent() && (item->getParent() != m_rootEntry.data())) {
            return createIndex(item->getParent()->row(), 0, item->getParent());
        }
    }
    return QModelIndex();
}
コード例 #2
0
ファイル: cliplugin.cpp プロジェクト: KDE/ark
void CliPlugin::handleUnrar4Entry()
{
    Archive::Entry *e = new Archive::Entry(this);

    QDateTime ts = QDateTime::fromString(QString(m_unrar4Details.at(4) + QLatin1Char(' ') + m_unrar4Details.at(5)),
                                         QStringLiteral("dd-MM-yy hh:mm"));
    // Unrar 3 & 4 output dates with a 2-digit year but QDateTime takes it as
    // 19??. Let's take 1950 as cut-off; similar to KDateTime.
    if (ts.date().year() < 1950) {
        ts = ts.addYears(100);
    }
    e->setProperty("timestamp", ts);

    bool isDirectory = ((m_unrar4Details.at(6).at(0) == QLatin1Char('d')) ||
                        (m_unrar4Details.at(6).at(1) == QLatin1Char('D')));
    e->setProperty("isDirectory", isDirectory);

    if (isDirectory && !m_unrar4Details.at(0).endsWith(QLatin1Char('/'))) {
        m_unrar4Details[0] += QLatin1Char('/');
    }

    // Unrar reports the ratio as ((compressed size * 100) / size);
    // we consider ratio as (100 * ((size - compressed size) / size)).
    // If the archive is a multivolume archive, a string indicating
    // whether the archive's position in the volume is displayed
    // instead of the compression ratio.
    QString compressionRatio = m_unrar4Details.at(3);
    if ((compressionRatio == QStringLiteral("<--")) ||
        (compressionRatio == QStringLiteral("<->")) ||
        (compressionRatio == QStringLiteral("-->"))) {
        compressionRatio = QLatin1Char('0');
    } else {
        compressionRatio.chop(1); // Remove the '%'
    }
    e->setProperty("ratio", compressionRatio);

    // TODO:
    // - Permissions differ depending on the system the entry was added
    //   to the archive.
    e->setProperty("fullPath", 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();
    emit entry(e);
}
コード例 #3
0
ファイル: cliplugin.cpp プロジェクト: KDE/ark
void CliPlugin::handleUnrar5Entry()
{
    Archive::Entry *e = new Archive::Entry(this);

    QString compressionRatio = m_unrar5Details.value(QStringLiteral("ratio"));
    compressionRatio.chop(1); // Remove the '%'
    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->setProperty("timestamp", ts);

    bool isDirectory = (m_unrar5Details.value(QStringLiteral("type")) == QLatin1String("Directory"));
    e->setProperty("isDirectory", isDirectory);

    if (isDirectory && !m_unrar5Details.value(QStringLiteral("name")).endsWith(QLatin1Char('/'))) {
        m_unrar5Details[QStringLiteral("name")] += QLatin1Char('/');
    }

    QString compression = m_unrar5Details.value(QStringLiteral("compression"));
    int optionPos = compression.indexOf(QLatin1Char('-'));
    if (optionPos != -1) {
        e->setProperty("method", compression.mid(optionPos));
        e->setProperty("version", compression.left(optionPos).trimmed());
    } else {
        // No method specified.
        e->setProperty("method", QStringLiteral(""));
        e->setProperty("version", compression);
    }

    m_isPasswordProtected = m_unrar5Details.value(QStringLiteral("flags")).contains(QStringLiteral("encrypted"));
    e->setProperty("isPasswordProtected", m_isPasswordProtected);
    if (m_isPasswordProtected) {
        m_isRAR5 ? emit encryptionMethodFound(QStringLiteral("AES256")) : emit encryptionMethodFound(QStringLiteral("AES128"));
    }

    e->setProperty("fullPath", 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->property("permissions").toString().startsWith(QLatin1Char('l'))) {
        e->setProperty("link", m_unrar5Details.value(QStringLiteral("target")));
    }

    m_unrar5Details.clear();
    emit entry(e);
}
コード例 #4
0
ファイル: cliplugin.cpp プロジェクト: KDE/ark
bool CliPlugin::readListLine(const QString &line)
{
    static const QRegularExpression entryPattern(QStringLiteral(
        "^(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\d{8}).(\\d{6})\\s+(.+)$") );

    // RegExp to identify the line preceding comments.
    const QRegularExpression commentPattern(QStringLiteral("^Archive:  .*$"));
    // RegExp to identify the line following comments.
    const QRegularExpression commentEndPattern(QStringLiteral("^Zip file size: .*$"));

    switch (m_parseState) {
    case ParseStateHeader:
        if (commentPattern.match(line).hasMatch()) {
            m_parseState = ParseStateComment;
        } else if (commentEndPattern.match(line).hasMatch()){
            m_parseState = ParseStateEntry;
        }
        break;
    case ParseStateComment:
        if (commentEndPattern.match(line).hasMatch()) {
            m_parseState = ParseStateEntry;
            if (!m_tempComment.trimmed().isEmpty()) {
                m_comment = m_tempComment.trimmed();
                m_linesComment = m_comment.count(QLatin1Char('\n')) + 1;
                qCDebug(ARK) << "Found a comment with" << m_linesComment << "lines";
            }
        } else {
            m_tempComment.append(line + QLatin1Char('\n'));
        }
    case ParseStateEntry:
        QRegularExpressionMatch rxMatch = entryPattern.match(line);
        if (rxMatch.hasMatch()) {
            Archive::Entry *e = new Archive::Entry(this);
            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->setProperty("isDirectory", rxMatch.captured(10).endsWith(QLatin1Char('/')));

            e->setProperty("size", rxMatch.captured(4));
            QString status = rxMatch.captured(5);
            if (status[0].isUpper()) {
                e->setProperty("isPasswordProtected", true);
            }
            e->setProperty("compressedSize", rxMatch.captured(6).toInt());
            e->setProperty("method", rxMatch.captured(7));

            QString method = convertCompressionMethod(rxMatch.captured(7));
            emit compressionMethodFound(method);

            const QDateTime ts(QDate::fromString(rxMatch.captured(8), QStringLiteral("yyyyMMdd")),
                               QTime::fromString(rxMatch.captured(9), QStringLiteral("hhmmss")));
            e->setProperty("timestamp", ts);

            e->setProperty("fullPath", rxMatch.captured(10));
            emit entry(e);
        }
        break;
    }

    return true;
}
コード例 #5
0
ファイル: archivemodel.cpp プロジェクト: aelog/ark
QVariant ArchiveModel::data(const QModelIndex &index, int role) const
{
    if (index.isValid()) {
        Archive::Entry *entry = static_cast<Archive::Entry*>(index.internalPointer());
        switch (role) {
        case Qt::DisplayRole: {
            // TODO: complete the columns.
            int column = m_showColumns.at(index.column());
            switch (column) {
            case FullPath:
                return entry->name();
            case Size:
                if (entry->isDir()) {
                    uint dirs;
                    uint files;
                    entry->countChildren(dirs, files);
                    return KIO::itemsSummaryString(dirs + files, files, dirs, 0, false);
                } else if (!entry->property("link").toString().isEmpty()) {
                    return QVariant();
                } else {
                    return KIO::convertSize(entry->property("size").toULongLong());
                }
            case CompressedSize:
                if (entry->isDir() || !entry->property("link").toString().isEmpty()) {
                    return QVariant();
                } else {
                    qulonglong compressedSize = entry->property("compressedSize").toULongLong();
                    if (compressedSize != 0) {
                        return KIO::convertSize(compressedSize);
                    } else {
                        return QVariant();
                    }
                }
            case Ratio: // TODO: Use entry->metaData()[Ratio] when available.
                if (entry->isDir() || !entry->property("link").toString().isEmpty()) {
                    return QVariant();
                } else {
                    qulonglong compressedSize = entry->property("compressedSize").toULongLong();
                    qulonglong size = entry->property("size").toULongLong();
                    if (compressedSize == 0 || size == 0) {
                        return QVariant();
                    } else {
                        int ratio = int(100 * ((double)size - compressedSize) / size);
                        return QString(QString::number(ratio) + QStringLiteral(" %"));
                    }
                }

            case Timestamp: {
                const QDateTime timeStamp = entry->property("timestamp").toDateTime();
                return QLocale().toString(timeStamp, QLocale::ShortFormat);
            }

            default:
                return entry->property(m_propertiesMap[column].constData());
            }
        }
        case Qt::DecorationRole:
            if (index.column() == 0) {
                const Archive::Entry *e = static_cast<Archive::Entry*>(index.internalPointer());
                QIcon::Mode mode = (filesToMove.contains(e->fullPath())) ? QIcon::Disabled : QIcon::Normal;
                return m_entryIcons.value(e->fullPath(NoTrailingSlash)).pixmap(IconSize(KIconLoader::Small), IconSize(KIconLoader::Small), mode);
            }
            return QVariant();
        case Qt::FontRole: {
            QFont f;
            f.setItalic(entry->property("isPasswordProtected").toBool());
            return f;
        }
        default:
            return QVariant();
        }
    }
    return QVariant();
}