File indexing completed on 2024-04-28 05:08:20

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 "exportdialog.h"
0026 #include "collection.h"
0027 #include "core/filehandler.h"
0028 #include "controller.h"
0029 #include "tellico_debug.h"
0030 
0031 #include "translators/exporter.h"
0032 #include "translators/tellicoxmlexporter.h"
0033 #include "translators/tellicozipexporter.h"
0034 #include "translators/htmlexporter.h"
0035 #include "translators/csvexporter.h"
0036 #include "translators/bibtexexporter.h"
0037 #include "translators/bibtexmlexporter.h"
0038 #include "translators/xsltexporter.h"
0039 #include "translators/alexandriaexporter.h"
0040 #include "translators/onixexporter.h"
0041 #include "translators/gcstarexporter.h"
0042 
0043 #include <KLocalizedString>
0044 #include <KSharedConfig>
0045 #include <KConfigGroup>
0046 
0047 #include <QLayout>
0048 #include <QCheckBox>
0049 #include <QGroupBox>
0050 #include <QButtonGroup>
0051 #include <QRadioButton>
0052 #include <QTextCodec>
0053 #include <QVBoxLayout>
0054 #include <QDialogButtonBox>
0055 #include <QPushButton>
0056 #include <QScopedPointer>
0057 
0058 using namespace Tellico;
0059 using Tellico::ExportDialog;
0060 
0061 ExportDialog::ExportDialog(Tellico::Export::Format format_, Tellico::Data::CollPtr coll_, QWidget* parent_)
0062     : QDialog(parent_),
0063       m_format(format_), m_coll(coll_), m_exporter(exporter(format_, coll_)) {
0064   setModal(true);
0065   setWindowTitle(i18n("Export Options"));
0066 
0067   QWidget* widget = new QWidget(this);
0068   QVBoxLayout* topLayout = new QVBoxLayout(widget);
0069   setLayout(topLayout);
0070   topLayout->addWidget(widget);
0071 
0072   QGroupBox* group1 = new QGroupBox(i18n("Formatting"), widget);
0073   topLayout->addWidget(group1, 0);
0074   QVBoxLayout* vlay = new QVBoxLayout(group1);
0075 
0076   m_formatFields = new QCheckBox(i18n("Format all fields"), group1);
0077   m_formatFields->setChecked(false);
0078   m_formatFields->setWhatsThis(i18n("If checked, the values of the fields will be "
0079                                     "automatically formatted according to their format type."));
0080   vlay->addWidget(m_formatFields);
0081 
0082   m_exportSelected = new QCheckBox(i18n("Export selected entries only"), group1);
0083   m_exportSelected->setChecked(false);
0084   m_exportSelected->setWhatsThis(i18n("If checked, only the currently selected entries will "
0085                                       "be exported."));
0086   vlay->addWidget(m_exportSelected);
0087 
0088   m_exportFields = new QCheckBox(i18n("Export visible fields only"), group1);
0089   m_exportFields->setChecked(false);
0090   m_exportFields->setWhatsThis(i18n("If checked, only the fields currently visible in the view will "
0091                                     "be exported."));
0092   vlay->addWidget(m_exportFields);
0093 
0094   QGroupBox* group2 = new QGroupBox(i18n("Encoding"), widget);
0095   topLayout->addWidget(group2, 0);
0096 
0097   QVBoxLayout* vlay2 = new QVBoxLayout(group2);
0098 
0099   m_encodeUTF8 = new QRadioButton(i18n("Encode in Unicode (UTF-8)"), group2);
0100   m_encodeUTF8->setChecked(true);
0101   m_encodeUTF8->setWhatsThis(i18n("Encode the exported file in Unicode (UTF-8)."));
0102   vlay2->addWidget(m_encodeUTF8);
0103 
0104   QString localStr = i18n("Encode in user locale (%1)",
0105                           QLatin1String(QTextCodec::codecForLocale()->name()));
0106   m_encodeLocale = new QRadioButton(localStr, group2);
0107   m_encodeLocale->setWhatsThis(i18n("Encode the exported file in the local encoding."));
0108   vlay2->addWidget(m_encodeLocale);
0109 
0110   if(QTextCodec::codecForLocale()->name() == "UTF-8") {
0111     m_encodeUTF8->setEnabled(false);
0112     m_encodeLocale->setChecked(true);
0113   }
0114 
0115   QButtonGroup* bg = new QButtonGroup(widget);
0116   bg->addButton(m_encodeUTF8);
0117   bg->addButton(m_encodeLocale);
0118 
0119   QWidget* w = m_exporter->widget(widget);
0120   if(w) {
0121     w->layout()->setMargin(0);
0122     topLayout->addWidget(w, 0);
0123   }
0124 
0125   topLayout->addStretch();
0126 
0127   QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
0128   QPushButton* okButton = buttonBox->button(QDialogButtonBox::Ok);
0129   okButton->setDefault(true);
0130   okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0131   connect(okButton, &QAbstractButton::clicked, this, &ExportDialog::slotSaveOptions);
0132   connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0133   connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0134   topLayout->addWidget(buttonBox);
0135 
0136   readOptions();
0137   if(format_ == Export::Alexandria) {
0138     // no encoding options enabled
0139     group2->setEnabled(false);
0140   }
0141 }
0142 
0143 ExportDialog::~ExportDialog() {
0144   delete m_exporter;
0145   m_exporter = nullptr;
0146 }
0147 
0148 QString ExportDialog::fileFilter() {
0149   return m_exporter ? m_exporter->fileFilter() : QString();
0150 }
0151 
0152 void ExportDialog::readOptions() {
0153   KConfigGroup config(KSharedConfig::openConfig(), "ExportOptions");
0154   bool format = config.readEntry("FormatFields", false);
0155   m_formatFields->setChecked(format);
0156   bool selected = config.readEntry("ExportSelectedOnly", false);
0157   m_exportSelected->setChecked(selected);
0158   bool encode = config.readEntry("EncodeUTF8", true);
0159   if(encode && m_encodeUTF8->isEnabled()) {
0160     m_encodeUTF8->setChecked(true);
0161   } else {
0162     m_encodeLocale->setChecked(true);
0163   }
0164 }
0165 
0166 void ExportDialog::slotSaveOptions() {
0167   KSharedConfigPtr config = KSharedConfig::openConfig();
0168   // each exporter sets its own group
0169   m_exporter->saveOptions(config);
0170 
0171   KConfigGroup configGroup(config, "ExportOptions");
0172   configGroup.writeEntry("FormatFields", m_formatFields->isChecked());
0173   configGroup.writeEntry("ExportSelectedOnly", m_exportSelected->isChecked());
0174   configGroup.writeEntry("EncodeUTF8", m_encodeUTF8->isChecked());
0175 }
0176 
0177 // static
0178 Tellico::Export::Exporter* ExportDialog::exporter(Tellico::Export::Format format_, Data::CollPtr coll_) {
0179   Export::Exporter* exporter = nullptr;
0180 
0181   switch(format_) {
0182     case Export::TellicoXML:
0183       exporter = new Export::TellicoXMLExporter(coll_);
0184       break;
0185 
0186     case Export::TellicoZip:
0187       exporter = new Export::TellicoZipExporter(coll_);
0188       break;
0189 
0190     case Export::HTML:
0191       {
0192         Export::HTMLExporter* htmlExp = new Export::HTMLExporter(coll_);
0193         htmlExp->setGroupBy(Controller::self()->expandedGroupBy());
0194         htmlExp->setSortTitles(Controller::self()->sortTitles());
0195         htmlExp->setColumns(Controller::self()->visibleColumns());
0196         exporter = htmlExp;
0197       }
0198       break;
0199 
0200     case Export::CSV:
0201       exporter = new Export::CSVExporter(coll_);
0202       break;
0203 
0204     case Export::Bibtex:
0205       exporter = new Export::BibtexExporter(coll_);
0206       break;
0207 
0208     case Export::Bibtexml:
0209       exporter = new Export::BibtexmlExporter(coll_);
0210       break;
0211 
0212     case Export::XSLT:
0213       exporter = new Export::XSLTExporter(coll_);
0214       break;
0215 
0216     case Export::Alexandria:
0217       exporter = new Export::AlexandriaExporter(coll_);
0218       break;
0219 
0220     case Export::ONIX:
0221       exporter = new Export::ONIXExporter(coll_);
0222       break;
0223 
0224     case Export::GCstar:
0225       exporter = new Export::GCstarExporter(coll_);
0226       break;
0227 
0228     default:
0229       myDebug() << "not implemented!";
0230       break;
0231   }
0232   if(exporter) {
0233     exporter->readOptions(KSharedConfig::openConfig());
0234   }
0235   return exporter;
0236 }
0237 
0238 bool ExportDialog::exportURL(const QUrl& url_/*=QUrl()*/) const {
0239   if(!m_exporter) {
0240     return false;
0241   }
0242 
0243   // exporter might need to know final URL, say for writing images or something
0244   m_exporter->setURL(url_);
0245   if(m_exportSelected->isChecked()) {
0246     m_exporter->setEntries(Controller::self()->selectedEntries());
0247   } else {
0248     m_exporter->setEntries(m_coll->entries());
0249   }
0250   if(m_exportFields->isChecked()) {
0251     Data::FieldList fields;
0252     foreach(const QString& title, Controller::self()->visibleColumns()) {
0253       Data::FieldPtr field = m_coll->fieldByTitle(title);
0254       if(field) {
0255         fields << field;
0256       }
0257     }
0258     m_exporter->setFields(fields);
0259   } else {
0260     m_exporter->setFields(m_coll->fields());
0261   }
0262   long opt = Export::ExportImages | Export::ExportComplete | Export::ExportProgress; // for now, always export images
0263   if(m_formatFields->isChecked()) {
0264     opt |= Export::ExportFormatted;
0265   }
0266   if(m_encodeUTF8->isChecked()) {
0267     opt |= Export::ExportUTF8;
0268   }
0269   // since we already asked about overwriting the file, force the save
0270   opt |= Export::ExportForce;
0271 
0272   m_exporter->setOptions(opt);
0273 
0274   return m_exporter->exec();
0275 }
0276 
0277 // static
0278 // alexandria is exported to known directory
0279 // all others are files
0280 Tellico::Export::Target ExportDialog::exportTarget(Tellico::Export::Format format_) {
0281   switch(format_) {
0282     case Export::Alexandria:
0283       return Export::None;
0284     default:
0285       return Export::File;
0286   }
0287 }
0288 
0289 // static
0290 bool ExportDialog::exportCollection(Data::CollPtr coll_, Data::EntryList entries_, Export::Format format_, const QUrl& url_) {
0291   QScopedPointer<Export::Exporter> exp(exporter(format_, coll_));
0292   exp->setURL(url_);
0293   exp->setEntries(entries_);
0294 
0295   KConfigGroup config(KSharedConfig::openConfig(), "ExportOptions");
0296   long options = 0;
0297   if(config.readEntry("FormatFields", false)) {
0298     options |= Export::ExportFormatted;
0299   }
0300   if(config.readEntry("EncodeUTF8", true)) {
0301     options |= Export::ExportUTF8;
0302   }
0303   exp->setOptions(options | Export::ExportForce);
0304 
0305   return exp->exec();
0306 }