/*************************************************************************** kwdwriter.cpp - description ------------------- begin : Wed Sep 5 2001 copyright : (C) 2001 by Frank Dekervel email : Frank.Dekervel@student.kuleuven.ac.be ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License * * as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kwdwriter.h" #include #include "tqrect.h" #include #include KWDWriter::KWDWriter(KoStore *store){ _zoomhandler = new KoTextZoomHandler(); _store=store; _doc= new TQDomDocument("DOC"); _docinfo = new TQDomDocument("document-info"); _doc->appendChild( _doc->createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); _docinfo->appendChild( _docinfo->createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); TQDomElement infodoc = _docinfo->createElement( "document-info" ); _docinfoMain=infodoc; _docinfo->appendChild(infodoc); tableNo=1; insidetable = false; TQDomElement kwdoc = _doc->createElement( "DOC" ); kwdoc.setAttribute( "editor", "HTML Import Filter" ); kwdoc.setAttribute( "mime", "application/x-kword" ); _doc->appendChild( kwdoc ); TQDomElement paper = _doc->createElement( "PAPER" ); kwdoc.appendChild( paper ); paper.setAttribute( "format", 1 ); paper.setAttribute( "width", 595 ); paper.setAttribute( "height", 841 ); paper.setAttribute( "orientation", 0 ); paper.setAttribute( "columns", 1 ); paper.setAttribute( "columnspacing", 3 ); paper.setAttribute( "hType", 0 ); paper.setAttribute( "fType", 0 ); TQDomElement borders = _doc->createElement( "PAPERBORDERS" ); paper.appendChild( borders ); borders.setAttribute( "left", 20 ); borders.setAttribute( "top", 10 ); borders.setAttribute( "right", 10 ); borders.setAttribute( "bottom", 10 ); TQDomElement docattrs = _doc->createElement( "ATTRIBUTES" ); kwdoc.appendChild( docattrs ); docattrs.setAttribute( "processing", 0 ); docattrs.setAttribute( "standardpage", 1 ); docattrs.setAttribute( "hasHeader", 0 ); docattrs.setAttribute( "hasFooter", 0 ); //docattrs.setAttribute( "unit", "mm" ); // use KWord default instead TQDomElement framesets = _doc->createElement("FRAMESETS"); kwdoc.appendChild(framesets); TQDomElement rootframeset = addFrameSet(framesets); _mainFrameset=rootframeset; TQDomElement mainframe= addFrame(rootframeset,TQRect(28,28,539,757)); TQDomElement styles=_doc->createElement("STYLES"); kwdoc.appendChild(styles); TQDomElement standard=_doc->createElement("STYLE"); styles.appendChild(standard); TQDomElement tmp; tmp=_doc->createElement("NAME"); tmp.setAttribute("value","Standard"); standard.appendChild(tmp); tmp=_doc->createElement("FOLLOWING"); tmp.setAttribute("name","Standard"); standard.appendChild(tmp); TQDomElement fmt; fmt=_doc->createElement("FORMAT"); fmt.setAttribute("id","1"); standard.appendChild(fmt); tmp=_doc->createElement("SIZE"); tmp.setAttribute("value","12"); // HACK ! fmt.appendChild(tmp); #define HEADINGSTYLE(a,b) standard=_doc->createElement("STYLE");\ styles.appendChild(standard);\ tmp=_doc->createElement("NAME");\ tmp.setAttribute("value",#a);\ standard.appendChild(tmp);\ tmp=_doc->createElement("FOLLOWING");\ tmp.setAttribute("name","Standard");\ standard.appendChild(tmp);\ fmt=_doc->createElement("FORMAT");\ fmt.setAttribute("id","1");\ standard.appendChild(fmt);\ tmp=_doc->createElement("SIZE");\ tmp.setAttribute("value",#b);\ fmt.appendChild(tmp); HEADINGSTYLE(h1,20); HEADINGSTYLE(h2,18); HEADINGSTYLE(h3,16); HEADINGSTYLE(h4,14); HEADINGSTYLE(h5,10); HEADINGSTYLE(h6,8); } bool KWDWriter::isInTable() const { return insidetable; } int KWDWriter::createTable() { insidetable = true; return tableNo++; } void KWDWriter::createDocInfo(TQString author, TQString title) { TQDomElement authorTag=_docinfo->createElement("author"); TQDomElement aboutTag=_docinfo->createElement("about"); TQDomElement fullNameTag=_docinfo->createElement("full-name"); TQDomText titleText=_docinfo->createTextNode(title); TQDomText authorText=_docinfo->createTextNode(author); fullNameTag.appendChild(authorText); authorTag.appendChild(fullNameTag); TQDomElement titleTag=_docinfo->createElement("title"); titleTag.appendChild(titleText); aboutTag.appendChild(titleTag); _docinfoMain.appendChild(authorTag); _docinfoMain.appendChild(aboutTag); } void KWDWriter::createInline(TQDomElement paragraph, TQDomElement toInline) { if (toInline.tagName() == "FRAMESET") { formatAttribute(paragraph,"ANCHOR","type","frameset"); // fixme: support other kinds of inlines. } if (!toInline.attribute("grpMgr").isEmpty()) { formatAttribute(paragraph,"ANCHOR","instance",toInline.attribute("grpMgr")); } addText(paragraph,"#",6); // the anchor. } TQDomElement KWDWriter::currentLayout(TQDomElement paragraph) { return paragraph.elementsByTagName("LAYOUT").item(0).toElement(); } TQDomElement KWDWriter::createTableCell(int tableno, int nrow, int ncol, int colspan, TQRect rect) { TQDomElement parent=docroot().elementsByTagName("FRAMESETS").item(0).toElement(); TQDomElement fs=addFrameSet(parent,1,0, TQString("Table %1 - %2,%3").arg(tableno).arg(nrow).arg(ncol), 1); fs.setAttribute("grpMgr",TQString("Table %1").arg(tableno)); fs.setAttribute("row",nrow); fs.setAttribute("col",ncol); fs.setAttribute("cols",colspan); // FIXME do colspan in finishTable // so we don't have to give it as an argument fs.setAttribute("rows",1); // FIXME support rowspan ? addFrame(fs,rect); return fs; } TQDomElement KWDWriter::fetchTableCell(int tableno, int rowno, int colno) { TQDomNodeList e=docroot().elementsByTagName("FRAMESET"); for (unsigned int i=0;i y) ? x : y) #define MIN(x,y) ((x < y) ? x : y) void KWDWriter::finishTable(int tableno) { finishTable(tableno,TQRect(-1,-1,-1,-1)); } void KWDWriter::createHR(TQDomElement paragraph, int width) { layoutAttribute(paragraph,"BOTTOMBORDER","width",TQString("%1").arg(width)); } void KWDWriter::finishTable(int tableno,TQRect rect) { int ncols=0; int nrows=0; insidetable = false; int x=rect.x(); int y=rect.y(); int w=rect.width(); int h=rect.height(); TQDomNodeList nl=docroot().elementsByTagName("FRAMESET"); //FIXME calculate nrows and stuff. //and add empty cells for missing ones. // first, see how big the table is (cols & rows) for (unsigned i=0;i0) must_resize=true; while (currow < nrows) { curcol=0; while (curcol < ncols) { TQDomElement e=fetchTableCell(tableno,currow,curcol); if (e.isNull()) { // a missing cell ! kdDebug(30503) << TQString("creating %1 %2").arg(currow).arg(curcol).latin1() << endl; createTableCell(tableno,currow,curcol,1, TQRect(x+step_x*curcol,y+step_y*currow,step_x,step_y) ); // fixme: what to do if we don't have to resize ? } // resize this one FIXME optimize this routine if (must_resize == true) { TQDomElement ee=e.firstChild().toElement(); // the frame in the frameset int cs=e.attribute("cols").toInt(); int rs=e.attribute("rows").toInt(); kdDebug(30503) << "resizing" << endl; addRect(ee,TQRect(x+step_x*curcol,0,step_x*cs,step_y*rs)); } if (curcol==0) currow_inc=e.attribute("rows").toInt(); curcol +=e.attribute("cols").toInt(); } currow+=currow_inc; } } TQDomElement KWDWriter::addFrameSet(TQDomElement parent, int frametype, int frameinfo, TQString name, int visible) { TQDomElement frameset=_doc->createElement("FRAMESET"); parent.appendChild(frameset); frameset.setAttribute("frameType",frametype); frameset.setAttribute("frameInfo",frameinfo); if (!name.isNull()) frameset.setAttribute("name",name); else frameset.setAttribute("name","Text-frameset 1"); frameset.setAttribute("visible",visible); return frameset; } TQDomElement KWDWriter::addParagraph(TQDomElement parent) { TQDomElement k; return addParagraph(parent,k); } void KWDWriter::appendKWordVariable(TQDomDocument& doc, TQDomElement& format, const TQString& text, const TQString& key, int type, TQDomElement& child) { TQDomElement variableElement ( doc.createElement("VARIABLE") ); TQDomElement typeElement ( doc.createElement("TYPE") ); typeElement.setAttribute("key",key); typeElement.setAttribute("type",type); typeElement.setAttribute("text",text); variableElement.appendChild(typeElement); //Append to variableElement.appendChild(child); //Append to format.appendChild(variableElement); } TQDomElement KWDWriter::createLink(TQDomElement paragraph, TQString linkName, TQString hrefName) { TQDomElement linkElement = _doc->createElement("LINK"); linkElement.setAttribute( "linkName", linkName ); linkElement.setAttribute( "hrefName", hrefName ); TQDomElement format = currentFormat(paragraph,true); format.setAttribute("id", 4); // change Variable appendKWordVariable(*_doc, format, linkName, "STRING", 9, linkElement); return linkElement; } TQDomElement KWDWriter::setLayout(TQDomElement paragraph, TQDomElement layout) { TQDomElement theLayout; if (layout.isNull()) theLayout=_doc->createElement("LAYOUT"); else theLayout=layout.cloneNode().toElement(); TQDomElement oldLayout=currentLayout(paragraph); paragraph.removeChild(oldLayout); paragraph.appendChild(theLayout); return theLayout; } TQRect getRect(TQDomElement frameset) { // returns the rect of the first frame. TQDomElement frame=frameset.elementsByTagName("FRAME").item(0).toElement(); return TQRect(frame.attribute("left").toInt(), frame.attribute("top").toInt(), frame.attribute("right").toInt()-frame.attribute("left").toInt(), frame.attribute("bottom").toInt()-frame.attribute("top").toInt() ); } TQDomElement KWDWriter::addParagraph(TQDomElement parent, TQDomElement layoutToClone) { TQDomElement paragraph=_doc->createElement("PARAGRAPH"); TQDomElement formats=_doc->createElement("FORMATS"); TQDomElement layout; if (layoutToClone.isNull()) { layout=_doc->createElement("LAYOUT"); } else { layout=layoutToClone.cloneNode().toElement(); } TQDomElement text=_doc->createElement("TEXT"); TQDomText t=_doc->createTextNode(TQString("")); text.appendChild(t); paragraph.appendChild(formats); paragraph.appendChild(text); parent.appendChild(paragraph); paragraph.appendChild(layout); layoutAttribute(paragraph,"NAME","value","Standard"); return paragraph; } TQDomElement KWDWriter::formatAttribute(TQDomElement paragraph, TQString name, TQString attrName, TQString attr) { kdDebug() << "Entering KWDWriter::formatAttribute" << endl; TQDomElement lastformat=currentFormat(paragraph,true); TQDomNodeList qdnl= lastformat.elementsByTagName(name); if (qdnl.length()) { TQDomElement el; el=qdnl.item(0).toElement(); el.setAttribute(attrName,attr); return el; } else { TQDomElement al=_doc->createElement(name); lastformat.appendChild(al); al.setAttribute(attrName,attr); return al; } } TQString KWDWriter::getLayoutAttribute(TQDomElement paragraph, TQString name, TQString attrName) { TQDomElement currentLayout=paragraph.elementsByTagName("LAYOUT").item(0).toElement(); TQDomNodeList qdnl= currentLayout.elementsByTagName(name); if (qdnl.length()) { TQDomElement el=qdnl.item(0).toElement(); return el.attribute(attrName); } return TQString(); } TQDomElement KWDWriter::layoutAttribute(TQDomElement paragraph, TQString name, TQString attrName, TQString attr) { kdDebug() << "Entering KWDWriter::layoutAttribute name=" << name << " attrName=" << attrName << " attr=" << attr << endl; TQDomElement currentLayout=paragraph.elementsByTagName("LAYOUT").item(0).toElement(); TQDomNodeList qdnl= currentLayout.elementsByTagName(name); if (qdnl.length()) { TQDomElement el; el=qdnl.item(0).toElement(); el.setAttribute(attrName,attr); return el; } else { TQDomElement al=_doc->createElement(name); currentLayout.appendChild(al); al.setAttribute(attrName,attr); return al; } } void KWDWriter::addText(TQDomElement paragraph, TQString text, int format_id, bool keep_formatting) { TQDomNode temp=paragraph.elementsByTagName("TEXT").item(0).firstChild(); TQDomText currentText=temp.toText(); if (temp.isNull()) { kdDebug(30503) << "no text" << endl; return; } TQString oldtext=currentText.data(); int oldLength=oldtext.length(); if (keep_formatting) { if (oldLength) { ++oldLength; oldtext.append('\n'); } } else { if (oldLength) ++oldLength; // add new trailing space char text=text.simplifyWhiteSpace(); // drop all unprintable chars } TQString newtext; if (keep_formatting) newtext=oldtext + text; else { newtext=oldtext + " " + text; // strip possible newline at beginning. while (newtext.left(1)=="\n" || newtext.left(1)==" ") newtext=newtext.right(newtext.length()-1); } currentText.setData(newtext); int newLength=text.length(); TQDomElement lastformat=currentFormat(paragraph,true); if (lastformat.attribute("id").isEmpty()) // keep old id value, e.g. for LINK URL lastformat.setAttribute("id",format_id); lastformat.setAttribute("pos",TQString("%1").arg(oldLength)); lastformat.setAttribute("len",TQString("%1").arg(newLength)); } TQString KWDWriter::getText(TQDomElement paragraph) { TQDomNode temp=paragraph.elementsByTagName("TEXT").item(0).firstChild(); TQDomText currentText=temp.toText(); if (temp.isNull()) { kdWarning(30503) << "no text" << endl; } return currentText.data(); } TQDomElement KWDWriter::startFormat(TQDomElement paragraph) { if (paragraph.isNull()) { kdWarning(30503) << "startFormat on empty paragraph" << endl; } TQDomElement format=_doc->createElement("FORMAT"); paragraph.elementsByTagName("FORMATS").item(0).appendChild(format); return format; } TQDomElement KWDWriter::startFormat(TQDomElement paragraph, TQDomElement formatToClone) { TQDomElement format=formatToClone.cloneNode().toElement(); if (format.isNull()) { kdWarning(30503) << "startFormat: null format cloned" << endl; } if (paragraph.isNull()) { kdWarning(30503) << "startFormat on empty paragraph" << endl; } format.removeAttribute("len"); format.removeAttribute("pos"); format.removeAttribute("id"); for (TQDomElement a=format.firstChild().toElement();!a.isNull();a=a.nextSibling().toElement()) { if (a.tagName() == "ANCHOR") { format.removeChild(a); } } paragraph.elementsByTagName("FORMATS").item(0).appendChild(format); return format; } TQDomElement KWDWriter::currentFormat(TQDomElement paragraph, bool start_new_one) { TQDomElement e=paragraph.elementsByTagName("FORMATS").item(0).lastChild().toElement(); if (e.isNull()) { // no current format, start a new one if (start_new_one) return startFormat(paragraph); else { kdWarning(30503) << "warning: returning null format" << endl; } } if (!e.attribute("len").isNull()) { // current format already has length, clone it. if (start_new_one) return startFormat(paragraph,e); } return e; } void KWDWriter::cleanUpParagraph(TQDomElement paragraph) { TQDomElement e=paragraph.elementsByTagName("FORMATS").item(0).toElement(); if (e.isNull()) { kdWarning(30503) << "cleanup : no valid paragraph" << endl; return; } for (TQDomElement k=e.firstChild().toElement();!k.isNull();k=k.nextSibling().toElement()) { if (k.attribute("len",TQString()).isNull()) { e.removeChild(k); cleanUpParagraph(paragraph); return; } } } TQDomElement KWDWriter::addFrame(TQDomElement frameset, TQRect rect, int runaround, int copy, int newFrameBehaviour, int runaroundGap ) { TQDomElement frame = _doc->createElement("FRAME"); frameset.appendChild(frame); frame.setAttribute("runaround",runaround); frame.setAttribute("copy",copy); frame.setAttribute("newFrameBehaviour",newFrameBehaviour); frame.setAttribute("runaroundGap",runaroundGap); addRect(frame,rect); return frame; } TQDomElement KWDWriter::docroot() { return _doc->elementsByTagName("DOC").item(0).toElement(); } bool KWDWriter::writeDoc() { TQCString str=_doc->toCString(); kdWarning(30503) << str << endl; if (!_store->open("root")) { return false; } else { _store->write((const char *)str, str.length()); _store->close(); } if (!_store->open("documentinfo.xml")) { kdWarning(30503) << "WARNING: unable to write out doc info. continuing anyway" << endl; } else { str=_docinfo->toCString(); _store->write((const char *)str, str.length()); _store->close(); } return true; } TQDomElement KWDWriter::mainFrameset() { return _mainFrameset; } void KWDWriter::addRect(TQDomElement e,TQRect rect) { e.setAttribute("top",_zoomhandler->pixelYToPt( rect.top())); e.setAttribute("left",_zoomhandler->pixelXToPt(rect.left())); e.setAttribute("bottom",_zoomhandler->pixelYToPt(rect.bottom())); e.setAttribute("right",_zoomhandler->pixelXToPt(rect.right())); } KWDWriter::~KWDWriter(){ delete(_zoomhandler); }