1 | /* This file is part of the KDE project |
2 | Copyright (C) 2003,2004 Ariya Hidayat <ariya@kde.org> |
3 | Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; only |
8 | version 2 of the License. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | // Local |
22 | #include "FunctionRepository.h" |
23 | |
24 | #include "Function.h" |
25 | #include "FunctionDescription.h" |
26 | #include "FunctionModuleRegistry.h" |
27 | |
28 | #include <QDomElement> |
29 | #include <QDomNode> |
30 | #include <QFile> |
31 | #include <QHash> |
32 | |
33 | #include <kdebug.h> |
34 | #include <kglobal.h> |
35 | #include <klocale.h> |
36 | |
37 | using namespace Calligra::Sheets; |
38 | |
39 | class FunctionRepository::Private |
40 | { |
41 | public: |
42 | QHash<QString, QSharedPointer<Function> > functions; |
43 | QHash<QString, QSharedPointer<Function> > alternates; |
44 | QHash<QString, FunctionDescription*> descriptions; |
45 | QStringList groups; |
46 | bool initialized; |
47 | }; |
48 | |
49 | FunctionRepository* FunctionRepository::self() |
50 | { |
51 | K_GLOBAL_STATIC(FunctionRepository, s_instance) |
52 | if (!s_instance.exists()) { |
53 | *s_instance; // creates the global instance |
54 | |
55 | // register all existing functions |
56 | FunctionModuleRegistry::instance()->registerFunctions(); |
57 | |
58 | #ifndef NDEBUG |
59 | kDebug(36005) << "functions registered:" << s_instance->d->functions.count() |
60 | << "descriptions loaded:" << s_instance->d->descriptions.count(); |
61 | |
62 | // Verify, that every function has a description. |
63 | QStringList missingDescriptions; |
64 | typedef QHash<QString, QSharedPointer<Function> > Functions; |
65 | Functions::ConstIterator end = s_instance->d->functions.constEnd(); |
66 | for (Functions::ConstIterator it = s_instance->d->functions.constBegin(); it != end; ++it) { |
67 | if (!s_instance->d->descriptions.contains(it.key())) |
68 | missingDescriptions << it.key(); |
69 | } |
70 | if (missingDescriptions.count() > 0) { |
71 | kDebug(36005) << "No function descriptions found for:" ; |
72 | foreach(const QString& missingDescription, missingDescriptions) { |
73 | kDebug(36005) << "\t" << missingDescription; |
74 | } |
75 | } |
76 | #endif |
77 | } |
78 | return s_instance; |
79 | } |
80 | |
81 | FunctionRepository::FunctionRepository() |
82 | : d(new Private) |
83 | { |
84 | d->initialized = false; |
85 | } |
86 | |
87 | FunctionRepository::~FunctionRepository() |
88 | { |
89 | qDeleteAll(d->descriptions); |
90 | delete d; |
91 | } |
92 | |
93 | void FunctionRepository::add(const QSharedPointer<Function>& function) |
94 | { |
95 | if (!function) return; |
96 | d->functions.insert(function->name().toUpper(), function); |
97 | |
98 | if (!function->alternateName().isNull()) { |
99 | d->alternates.insert(function->alternateName().toUpper(), function); |
100 | } |
101 | } |
102 | |
103 | void FunctionRepository::add(FunctionDescription *desc) |
104 | { |
105 | if (!desc) return; |
106 | if (!d->functions.contains(desc->name())) return; |
107 | d->descriptions.insert(desc->name(), desc); |
108 | } |
109 | |
110 | void FunctionRepository::remove(const QSharedPointer<Function>& function) |
111 | { |
112 | const QString functionName = function->name().toUpper(); |
113 | delete d->descriptions.take(functionName); |
114 | if (d->functions.contains(functionName)) { |
115 | QSharedPointer<Function> function = d->functions.take(functionName); |
116 | d->alternates.remove(function->alternateName().toUpper()); |
117 | } |
118 | } |
119 | |
120 | QSharedPointer<Function> FunctionRepository::function(const QString& name) |
121 | { |
122 | const QString n = name.toUpper(); |
123 | QSharedPointer<Function> f = d->functions.value(n); |
124 | return !f.isNull() ? f : d->alternates.value(n); |
125 | } |
126 | |
127 | FunctionDescription *FunctionRepository::functionInfo(const QString& name) |
128 | { |
129 | return d->descriptions.value(name.toUpper()); |
130 | } |
131 | |
132 | // returns names of function in certain group |
133 | QStringList FunctionRepository::functionNames(const QString& group) |
134 | { |
135 | QStringList lst; |
136 | |
137 | foreach(FunctionDescription* description, d->descriptions) { |
138 | if (group.isNull() || (description->group() == group)) |
139 | lst.append(description->name()); |
140 | } |
141 | |
142 | lst.sort(); |
143 | return lst; |
144 | } |
145 | |
146 | const QStringList& FunctionRepository::groups() const |
147 | { |
148 | return d->groups; |
149 | } |
150 | |
151 | void FunctionRepository::addGroup(const QString& groupname) |
152 | { |
153 | d->groups.append(groupname); |
154 | d->groups.sort(); |
155 | } |
156 | |
157 | void FunctionRepository::loadFunctionDescriptions(const QString& filename) |
158 | { |
159 | QFile file(filename); |
160 | if (!file.open(QIODevice::ReadOnly)) |
161 | return; |
162 | |
163 | QDomDocument doc; |
164 | doc.setContent(&file); |
165 | file.close(); |
166 | |
167 | QString group; |
168 | |
169 | QDomNode n = doc.documentElement().firstChild(); |
170 | for (; !n.isNull(); n = n.nextSibling()) { |
171 | if (!n.isElement()) |
172 | continue; |
173 | QDomElement e = n.toElement(); |
174 | if (e.tagName() == "Group" ) { |
175 | group = i18n(e.namedItem("GroupName" ).toElement().text().toUtf8()); |
176 | addGroup(group); |
177 | |
178 | QDomNode n2 = e.firstChild(); |
179 | for (; !n2.isNull(); n2 = n2.nextSibling()) { |
180 | if (!n2.isElement()) |
181 | continue; |
182 | QDomElement e2 = n2.toElement(); |
183 | if (e2.tagName() == "Function" ) { |
184 | FunctionDescription* desc = new FunctionDescription(e2); |
185 | desc->setGroup(group); |
186 | if (d->functions.contains(desc->name())) |
187 | d->descriptions.insert(desc->name(), desc); |
188 | else { |
189 | kDebug(36005) << "Description for unknown function" << desc->name() << "found." ; |
190 | delete desc; |
191 | } |
192 | } |
193 | } |
194 | group.clear(); |
195 | } |
196 | } |
197 | } |
198 | |