1 /*
2 SPDX-FileCopyrightText: 2013-2021 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "templatemanager.h"
8 #include "pimcommon_debug.h"
9 #include "templatewidgets/templatelistwidget.h"
10
11 #include <KDirWatch>
12
13 #include <KConfig>
14 #include <KConfigGroup>
15
16 #include <QDirIterator>
17 #include <QStandardPaths>
18
19 using namespace PimCommon;
20
21 class PimCommon::TemplateManagerPrivate
22 {
23 public:
24 QStringList mTemplatesDirectories;
25 PimCommon::TemplateListWidget *mTemplateListWidget = nullptr;
26 KDirWatch *mDirWatch = nullptr;
27 };
28
TemplateManager(const QString & relativeTemplateDir,PimCommon::TemplateListWidget * templateListWidget)29 TemplateManager::TemplateManager(const QString &relativeTemplateDir, PimCommon::TemplateListWidget *templateListWidget)
30 : QObject(templateListWidget)
31 , d(new PimCommon::TemplateManagerPrivate)
32 {
33 d->mTemplateListWidget = templateListWidget;
34 d->mDirWatch = new KDirWatch(this);
35 initTemplatesDirectories(relativeTemplateDir);
36
37 connect(d->mDirWatch, &KDirWatch::dirty, this, &TemplateManager::slotDirectoryChanged);
38 loadTemplates(true);
39 }
40
41 TemplateManager::~TemplateManager() = default;
42
slotDirectoryChanged()43 void TemplateManager::slotDirectoryChanged()
44 {
45 d->mTemplateListWidget->loadTemplates();
46 loadTemplates();
47 }
48
initTemplatesDirectories(const QString & templatesRelativePath)49 void TemplateManager::initTemplatesDirectories(const QString &templatesRelativePath)
50 {
51 if (!templatesRelativePath.isEmpty()) {
52 d->mTemplatesDirectories = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, templatesRelativePath, QStandardPaths::LocateDirectory);
53 if (d->mTemplatesDirectories.count() < 2) {
54 // Make sure to add local directory
55 const QString localDirectory = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + templatesRelativePath;
56 if (!d->mTemplatesDirectories.contains(localDirectory)) {
57 d->mTemplatesDirectories.append(localDirectory);
58 }
59 }
60 }
61 }
62
loadTemplates(bool init)63 void TemplateManager::loadTemplates(bool init)
64 {
65 if (!init) {
66 if (!d->mTemplatesDirectories.isEmpty()) {
67 for (const QString &directory : std::as_const(d->mTemplatesDirectories)) {
68 d->mDirWatch->removeDir(directory);
69 }
70 } else {
71 return;
72 }
73 }
74
75 for (const QString &directory : std::as_const(d->mTemplatesDirectories)) {
76 QDirIterator dirIt(directory, QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);
77 while (dirIt.hasNext()) {
78 dirIt.next();
79 TemplateInfo info = loadTemplate(dirIt.filePath(), QStringLiteral("template.desktop"));
80 if (info.isValid()) {
81 d->mTemplateListWidget->addDefaultTemplate(info.name, info.script);
82 }
83 }
84 d->mDirWatch->addDir(directory);
85 }
86 d->mDirWatch->startScan();
87 }
88
loadTemplate(const QString & themePath,const QString & defaultDesktopFileName)89 TemplateInfo TemplateManager::loadTemplate(const QString &themePath, const QString &defaultDesktopFileName)
90 {
91 TemplateInfo info;
92 const QString themeInfoFile = themePath + QLatin1Char('/') + defaultDesktopFileName;
93 KConfig config(themeInfoFile);
94 KConfigGroup group(&config, QStringLiteral("Desktop Entry"));
95
96 info.name = group.readEntry("Name", QString());
97 const QString filename = group.readEntry("FileName", QString());
98 if (!filename.isEmpty()) {
99 QFile file(themePath + QLatin1Char('/') + filename);
100 if (file.exists()) {
101 if (file.open(QIODevice::ReadOnly)) {
102 info.script = QString::fromUtf8(file.readAll());
103 }
104 }
105 }
106 return info;
107 }
108
debug() const109 void TemplateInfo::debug() const
110 {
111 qCDebug(PIMCOMMON_LOG) << " name :" << name << " script :" << script;
112 }
113