File indexing completed on 2024-05-05 04:22:03

0001 /* SPDX-FileCopyrightText: 2003-2020 The KPhotoAlbum Development Team
0002 
0003    SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 #include "XMLHandler.h"
0006 
0007 #include <DB/ImageDB.h>
0008 #include <Utilities/FileUtil.h>
0009 #include <kpabase/FileName.h>
0010 
0011 using Utilities::StringSet;
0012 
0013 /**
0014  * \class ImportExport::XMLHandler
0015  * \brief Helper class for
0016  * reading and writing the index.xml file located in exported .kim file.
0017  * This class is a simple helper class which encapsulate the code needed for generating an index.xml for the export file.
0018  * There should never be a need to keep any instances around of this class, simply create one on the stack, and call
0019  * thee method \ref createIndexXML().
0020  *
0021  * Notice, you will find a lot of duplicated code inhere from the XML database, there are two reasons for this
0022  * (1) In the long run the XML database ought to be an optional part (users might instead use, say an SQL database)
0023  * (2) To ensure that the .kim files are compatible both forth and back between versions, I'd rather keep that code
0024  * separate from the normal index.xml file, which might change with KPhotoAlbum versions to e.g. support compression.
0025  */
0026 QByteArray ImportExport::XMLHandler::createIndexXML(
0027     const DB::FileNameList &images,
0028     const QString &baseUrl,
0029     ImageFileLocation location,
0030     Utilities::UniqFilenameMapper *nameMap)
0031 {
0032     QDomDocument doc;
0033     doc.appendChild(doc.createProcessingInstruction(QString::fromLatin1("xml"),
0034                                                     QString::fromLatin1("version=\"1.0\" encoding=\"UTF-8\"")));
0035 
0036     QDomElement top = doc.createElement(QString::fromLatin1("KimDaBa-export")); // Don't change, as this will make the files unreadable for KimDaBa 2.1 and back.
0037     top.setAttribute(QString::fromLatin1("location"),
0038                      location == Inline ? QString::fromLatin1("inline") : QString::fromLatin1("external"));
0039     if (!baseUrl.isEmpty())
0040         top.setAttribute(QString::fromLatin1("baseurl"), baseUrl);
0041     doc.appendChild(top);
0042 
0043     for (const DB::FileName &fileName : images) {
0044         const QString mappedFile = nameMap->uniqNameFor(fileName);
0045         const auto info = DB::ImageDB::instance()->info(fileName);
0046         QDomElement elm = save(doc, info);
0047         elm.setAttribute(QString::fromLatin1("file"), mappedFile);
0048         top.appendChild(elm);
0049     }
0050     return doc.toByteArray();
0051 }
0052 
0053 QDomElement ImportExport::XMLHandler::save(QDomDocument doc, const DB::ImageInfoPtr &info)
0054 {
0055     QDomElement elm = doc.createElement(QString::fromLatin1("image"));
0056     elm.setAttribute(QString::fromLatin1("label"), info->label());
0057     elm.setAttribute(QString::fromLatin1("description"), info->description());
0058 
0059     DB::ImageDate date = info->date();
0060     Utilities::FastDateTime start = date.start();
0061     Utilities::FastDateTime end = date.end();
0062 
0063     elm.setAttribute(QString::fromLatin1("yearFrom"), start.date().year());
0064     elm.setAttribute(QString::fromLatin1("monthFrom"), start.date().month());
0065     elm.setAttribute(QString::fromLatin1("dayFrom"), start.date().day());
0066     elm.setAttribute(QString::fromLatin1("hourFrom"), start.time().hour());
0067     elm.setAttribute(QString::fromLatin1("minuteFrom"), start.time().minute());
0068     elm.setAttribute(QString::fromLatin1("secondFrom"), start.time().second());
0069 
0070     elm.setAttribute(QString::fromLatin1("yearTo"), end.date().year());
0071     elm.setAttribute(QString::fromLatin1("monthTo"), end.date().month());
0072     elm.setAttribute(QString::fromLatin1("dayTo"), end.date().day());
0073 
0074     elm.setAttribute(QString::fromLatin1("width"), info->size().width());
0075     elm.setAttribute(QString::fromLatin1("height"), info->size().height());
0076     elm.setAttribute(QString::fromLatin1("md5sum"), info->MD5Sum().toHexString());
0077     elm.setAttribute(QString::fromLatin1("angle"), info->angle());
0078 
0079     writeCategories(doc, elm, info);
0080 
0081     return elm;
0082 }
0083 
0084 void ImportExport::XMLHandler::writeCategories(QDomDocument doc, QDomElement root, const DB::ImageInfoPtr &info)
0085 {
0086     QDomElement elm = doc.createElement(QString::fromLatin1("options"));
0087 
0088     bool anyAtAll = false;
0089     const QStringList grps = info->availableCategories();
0090     for (const QString &name : grps) {
0091         QDomElement opt = doc.createElement(QString::fromLatin1("option"));
0092         opt.setAttribute(QString::fromLatin1("name"), name);
0093 
0094         const StringSet items = info->itemsOfCategory(name);
0095         bool any = false;
0096         for (const QString &item : items) {
0097             QDomElement val = doc.createElement(QString::fromLatin1("value"));
0098             val.setAttribute(QString::fromLatin1("value"), item);
0099             opt.appendChild(val);
0100             any = true;
0101             anyAtAll = true;
0102         }
0103         if (any)
0104             elm.appendChild(opt);
0105     }
0106 
0107     if (anyAtAll)
0108         root.appendChild(elm);
0109 }
0110 // vi:expandtab:tabstop=4 shiftwidth=4: