1 /*
2 * templatemanager.cpp
3 * Copyright 2017, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
4 * Copyright 2017, Mohamed Thabet <thabetx@gmail.com>
5 *
6 * This file is part of Tiled.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "templatemanager.h"
23
24 #include <memory>
25
26 #include "objecttemplate.h"
27 #include "objecttemplateformat.h"
28 #include "logginginterface.h"
29
30 #include <QFile>
31 #include <QFileInfo>
32
33 using namespace Tiled;
34
35 TemplateManager *TemplateManager::mInstance;
36
instance()37 TemplateManager *TemplateManager::instance()
38 {
39 if (!mInstance)
40 mInstance = new TemplateManager;
41
42 return mInstance;
43 }
44
deleteInstance()45 void TemplateManager::deleteInstance()
46 {
47 delete mInstance;
48 mInstance = nullptr;
49 }
50
TemplateManager(QObject * parent)51 TemplateManager::TemplateManager(QObject *parent)
52 : QObject(parent),
53 mWatcher(new FileSystemWatcher(this))
54 {
55 connect(mWatcher, &FileSystemWatcher::pathsChanged,
56 this, &TemplateManager::pathsChanged);
57 }
58
~TemplateManager()59 TemplateManager::~TemplateManager()
60 {
61 qDeleteAll(mObjectTemplates);
62 }
63
loadObjectTemplate(const QString & fileName,QString * error)64 ObjectTemplate *TemplateManager::loadObjectTemplate(const QString &fileName, QString *error)
65 {
66 ObjectTemplate *objectTemplate = findObjectTemplate(fileName);
67
68 if (!objectTemplate) {
69 auto newTemplate = readObjectTemplate(fileName, error);
70
71 // This instance will not have an object. It is used to detect broken
72 // template references.
73 if (!newTemplate)
74 newTemplate = std::make_unique<ObjectTemplate>(fileName);
75
76 // If the file exists, watch it, regardless of whether the parse was successful.
77 if (QFile::exists(fileName))
78 mWatcher->addPath(fileName);
79
80 objectTemplate = newTemplate.get();
81 mObjectTemplates.insert(fileName, newTemplate.release());
82 }
83
84 return objectTemplate;
85 }
86
pathsChanged(const QStringList & paths)87 void TemplateManager::pathsChanged(const QStringList &paths)
88 {
89 for (const QString &fileName : paths) {
90 ObjectTemplate *objectTemplate = findObjectTemplate(fileName);
91
92 // Most likely the file was removed.
93 if (!objectTemplate)
94 continue;
95
96 // Check whether we were the ones saving this file.
97 if (objectTemplate->lastSaved() == QFileInfo(fileName).lastModified())
98 continue;
99
100 auto newTemplate = readObjectTemplate(fileName);
101 if (newTemplate) {
102 objectTemplate->setObject(newTemplate->object());
103 objectTemplate->setFormat(newTemplate->format());
104 emit objectTemplateChanged(objectTemplate);
105 } else if (objectTemplate->object()) { // only report error if it had loaded fine before
106 ERROR(tr("Unable to reload template file: %1").arg(fileName));
107 }
108 }
109 }
110
111 #include "moc_templatemanager.cpp"
112