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 }