File indexing completed on 2025-02-02 12:00:33

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2002 Ariya Hidayat <ariyahidayat@yahoo.de>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include <dbaseimport.h>
0008 
0009 #include <dbase.h>
0010 
0011 #include <QFont>
0012 #include <QFontMetrics>
0013 #include <QString>
0014 #include <QByteArray>
0015 
0016 #include <KoFilterChain.h>
0017 #include <KoGlobal.h>
0018 #include <KoUnit.h>
0019 #include <kpluginfactory.h>
0020 #include <kmessagebox.h>
0021 #include <KLocalizedString>
0022 
0023 
0024 K_PLUGIN_FACTORY_WITH_JSON(DBaseImportFactory, "calligra_filter_dbase2kspread.json",
0025                            registerPlugin<DBaseImport>();)
0026 
0027 
0028 DBaseImport::DBaseImport(QObject* parent, const QVariantList&)
0029         : KoFilter(parent)
0030 {
0031 }
0032 
0033 KoFilter::ConversionStatus DBaseImport::convert(const QByteArray& from, const QByteArray& to)
0034 {
0035     if (to != "application/x-kspread" || from != "application/x-dbf")
0036         return KoFilter::NotImplemented;
0037 
0038     QString inputFile = m_chain->inputFile();
0039 
0040     DBase dbase;
0041     bool result = dbase.load(inputFile);
0042 
0043     if (dbase.version() != 3) {
0044         KMessageBox::sorry(0, i18n("File format is not supported."));
0045         return KoFilter::NotImplemented;
0046     }
0047 
0048     if (!result) {
0049         KMessageBox::sorry(0, i18n("Could not read from file."));
0050         return KoFilter::StupidError;
0051     }
0052 
0053     QString documentInfo;
0054 
0055     QString root = QLatin1String(
0056         "<!DOCTYPE spreadsheet >\n"
0057         "<spreadsheet mime=\"application/x-kspread\" editor=\"KSpread\" >\n"
0058         "<paper format=\"A4\" orientation=\"Portrait\" >\n"
0059         "<borders right=\"20\" left=\"20\" bottom=\"20\" top=\"20\" />\n"
0060         "<head/>\n"
0061         "<foot/>\n"
0062         "</paper>\n"
0063         "<map activeTable=\"Table1\" >\n"
0064 
0065         "<locale positivePrefixCurrencySymbol=\"True\""
0066         "  negativeMonetarySignPosition=\"0\""
0067         "  negativePrefixCurrencySymbol=\"True\" fracDigits=\"2\""
0068         "  thousandsSeparator=\",\" dateFormat=\"%A %d %B %Y\""
0069         "  timeFormat=\"%H:%M:%S\" monetaryDecimalSymbol=\".\""
0070         "  weekStartsMonday=\"True\" currencySymbol=\"$\""
0071         "  negativeSign=\"-\" positiveSign=\"\""
0072         "  positiveMonetarySignPosition=\"1\" decimalSymbol=\".\""
0073         "  monetaryThousandsSeparator=\",\" dateFormatShort=\"%Y-%m-%d\" />\n"
0074 
0075         "<table name=\"Table1\" columnnumber=\"0\" borders=\"0\""
0076         "  hide=\"0\" hidezero=\"0\" firstletterupper=\"0\" grid=\"1\""
0077         "  formular=\"0\" lcmode=\"0\" >\n");
0078 
0079     // Calligra default font
0080     QFont font = KoGlobal::defaultFont();
0081 
0082     // define columns
0083     QFontMetrics fm(font);
0084     for (int i = 0; i < dbase.fields.count(); ++i) {
0085         int mw = qMax((int)dbase.fields.at(i)->length, dbase.fields.at(i)->name.length());
0086         double w = POINT_TO_MM(fm.maxWidth() * mw);
0087         root += "<column column=\"" + QString::number(i + 1) + "\"";
0088         root += " width=\"" + QString::number(w) + "\"><format/></column>\n";
0089     }
0090 
0091     // define rows
0092     double h = POINT_TO_MM(5 + fm.height() + fm.leading());
0093     for (unsigned j = 0; j < dbase.recordCount(); ++j) {
0094         root += "<row row=\"" + QString::number(j + 1) + "\""
0095                 " height=\"" + QString::number(h) + "\" ><format/></row>\n";
0096     }
0097 
0098     // field names come as first row
0099     for (int i = 0; i < dbase.fields.count(); ++i) {
0100         root += "<cell row=\"1\" column=\"" + QString::number(i + 1) + "\" >\n"
0101                 "<format><pen width=\"0\" style=\"1\" color=\"#000000\" />"
0102                 "<font family=\"" + font.family() + "\"" +
0103                 " size=\"" + QString::number(font.pointSizeF()) + "\"" +
0104                 " weight=\"50\" />"
0105                 "</format>\n"
0106                 "<text>" + dbase.fields.at(i)->name + "</text></cell>\n";
0107     }
0108 
0109     // process all records
0110     unsigned row = 1;
0111     for (unsigned j = 0; j < dbase.recordCount(); ++j) {
0112         QStringList rec = dbase.readRecord(j);
0113         if (rec.count()) {
0114             row++;
0115             for (int i = 0; i < rec.count(); ++i) {
0116                 root += "<cell row=\"" + QString::number(row) + "\""
0117                         "column=\"" + QString::number(i + 1) + "\" >\n"
0118                         "<format><pen width=\"0\" style=\"1\" color=\"#000000\" />"
0119                         "<font family=\"" + font.family() + "\""
0120                         " size=\"" + QString::number(font.pointSizeF()) + "\""
0121                         " weight=\"50\" />"
0122                         "</format>\n"
0123                         "<text>" + rec[i] + "</text></cell>\n";
0124             }
0125         }
0126     }
0127 
0128     dbase.close();
0129 
0130     root += "</table>\n"
0131             "</map>\n"
0132             "</spreadsheet>";
0133 
0134     // prepare storage
0135     KoStoreDevice* out = m_chain->storageFile("root", KoStore::Write);
0136 
0137     // store output document
0138     if (out) {
0139         QByteArray cstring = root.toUtf8();
0140         cstring.prepend("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
0141         out->write((const char*) cstring, cstring.length());
0142     }
0143 
0144     // store document info
0145     out = m_chain->storageFile("documentinfo.xml", KoStore::Write);
0146     if (out) {
0147         QByteArray cstring = documentInfo.toUtf8();
0148         cstring.prepend("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
0149 
0150         out->write((const char*) cstring, cstring.length());
0151     }
0152 
0153     return KoFilter::OK;
0154 }
0155 
0156 #include <dbaseimport.moc>