File indexing completed on 2024-04-28 16:21:23
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003,2004 Ariya Hidayat <ariya@kde.org> 0003 Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; only 0008 version 2 of the License. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 // Local 0022 #include "FunctionRepository.h" 0023 0024 #include "SheetsDebug.h" 0025 #include "Function.h" 0026 #include "FunctionDescription.h" 0027 #include "FunctionModuleRegistry.h" 0028 0029 #include <QDomElement> 0030 #include <QDomNode> 0031 #include <QFile> 0032 #include <QHash> 0033 0034 #include <QGlobalStatic> 0035 #include <KLocalizedString> 0036 0037 Q_GLOBAL_STATIC(Calligra::Sheets::FunctionRepository, s_instance) 0038 0039 using namespace Calligra::Sheets; 0040 0041 class Q_DECL_HIDDEN FunctionRepository::Private 0042 { 0043 public: 0044 QHash<QString, QSharedPointer<Function> > functions; 0045 QHash<QString, QSharedPointer<Function> > alternates; 0046 QHash<QString, FunctionDescription*> descriptions; 0047 QStringList groups; 0048 bool initialized; 0049 }; 0050 0051 FunctionRepository* FunctionRepository::self() 0052 { 0053 if (!s_instance.exists()) { 0054 *s_instance; // creates the global instance 0055 0056 // register all existing functions 0057 FunctionModuleRegistry::instance()->registerFunctions(); 0058 0059 #ifndef NDEBUG 0060 debugSheetsUI << "functions registered:" << s_instance->d->functions.count() 0061 << "descriptions loaded:" << s_instance->d->descriptions.count(); 0062 0063 // Verify, that every function has a description. 0064 QStringList missingDescriptions; 0065 typedef QHash<QString, QSharedPointer<Function> > Functions; 0066 Functions::ConstIterator end = s_instance->d->functions.constEnd(); 0067 for (Functions::ConstIterator it = s_instance->d->functions.constBegin(); it != end; ++it) { 0068 if (!s_instance->d->descriptions.contains(it.key())) 0069 missingDescriptions << it.key(); 0070 } 0071 if (missingDescriptions.count() > 0) { 0072 debugSheetsUI << "No function descriptions found for:"; 0073 foreach(const QString& missingDescription, missingDescriptions) { 0074 debugSheetsUI << "\t" << missingDescription; 0075 } 0076 } 0077 #endif 0078 } 0079 return s_instance; 0080 } 0081 0082 FunctionRepository::FunctionRepository() 0083 : d(new Private) 0084 { 0085 d->initialized = false; 0086 } 0087 0088 FunctionRepository::~FunctionRepository() 0089 { 0090 qDeleteAll(d->descriptions); 0091 delete d; 0092 } 0093 0094 void FunctionRepository::add(const QSharedPointer<Function>& function) 0095 { 0096 if (!function) return; 0097 d->functions.insert(function->name().toUpper(), function); 0098 0099 if (!function->alternateName().isNull()) { 0100 d->alternates.insert(function->alternateName().toUpper(), function); 0101 } 0102 } 0103 0104 void FunctionRepository::add(FunctionDescription *desc) 0105 { 0106 if (!desc) return; 0107 if (!d->functions.contains(desc->name())) return; 0108 d->descriptions.insert(desc->name(), desc); 0109 } 0110 0111 void FunctionRepository::remove(const QSharedPointer<Function>& function) 0112 { 0113 const QString functionName = function->name().toUpper(); 0114 delete d->descriptions.take(functionName); 0115 if (d->functions.contains(functionName)) { 0116 QSharedPointer<Function> function = d->functions.take(functionName); 0117 d->alternates.remove(function->alternateName().toUpper()); 0118 } 0119 } 0120 0121 QSharedPointer<Function> FunctionRepository::function(const QString& name) 0122 { 0123 const QString n = name.toUpper(); 0124 QSharedPointer<Function> f = d->functions.value(n); 0125 return !f.isNull() ? f : d->alternates.value(n); 0126 } 0127 0128 FunctionDescription *FunctionRepository::functionInfo(const QString& name) 0129 { 0130 return d->descriptions.value(name.toUpper()); 0131 } 0132 0133 // returns names of function in certain group 0134 QStringList FunctionRepository::functionNames(const QString& group) 0135 { 0136 QStringList lst; 0137 0138 foreach(FunctionDescription* description, d->descriptions) { 0139 if (group.isNull() || (description->group() == group)) 0140 lst.append(description->name()); 0141 } 0142 0143 lst.sort(); 0144 return lst; 0145 } 0146 0147 const QStringList& FunctionRepository::groups() const 0148 { 0149 return d->groups; 0150 } 0151 0152 void FunctionRepository::addGroup(const QString& groupname) 0153 { 0154 d->groups.append(groupname); 0155 d->groups.sort(); 0156 } 0157 0158 void FunctionRepository::loadFunctionDescriptions(const QString& filename) 0159 { 0160 QFile file(filename); 0161 if (!file.open(QIODevice::ReadOnly)) 0162 return; 0163 0164 QDomDocument doc; 0165 doc.setContent(&file); 0166 file.close(); 0167 0168 QString group; 0169 0170 QDomNode n = doc.documentElement().firstChild(); 0171 for (; !n.isNull(); n = n.nextSibling()) { 0172 if (!n.isElement()) 0173 continue; 0174 QDomElement e = n.toElement(); 0175 if (e.tagName() == "Group") { 0176 group = i18n(e.namedItem("GroupName").toElement().text().toUtf8()); 0177 addGroup(group); 0178 0179 QDomNode n2 = e.firstChild(); 0180 for (; !n2.isNull(); n2 = n2.nextSibling()) { 0181 if (!n2.isElement()) 0182 continue; 0183 QDomElement e2 = n2.toElement(); 0184 if (e2.tagName() == "Function") { 0185 FunctionDescription* desc = new FunctionDescription(e2); 0186 desc->setGroup(group); 0187 if (d->functions.contains(desc->name())) 0188 d->descriptions.insert(desc->name(), desc); 0189 else { 0190 debugSheetsUI << "Description for unknown function" << desc->name() << "found."; 0191 delete desc; 0192 } 0193 } 0194 } 0195 group.clear(); 0196 } 0197 } 0198 }