File indexing completed on 2025-01-12 13:05:38

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