File indexing completed on 2024-05-12 05:10:11
0001 /*************************************************************************** 0002 Copyright (C) 2009-2022 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "gcstarexporter.h" 0026 #include "xslthandler.h" 0027 #include "tellicoxmlexporter.h" 0028 #include "../collection.h" 0029 #include "../core/filehandler.h" 0030 #include "../images/imagefactory.h" 0031 #include "../images/image.h" 0032 #include "../progressmanager.h" 0033 #include "../utils/datafileregistry.h" 0034 #include "../tellico_debug.h" 0035 0036 #include <KLocalizedString> 0037 0038 #include <QDomDocument> 0039 #include <QFile> 0040 #include <QDir> 0041 #include <QTextStream> 0042 #include <QStandardPaths> 0043 #include <QApplication> 0044 0045 using Tellico::Export::GCstarExporter; 0046 0047 GCstarExporter::GCstarExporter(Tellico::Data::CollPtr coll_) : Tellico::Export::Exporter(coll_), 0048 m_handler(nullptr), 0049 m_xsltFile(QStringLiteral("tellico2gcstar.xsl")) { 0050 } 0051 0052 GCstarExporter::~GCstarExporter() { 0053 delete m_handler; 0054 m_handler = nullptr; 0055 } 0056 0057 QString GCstarExporter::formatString() const { 0058 return QStringLiteral("GCstar"); 0059 } 0060 0061 QString GCstarExporter::fileFilter() const { 0062 return i18n("GCstar Data Files") + QLatin1String(" (*.gcs)") + QLatin1String(";;") + i18n("All Files") + QLatin1String(" (*)"); 0063 } 0064 0065 bool GCstarExporter::exec() { 0066 const QString text = this->text(); 0067 0068 bool success = true; 0069 if(options() & ExportImages) { 0070 writeImages(); 0071 } 0072 return !text.isEmpty() && 0073 FileHandler::writeTextURL(url(), text, options() & ExportUTF8, options() & Export::ExportForce) && 0074 success; 0075 } 0076 0077 QString GCstarExporter::text() { 0078 QString xsltFile = DataFileRegistry::self()->locate(m_xsltFile); 0079 if(xsltFile.isNull()) { 0080 myDebug() << "no xslt file for " << m_xsltFile; 0081 return QString(); 0082 } 0083 0084 Data::CollPtr coll = collection(); 0085 if(!coll) { 0086 myDebug() << "no collection pointer!"; 0087 return QString(); 0088 } 0089 0090 // notes about utf-8 encoding: 0091 // all params should be passed to XSLTHandler in utf8 0092 // input string to XSLTHandler should be in utf-8, EVEN IF DOM STRING SAYS OTHERWISE 0093 0094 QUrl u = QUrl::fromLocalFile(xsltFile); 0095 // do NOT do namespace processing, it messes up the XSL declaration since 0096 // QDom thinks there are no elements in the Tellico namespace and as a result 0097 // removes the namespace declaration 0098 QDomDocument dom = FileHandler::readXMLDocument(u, false); 0099 if(dom.isNull()) { 0100 myDebug() << "error loading xslt file: " << xsltFile; 0101 return QString(); 0102 } 0103 0104 // the stylesheet prints utf-8 by default, if using locale encoding, need 0105 // to change the encoding attribute on the xsl:output element 0106 if(!(options() & Export::ExportUTF8)) { 0107 XSLTHandler::setLocaleEncoding(dom); 0108 } 0109 0110 delete m_handler; 0111 m_handler = new XSLTHandler(dom, QFile::encodeName(xsltFile)); 0112 if(!m_handler->isValid()) { 0113 return QString(); 0114 } 0115 0116 if(options() & ExportImages) { 0117 m_handler->addStringParam("imageDir", QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation).toLocal8Bit() + "/gcstar/images/"); 0118 writeImages(); 0119 } 0120 0121 // now grab the XML 0122 TellicoXMLExporter exporter(coll); 0123 exporter.setEntries(entries()); 0124 exporter.setFields(fields()); 0125 exporter.setIncludeImages(false); // do not include images in XML 0126 // yes, this should be in utf8, always 0127 exporter.setOptions(options() | Export::ExportUTF8); 0128 return m_handler->applyStylesheet(exporter.exportXML().toString()); 0129 } 0130 0131 QWidget* GCstarExporter::widget(QWidget* parent_) { 0132 Q_UNUSED(parent_); 0133 return nullptr; 0134 } 0135 0136 bool GCstarExporter::writeImages() { 0137 const QString imgDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/gcstar/images/"); 0138 QDir dir(imgDir); 0139 if(!dir.exists() && !dir.mkpath(QLatin1String("."))) return false; 0140 0141 ProgressItem& item = ProgressManager::self()->newProgressItem(this, QString(), false); 0142 item.setTotalSteps(entries().count()); 0143 ProgressItem::Done done(this); 0144 const uint stepSize = qMax(1, entries().count()/100); 0145 const bool showProgress = options() & ExportProgress; 0146 0147 bool success = true; 0148 uint j = 0; 0149 foreach(const Data::EntryPtr& entry, entries()) { 0150 foreach(Data::FieldPtr field, entry->collection()->imageFields()) { 0151 if(entry->field(field).isEmpty()) { 0152 break; 0153 } 0154 0155 const Data::Image& img = ImageFactory::imageById(entry->field(field)); 0156 if(img.isNull()) { 0157 break; 0158 } 0159 0160 QUrl target = QUrl::fromLocalFile(imgDir); 0161 target.setPath(target.path() + img.id()); 0162 success &= FileHandler::writeDataURL(target, img.byteArray(), true /* force */); 0163 } 0164 if(showProgress && j%stepSize == 0) { 0165 item.setProgress(j); 0166 qApp->processEvents(); 0167 } 0168 ++j; 0169 } 0170 return success; 0171 }