Warning, file /office/calligra/braindump/braindumpcore/StatesRegistry.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright (c) 2009 Cyrille Berger <cberger@cberger.net> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; 0007 * either version 2, or (at your option) any later version of the License. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public License 0015 * along with this library; see the file COPYING. If not, write to 0016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "StatesRegistry.h" 0021 0022 #include <QDomDocument> 0023 #include <QFile> 0024 #include <QFileInfo> 0025 #include <QDir> 0026 #include <QStandardPaths> 0027 #include <QDirIterator> 0028 #include <QDebug> 0029 0030 #include <KLocalizedString> 0031 0032 #include "State.h" 0033 #include "StateCategory.h" 0034 #include "StateCategory_p.h" 0035 0036 struct Q_DECL_HIDDEN StatesRegistry::Private { 0037 static StatesRegistry* s_instance; 0038 QMap<QString, StateCategory*> categories; 0039 void parseStatesRC(const QString& _filename); 0040 }; 0041 0042 StatesRegistry* StatesRegistry::Private::s_instance = 0; 0043 0044 void StatesRegistry::Private::parseStatesRC(const QString& _filename) 0045 { 0046 QDomDocument doc; 0047 QFile file(_filename); 0048 if(!file.open(QIODevice::ReadOnly)) { 0049 qCritical() << "Can't open " << _filename; 0050 return; 0051 } 0052 QString errMsg; 0053 int line, column; 0054 if(!doc.setContent(&file, &errMsg, &line, &column)) { 0055 qCritical() << "At (" << line << ", " << column << ") " << errMsg; 0056 file.close(); 0057 return; 0058 } 0059 file.close(); 0060 0061 QDir directory = QFileInfo(_filename).absoluteDir(); 0062 0063 QDomElement docElem = doc.documentElement(); 0064 if(docElem.nodeName() != "states") { 0065 qCritical() << "Invalid state file"; 0066 return; 0067 } 0068 QDomNode nCat = docElem.firstChild(); 0069 while(!nCat.isNull()) { 0070 QDomElement eCat = nCat.toElement(); // try to convert the node to an element. 0071 if(!eCat.isNull() && eCat.tagName() == "category") { 0072 QString catId = eCat.attribute("id"); 0073 QString catName = eCat.attribute("name"); 0074 int catPriority = eCat.attribute("priority", "1000").toInt(); 0075 StateCategory* category = 0; 0076 if(catId.isEmpty()) { 0077 qCritical() << "Missing category id"; 0078 } else { 0079 if(categories.contains(catId)) { 0080 category = categories[catId]; 0081 } else if(!catName.isEmpty()) { 0082 category = new StateCategory(catId, i18n(catName.toUtf8()), catPriority); 0083 categories[catId] = category; 0084 } 0085 if(category) { 0086 // Parse the states 0087 QDomNode nState = eCat.firstChild(); 0088 while(!nState.isNull()) { 0089 QDomElement eState = nState.toElement(); 0090 if(!eState.isNull() && eState.tagName() == "state") { 0091 QString stateId = eState.attribute("id"); 0092 QString stateName = eState.attribute("name"); 0093 QString stateFilename = eState.attribute("filename"); 0094 int statePriority = eState.attribute("priority", "1000").toInt(); 0095 if(stateId.isEmpty() || stateName.isEmpty() || stateFilename.isEmpty()) { 0096 qCritical() << "Missing attribute: id = " << stateId << " name = " << stateName << " filename = " << stateFilename; 0097 } else { 0098 QString file = directory.absoluteFilePath(stateFilename); 0099 if(QFileInfo(file).exists()) { 0100 if(category->d->states.contains(stateId)) { 0101 delete category->d->states[stateId]; 0102 } 0103 qDebug() << "Adding state id = " << stateId << " name = " << stateName << " filename = " << stateFilename; 0104 category->d->states[stateId] = new State(stateId, stateName, category, file, statePriority); 0105 } else { 0106 qCritical() << "Missing file " << file; 0107 } 0108 } 0109 } else { 0110 qCritical() << "Invalid node in category " << catId; 0111 } 0112 nState = nState.nextSibling(); 0113 } 0114 } else { 0115 qCritical() << "Couldn't make a category for " << catId; 0116 } 0117 } 0118 } else { 0119 qCritical() << "Invalid XML node."; 0120 } 0121 nCat = nCat.nextSibling(); 0122 } 0123 } 0124 0125 StatesRegistry::StatesRegistry() : d(new Private) 0126 { 0127 QStringList statesFilenames; 0128 const QStringList stateFileDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, 0129 "calligra_shape_state/states/", 0130 QStandardPaths::LocateDirectory); 0131 Q_FOREACH(const QString &dir, stateFileDirs) { 0132 QDirIterator iter(dir, QStringList() << QStringLiteral("*.xml")); 0133 while(iter.hasNext()) { 0134 statesFilenames.append(iter.next()); 0135 } 0136 } 0137 0138 foreach(const QString & filename, statesFilenames) { 0139 qDebug() << "Load state: " << filename; 0140 d->parseStatesRC(filename); 0141 } 0142 } 0143 0144 StatesRegistry::~StatesRegistry() 0145 { 0146 delete d; 0147 } 0148 0149 const StatesRegistry* StatesRegistry::instance() 0150 { 0151 if(!Private::s_instance) { 0152 Private::s_instance = new StatesRegistry; 0153 } 0154 return Private::s_instance; 0155 } 0156 0157 QList<QString> StatesRegistry::categorieIds() const 0158 { 0159 return d->categories.keys(); 0160 } 0161 0162 QList<QString> StatesRegistry::stateIds(const QString& _id) const 0163 { 0164 Q_ASSERT(d->categories.contains(_id)); 0165 return d->categories[_id]->stateIds(); 0166 } 0167 0168 const State* StatesRegistry::state(const QString& _category, const QString& _state) const 0169 { 0170 if(d->categories.contains(_category)) return d->categories[_category]->state(_state); 0171 qWarning() << "No category " << _category << " found among " << d->categories.keys(); 0172 return 0; 0173 } 0174 0175 const State* StatesRegistry::nextState(const State* _state) const 0176 { 0177 if(_state) { 0178 QList<const State*> states = _state->category()->d->states.values(); 0179 int idx = states.indexOf(_state); 0180 idx += 1; 0181 if(idx >= states.count()) idx = 0; 0182 return states[idx]; 0183 } 0184 return 0; 0185 }