/*************************************************************************** * This file is part of the Lime Report project * * Copyright (C) 2021 by Alexander Arin * * arin_a@bk.ru * * * ** GNU General Public License Usage ** * * * This library is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ** GNU Lesser General Public License ** * * * This library is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public * * License along with this library. * * If not, see . * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * ****************************************************************************/ #include "lrxmlreader.h" #include "lrbasedesignintf.h" #include "lrcollection.h" #include "lrdesignelementsfactory.h" #include "lrreporttranslation.h" #include "stdexcept" #include #ifdef BUILD_WITH_EASY_PROFILER #include "easy/profiler.h" #else #define EASY_BLOCK(...) #define EASY_END_BLOCK #endif namespace LimeReport { XMLReader::XMLReader(): m_doc(new QDomDocument) { } XMLReader::XMLReader(QSharedPointer doc): m_doc(doc) { } bool XMLReader::prepareReader(QDomDocument* doc) { Q_UNUSED(doc); m_error = QLatin1String("Context not initialized"); return false; } int XMLReader::firstLevelItemsCount() { if (m_firstNode.childNodes().count() == 0) return 0; QDomElement tmpNode = m_firstNode; int res = 0; while (!tmpNode.isNull()) { res++; tmpNode = tmpNode.nextSiblingElement(); } return res; } bool XMLReader::first() { if (extractFirstNode()) { m_curNode = m_firstNode; return !m_curNode.isNull(); } return false; } bool XMLReader::next() { m_curNode = m_curNode.nextSiblingElement(); return !m_curNode.isNull(); } bool XMLReader::prior() { m_curNode = m_curNode.previousSiblingElement(); return !m_curNode.isNull(); } QString XMLReader::itemType() { return m_curNode.attribute("Type"); } QString XMLReader::itemClassName() { return m_curNode.attribute("ClassName"); } bool XMLReader::readItem(QObject* item) { if (!m_curNode.isNull()) { readItemFromNode(item, &m_curNode); } else { m_error = QString("Object %1 not founded").arg(item->objectName()); return false; } return true; } void XMLReader::readItemFromNode(QObject* item, QDomElement* node) { EASY_BLOCK("readItemFromNode"); ObjectLoadingStateIntf* lf = dynamic_cast(item); if (lf) lf->objectLoadStarted(); for (int i = 0; i < node->childNodes().count(); i++) { QDomElement currentNode = node->childNodes().at(i).toElement(); if (currentNode.attribute("Type") == "Object") { readQObject(item, ¤tNode); } else if (currentNode.attribute("Type") == "Collection") { readCollection(item, ¤tNode); } else if (currentNode.attribute("Type") == "Translation") { readTranslation(item, ¤tNode); } else readProperty(item, ¤tNode); } if (lf) lf->objectLoadFinished(); BaseDesignIntf* baseObj = dynamic_cast(item); if (baseObj) { foreach (QGraphicsItem* childItem, baseObj->childItems()) { BaseDesignIntf* baseItem = dynamic_cast(childItem); if (baseItem) baseItem->parentObjectLoadFinished(); } } EASY_END_BLOCK; } QString XMLReader::lastError() { return m_error; } void XMLReader::setPassPhrase(const QString& passPhrase) { m_passPhrase = passPhrase; } bool XMLReader::extractFirstNode() { if (m_firstNode.isNull()) { if (m_doc->childNodes().count() == 0) { if (!prepareReader(m_doc.data())) return false; } m_firstNode = m_doc->documentElement(); if (!m_firstNode.hasAttributes()) m_firstNode = m_firstNode.firstChildElement(); } return !m_firstNode.isNull(); } void XMLReader::readProperty(QObject* item, QDomElement* node) { item->setProperty(node->nodeName().toLatin1(), getValue(node)); } QVariant XMLReader::getValue(QDomElement* node) { CreateSerializator creator = 0; try { creator = XMLAbstractSerializatorFactory::instance().objectCreator(node->attribute("Type")); } catch (ReportError& e) { qDebug() << node->attribute("Type") << e.what(); } if (creator) { QScopedPointer serializator(creator(m_doc.data(), node)); CryptedSerializator* cs = dynamic_cast(serializator.data()); if (cs) { cs->setPassPhrase(m_passPhrase); } return serializator->loadValue(); } return QVariant(); } void XMLReader::readQObject(QObject* item, QDomElement* node) { EASY_BLOCK("readQObject"); QObject* childItem = qvariant_cast(item->property(node->nodeName().toLatin1())); if (childItem) readItemFromNode(childItem, node); EASY_END_BLOCK; } void XMLReader::readCollection(QObject* item, QDomElement* node) { EASY_BLOCK("readCollection") ICollectionContainer* collection = dynamic_cast(item); if (collection) { QString collectionName = node->nodeName(); for (int i = 0; i < node->childNodes().count(); ++i) { QDomElement currentNode = node->childNodes().at(i).toElement(); QObject* obj = collection->createElement(collectionName, currentNode.attribute("ClassName")); if (obj) readItemFromNode(obj, ¤tNode); } collection->collectionLoadFinished(collectionName); } EASY_END_BLOCK; } void XMLReader::readTranslation(QObject* item, QDomElement* node) { ITranslationContainer* tranclationContainer = dynamic_cast(item); if (tranclationContainer) { Translations* translations = tranclationContainer->translations(); for (int langIndex = 0; langIndex < node->childNodes().count(); ++langIndex) { QDomElement languageNode = node->childNodes().at(langIndex).toElement(); ReportTranslation* curTranslation = new ReportTranslation( (QLocale::Language)(languageNode.attributeNode("Value").value().toInt())); for (int pageIndex = 0; pageIndex < languageNode.childNodes().count(); ++pageIndex) { QDomElement pageNode = languageNode.childNodes().at(pageIndex).toElement(); PageTranslation* pageTranslation = curTranslation->createEmptyPageTranslation(); pageTranslation->pageName = pageNode.nodeName(); for (int itemIndex = 0; itemIndex < pageNode.childNodes().count(); ++itemIndex) { QDomElement itemNode = pageNode.childNodes().at(itemIndex).toElement(); ItemTranslation* itemTranslation = new ItemTranslation(); itemTranslation->itemName = itemNode.nodeName(); for (int propertyIndex = 0; propertyIndex < itemNode.childNodes().count(); ++propertyIndex) { QDomElement propertyNode = itemNode.childNodes().at(propertyIndex).toElement(); PropertyTranslation* propertyTranslation = new PropertyTranslation; propertyTranslation->propertyName = propertyNode.nodeName(); propertyTranslation->value = propertyNode.attribute("Value"); propertyTranslation->sourceValue = propertyNode.attribute("SourceValue"); propertyTranslation->checked = propertyNode.attribute("Checked").compare("Y") == 0; itemTranslation->propertyesTranslation.append(propertyTranslation); } pageTranslation->itemsTranslation.insert(itemTranslation->itemName, itemTranslation); } } translations->insert(curTranslation->language(), curTranslation); } } } FileXMLReader::FileXMLReader(QString fileName): m_fileName(fileName) { } bool FileXMLReader::prepareReader(QDomDocument* doc) { if (!m_fileName.isEmpty()) { QFile source(m_fileName); if (source.open(QFile::ReadOnly)) { doc->setContent(&source); if (doc->documentElement().nodeName() != "Report") { m_error = QString(QObject::tr("Wrong file format")); return false; } } else { m_error = QString(QObject::tr("File %1 not opened")).arg(m_fileName); return false; } } return true; } bool StringXMLreader::prepareReader(QDomDocument* doc) { if (!m_content.isEmpty()) { doc->setContent(m_content); } else { m_error = QString(QObject::tr("Content string is empty")); return false; } return true; } bool ByteArrayXMLReader::prepareReader(QDomDocument* doc) { if (m_content) { doc->setContent(*m_content); } else { m_error = QString(QObject::tr("Content is empty")); return false; } return true; } } // namespace LimeReport