File indexing completed on 2025-01-05 03:52:04

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2006-04-04
0007  * Description : a tool to generate HTML image galleries
0008  *
0009  * SPDX-FileCopyrightText: 2006-2010 by Aurelien Gateau <aurelien dot gateau at free dot fr>
0010  * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "gallerytheme.h"
0017 
0018 // Qt includes
0019 
0020 #include <QFile>
0021 #include <QFileInfo>
0022 #include <QTextStream>
0023 #include <QUrl>
0024 #include <QDir>
0025 
0026 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0027 
0028 #   include <QTextCodec>
0029 
0030 #endif
0031 
0032 // KDE includes
0033 
0034 #include <kconfiggroup.h>
0035 #include <kdesktopfile.h>
0036 
0037 // Local includes
0038 
0039 #include "digikam_debug.h"
0040 #include "colorthemeparameter.h"
0041 #include "intthemeparameter.h"
0042 #include "listthemeparameter.h"
0043 #include "stringthemeparameter.h"
0044 #include "captionthemeparameter.h"
0045 
0046 namespace DigikamGenericHtmlGalleryPlugin
0047 {
0048 
0049 static const QLatin1String AUTHOR_GROUP           ("X-HTMLGallery Author");
0050 static const QLatin1String PARAMETER_GROUP_PREFIX ("X-HTMLGallery Parameter ");
0051 static const QLatin1String PARAMETER_TYPE_KEY     ("Type");
0052 static const QLatin1String PREVIEW_GROUP          ("X-HTMLGallery Preview");
0053 static const QLatin1String OPTIONS_GROUP          ("X-HTMLGallery Options");
0054 static const QLatin1String CAPTION_PARAMETER_TYPE ("caption");
0055 static const QLatin1String STRING_PARAMETER_TYPE  ("string");
0056 static const QLatin1String LIST_PARAMETER_TYPE    ("list");
0057 static const QLatin1String COLOR_PARAMETER_TYPE   ("color");
0058 static const QLatin1String INT_PARAMETER_TYPE     ("int");
0059 
0060 static GalleryTheme::List sList;
0061 
0062 class Q_DECL_HIDDEN GalleryTheme::Private
0063 {
0064 public:
0065 
0066     explicit Private()
0067         : desktopFile(nullptr)
0068     {
0069     }
0070 
0071     KDesktopFile* desktopFile;
0072     QUrl          url;
0073     ParameterList parameterList;
0074 
0075 public:
0076 
0077     /**
0078      * Return the list of parameters defined in the desktop file. We need to
0079      * parse the file ourselves to preserve parameter order.
0080      */
0081     QStringList readParameterNameList(const QString& desktopFileName)
0082     {
0083         QStringList list;
0084         QFile file(desktopFileName);
0085 
0086         if (!file.open(QIODevice::ReadOnly))
0087         {
0088             return QStringList();
0089         }
0090 
0091         QTextStream stream(&file);
0092 
0093 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0094 
0095         stream.setEncoding(QStringConverter::Utf8);
0096 
0097 #else
0098 
0099         stream.setCodec(QTextCodec::codecForName("UTF-8"));
0100 
0101 #endif
0102 
0103         QString prefix = QLatin1String("[") + QLatin1String(PARAMETER_GROUP_PREFIX);
0104 
0105         while (!stream.atEnd())
0106         {
0107             QString line = stream.readLine();
0108             line         = line.trimmed();
0109 
0110             if (!line.startsWith(prefix))
0111             {
0112                 continue;
0113             }
0114 
0115             // Remove opening bracket and group prefix
0116 
0117             line         = line.mid(prefix.length());
0118 
0119             // Remove closing bracket
0120 
0121             line.truncate(line.length() - 1);
0122 
0123             list.append(line);
0124         }
0125 
0126         file.close();
0127         return list;
0128     }
0129 
0130     void init(const QString& desktopFileName)
0131     {
0132         delete desktopFile;
0133 
0134         desktopFile                   = new KDesktopFile(desktopFileName);
0135         url                           = QUrl::fromLocalFile(desktopFileName);
0136         QStringList parameterNameList = readParameterNameList(desktopFileName);
0137 
0138         readParameters(parameterNameList);
0139     }
0140 
0141     void readParameters(const QStringList& list)
0142     {
0143         QStringList::ConstIterator it  = list.constBegin();
0144         QStringList::ConstIterator end = list.constEnd();
0145 
0146         for ( ; it != end ; ++it)
0147         {
0148             QString groupName                 = QLatin1String(PARAMETER_GROUP_PREFIX) + *it;
0149             QByteArray internalName           = it->toUtf8();
0150             KConfigGroup group                = desktopFile->group(groupName);
0151             QString type                      = group.readEntry(PARAMETER_TYPE_KEY);
0152             AbstractThemeParameter* parameter = nullptr;
0153 
0154             if      (type == QLatin1String(STRING_PARAMETER_TYPE))
0155             {
0156                 parameter = new StringThemeParameter();
0157             }
0158             else if (type == QLatin1String(CAPTION_PARAMETER_TYPE))
0159             {
0160                 parameter = new CaptionThemeParameter();
0161             }
0162             else if (type == QLatin1String(LIST_PARAMETER_TYPE))
0163             {
0164                 parameter = new ListThemeParameter();
0165             }
0166             else if (type == QLatin1String(COLOR_PARAMETER_TYPE))
0167             {
0168                 parameter = new ColorThemeParameter();
0169             }
0170             else if (type == QLatin1String(INT_PARAMETER_TYPE))
0171             {
0172                 parameter = new IntThemeParameter();
0173             }
0174             else
0175             {
0176                 qCWarning(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Parameter '" << internalName
0177                                                        << "' has unknown type '" << type
0178                                                        << "'. Falling back to string type\n";
0179                 parameter = new StringThemeParameter();
0180             }
0181 
0182             parameter->init(internalName, &group);
0183             parameterList << parameter;
0184         }
0185     }
0186 };
0187 
0188 GalleryTheme::GalleryTheme()
0189    : d(new Private)
0190 {
0191 }
0192 
0193 GalleryTheme::~GalleryTheme()
0194 {
0195     delete d->desktopFile;
0196     delete d;
0197 }
0198 
0199 const GalleryTheme::List& GalleryTheme::getList()
0200 {
0201     if (sList.isEmpty())
0202     {
0203         QStringList list;
0204         QStringList internalNameList;
0205         const QStringList filter     = QStringList() << QLatin1String("*.desktop");
0206         const QStringList themesDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
0207                                                                  QLatin1String("digikam/themes"),
0208                                                                  QStandardPaths::LocateDirectory);
0209 
0210         Q_FOREACH (const QString& themeDir, themesDirs)
0211         {
0212             Q_FOREACH (const QFileInfo& themeInfo, QDir(themeDir).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot))
0213             {
0214                 Q_FOREACH (const QFileInfo& deskFile, QDir(themeInfo.absoluteFilePath()).entryInfoList(filter))
0215                 {
0216                     list << deskFile.absoluteFilePath();
0217                 }
0218             }
0219         }
0220 
0221         QStringList::ConstIterator it  = list.constBegin();
0222         QStringList::ConstIterator end = list.constEnd();
0223 
0224         for ( ; it != end ; ++it)
0225         {
0226             GalleryTheme::Ptr theme(new GalleryTheme);
0227             theme->d->init(*it);
0228             QString internalName = theme->internalName();
0229 
0230             if (!internalNameList.contains(internalName))
0231             {
0232                 sList << theme;
0233                 internalNameList << internalName;
0234             }
0235         }
0236     }
0237 
0238     qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "HTML Gallery Themes found:" << sList.size();
0239 
0240     return sList;
0241 }
0242 
0243 GalleryTheme::Ptr GalleryTheme::findByInternalName(const QString& internalName)
0244 {
0245     const GalleryTheme::List& lst         = getList();
0246     GalleryTheme::List::ConstIterator it  = lst.constBegin();
0247     GalleryTheme::List::ConstIterator end = lst.constEnd();
0248 
0249     for ( ; it != end ; ++it)
0250     {
0251         GalleryTheme::Ptr theme = *it;
0252 
0253         if (theme->internalName() == internalName)
0254         {
0255             return theme;
0256         }
0257     }
0258 
0259     return GalleryTheme::Ptr(nullptr);
0260 }
0261 
0262 QString GalleryTheme::internalName() const
0263 {
0264     return d->url.fileName();
0265 }
0266 
0267 QString GalleryTheme::name() const
0268 {
0269     return d->desktopFile->readName();
0270 }
0271 
0272 QString GalleryTheme::comment() const
0273 {
0274     return d->desktopFile->readComment();
0275 }
0276 
0277 QString GalleryTheme::directory() const
0278 {
0279     return d->url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toLocalFile();
0280 }
0281 
0282 QString GalleryTheme::authorName() const
0283 {
0284     return d->desktopFile->group(AUTHOR_GROUP).readEntry("Name");
0285 }
0286 
0287 QString GalleryTheme::authorUrl() const
0288 {
0289     return d->desktopFile->group(AUTHOR_GROUP).readEntry("Url");
0290 }
0291 
0292 QString GalleryTheme::previewName() const
0293 {
0294     return d->desktopFile->group(PREVIEW_GROUP).readEntry("Name");
0295 }
0296 
0297 QString GalleryTheme::previewUrl() const
0298 {
0299     return d->desktopFile->group(PREVIEW_GROUP).readEntry("Url");
0300 }
0301 
0302 bool GalleryTheme::allowNonsquareThumbnails() const
0303 {
0304     return d->desktopFile->group(OPTIONS_GROUP).readEntry("Allow-non-square-thumbnails", false);
0305 }
0306 
0307 GalleryTheme::ParameterList GalleryTheme::parameterList() const
0308 {
0309     return d->parameterList;
0310 }
0311 
0312 } // namespace DigikamGenericHtmlGalleryPlugin