00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <limits.h>
00026
00027 #include <qcstring.h>
00028 #include <qfile.h>
00029 #include <qiodevice.h>
00030 #include <qstring.h>
00031 #include <qtextcodec.h>
00032 #include <qtextstream.h>
00033
00034 #include <kdebug.h>
00035 #include <kgenericfactory.h>
00036
00037 #include <KoFilterChain.h>
00038 #include <KoFilterManager.h>
00039 #include <KoStore.h>
00040
00041 #include <KWEFStructures.h>
00042 #include <KWEFBaseWorker.h>
00043 #include <KWEFKWordLeader.h>
00044
00045 #include <ExportDialog.h>
00046 #include <asciiexport.h>
00047
00048
00049 class ASCIIExportFactory : KGenericFactory<ASCIIExport, KoFilter>
00050 {
00051 public:
00052 ASCIIExportFactory() : KGenericFactory<ASCIIExport, KoFilter>("kwordasciiexport")
00053 {
00054 }
00055
00056 protected:
00057 virtual void setupTranslations(void)
00058 {
00059 KGlobal::locale()->insertCatalogue("kofficefilters");
00060 }
00061 };
00062
00063 K_EXPORT_COMPONENT_FACTORY(libasciiexport, ASCIIExportFactory())
00064
00065
00066 class ASCIIWorker : public KWEFBaseWorker
00067 {
00068 public:
00069 ASCIIWorker() : m_ioDevice(NULL), m_streamOut(NULL), m_eol("\n")
00070
00071 {
00072 }
00073
00074 virtual ~ASCIIWorker()
00075 {
00076 delete m_streamOut; delete m_ioDevice;
00077 }
00078
00079 public:
00080 virtual bool doOpenFile(const QString& filenameOut, const QString& to);
00081 virtual bool doCloseFile(void);
00082
00083 virtual bool doOpenDocument(void);
00084 virtual bool doCloseDocument(void);
00085
00086 virtual bool doFullParagraphList(const QValueList<ParaData>& paraList);
00087 virtual bool doFullParagraph(const ParaData& para);
00088 virtual bool doFullParagraph(const QString& paraText,
00089 const LayoutData& layout,
00090 const ValueListFormatData& paraFormatDataList);
00091
00092 public:
00093 QString getEndOfLine(void) const { return m_eol; }
00094 void setEndOfLine(const QString& str) { m_eol = str; }
00095
00096 QTextCodec* getCodec(void) const { return m_codec; }
00097 void setCodec(QTextCodec* codec) { m_codec = codec; }
00098
00099 private:
00100 virtual bool ProcessTable(const Table& table);
00101 virtual bool ProcessParagraphData (const QString& paraText,
00102 const ValueListFormatData& paraFormatDataList);
00103
00104 private:
00105 QIODevice* m_ioDevice;
00106 QTextStream* m_streamOut;
00107
00108 QTextCodec* m_codec;
00109 QString m_eol;
00110 QStringList m_automaticNotes;
00111 QString m_manualNotes;
00112
00113 #if 0
00114 CounterData::Style m_typeList;
00115 bool m_inList;
00116 bool m_orderedList;
00117 int m_counterList;
00118 #endif
00119 };
00120
00121 bool ASCIIWorker::doOpenFile(const QString& filenameOut, const QString& )
00122 {
00123 m_ioDevice = new QFile(filenameOut);
00124
00125 if (!m_ioDevice)
00126 {
00127 kdError(30502) << "No output file! Aborting!" << endl;
00128 return false;
00129 }
00130
00131 if (!m_ioDevice->open(IO_WriteOnly))
00132 {
00133 kdError(30502) << "Unable to open output file!" << endl;
00134 return false;
00135 }
00136
00137 m_streamOut = new QTextStream(m_ioDevice);
00138 if (!m_streamOut)
00139 {
00140 kdError(30502) << "Could not create output stream! Aborting!" << endl;
00141 m_ioDevice->close();
00142 return false;
00143 }
00144
00145 kdDebug(30502) << "Charset used: " << getCodec()->name() << endl;
00146
00147 if (!getCodec())
00148 {
00149 kdError(30502) << "Could not create QTextCodec! Aborting" << endl;
00150 return false;
00151 }
00152
00153 m_streamOut->setCodec(getCodec());
00154
00155 return true;
00156 }
00157
00158 bool ASCIIWorker::doCloseFile(void)
00159 {
00160 delete m_streamOut;
00161 m_streamOut=NULL;
00162 if (m_ioDevice)
00163 m_ioDevice->close();
00164 return (m_ioDevice);
00165 }
00166
00167 bool ASCIIWorker::doOpenDocument(void)
00168 {
00169
00170 return true;
00171 }
00172
00173 bool ASCIIWorker::doCloseDocument(void)
00174 {
00175
00176 if (!m_automaticNotes.empty())
00177 {
00178 *m_streamOut << m_eol;
00179 int noteNumber = 1;
00180 for (QStringList::Iterator it = m_automaticNotes.begin(); it != m_automaticNotes.end(); ++it)
00181 {
00182 *m_streamOut << "[" << noteNumber << "] " << *it;
00183 noteNumber++;
00184 }
00185 }
00186
00187 if (!m_manualNotes.isEmpty())
00188 *m_streamOut << m_eol << m_manualNotes;
00189
00190 return true;
00191 }
00192
00193 bool ASCIIWorker::doFullParagraphList(const QValueList<ParaData>& paraList)
00194 {
00195 for (QValueList<ParaData>::ConstIterator it = paraList.begin();
00196 it != paraList.end();
00197 it++)
00198 {
00199 if (!doFullParagraph(*it)) return false;
00200 }
00201
00202 return true;
00203 }
00204
00205 bool ASCIIWorker::doFullParagraph(const ParaData& para)
00206 {
00207 return doFullParagraph(para.text, para.layout, para.formattingList);
00208 }
00209
00210 bool ASCIIWorker::doFullParagraph(const QString& paraText, const LayoutData& layout,
00211 const ValueListFormatData& paraFormatDataList)
00212 {
00213 kdDebug(30502) << "Entering ASCIIWorker::doFullParagraph" << endl;
00214
00215 #if 0
00216
00217
00218
00219 if ( layout.counter.numbering == CounterData::NUM_LIST )
00220 {
00221
00222 if (!m_inList || (layout.counter.style!=m_typeList))
00223 {
00224
00225 m_inList=true;
00226 m_counterList=1;
00227 m_typeList=layout.counter.style;
00228 }
00229
00230 switch (m_typeList)
00231
00232
00233 {
00234 case CounterData::STYLE_CUSTOMBULLET:
00235 default:
00236 {
00237 m_orderedList=false;
00238 *m_streamOut << "- ";
00239 break;
00240 }
00241 case CounterData::STYLE_NONE:
00242 {
00243 m_orderedList=false;
00244 break;
00245 }
00246 case CounterData::STYLE_CIRCLEBULLET:
00247 {
00248 m_orderedList=false;
00249 *m_streamOut << "o ";
00250 break;
00251 }
00252 case CounterData::STYLE_SQUAREBULLET:
00253 {
00254 m_orderedList=false;
00255 *m_streamOut << "~ ";
00256 break;
00257 }
00258 case CounterData::STYLE_DISCBULLET:
00259 {
00260 m_orderedList=false;
00261 *m_streamOut << "* ";
00262 break;
00263 }
00264 case CounterData::STYLE_NUM:
00265 case CounterData::STYLE_CUSTOM:
00266 {
00267 m_orderedList=true;
00268 *m_streamOut << QString::number(m_counterList,10);
00269 break;
00270 }
00271 case CounterData::STYLE_ALPHAB_L:
00272 {
00273 m_orderedList=true;
00274 QString strTemp;
00275 for (int i=m_counterList;i>0;i/=26)
00276 strTemp=QChar(0x40+i%26)+strTemp;
00277 *m_streamOut << strTemp;
00278 break;
00279 }
00280 case CounterData::STYLE_ALPHAB_U:
00281 {
00282 m_orderedList=true;
00283 QString strTemp;
00284 for (int i=m_counterList;i>0;i/=26)
00285 strTemp=QChar(0x40+i%26)+strTemp;
00286 *m_streamOut << strTemp;
00287 break;
00288 }
00289 case CounterData::STYLE_ROM_NUM_L:
00290 {
00291
00292 m_orderedList=true;
00293 *m_streamOut << QString::number(m_counterList,10);
00294 break;
00295 }
00296 case CounterData::STYLE_ROM_NUM_U:
00297 {
00298
00299 m_orderedList=true;
00300 *m_streamOut << QString::number(m_counterList,10);
00301 break;
00302 }
00303 }
00304 ProcessParagraphData ( paraText, paraFormatDataList);
00305 m_counterList++;
00306 }
00307 else
00308 {
00309 m_inList=false;
00310 if ( layout.counter.numbering == CounterData::NUM_CHAPTER )
00311 {
00312 if (!layout.counter.depth)
00313 {
00314 *m_streamOut << "###################################" << m_eol;
00315 *m_streamOut << "# ";
00316 ProcessParagraphData ( paraText, paraFormatDataList);
00317 *m_streamOut << "###################################" << m_eol;
00318 }
00319 else if (layout.counter.depth==1)
00320 {
00321 *m_streamOut << "#### ";
00322 ProcessParagraphData ( paraText, paraFormatDataList);
00323 }
00324 else if (layout.counter.depth==2)
00325 {
00326 *m_streamOut << "## ";
00327 ProcessParagraphData ( paraText, paraFormatDataList);
00328 }
00329 else if (layout.counter.depth==3)
00330 {
00331 *m_streamOut << "# ";
00332 ProcessParagraphData ( paraText, paraFormatDataList);
00333 }
00334 else
00335 {
00336 ProcessParagraphData ( paraText, paraFormatDataList);
00337 }
00338 }
00339 else
00340 {
00341 ProcessParagraphData ( paraText, paraFormatDataList);
00342 }
00343 }
00344 #else
00345 if (!layout.counter.text.isEmpty())
00346 *m_streamOut << layout.counter.text << " ";
00347
00348 if (!ProcessParagraphData(paraText, paraFormatDataList)) return false;
00349 #endif
00350
00351 kdDebug(30502) << "Exiting ASCIIWorker::doFullParagraph" << endl;
00352 return true;
00353 }
00354
00355
00356 bool ASCIIWorker::ProcessTable(const Table& table)
00357 {
00358 kdDebug(30502) << "processTable CALLED!" << endl;
00359
00360
00361 for (QValueList<TableCell>::ConstIterator it = table.cellList.begin();
00362 it != table.cellList.end();
00363 it++)
00364 {
00365 if (!doFullParagraphList(*(*it).paraList)) return false;
00366 }
00367
00368 return true;
00369 }
00370
00371
00372
00373
00374 bool ASCIIWorker::ProcessParagraphData(const QString& paraText,
00375 const ValueListFormatData& paraFormatDataList)
00376 {
00377 bool lastSegmentWasText = true;
00378
00379 if (!paraText.isEmpty())
00380 {
00381 ValueListFormatData::ConstIterator paraFormatDataIt;
00382
00383 for (paraFormatDataIt = paraFormatDataList.begin ();
00384 paraFormatDataIt != paraFormatDataList.end ();
00385 paraFormatDataIt++)
00386 {
00387 lastSegmentWasText = true;
00388
00389 switch ((*paraFormatDataIt).id)
00390 {
00391 case 1:
00392 {
00393 QString strText(paraText.mid((*paraFormatDataIt).pos,(*paraFormatDataIt).len));
00394 strText = strText.replace(QChar(10), m_eol, true);
00395 *m_streamOut << strText;
00396 break;
00397 }
00398 case 4:
00399 {
00400 if (11==(*paraFormatDataIt).variable.m_type)
00401 {
00402
00403 QString value = (*paraFormatDataIt).variable.getFootnoteValue();
00404 bool automatic = (*paraFormatDataIt).variable.getFootnoteAuto();
00405 QValueList<ParaData> *paraList = (*paraFormatDataIt).variable.getFootnotePara();
00406 if (paraList)
00407 {
00408 QString notestr;
00409 QValueList<ParaData>::ConstIterator it;
00410 QValueList<ParaData>::ConstIterator end(paraList->end());
00411 for (it=paraList->begin();it!=end;++it)
00412 notestr += (*it).text.stripWhiteSpace().replace(QChar(10), m_eol, true) + m_eol;
00413
00414 *m_streamOut << "[";
00415 if (automatic) {
00416
00417 *m_streamOut << m_automaticNotes.count() + 1;
00418 m_automaticNotes.append(notestr);
00419 }
00420 else
00421 {
00422
00423 *m_streamOut << value;
00424 m_manualNotes += "[" + value + "] " + notestr;
00425 }
00426 *m_streamOut << "]";
00427 }
00428 }
00429 else
00430 {
00431
00432 *m_streamOut << (*paraFormatDataIt).variable.m_text;
00433 }
00434 break;
00435 }
00436 case 6:
00437 {
00438 if ((*paraFormatDataIt).frameAnchor.type == 6)
00439 {
00440 if ((*paraFormatDataIt).pos)
00441 *m_streamOut << m_eol;
00442
00443 if (!ProcessTable((*paraFormatDataIt).frameAnchor.table))
00444 return false;
00445 }
00446 else
00447 {
00448 kdWarning(30502) << "Unsupported frame anchor type: "
00449 << (*paraFormatDataIt).frameAnchor.type << endl;
00450 }
00451
00452 lastSegmentWasText = false;
00453 break;
00454 }
00455 default:
00456 {
00457 kdWarning(30502) << "Not supported paragraph type: "
00458 << (*paraFormatDataIt).id << endl;
00459 break;
00460 }
00461 }
00462 }
00463 }
00464
00465 if (lastSegmentWasText)
00466 *m_streamOut << m_eol;
00467
00468 return true;
00469 }
00470
00471
00472 ASCIIExport::ASCIIExport(KoFilter*, const char*, const QStringList&)
00473 : KoFilter()
00474 {
00475 }
00476
00477 KoFilter::ConversionStatus ASCIIExport::convert(const QCString& from, const QCString& to)
00478 {
00479 if (to != "text/plain" || from != "application/x-kword")
00480 {
00481 return KoFilter::NotImplemented;
00482 }
00483 AsciiExportDialog* dialog = 0;
00484 if (!m_chain->manager()->getBatchMode())
00485 {
00486 dialog = new AsciiExportDialog();
00487 if (!dialog)
00488 {
00489 kdError(30502) << "Dialog has not been created! Aborting!" << endl;
00490 return KoFilter::StupidError;
00491 }
00492
00493 if (!dialog->exec())
00494 {
00495 kdError(30502) << "Dialog was aborted! Aborting filter!" << endl;
00496 return KoFilter::UserCancelled;
00497 }
00498 }
00499 ASCIIWorker* worker = new ASCIIWorker();
00500
00501 if (!worker)
00502 {
00503 kdError(30502) << "Cannot create Worker! Aborting!" << endl;
00504 delete dialog;
00505 return KoFilter::StupidError;
00506 }
00507 QTextCodec* codec;
00508 if (dialog)
00509 codec = dialog->getCodec();
00510 else
00511 codec = QTextCodec::codecForName("UTF-8");
00512
00513 if ( !codec )
00514 {
00515 kdError(30502) << "No codec!" << endl;
00516 delete dialog;
00517 return KoFilter::StupidError;
00518 }
00519
00520 worker->setCodec( codec );
00521 if (dialog)
00522 worker->setEndOfLine(dialog->getEndOfLine());
00523 else
00524 worker->setEndOfLine("\n");
00525
00526 delete dialog;
00527
00528 KWEFKWordLeader* leader = new KWEFKWordLeader(worker);
00529
00530 if (!leader)
00531 {
00532 kdError(30502) << "Cannot create Worker! Aborting!" << endl;
00533 delete worker;
00534 return KoFilter::StupidError;
00535 }
00536
00537 KoFilter::ConversionStatus result = leader->convert(m_chain,from,to);
00538
00539 delete leader;
00540 delete worker;
00541
00542 return result;
00543 }
00544
00545 #include <asciiexport.moc>