diff options
Diffstat (limited to 'filters/kword/ascii/asciiexport.cpp')
-rw-r--r-- | filters/kword/ascii/asciiexport.cpp | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/filters/kword/ascii/asciiexport.cpp b/filters/kword/ascii/asciiexport.cpp new file mode 100644 index 000000000..1bea9a269 --- /dev/null +++ b/filters/kword/ascii/asciiexport.cpp @@ -0,0 +1,545 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org> + Copyright (c) 2000 ID-PRO Deutschland GmbH. All rights reserved. + Contact: Wolf-Michael Bolle <Bolle@ID-PRO.de> + Copyright (C) 2001, 2002, 2004 Nicolas GOUTTE <goutte@kde.org> + Copyright (C) 2003 Clarence Dang <dang@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#include <limits.h> + +#include <tqcstring.h> +#include <tqfile.h> +#include <tqiodevice.h> +#include <tqstring.h> +#include <tqtextcodec.h> +#include <tqtextstream.h> + +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <KoFilterChain.h> +#include <KoFilterManager.h> +#include <KoStore.h> + +#include <KWEFStructures.h> +#include <KWEFBaseWorker.h> +#include <KWEFKWordLeader.h> + +#include <ExportDialog.h> +#include <asciiexport.h> + + +class ASCIIExportFactory : KGenericFactory<ASCIIExport, KoFilter> +{ +public: + ASCIIExportFactory() : KGenericFactory<ASCIIExport, KoFilter>("kwordasciiexport") + { + } + +protected: + virtual void setupTranslations(void) + { + TDEGlobal::locale()->insertCatalogue("kofficefilters"); + } +}; + +K_EXPORT_COMPONENT_FACTORY(libasciiexport, ASCIIExportFactory()) + + +class ASCIIWorker : public KWEFBaseWorker +{ +public: + ASCIIWorker() : m_ioDevice(NULL), m_streamOut(NULL), m_eol("\n")/*, + m_inList(false)*/ + { + } + + virtual ~ASCIIWorker() + { + delete m_streamOut; delete m_ioDevice; + } + +public: + virtual bool doOpenFile(const TQString& filenameOut, const TQString& to); + virtual bool doCloseFile(void); // Close file in normal conditions + + virtual bool doOpenDocument(void); + virtual bool doCloseDocument(void); + + virtual bool doFullParagraphList(const TQValueList<ParaData>& paraList); + virtual bool doFullParagraph(const ParaData& para); + virtual bool doFullParagraph(const TQString& paraText, + const LayoutData& layout, + const ValueListFormatData& paraFormatDataList); + +public: + TQString getEndOfLine(void) const { return m_eol; } + void setEndOfLine(const TQString& str) { m_eol = str; } + + TQTextCodec* getCodec(void) const { return m_codec; } + void setCodec(TQTextCodec* codec) { m_codec = codec; } + +private: + virtual bool ProcessTable(const Table& table); + virtual bool ProcessParagraphData (const TQString& paraText, + const ValueListFormatData& paraFormatDataList); + +private: + TQIODevice* m_ioDevice; + TQTextStream* m_streamOut; + + TQTextCodec* m_codec; // TQTextCodec in which the file will be written + TQString m_eol; // End of line character(s) + TQStringList m_automaticNotes; // Automatic foot-/endnotes + TQString m_manualNotes; // Manual foot-/endnotes + +#if 0 + CounterData::Style m_typeList; // What is the style of the current list (undefined, if we are not in a list) + bool m_inList; // Are we currently in a list? + bool m_orderedList; // Is the current list ordered or not (undefined, if we are not in a list) + int m_counterList; // Counter for te lists +#endif +}; + +bool ASCIIWorker::doOpenFile(const TQString& filenameOut, const TQString& /*to*/) +{ + m_ioDevice = TQT_TQIODEVICE(new TQFile(filenameOut)); + + if (!m_ioDevice) + { + kdError(30502) << "No output file! Aborting!" << endl; + return false; + } + + if (!m_ioDevice->open(IO_WriteOnly)) + { + kdError(30502) << "Unable to open output file!" << endl; + return false; + } + + m_streamOut = new TQTextStream(m_ioDevice); + if (!m_streamOut) + { + kdError(30502) << "Could not create output stream! Aborting!" << endl; + m_ioDevice->close(); + return false; + } + + kdDebug(30502) << "Charset used: " << getCodec()->name() << endl; + + if (!getCodec()) + { + kdError(30502) << "Could not create TQTextCodec! Aborting" << endl; + return false; + } + + m_streamOut->setCodec(getCodec()); + + return true; +} + +bool ASCIIWorker::doCloseFile(void) +{ + delete m_streamOut; + m_streamOut=NULL; + if (m_ioDevice) + m_ioDevice->close(); + return (m_ioDevice); +} + +bool ASCIIWorker::doOpenDocument(void) +{ + // We have nothing to do, but to give our OK to continue + return true; +} + +bool ASCIIWorker::doCloseDocument(void) +{ + // Add foot-/endnotes + if (!m_automaticNotes.empty()) + { + *m_streamOut << m_eol; + int noteNumber = 1; + for (TQStringList::Iterator it = m_automaticNotes.begin(); it != m_automaticNotes.end(); ++it) + { + *m_streamOut << "[" << noteNumber << "] " << *it; + noteNumber++; + } + } + + if (!m_manualNotes.isEmpty()) + *m_streamOut << m_eol << m_manualNotes; + + return true; +} + +bool ASCIIWorker::doFullParagraphList(const TQValueList<ParaData>& paraList) +{ + for (TQValueList<ParaData>::ConstIterator it = paraList.begin(); + it != paraList.end(); + it++) + { + if (!doFullParagraph(*it)) return false; + } + + return true; +} + +bool ASCIIWorker::doFullParagraph(const ParaData& para) +{ + return doFullParagraph(para.text, para.layout, para.formattingList); +} + +bool ASCIIWorker::doFullParagraph(const TQString& paraText, const LayoutData& layout, + const ValueListFormatData& paraFormatDataList) +{ + kdDebug(30502) << "Entering ASCIIWorker::doFullParagraph" << endl; + +#if 0 + // As KWord has only one depth of lists, we can process lists very simply. + // -- + // Not anymore - Clarence + if ( layout.counter.numbering == CounterData::NUM_LIST ) + { + // Are we still in a list of the right type? + if (!m_inList || (layout.counter.style!=m_typeList)) + { + // We are not yet part of a list + m_inList=true; + m_counterList=1; // Start numbering + m_typeList=layout.counter.style; + } + + switch (m_typeList) + // TODO: when we would be able to save to UTF-8, + // use correct symbols + { + case CounterData::STYLE_CUSTOMBULLET: // We cannot keep the custom type/style + default: + { + m_orderedList=false; + *m_streamOut << "- "; + break; + } + case CounterData::STYLE_NONE: + { + m_orderedList=false; + break; + } + case CounterData::STYLE_CIRCLEBULLET: + { + m_orderedList=false; + *m_streamOut << "o "; + break; + } + case CounterData::STYLE_SQUAREBULLET: + { + m_orderedList=false; + *m_streamOut << "~ "; // Not much a square + break; + } + case CounterData::STYLE_DISCBULLET: + { + m_orderedList=false; + *m_streamOut << "* "; // Not much a disc + break; + } + case CounterData::STYLE_NUM: + case CounterData::STYLE_CUSTOM: + { + m_orderedList=true; + *m_streamOut << TQString::number(m_counterList,10); + break; + } + case CounterData::STYLE_ALPHAB_L: + { + m_orderedList=true; + TQString strTemp; + for (int i=m_counterList;i>0;i/=26) + strTemp=TQChar(0x40+i%26)+strTemp; // Lower alpha + *m_streamOut << strTemp; + break; + } + case CounterData::STYLE_ALPHAB_U: + { + m_orderedList=true; + TQString strTemp; + for (int i=m_counterList;i>0;i/=26) + strTemp=TQChar(0x40+i%26)+strTemp; // Lower alpha + *m_streamOut << strTemp; + break; + } + case CounterData::STYLE_ROM_NUM_L: + { + // For now, we do not support lower-case Roman numbering (TODO) + m_orderedList=true; + *m_streamOut << TQString::number(m_counterList,10); + break; + } + case CounterData::STYLE_ROM_NUM_U: + { + // For now, we do not support upper-case Roman numbering (TODO) + m_orderedList=true; + *m_streamOut << TQString::number(m_counterList,10); + break; + } + } + ProcessParagraphData ( paraText, paraFormatDataList); + m_counterList++; // Increment the list counter + } + else + { + m_inList=false; // Close an eventual list + if ( layout.counter.numbering == CounterData::NUM_CHAPTER ) + { + if (!layout.counter.depth) + { // HEAD 1 + *m_streamOut << "###################################" << m_eol; + *m_streamOut << "# "; + ProcessParagraphData ( paraText, paraFormatDataList); + *m_streamOut << "###################################" << m_eol; + } + else if (layout.counter.depth==1) + { // HEAD 2 + *m_streamOut << "#### "; + ProcessParagraphData ( paraText, paraFormatDataList); + } + else if (layout.counter.depth==2) + { // HEAD 3 + *m_streamOut << "## "; + ProcessParagraphData ( paraText, paraFormatDataList); + } + else if (layout.counter.depth==3) + { // HEAD 4 + *m_streamOut << "# "; + ProcessParagraphData ( paraText, paraFormatDataList); + } + else + { + ProcessParagraphData ( paraText, paraFormatDataList); + } + } + else + { + ProcessParagraphData ( paraText, paraFormatDataList); + } + } +#else + if (!layout.counter.text.isEmpty()) + *m_streamOut << layout.counter.text << " "; + + if (!ProcessParagraphData(paraText, paraFormatDataList)) return false; +#endif + + kdDebug(30502) << "Exiting ASCIIWorker::doFullParagraph" << endl; + return true; +} + + +bool ASCIIWorker::ProcessTable(const Table& table) +{ + kdDebug(30502) << "processTable CALLED!" << endl; + + // just dump the table out (no layout for now) + for (TQValueList<TableCell>::ConstIterator it = table.cellList.begin(); + it != table.cellList.end(); + it++) + { + if (!doFullParagraphList(*(*it).paraList)) return false; + } + + return true; +} + +// ProcessParagraphData () mangles the pure text through the +// formatting information stored in the FormatData list and prints it +// out to the export file. +bool ASCIIWorker::ProcessParagraphData(const TQString& paraText, + const ValueListFormatData& paraFormatDataList) +{ + bool lastSegmentWasText = true; + + if (!paraText.isEmpty()) + { + ValueListFormatData::ConstIterator paraFormatDataIt; + + for (paraFormatDataIt = paraFormatDataList.begin (); + paraFormatDataIt != paraFormatDataList.end (); + paraFormatDataIt++) + { + lastSegmentWasText = true; + + switch ((*paraFormatDataIt).id) + { + case 1: // Normal text + { + TQString strText(paraText.mid((*paraFormatDataIt).pos,(*paraFormatDataIt).len)); + strText = strText.replace(TQChar(10), m_eol, true); + *m_streamOut << strText; + break; + } + case 4: // Variable + { + if (11==(*paraFormatDataIt).variable.m_type) + { + // Footnote + TQString value = (*paraFormatDataIt).variable.getFootnoteValue(); + bool automatic = (*paraFormatDataIt).variable.getFootnoteAuto(); + TQValueList<ParaData> *paraList = (*paraFormatDataIt).variable.getFootnotePara(); + if (paraList) + { + TQString notestr; + TQValueList<ParaData>::ConstIterator it; + TQValueList<ParaData>::ConstIterator end(paraList->end()); + for (it=paraList->begin();it!=end;++it) + notestr += (*it).text.stripWhiteSpace().replace(TQChar(10), m_eol, true) + m_eol; + + *m_streamOut << "["; + if (automatic) { + // Automatic footnote + *m_streamOut << m_automaticNotes.count() + 1; + m_automaticNotes.append(notestr); + } + else + { + // Manual footnote + *m_streamOut << value; + m_manualNotes += "[" + value + "] " + notestr; + } + *m_streamOut << "]"; + } + } + else + { + // Generic variable + *m_streamOut << (*paraFormatDataIt).variable.m_text; + } + break; + } + case 6: // Frame Anchor + { + if ((*paraFormatDataIt).frameAnchor.type == 6) // Table + { + if ((*paraFormatDataIt).pos) + *m_streamOut << m_eol; + + if (!ProcessTable((*paraFormatDataIt).frameAnchor.table)) + return false; + } + else + { + kdWarning(30502) << "Unsupported frame anchor type: " + << (*paraFormatDataIt).frameAnchor.type << endl; + } + + lastSegmentWasText = false; + break; + } + default: + { + kdWarning(30502) << "Not supported paragraph type: " + << (*paraFormatDataIt).id << endl; + break; + } + } + } + } + + if (lastSegmentWasText) + *m_streamOut << m_eol; // Write end of line + + return true; +} + + +ASCIIExport::ASCIIExport(KoFilter*, const char*, const TQStringList&) + : KoFilter() +{ +} + +KoFilter::ConversionStatus ASCIIExport::convert(const TQCString& from, const TQCString& to) +{ + if (to != "text/plain" || from != "application/x-kword") + { + return KoFilter::NotImplemented; + } + AsciiExportDialog* dialog = 0; + if (!m_chain->manager()->getBatchMode()) + { + dialog = new AsciiExportDialog(); + if (!dialog) + { + kdError(30502) << "Dialog has not been created! Aborting!" << endl; + return KoFilter::StupidError; + } + + if (!dialog->exec()) + { + kdError(30502) << "Dialog was aborted! Aborting filter!" << endl; + return KoFilter::UserCancelled; + } + } + ASCIIWorker* worker = new ASCIIWorker(); + + if (!worker) + { + kdError(30502) << "Cannot create Worker! Aborting!" << endl; + delete dialog; + return KoFilter::StupidError; + } + TQTextCodec* codec; + if (dialog) + codec = dialog->getCodec(); + else + codec = TQTextCodec::codecForName("UTF-8"); + + if ( !codec ) + { + kdError(30502) << "No codec!" << endl; + delete dialog; + return KoFilter::StupidError; + } + + worker->setCodec( codec ); + if (dialog) + worker->setEndOfLine(dialog->getEndOfLine()); + else + worker->setEndOfLine("\n"); + + delete dialog; + + KWEFKWordLeader* leader = new KWEFKWordLeader(worker); + + if (!leader) + { + kdError(30502) << "Cannot create Worker! Aborting!" << endl; + delete worker; + return KoFilter::StupidError; + } + + KoFilter::ConversionStatus result = leader->convert(m_chain,from,to); + + delete leader; + delete worker; + + return result; +} + +#include <asciiexport.moc> |