File indexing completed on 2025-01-12 13:05:56
0001 0002 /* This file is part of the KDE project 0003 Copyright (C) 2001 Graham Short <grahshrt@netscape.net> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include <qproimport.h> 0022 0023 #include <sstream> 0024 0025 #include <kdebug.h> 0026 #include <kmessagebox.h> 0027 #include <kpluginfactory.h> 0028 #include <KoFilterChain.h> 0029 0030 #include <sheets/part/Doc.h> 0031 #include <sheets/Sheet.h> 0032 #include <sheets/Cell.h> 0033 #include <sheets/Value.h> 0034 #include <sheets/Map.h> 0035 #include <sheets/LoadingInfo.h> 0036 0037 #include <qproformula.h> 0038 #include <qpro/stream.h> 0039 #include <qpro/record_factory.h> 0040 #include <QFile> 0041 #include <QByteArray> 0042 0043 using namespace Calligra::Sheets; 0044 0045 K_PLUGIN_FACTORY_WITH_JSON(QPROImportFactory, "calligra_filter_qpro2sheets.json", 0046 registerPlugin<QpImport>();) 0047 0048 // --------------------------------------------------------------- 0049 0050 QpTableList::QpTableList() 0051 { 0052 for (int lIdx = 0; lIdx < cNameCnt; ++lIdx) { 0053 cTable[lIdx] = 0; 0054 } 0055 } 0056 0057 QpTableList::~QpTableList() 0058 { 0059 // don't delete the list of tables 0060 } 0061 0062 0063 void 0064 QpTableList::table(unsigned pIdx, Sheet* pTable) 0065 { 0066 if (pIdx < cNameCnt) { 0067 cTable[pIdx] = pTable; 0068 } 0069 } 0070 0071 Sheet* 0072 QpTableList::table(unsigned pIdx) 0073 { 0074 return (pIdx < cNameCnt ? cTable[pIdx] : 0); 0075 } 0076 0077 0078 // --------------------------------------------------------------- 0079 0080 QpImport::QpImport(QObject* parent, const QVariantList&) 0081 : KoFilter(parent) 0082 { 0083 } 0084 0085 void 0086 QpImport::InitTableName(int pIdx, QString& pResult) 0087 { 0088 if (pIdx < 26) { 0089 pResult = (char)('A' + pIdx); 0090 } else { 0091 pResult = (char)('A' - 1 + pIdx / 26); 0092 pResult += (char)('A' + pIdx % 26); 0093 } 0094 } 0095 0096 KoFilter::ConversionStatus QpImport::convert(const QByteArray& from, const QByteArray& to) 0097 { 0098 bool bSuccess = true; 0099 0100 KoDocument* document = m_chain->outputDocument(); 0101 if (!document) 0102 return KoFilter::StupidError; 0103 0104 kDebug(30523) << "here we go..." << document->metaObject()->className(); 0105 0106 if (!::qobject_cast<const Calligra::Sheets::Doc *>(document)) { // it's safer that way :) 0107 kWarning(30501) << "document isn't a Calligra::Sheets::Doc but a " << document->metaObject()->className(); 0108 return KoFilter::NotImplemented; 0109 } 0110 if (from != "application/x-quattropro" || to != "application/x-kspread") { 0111 kWarning(30501) << "Invalid mimetypes " << from << " " << to; 0112 return KoFilter::NotImplemented; 0113 } 0114 0115 kDebug(30523) << "...still here..."; 0116 0117 // No need for a dynamic cast here, since we use Qt's moc magic 0118 Doc *ksdoc = (Doc*)document; 0119 0120 if (ksdoc->mimeType() != "application/x-ole-storage") { 0121 kWarning(30501) << "Invalid document mimetype " << ksdoc->mimeType(); 0122 return KoFilter::NotImplemented; 0123 } 0124 0125 QpIStream lIn(QFile::encodeName(m_chain->inputFile())); 0126 0127 if (!lIn) { 0128 KMessageBox::sorry(0L, i18n("QPRO filter cannot open input file - please report.")); 0129 return KoFilter::FileNotFound; 0130 } 0131 0132 Sheet *table = 0; 0133 0134 QString field; 0135 int value = 0; 0136 emit sigProgress(value); 0137 0138 QpRecFactory lFactory(lIn); 0139 QpTableList lTableNames; 0140 QP_UINT8 lPageIdx = 0; 0141 0142 QpRec* lRec = 0; 0143 QpRecBop* lRecBop = 0; 0144 QpRecIntegerCell* lRecInt = 0; 0145 QpRecFloatingPointCell* lRecFloat = 0; 0146 QpRecFormulaCell* lRecFormula = 0; 0147 QpRecLabelCell* lRecLabel = 0; 0148 QpRecPageName* lRecPageName = 0; 0149 0150 do { 0151 field.clear(); 0152 lRec = lFactory.nextRecord(); 0153 0154 switch (lRec->type()) { 0155 case QpBop: 0156 lRecBop = (QpRecBop*)lRec; 0157 lPageIdx = lRecBop->pageIndex(); 0158 0159 // find out if we know about this table already, if not create it 0160 table = lTableNames.table(lPageIdx); 0161 0162 if (table == 0) { 0163 table = ksdoc->map()->addNewSheet(); 0164 // set up a default name for the table 0165 table->setSheetName(lTableNames.name(lPageIdx) 0166 , true 0167 ); 0168 lTableNames.table(lPageIdx, table); 0169 } 0170 break; 0171 0172 case QpIntegerCell: 0173 lRecInt = (QpRecIntegerCell*)lRec; 0174 field.setNum(lRecInt->integer()); 0175 //cout << "Setting R " << lRecInt->row()+1 << ", C " << ((unsigned)lRecInt->column()) << endl; 0176 if (table) 0177 setText(table, lRecInt->row() + 1, ((unsigned)lRecInt->column()) + 1, field, false); 0178 break; 0179 0180 case QpFormulaCell: 0181 lRecFormula = (QpRecFormulaCell*)lRec; 0182 { 0183 QuattroPro::Formula lAnswer(*lRecFormula, lTableNames); 0184 0185 char* lFormula = lAnswer.formula(); 0186 0187 field = lFormula; 0188 0189 delete [] lFormula; 0190 } 0191 0192 // check for referenced tables that haven't been created yet 0193 for (unsigned lIdx = 0; lIdx < lTableNames.cNameCnt; ++lIdx) { 0194 if (lTableNames.allocated(lIdx) && (lTableNames.table(lIdx) == 0)) { 0195 // we're about to reference a table that hasn't been created yet. 0196 // setText gets upset about this, so create a blank table 0197 0198 Sheet* lNewTable = ksdoc->map()->addNewSheet(); 0199 0200 // set up a default name for the table 0201 lNewTable->setSheetName(lTableNames.name(lIdx) 0202 , true 0203 ); 0204 lTableNames.table(lIdx, lNewTable); 0205 } 0206 } 0207 0208 if (table) 0209 setText(table, lRecFormula->row() + 1, lRecFormula->column() + 1, field, false); 0210 break; 0211 0212 case QpFloatingPointCell: 0213 lRecFloat = (QpRecFloatingPointCell*)lRec; 0214 field.setNum(lRecFloat->value()); 0215 if (table) 0216 setText(table, lRecFloat->row() + 1, lRecFloat->column() + 1, field, false); 0217 break; 0218 0219 case QpLabelCell: 0220 lRecLabel = (QpRecLabelCell*)lRec; 0221 field = "'"; 0222 field += lRecLabel->label(); 0223 if (table) 0224 setText(table, lRecLabel->row() + 1, lRecLabel->column() + 1, field, false); 0225 break; 0226 0227 case QpPageName: 0228 lRecPageName = (QpRecPageName*)lRec; 0229 0230 if (lTableNames.allocated(lPageIdx) && lTableNames.table(lPageIdx)) { 0231 lTableNames.table(lPageIdx)->setSheetName(lRecPageName->pageName() 0232 // , true 0233 ); 0234 lTableNames.name(lPageIdx, lRecPageName->pageName()); 0235 } 0236 break; 0237 0238 case QpPassword: 0239 KMessageBox::sorry(0L, i18n("Unable to open password protected files.\n" 0240 "The password algorithm has not been published") 0241 ); 0242 delete lRec; 0243 return KoFilter::NotImplemented; 0244 } 0245 0246 delete lRec; 0247 lRec = 0; 0248 } while (lIn); 0249 0250 ksdoc->map()->loadingInfo()->setInitialActiveSheet(table); 0251 0252 emit sigProgress(100); 0253 if (bSuccess) 0254 return KoFilter::OK; 0255 else 0256 return KoFilter::StupidError; 0257 } 0258 0259 void QpImport::setText(Sheet* sheet, int _row, int _column, const QString& _text, bool asString) 0260 { 0261 Cell cell(sheet, _column, _row); 0262 if (asString) { 0263 cell.setUserInput(_text); 0264 cell.setValue(Value(_text)); 0265 } else { 0266 cell.parseUserInput(_text); 0267 } 0268 } 0269 0270 #include <qproimport.moc>