File indexing completed on 2024-04-28 04:58:03

0001 /*
0002  * SPDX-FileCopyrightText: 2018-2019 Kai Uwe Broulik <kde@broulik.de>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #include "opendocumentcreator.h"
0008 
0009 #include <QImage>
0010 #include <QScopedPointer>
0011 #include <QXmlStreamReader>
0012 
0013 #include <KPluginFactory>
0014 #include <KZip>
0015 
0016 K_PLUGIN_CLASS_WITH_JSON(OpenDocumentCreator, "opendocumentthumbnail.json")
0017 
0018 OpenDocumentCreator::OpenDocumentCreator(QObject *parent, const QVariantList &args)
0019     : KIO::ThumbnailCreator(parent, args)
0020 {
0021 }
0022 
0023 OpenDocumentCreator::~OpenDocumentCreator() = default;
0024 
0025 KIO::ThumbnailResult OpenDocumentCreator::create(const KIO::ThumbnailRequest &request)
0026 {
0027     KZip zip(request.url().toLocalFile());
0028     if (!zip.open(QIODevice::ReadOnly)) {
0029         return KIO::ThumbnailResult::fail();
0030     }
0031 
0032     // Open Document
0033     const KArchiveEntry *entry = zip.directory()->entry(QStringLiteral("Thumbnails/thumbnail.png"));
0034 
0035     if (entry && entry->isFile()) {
0036         const KZipFileEntry *zipFileEntry = static_cast<const KZipFileEntry *>(entry);
0037         QImage image;
0038         if (image.loadFromData(zipFileEntry->data(), "PNG")) {
0039             return KIO::ThumbnailResult::pass(image);
0040         }
0041     }
0042 
0043     // Open Packaging Conventions (e.g. Office "Open" XML)
0044     const KArchiveEntry *relsEntry = zip.directory()->entry(QStringLiteral("_rels/.rels"));
0045     if (relsEntry && relsEntry->isFile()) {
0046         const auto *relsFileEntry = static_cast<const KZipFileEntry *>(relsEntry);
0047 
0048         QScopedPointer<QIODevice> relsDevice(relsFileEntry->createDevice());
0049 
0050         QString thumbnailPath;
0051 
0052         QXmlStreamReader xml(relsDevice.data());
0053         while (!xml.atEnd() && !xml.hasError()) {
0054             xml.readNext();
0055             if (xml.isStartElement() && xml.name() == QLatin1String("Relationship")) {
0056                 const auto attributes = xml.attributes();
0057                 if (attributes.value(QStringLiteral("Type"))
0058                     == QLatin1String("http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail")) {
0059                     thumbnailPath = attributes.value(QStringLiteral("Target")).toString();
0060                     break;
0061                 }
0062             }
0063         }
0064 
0065         if (!thumbnailPath.isEmpty()) {
0066             const auto *thumbnailEntry = zip.directory()->entry(thumbnailPath);
0067             if (thumbnailEntry && thumbnailEntry->isFile()) {
0068                 QImage image;
0069                 image.loadFromData(static_cast<const KZipFileEntry *>(thumbnailEntry)->data());
0070                 return KIO::ThumbnailResult::pass(image);
0071             }
0072         }
0073     }
0074 
0075     return KIO::ThumbnailResult::fail();
0076 }
0077 
0078 #include "moc_opendocumentcreator.cpp"
0079 #include "opendocumentcreator.moc"