/* This file is part of the KDE project Copyright (C) 2001, 2002, 2003, 2004 Nicolas GOUTTE 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. */ /* This file is based on the old file: /home/kde/koffice/filters/kword/ascii/asciiexport.cc The old file was copyrighted by Copyright (C) 1998, 1999 Reginald Stadlbauer Copyright (c) 2000 ID-PRO Deutschland GmbH. All rights reserved. Contact: Wolf-Michael Bolle The old file was licensed under the terms of the GNU Library General Public License version 2. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class ABIWORDExportFactory : KGenericFactory { public: ABIWORDExportFactory(void) : KGenericFactory ("kwordabiwordexport") {} protected: virtual void setupTranslations( void ) { TDEGlobal::locale()->insertCatalogue( "kofficefilters" ); } }; K_EXPORT_COMPONENT_FACTORY( libabiwordexport, ABIWORDExportFactory() ) class StyleMap : public TQMap { public: StyleMap(void) {} ~StyleMap(void) {} }; class AbiWordWorker : public KWEFBaseWorker { public: AbiWordWorker(void); virtual ~AbiWordWorker(void) { 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 doFullParagraph(const TQString& paraText, const LayoutData& layout, const ValueListFormatData& paraFormatDataList); virtual bool doOpenTextFrameSet(void); // AbiWord's
virtual bool doCloseTextFrameSet(void); // AbiWord's
virtual bool doFullPaperFormat(const int format, const double width, const double height, const int orientation); // Calc AbiWord's virtual bool doFullPaperBorders (const double top, const double left, const double bottom, const double right); // Like KWord's virtual bool doCloseHead(void); // Write virtual bool doOpenStyles(void); // AbiWord's virtual bool doCloseStyles(void); // AbiWord's virtual bool doFullDefineStyle(LayoutData& layout); // AbiWord's virtual bool doOpenSpellCheckIgnoreList (void); // AbiWord's virtual bool doCloseSpellCheckIgnoreList (void); // AbiWord's virtual bool doFullSpellCheckIgnoreWord (const TQString& ignoreword); // AbiWord's virtual bool doFullDocumentInfo(const KWEFDocumentInfo& docInfo); // AbiWord's private: void processParagraphData (const TQString& paraText, const TextFormatting& formatLayout, const ValueListFormatData& paraFormatDataList); void processNormalText ( const TQString& paraText, const TextFormatting& formatLayout, const FormatData& formatData); void processVariable ( const TQString& paraText, const TextFormatting& formatLayout, const FormatData& formatData); void processAnchor ( const TQString& paraText, const TextFormatting& formatLayout, const FormatData& formatData); TQString textFormatToAbiProps(const TextFormatting& formatOrigin, const TextFormatting& formatData, const bool force) const; TQString layoutToCss(const LayoutData& layoutOrigin, const LayoutData& layout, const bool force) const; TQString escapeAbiWordText(const TQString& strText) const; bool makeTable(const FrameAnchor& anchor); bool makePicture(const FrameAnchor& anchor); void writeAbiProps(const TextFormatting& formatLayout, const TextFormatting& format); void writePictureData(const TQString& koStoreName, const TQString& keyName); TQString transformToTextDate(const TQDateTime& dt); private: TQIODevice* m_ioDevice; TQTextStream* m_streamOut; TQString m_pagesize; // Buffer for the tag TQMap m_mapPictureData; StyleMap m_styleMap; double m_paperBorderTop,m_paperBorderLeft,m_paperBorderBottom,m_paperBorderRight; bool m_inIgnoreWords; // true if has been written KWEFDocumentInfo m_docInfo; // document information }; AbiWordWorker::AbiWordWorker(void) : m_ioDevice(NULL), m_streamOut(NULL), m_paperBorderTop(0.0),m_paperBorderLeft(0.0), m_paperBorderBottom(0.0),m_paperBorderRight(0.0) { } TQString AbiWordWorker::escapeAbiWordText(const TQString& strText) const { // Escape quotes (needed in attributes) // Escape apostrophs (allowed by XML) return KWEFUtil::EscapeSgmlText(NULL,strText,true,true); } bool AbiWordWorker::doOpenFile(const TQString& filenameOut, const TQString& ) { kdDebug(30506) << "Opening file: " << filenameOut << " (in AbiWordWorker::doOpenFile)" << endl; //Find the last extension TQString strExt; const int result=filenameOut.findRev('.'); if (result>=0) { strExt=filenameOut.mid(result); } TQString strMimeType; // Mime type of the compressor if ((strExt==".gz")||(strExt==".GZ") //in case of .abw.gz (logical extension) ||(strExt==".zabw")||(strExt==".ZABW")) //in case of .zabw (extension used prioritary with AbiWord) { // Compressed with gzip strMimeType="application/x-gzip"; } else if ((strExt==".bz2")||(strExt==".BZ2") //in case of .abw.bz2 (logical extension) ||(strExt==".bzabw")||(strExt==".BZABW")) //in case of .bzabw (extension used prioritary with AbiWord) { // Compressed with bzip2 strMimeType="application/x-bzip2"; } else { // No compression strMimeType="text/plain"; } kdDebug(30506) << "Compression: " << strMimeType << endl; m_ioDevice = KFilterDev::deviceForFile(filenameOut,strMimeType); if (!m_ioDevice) { kdError(30506) << "No output file! Aborting!" << endl; return false; } if ( !m_ioDevice->open (IO_WriteOnly) ) { kdError(30506) << "Unable to open output file! Aborting!" << endl; return false; } m_streamOut=new TQTextStream(m_ioDevice); // We only export in UTF-8 (are there AbiWord ports that cannot read UTF-8? Be careful SVG uses UTF-8 too!) m_streamOut->setEncoding( TQTextStream::UnicodeUTF8 ); return true; } bool AbiWordWorker::doCloseFile(void) { delete m_streamOut; m_streamOut=NULL; if (m_ioDevice) m_ioDevice->close(); return (m_ioDevice); } bool AbiWordWorker::doOpenDocument(void) { kdDebug(30506)<< "AbiWordWorker::doOpenDocument" << endl; // Make the file header // First the XML header in UTF-8 version // (AbiWord and QT handle UTF-8 well, so we stay with this encoding!) *m_streamOut << "\n"; // NOTE: AbiWord CVS 2002-02-?? has a new DOCTYPE *m_streamOut << "\n"; // First magic: "\n"; // Second magic: "\n"; // We have chosen NOT to have the full comment header that AbiWord files normally have. // ### TODO: perhaps we should add the comment: do not edit the file *m_streamOut << "\n"; return true; } void AbiWordWorker::writePictureData(const TQString& koStoreName, const TQString& keyName) { kdDebug(30506) << "AbiWordWorker::writeImageData" << endl; TQByteArray image; TQString strExtension(koStoreName.lower()); const int result=koStoreName.findRev("."); if (result>=0) { strExtension=koStoreName.mid(result+1); } bool isImageLoaded=false; if (strExtension=="png") { isImageLoaded=loadSubFile(koStoreName,image); } else { // All other picture types must be converted to PNG // (yes, even JPEG, SVG or WMF!) isImageLoaded=loadAndConvertToImage(koStoreName,strExtension,"PNG",image); } if (isImageLoaded) { *m_streamOut << "\n"; TQCString base64=KCodecs::base64Encode(image,true); *m_streamOut << base64 << "\n"; // TQCString is taken as Latin1 by TQTextStream *m_streamOut << "\n"; } else { kdWarning(30506) << "Unable to load picture: " << koStoreName << endl; } } bool AbiWordWorker::doCloseDocument(void) { // Before writing the element, // we must be sure that we have data and that we can retrieve it. if (m_kwordLeader && !m_mapPictureData.isEmpty()) { *m_streamOut << "\n"; TQMap::ConstIterator it; TQMap::ConstIterator end(m_mapPictureData.end()); // all images first for (it=m_mapPictureData.begin(); it!=end; ++it) { // Warning: do not mix up KWord's key and the iterator's key! writePictureData(it.key(),it.data().filename()); } *m_streamOut << "\n"; } *m_streamOut << "\n"; //Close the file for XML return true; } bool AbiWordWorker::doOpenTextFrameSet(void) { *m_streamOut << "
\n"; return true; } bool AbiWordWorker::doCloseTextFrameSet(void) { *m_streamOut << "
\n"; return true; } bool AbiWordWorker::doOpenStyles(void) { *m_streamOut << "\n"; return true; } bool AbiWordWorker::doCloseStyles(void) { *m_streamOut << "\n"; return true; } TQString AbiWordWorker::textFormatToAbiProps(const TextFormatting& formatOrigin, const TextFormatting& formatData, const bool force) const { // TODO: rename variable formatData TQString strElement; // TODO: rename this variable // Font name TQString fontName = formatData.fontName; if ( !fontName.isEmpty() && (force || (formatOrigin.fontName!=formatData.fontName))) { strElement+="font-family: "; strElement+= escapeAbiWordText(fontName); // TODO: add alternative font names strElement+="; "; } if (force || (formatOrigin.italic!=formatData.italic)) { // Font style strElement+="font-style: "; if ( formatData.italic ) { strElement+="italic"; } else { strElement+="normal"; } strElement+="; "; } if (force || ((formatOrigin.weight>=75)!=(formatData.weight>=75))) { strElement+="font-weight: "; if ( formatData.weight >= 75 ) { strElement+="bold"; } else { strElement+="normal"; } strElement+="; "; } if (force || (formatOrigin.fontSize!=formatData.fontSize)) { const int size=formatData.fontSize; if (size>0) { // We use absolute font sizes. strElement+="font-size: "; strElement+=TQString::number(size,10); strElement+="pt; "; } } if (force || (formatOrigin.fgColor!=formatData.fgColor)) { if ( formatData.fgColor.isValid() ) { // Give colour strElement+="color: "; // No leading # (unlike CSS2) // We must have two hex digits for each colour channel! const int red=formatData.fgColor.red(); strElement += TQString::number((red&0xf0)>>4,16); strElement += TQString::number(red&0x0f,16); const int green=formatData.fgColor.green(); strElement += TQString::number((green&0xf0)>>4,16); strElement += TQString::number(green&0x0f,16); const int blue=formatData.fgColor.blue(); strElement += TQString::number((blue&0xf0)>>4,16); strElement += TQString::number(blue&0x0f,16); strElement+="; "; } } if (force || (formatOrigin.bgColor!=formatData.bgColor)) { if ( formatData.bgColor.isValid() ) { // Give background colour strElement+="bgcolor: "; // No leading # (unlike CSS2) // We must have two hex digits for each colour channel! const int red=formatData.bgColor.red(); strElement += TQString::number((red&0xf0)>>4,16); strElement += TQString::number(red&0x0f,16); const int green=formatData.bgColor.green(); strElement += TQString::number((green&0xf0)>>4,16); strElement += TQString::number(green&0x0f,16); const int blue=formatData.bgColor.blue(); strElement += TQString::number((blue&0xf0)>>4,16); strElement += TQString::number(blue&0x0f,16); strElement+="; "; } } if (force || (formatOrigin.underline!=formatData.underline) || (formatOrigin.strikeout!=formatData.strikeout)) { strElement+="text-decoration: "; if ( formatData.underline ) { strElement+="underline"; } else if ( formatData.strikeout ) { strElement+="line-through"; } else { strElement+="none"; } strElement+="; "; } return strElement; } bool AbiWordWorker::makeTable(const FrameAnchor& anchor) { #if 0 *m_streamOut << "

\n"; // Close previous paragraph ### TODO: do it correctly like for HTML *m_streamOut << "\n"; #endif TQValueList::ConstIterator itCell; for (itCell=anchor.table.cellList.begin(); itCell!=anchor.table.cellList.end(); itCell++) { #if 0 // ### TODO: rowspan, colspan // AbiWord seems to work by attaching to the cell borders *m_streamOut << "\n"; #endif if (!doFullAllParagraphs(*(*itCell).paraList)) { return false; } #if 0 *m_streamOut << "\n"; #endif } #if 0 *m_streamOut << "
\n"; *m_streamOut << "

\n"; // Re-open the "previous" paragraph ### TODO: do it correctly like for HTML #endif return true; } bool AbiWordWorker::makePicture(const FrameAnchor& anchor) { kdDebug(30506) << "New image/clipart: " << anchor.picture.koStoreName << " , " << anchor.picture.key.toString() << endl; const double height=anchor.frame.bottom - anchor.frame.top; const double width =anchor.frame.right - anchor.frame.left; // TODO: we are only using the filename, not the rest of the key // TODO: (bad if there are two images of the same name, but of a different key) *m_streamOut << ""; // NO end of line! // TODO: other props for image m_mapPictureData[anchor.picture.koStoreName]=anchor.picture.key; return true; } void AbiWordWorker::writeAbiProps (const TextFormatting& formatLayout, const TextFormatting& format) { TQString abiprops=textFormatToAbiProps(formatLayout,format,false); // Erase the last semi-comma (as in CSS2, semi-commas only separate instructions and do not terminate them) const int result=abiprops.findRev(";"); if (result>=0) { // Remove the last semi-comma and the space thereafter abiprops.remove(result,2); } if (!abiprops.isEmpty()) { *m_streamOut << " props=\"" << abiprops << "\""; } } void AbiWordWorker::processNormalText ( const TQString ¶Text, const TextFormatting& formatLayout, const FormatData& formatData) { // Retrieve text and escape it TQString partialText=escapeAbiWordText(paraText.mid(formatData.pos,formatData.len)); // Replace line feeds by line breaks int pos; while ((pos=partialText.find(TQChar(10)))>-1) { partialText.replace(pos,1,"
"); } if (formatData.text.missing) { // It's just normal text, so we do not need a element! *m_streamOut << partialText; } else { // Text with properties, so use a element! *m_streamOut << "" << partialText << ""; } } void AbiWordWorker::processVariable ( const TQString&, const TextFormatting& formatLayout, const FormatData& formatData) { if (0==formatData.variable.m_type) { // As AbiWord's field is inflexible, we cannot make the date custom *m_streamOut << ""; } else if (2==formatData.variable.m_type) { // As AbiWord's field is inflexible, we cannot make the time custom *m_streamOut << ""; } else if (4==formatData.variable.m_type) { // As AbiWord's field is inflexible, we cannot make the time custom TQString strFieldType; if (formatData.variable.isPageNumber()) { strFieldType="page_number"; } else if (formatData.variable.isPageCount()) { strFieldType="page_count"; } if (strFieldType.isEmpty()) { // Unknown subtype, therefore write out the result *m_streamOut << formatData.variable.m_text; } else { *m_streamOut << ""; } } else if (9==formatData.variable.m_type) { // A link *m_streamOut << " has always a child writeAbiProps(formatLayout,formatData.text); *m_streamOut << ">" << escapeAbiWordText(formatData.variable.getLinkName()) << ""; } #if 0 else if (11==(*paraFormatDataIt).variable.m_type) { // Footnote TQString value = (*paraFormatDataIt).variable.getFootnoteValue(); bool automatic = (*paraFormatDataIt).variable.getFootnoteAuto(); TQValueList *paraList = (*paraFormatDataIt).variable.getFootnotePara(); if( paraList ) { TQString fstr; TQValueList::ConstIterator it; for (it=paraList->begin();it!=paraList->end();it++) fstr += ProcessParagraphData( (*it).text, (*it).layout,(*it).formattingList); str += "{\\super "; str += automatic ? "\\chftn " : value; str += "{\\footnote "; str += "{\\super "; str += automatic ? "\\chftn " : value; str += fstr; str += " }"; str += " }"; str += " }"; } } #endif else { // Generic variable *m_streamOut << formatData.variable.m_text; } } void AbiWordWorker::processAnchor ( const TQString&, const TextFormatting& /*formatLayout*/, //TODO const FormatData& formatData) { // We have an image or a table if ( (2==formatData.frameAnchor.type) // or || (5==formatData.frameAnchor.type) ) // { makePicture(formatData.frameAnchor); } else if (6==formatData.frameAnchor.type) { makeTable(formatData.frameAnchor); } else { kdWarning(30506) << "Unsupported anchor type: " << formatData.frameAnchor.type << endl; } } void AbiWordWorker::processParagraphData ( const TQString ¶Text, const TextFormatting& formatLayout, const ValueListFormatData ¶FormatDataList) { if ( paraText.length () > 0 ) { ValueListFormatData::ConstIterator paraFormatDataIt; for ( paraFormatDataIt = paraFormatDataList.begin (); paraFormatDataIt != paraFormatDataList.end (); paraFormatDataIt++ ) { if (1==(*paraFormatDataIt).id) { processNormalText(paraText, formatLayout, (*paraFormatDataIt)); } else if (4==(*paraFormatDataIt).id) { processVariable(paraText, formatLayout, (*paraFormatDataIt)); } else if (6==(*paraFormatDataIt).id) { processAnchor(paraText, formatLayout, (*paraFormatDataIt)); } } } } TQString AbiWordWorker::layoutToCss(const LayoutData& layoutOrigin, const LayoutData& layout, const bool force) const { TQString props; if (force || (layoutOrigin.alignment!=layout.alignment)) { // Check if the current alignment is a valid one for AbiWord. if ((layout.alignment == "left") || (layout.alignment == "right") || (layout.alignment == "center") || (layout.alignment == "justify")) { props += "text-align:"; props += layout.alignment; props += "; "; } else if (layout.alignment == "auto") { // We assume a left alignment as AbiWord is not really bi-di (and this filter even less.) props += "text-align:left; "; } else { kdWarning(30506) << "Unknown alignment: " << layout.alignment << endl; } } // TODO/FIXME: what if all tabulators must be erased? #if 0 // DEPRECATED! if (!layout.tabulator.isEmpty() && (force || (layoutOrigin.tabulator!=layout.tabulator))) { props += "tabstops:"; props += layout.tabulator; props += "; "; } #endif if (!layout.tabulatorList.isEmpty() && (force || (layoutOrigin.tabulatorList!=layout.tabulatorList) )) { props += "tabstops:"; bool first=true; TabulatorList::ConstIterator it; TabulatorList::ConstIterator end(layout.tabulatorList.end()); for (it=layout.tabulatorList.begin();it!=end;++it) { if (first) { first=false; } else { props += ","; } props += TQString::number((*it).m_ptpos); props += "pt"; switch ((*it).m_type) { case 0: props += "/L"; break; case 1: props += "/C"; break; case 2: props += "/R"; break; case 3: props += "/D"; break; default: props += "/L"; } props += "0"; // No filling } props += "; "; } if ((layout.indentLeft>=0.0) && (force || (layoutOrigin.indentLeft!=layout.indentLeft))) { props += TQString("margin-left:%1pt; ").arg(layout.indentLeft); } if ((layout.indentRight>=0.0) && (force || (layoutOrigin.indentRight!=layout.indentRight))) { props += TQString("margin-right:%1pt; ").arg(layout.indentRight); } if (force || (layoutOrigin.indentLeft!=layout.indentLeft)) { props += "text-indent: "; props += TQString::number(layout.indentFirst); props += "pt; "; } if ((layout.marginBottom>=0.0) && ( force || ( layoutOrigin.marginBottom != layout.marginBottom ) ) ) { props += TQString("margin-bottom:%1pt; ").arg(layout.marginBottom); } if ((layout.marginTop>=0.0) && ( force || ( layoutOrigin.marginTop != layout.marginTop ) ) ) { props += TQString("margin-top:%1pt; ").arg(layout.marginTop); } if (force || ( layoutOrigin.lineSpacingType != layout.lineSpacingType ) || ( layoutOrigin.lineSpacing != layout.lineSpacing ) ) { switch ( layout.lineSpacingType ) { case LayoutData::LS_CUSTOM: { // We have a custom line spacing (in points). However AbiWord cannot do it, so transform in "at-least" props += "line-height=:"; props += TQString::number( layout.lineSpacing ); // ### TODO: rounding? props += "pt+; "; break; } case LayoutData::LS_SINGLE: { props += "line-height:1.0; "; // One break; } case LayoutData::LS_ONEANDHALF: { props += "line-height:1.5; "; // One-and-half break; } case LayoutData::LS_DOUBLE: { props += "line-height:2.0; "; // Two break; } case LayoutData::LS_MULTIPLE: { props += "line-height:"; props += TQString::number( layout.lineSpacing ); // ### TODO: rounding? props += "; "; break; } case LayoutData::LS_FIXED: { // We have a fixed line height (in points) props += "line-height:"; props += TQString::number( layout.lineSpacing ); // ### TODO: rounding? props += "pt; "; break; } case LayoutData::LS_ATLEAST: { // We have an "at-least" line height (in points) props += "line-height=:"; props += TQString::number( layout.lineSpacing ); // ### TODO: rounding? props += "pt+; "; // The + makes the difference break; } default: { kdWarning(30506) << "Unsupported lineSpacingType: " << layout.lineSpacingType << " (Ignoring!)" << endl; break; } } } // Add all AbiWord properties collected in the element props += textFormatToAbiProps(layoutOrigin.formatData.text,layout.formatData.text,force); return props; } bool AbiWordWorker::doFullParagraph(const TQString& paraText, const LayoutData& layout, const ValueListFormatData& paraFormatDataList) { TQString style=layout.styleName; const LayoutData& styleLayout=m_styleMap[style]; TQString props=layoutToCss(styleLayout,layout,false); *m_streamOut << "=0) { // Remove the last semi-comma and the space thereafter props.remove(result,2); } *m_streamOut << " props=\"" << props << "\""; } *m_streamOut << ">"; //Warning: No trailing white space or else it's in the text!!! // Before processing the text, test if we have a page break if (layout.pageBreakBefore) { // We have a page break before the paragraph *m_streamOut << ""; } processParagraphData(paraText, layout.formatData.text, paraFormatDataList); // Before closing the paragraph, test if we have a page break if (layout.pageBreakAfter) { // We have a page break after the paragraph *m_streamOut << ""; } *m_streamOut << "

\n"; return true; } bool AbiWordWorker::doFullDefineStyle(LayoutData& layout) { //Register style in the style map m_styleMap[layout.styleName]=layout; *m_streamOut << "=0) { // Remove the last semi-comma and the space thereafter abiprops.remove(result,2); } *m_streamOut << " props=\"" << abiprops << "\""; *m_streamOut << "/>\n"; return true; } bool AbiWordWorker::doFullPaperFormat(const int format, const double width, const double height, const int orientation) { TQString outputText = "\n"; // KWord has no page scale, so assume 100% m_pagesize=outputText; return true; } bool AbiWordWorker::doFullPaperBorders (const double top, const double left, const double bottom, const double right) { m_paperBorderTop=top; m_paperBorderLeft=left; m_paperBorderBottom=bottom; m_paperBorderRight=right; return true; } bool AbiWordWorker::doCloseHead(void) { if (!m_pagesize.isEmpty()) { *m_streamOut << m_pagesize; } return true; } bool AbiWordWorker::doOpenSpellCheckIgnoreList (void) { kdDebug(30506) << "AbiWordWorker::doOpenSpellCheckIgnoreList" << endl; m_inIgnoreWords=false; // reset return true; } bool AbiWordWorker::doCloseSpellCheckIgnoreList (void) { kdDebug(30506) << "AbiWordWorker::doCloseSpellCheckIgnoreList" << endl; if (m_inIgnoreWords) *m_streamOut << "
\n"; return true; } bool AbiWordWorker::doFullSpellCheckIgnoreWord (const TQString& ignoreword) { kdDebug(30506) << "AbiWordWorker::doFullSpellCheckIgnoreWord: " << ignoreword << endl; if (!m_inIgnoreWords) { *m_streamOut << "\n"; m_inIgnoreWords=true; } *m_streamOut << " " << ignoreword << "\n"; return true; } // Similar to TQDateTime::toString, but guaranteed *not* to be translated TQString AbiWordWorker::transformToTextDate(const TQDateTime& dt) { if (dt.isValid()) { TQString result; const TQDate date(dt.date()); const char* dayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; const int dow = date.dayOfWeek() - 1; if ((dow<0) || (dow>6)) result += "Mon"; // Unknown day, rename it Monday. else result += dayName[dow]; result += ' '; const char* monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; const int month = date.month() - 1; if ((month<0) || (month>11)) result += "Jan"; // Unknown month, rename it January else result += monthName[month]; result += ' '; TQString temp; temp = "00"; temp += TQString::number(date.day(), 10); result += temp.right(2); result += ' '; const TQTime time(dt.time()); temp = "00"; temp += TQString::number(time.hour(), 10); result += temp.right(2); result += ':'; temp = "00"; temp += TQString::number(time.minute(), 10); result += temp.right(2); result += ':'; temp = "00"; temp += TQString::number(time.second(), 10); result += temp.right(2); result += ' '; temp = "0000"; temp += TQString::number(date.year(), 10); result += temp.right(4); return result; } else { // Invalid, so give back 1970-01-01 return "Thu Jan 01 00:00:00 1970"; } } bool AbiWordWorker::doFullDocumentInfo(const KWEFDocumentInfo& docInfo) { m_docInfo=docInfo; *m_streamOut << "\n"; // First all Dublin Core data *m_streamOut << "application/x-abiword\n"; if (!m_docInfo.title.isEmpty()) { *m_streamOut << "" << escapeAbiWordText(m_docInfo.title) << "\n"; } if (!m_docInfo.abstract.isEmpty()) { *m_streamOut << "" << escapeAbiWordText(m_docInfo.abstract) << "\n"; } if ( !m_docInfo.keywords.isEmpty() ) { *m_streamOut << "" << escapeAbiWordText(m_docInfo.keywords) << "\n"; } if ( !m_docInfo.subject.isEmpty() ) { *m_streamOut << "" << escapeAbiWordText(m_docInfo.subject) << "\n"; } // Say who we are (with the CVS revision number) in case we have a bug in our filter output! *m_streamOut << "KWord Export Filter"; TQString strVersion("$Revision: 508787 $"); // Remove the dollar signs // (We don't want that the version number changes if the AbiWord file is itself put in a CVS storage.) *m_streamOut << strVersion.mid(10).remove('$'); *m_streamOut << "\n"; TQDateTime now (TQDateTime::currentDateTime(Qt::UTC)); // current time in UTC *m_streamOut << "" << escapeAbiWordText(transformToTextDate(now)) << "\n"; *m_streamOut << "\n"; return true; } // ========================================================================================== ABIWORDExport::ABIWORDExport(KoFilter */*parent*/, const char */*name*/, const TQStringList &) : KoFilter() { } KoFilter::ConversionStatus ABIWORDExport::convert( const TQCString& from, const TQCString& to ) { if ( to != "application/x-abiword" || from != "application/x-kword" ) { return KoFilter::NotImplemented; } // We need KimageIO's help in AbiWordWorker::convertUnknownImage KImageIO::registerFormats(); AbiWordWorker* worker=new AbiWordWorker(); if (!worker) { kdError(30506) << "Cannot create Worker! Aborting!" << endl; return KoFilter::StupidError; } KWEFKWordLeader* leader=new KWEFKWordLeader(worker); if (!leader) { kdError(30506) << "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; }