File indexing completed on 2024-05-19 16:19:25
0001 /*************************************************************************** 0002 Copyright (C) 2003-2009 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 "tellicozipexporter.h" 0026 #include "tellicoxmlexporter.h" 0027 #include "../collection.h" 0028 #include "../images/imagefactory.h" 0029 #include "../images/image.h" 0030 #include "../images/imageinfo.h" 0031 #include "../core/filehandler.h" 0032 #include "../tellico_debug.h" 0033 #include "../progressmanager.h" 0034 0035 #include <KLocalizedString> 0036 #include <KZip> 0037 0038 #include <QDomDocument> 0039 #include <QBuffer> 0040 #include <QApplication> 0041 0042 using namespace Tellico; 0043 using Tellico::Export::TellicoZipExporter; 0044 0045 TellicoZipExporter::TellicoZipExporter(Data::CollPtr coll) : Exporter(coll) 0046 , m_includeImages(true), m_cancelled(false) { 0047 } 0048 0049 QString TellicoZipExporter::formatString() const { 0050 return i18n("Tellico Zip File"); 0051 } 0052 0053 QString TellicoZipExporter::fileFilter() const { 0054 return i18n("Tellico Files") + QLatin1String(" (*.tc *.bc)") + QLatin1String(";;") + i18n("All Files") + QLatin1String(" (*)"); 0055 } 0056 0057 bool TellicoZipExporter::exec() { 0058 m_cancelled = false; 0059 Data::CollPtr coll = collection(); 0060 if(!coll) { 0061 return false; 0062 } 0063 0064 // TODO: maybe need label? 0065 ProgressItem& item = ProgressManager::self()->newProgressItem(this, QString(), true); 0066 item.setTotalSteps(100); 0067 connect(&item, &Tellico::ProgressItem::signalCancelled, this, &Tellico::Export::TellicoZipExporter::slotCancel); 0068 ProgressItem::Done done(this); 0069 0070 TellicoXMLExporter exp(coll); 0071 exp.setEntries(entries()); 0072 exp.setFields(fields()); 0073 exp.setURL(url()); // needed in case of relative URL values 0074 long opt = options(); 0075 opt |= Export::ExportUTF8; // always export to UTF-8 0076 opt |= Export::ExportImages; // always list the images in the xml 0077 opt &= ~Export::ExportProgress; // don't show progress for xml export 0078 exp.setOptions(opt); 0079 exp.setIncludeImages(false); // do not include the images themselves in XML 0080 QByteArray xml = exp.exportXML().toByteArray(); // encoded in utf-8 0081 ProgressManager::self()->setProgress(this, 5); 0082 0083 QByteArray data; 0084 QBuffer buf(&data); 0085 0086 if(m_cancelled) { 0087 return true; // intentionally cancelled 0088 } 0089 0090 KZip zip(&buf); 0091 zip.open(QIODevice::WriteOnly); 0092 zip.writeFile(QStringLiteral("tellico.xml"), xml); 0093 0094 if(m_includeImages) { 0095 ProgressManager::self()->setProgress(this, 10); 0096 const QString imagesDir = QStringLiteral("images/"); 0097 StringSet imageSet; 0098 // take intersection with the fields to be exported 0099 Data::FieldList imageFields = Tellico::listIntersection(coll->imageFields(), fields()); 0100 // already took 10%, only 90% left 0101 const int stepSize = qMax(1, (coll->entryCount() * imageFields.count()) / 90); 0102 int j = 0; 0103 foreach(Data::EntryPtr entry, entries()) { 0104 if(m_cancelled) { 0105 break; 0106 } 0107 foreach(Data::FieldPtr imageField, imageFields) { 0108 const QString id = entry->field(imageField); 0109 if(id.isEmpty() || imageSet.has(id)) { 0110 continue; 0111 } 0112 const Data::ImageInfo& info = ImageFactory::imageInfo(id); 0113 if(info.linkOnly) { 0114 myLog() << "not copying linked image: " << id; 0115 continue; 0116 } 0117 const Data::Image& img = ImageFactory::imageById(id); 0118 // if no image, continue 0119 if(img.isNull()) { 0120 myWarning() << "no image found for " << imageField->title() << " field"; 0121 myWarning() << "...for the entry titled " << entry->title(); 0122 continue; 0123 } 0124 QByteArray ba = img.byteArray(); 0125 // myDebug() << "adding image id = " << it->field(fIt); 0126 zip.writeFile(imagesDir + id, ba); 0127 imageSet.add(id); 0128 if(j%stepSize == 0) { 0129 ProgressManager::self()->setProgress(this, qMin(10+j/stepSize, 99)); 0130 qApp->processEvents(); 0131 } 0132 ++j; 0133 } 0134 } 0135 } else { 0136 ProgressManager::self()->setProgress(this, 80); 0137 } 0138 0139 zip.close(); 0140 if(m_cancelled) { 0141 return true; 0142 } 0143 0144 return FileHandler::writeDataURL(url(), data, options() & Export::ExportForce); 0145 } 0146 0147 void TellicoZipExporter::slotCancel() { 0148 m_cancelled = true; 0149 }