00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kwdwriter.h"
00020 #include <stdlib.h>
00021 #include "qrect.h"
00022 #include <KoTextZoomHandler.h>
00023 #include <qpaintdevice.h>
00024
00025 KWDWriter::KWDWriter(KoStore *store){
00026 _zoomhandler = new KoTextZoomHandler();
00027
00028 _store=store;
00029 _doc= new QDomDocument("DOC");
00030 _docinfo = new QDomDocument("document-info");
00031
00032 _doc->appendChild( _doc->createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
00033 _docinfo->appendChild( _docinfo->createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
00034
00035 QDomElement infodoc = _docinfo->createElement( "document-info" );
00036 _docinfoMain=infodoc;
00037 _docinfo->appendChild(infodoc);
00038
00039 tableNo=1;
00040 insidetable = false;
00041 QDomElement kwdoc = _doc->createElement( "DOC" );
00042 kwdoc.setAttribute( "editor", "HTML Import Filter" );
00043 kwdoc.setAttribute( "mime", "application/x-kword" );
00044 _doc->appendChild( kwdoc );
00045
00046 QDomElement paper = _doc->createElement( "PAPER" );
00047 kwdoc.appendChild( paper );
00048 paper.setAttribute( "format", 1 );
00049 paper.setAttribute( "width", 595 );
00050 paper.setAttribute( "height", 841 );
00051 paper.setAttribute( "orientation", 0 );
00052 paper.setAttribute( "columns", 1 );
00053 paper.setAttribute( "columnspacing", 3 );
00054 paper.setAttribute( "hType", 0 );
00055 paper.setAttribute( "fType", 0 );
00056
00057 QDomElement borders = _doc->createElement( "PAPERBORDERS" );
00058 paper.appendChild( borders );
00059 borders.setAttribute( "left", 20 );
00060 borders.setAttribute( "top", 10 );
00061 borders.setAttribute( "right", 10 );
00062 borders.setAttribute( "bottom", 10 );
00063
00064 QDomElement docattrs = _doc->createElement( "ATTRIBUTES" );
00065 kwdoc.appendChild( docattrs );
00066 docattrs.setAttribute( "processing", 0 );
00067 docattrs.setAttribute( "standardpage", 1 );
00068 docattrs.setAttribute( "hasHeader", 0 );
00069 docattrs.setAttribute( "hasFooter", 0 );
00070
00071
00072 QDomElement framesets = _doc->createElement("FRAMESETS");
00073 kwdoc.appendChild(framesets);
00074 QDomElement rootframeset = addFrameSet(framesets);
00075 _mainFrameset=rootframeset;
00076 QDomElement mainframe= addFrame(rootframeset,QRect(28,28,539,757));
00077
00078 QDomElement styles=_doc->createElement("STYLES");
00079 kwdoc.appendChild(styles);
00080
00081 QDomElement standard=_doc->createElement("STYLE");
00082 styles.appendChild(standard);
00083
00084 QDomElement tmp;
00085 tmp=_doc->createElement("NAME");
00086 tmp.setAttribute("value","Standard");
00087 standard.appendChild(tmp);
00088
00089 tmp=_doc->createElement("FOLLOWING");
00090 tmp.setAttribute("name","Standard");
00091 standard.appendChild(tmp);
00092 QDomElement fmt;
00093
00094 fmt=_doc->createElement("FORMAT");
00095 fmt.setAttribute("id","1");
00096 standard.appendChild(fmt);
00097
00098 tmp=_doc->createElement("SIZE");
00099 tmp.setAttribute("value","12");
00100 fmt.appendChild(tmp);
00101
00102
00103 #define HEADINGSTYLE(a,b) standard=_doc->createElement("STYLE");\
00104 styles.appendChild(standard);\
00105 tmp=_doc->createElement("NAME");\
00106 tmp.setAttribute("value",#a);\
00107 standard.appendChild(tmp);\
00108 tmp=_doc->createElement("FOLLOWING");\
00109 tmp.setAttribute("name","Standard");\
00110 standard.appendChild(tmp);\
00111 fmt=_doc->createElement("FORMAT");\
00112 fmt.setAttribute("id","1");\
00113 standard.appendChild(fmt);\
00114 tmp=_doc->createElement("SIZE");\
00115 tmp.setAttribute("value",#b);\
00116 fmt.appendChild(tmp);
00117
00118 HEADINGSTYLE(h1,20);
00119 HEADINGSTYLE(h2,18);
00120 HEADINGSTYLE(h3,16);
00121 HEADINGSTYLE(h4,14);
00122 HEADINGSTYLE(h5,10);
00123 HEADINGSTYLE(h6,8);
00124
00125
00126 }
00127
00128 bool KWDWriter::isInTable() const {
00129 return insidetable;
00130 }
00131
00132 int KWDWriter::createTable() {
00133 insidetable = true;
00134 return tableNo++;
00135 }
00136
00137 void KWDWriter::createDocInfo(QString author, QString title) {
00138 QDomElement authorTag=_docinfo->createElement("author");
00139 QDomElement aboutTag=_docinfo->createElement("about");
00140 QDomElement fullNameTag=_docinfo->createElement("full-name");
00141 QDomText titleText=_docinfo->createTextNode(title);
00142 QDomText authorText=_docinfo->createTextNode(author);
00143 fullNameTag.appendChild(authorText);
00144 authorTag.appendChild(fullNameTag);
00145 QDomElement titleTag=_docinfo->createElement("title");
00146 titleTag.appendChild(titleText);
00147 aboutTag.appendChild(titleTag);
00148 _docinfoMain.appendChild(authorTag);
00149 _docinfoMain.appendChild(aboutTag);
00150 }
00151
00152
00153 void KWDWriter::createInline(QDomElement paragraph, QDomElement toInline) {
00154 if (toInline.tagName() == "FRAMESET") {
00155 formatAttribute(paragraph,"ANCHOR","type","frameset");
00156
00157 }
00158 if (!toInline.attribute("grpMgr").isEmpty()) {
00159 formatAttribute(paragraph,"ANCHOR","instance",toInline.attribute("grpMgr"));
00160 }
00161 addText(paragraph,"#",6);
00162 }
00163
00164
00165 QDomElement KWDWriter::currentLayout(QDomElement paragraph) {
00166 return paragraph.elementsByTagName("LAYOUT").item(0).toElement();
00167 }
00168
00169
00170
00171 QDomElement KWDWriter::createTableCell(int tableno, int nrow,
00172 int ncol, int colspan, QRect rect) {
00173 QDomElement parent=docroot().elementsByTagName("FRAMESETS").item(0).toElement();
00174
00175 QDomElement fs=addFrameSet(parent,1,0,
00176 QString("Table %1 - %2,%3").arg(tableno).arg(nrow).arg(ncol),
00177 1);
00178 fs.setAttribute("grpMgr",QString("Table %1").arg(tableno));
00179 fs.setAttribute("row",nrow);
00180 fs.setAttribute("col",ncol);
00181 fs.setAttribute("cols",colspan);
00182
00183 fs.setAttribute("rows",1);
00184 addFrame(fs,rect);
00185 return fs;
00186 }
00187
00188 QDomElement KWDWriter::fetchTableCell(int tableno, int rowno, int colno) {
00189 QDomNodeList e=docroot().elementsByTagName("FRAMESET");
00190 for (unsigned int i=0;i<e.count();i++) {
00191 QDomElement k=e.item(i).toElement();
00192 if (k.attribute("grpMgr") == QString("Table %1").arg(tableno))
00193 if (k.attribute("row") == QString("%1").arg(rowno))
00194 if (k.attribute("col") == QString("%1").arg(colno))
00195 return k;
00196 }
00197 QDomElement dummy;
00198 return dummy;
00199 }
00200
00201 #define MAX(x,y) ((x > y) ? x : y)
00202 #define MIN(x,y) ((x < y) ? x : y)
00203
00204 void KWDWriter::finishTable(int tableno) {
00205 finishTable(tableno,QRect(-1,-1,-1,-1));
00206 }
00207
00208
00209 void KWDWriter::createHR(QDomElement paragraph, int width) {
00210 layoutAttribute(paragraph,"BOTTOMBORDER","width",QString("%1").arg(width));
00211 }
00212
00213 void KWDWriter::finishTable(int tableno,QRect rect) {
00214 int ncols=0;
00215 int nrows=0;
00216 insidetable = false;
00217
00218 int x=rect.x();
00219 int y=rect.y();
00220 int w=rect.width();
00221 int h=rect.height();
00222
00223 QDomNodeList nl=docroot().elementsByTagName("FRAMESET");
00224
00225
00226
00227
00228 for (unsigned i=0;i<nl.count();i++) {
00229 QDomElement k=nl.item(i).toElement();
00230 if (k.attribute("grpMgr") == QString("Table %1").arg(tableno)) {
00231 ncols=MAX(ncols,k.attribute("col").toInt()+1);
00232 nrows=MAX(nrows,k.attribute("row").toInt()+1);
00233 }
00234 }
00235 int curcol=0;
00236 int currow=0;
00237 int currow_inc=0;
00238 if (ncols == 0) ncols=1;
00239 if (nrows == 0) nrows=1;
00240
00241 int step_x=(w-x)/ncols;
00242 int step_y=(h-y)/nrows;
00243
00244
00245
00246 bool must_resize=false;
00247 if (x>0) must_resize=true;
00248 while (currow < nrows) {
00249 curcol=0;
00250 while (curcol < ncols) {
00251 QDomElement e=fetchTableCell(tableno,currow,curcol);
00252 if (e.isNull()) {
00253
00254 kdDebug(30503) << QString("creating %1 %2").arg(currow).arg(curcol).latin1() << endl;
00255 createTableCell(tableno,currow,curcol,1,
00256 QRect(x+step_x*curcol,y+step_y*currow,step_x,step_y)
00257 );
00258
00259 }
00260
00261
00262 if (must_resize == true) {
00263 QDomElement ee=e.firstChild().toElement();
00264 int cs=e.attribute("cols").toInt();
00265 int rs=e.attribute("rows").toInt();
00266 kdDebug(30503) << "resizing" << endl;
00267 addRect(ee,QRect(x+step_x*curcol,0,step_x*cs,step_y*rs));
00268 }
00269 if (curcol==0) currow_inc=e.attribute("rows").toInt();
00270 curcol +=e.attribute("cols").toInt();
00271
00272
00273 }
00274 currow+=currow_inc;
00275 }
00276
00277
00278 }
00279
00280
00281 QDomElement KWDWriter::addFrameSet(QDomElement parent, int frametype,
00282 int frameinfo, QString name, int visible) {
00283
00284 QDomElement frameset=_doc->createElement("FRAMESET");
00285 parent.appendChild(frameset);
00286 frameset.setAttribute("frameType",frametype);
00287 frameset.setAttribute("frameInfo",frameinfo);
00288
00289 if (!name.isNull())
00290 frameset.setAttribute("name",name);
00291 else
00292 frameset.setAttribute("name","Text-frameset 1");
00293
00294 frameset.setAttribute("visible",visible);
00295 return frameset;
00296 }
00297
00298 QDomElement KWDWriter::addParagraph(QDomElement parent) {
00299 QDomElement k;
00300 return addParagraph(parent,k);
00301 }
00302
00303 void KWDWriter::appendKWordVariable(QDomDocument& doc, QDomElement& format,
00304 const QString& text, const QString& key, int type, QDomElement& child) {
00305
00306 QDomElement variableElement ( doc.createElement("VARIABLE") );
00307
00308 QDomElement typeElement ( doc.createElement("TYPE") );
00309 typeElement.setAttribute("key",key);
00310 typeElement.setAttribute("type",type);
00311 typeElement.setAttribute("text",text);
00312 variableElement.appendChild(typeElement);
00313
00314 variableElement.appendChild(child);
00315
00316 format.appendChild(variableElement);
00317 }
00318
00319 QDomElement KWDWriter::createLink(QDomElement paragraph, QString linkName, QString hrefName) {
00320 QDomElement linkElement = _doc->createElement("LINK");
00321 linkElement.setAttribute( "linkName", linkName );
00322 linkElement.setAttribute( "hrefName", hrefName );
00323 QDomElement format = currentFormat(paragraph,true);
00324 format.setAttribute("id", 4);
00325 appendKWordVariable(*_doc, format, linkName, "STRING", 9, linkElement);
00326
00327 return linkElement;
00328 }
00329
00330
00331 QDomElement KWDWriter::setLayout(QDomElement paragraph, QDomElement layout) {
00332 QDomElement theLayout;
00333 if (layout.isNull())
00334 theLayout=_doc->createElement("LAYOUT");
00335 else
00336 theLayout=layout.cloneNode().toElement();
00337 QDomElement oldLayout=currentLayout(paragraph);
00338 paragraph.removeChild(oldLayout);
00339 paragraph.appendChild(theLayout);
00340 return theLayout;
00341 }
00342
00343
00344 QRect getRect(QDomElement frameset) {
00345
00346 QDomElement frame=frameset.elementsByTagName("FRAME").item(0).toElement();
00347 return QRect(frame.attribute("left").toInt(),
00348 frame.attribute("top").toInt(),
00349 frame.attribute("right").toInt()-frame.attribute("left").toInt(),
00350 frame.attribute("bottom").toInt()-frame.attribute("top").toInt()
00351 );
00352
00353 }
00354
00355
00356 QDomElement KWDWriter::addParagraph(QDomElement parent, QDomElement layoutToClone) {
00357
00358 QDomElement paragraph=_doc->createElement("PARAGRAPH");
00359 QDomElement formats=_doc->createElement("FORMATS");
00360 QDomElement layout;
00361 if (layoutToClone.isNull()) {
00362 layout=_doc->createElement("LAYOUT");
00363 }
00364 else {
00365 layout=layoutToClone.cloneNode().toElement();
00366 }
00367 QDomElement text=_doc->createElement("TEXT");
00368 QDomText t=_doc->createTextNode(QString(""));
00369 text.appendChild(t);
00370 paragraph.appendChild(formats);
00371 paragraph.appendChild(text);
00372 parent.appendChild(paragraph);
00373 paragraph.appendChild(layout);
00374 layoutAttribute(paragraph,"NAME","value","Standard");
00375 return paragraph;
00376 }
00377
00378 QDomElement KWDWriter::formatAttribute(QDomElement paragraph, QString name, QString attrName, QString attr) {
00379 kdDebug() << "Entering KWDWriter::formatAttribute" << endl;
00380 QDomElement lastformat=currentFormat(paragraph,true);
00381 QDomNodeList qdnl= lastformat.elementsByTagName(name);
00382 if (qdnl.length()) {
00383 QDomElement el;
00384 el=qdnl.item(0).toElement();
00385 el.setAttribute(attrName,attr);
00386 return el;
00387 } else {
00388 QDomElement al=_doc->createElement(name);
00389 lastformat.appendChild(al);
00390 al.setAttribute(attrName,attr);
00391 return al;
00392 }
00393
00394 }
00395
00396 QString KWDWriter::getLayoutAttribute(QDomElement paragraph, QString name, QString attrName) {
00397 QDomElement currentLayout=paragraph.elementsByTagName("LAYOUT").item(0).toElement();
00398 QDomNodeList qdnl= currentLayout.elementsByTagName(name);
00399 if (qdnl.length()) {
00400 QDomElement el=qdnl.item(0).toElement();
00401 return el.attribute(attrName);
00402 }
00403 return QString::null;
00404 }
00405
00406 QDomElement KWDWriter::layoutAttribute(QDomElement paragraph, QString name, QString attrName, QString attr)
00407 {
00408 kdDebug() << "Entering KWDWriter::layoutAttribute" << endl;
00409 QDomElement currentLayout=paragraph.elementsByTagName("LAYOUT").item(0).toElement();
00410 QDomNodeList qdnl= currentLayout.elementsByTagName(name);
00411
00412 if (qdnl.length()) {
00413 QDomElement el;
00414 el=qdnl.item(0).toElement();
00415 el.setAttribute(attrName,attr);
00416 return el;
00417 } else {
00418 QDomElement al=_doc->createElement(name);
00419 currentLayout.appendChild(al);
00420 al.setAttribute(attrName,attr);
00421 return al;
00422 }
00423 }
00424
00425 void KWDWriter::addText(QDomElement paragraph, QString text, int format_id, bool keep_formatting) {
00426 QDomNode temp=paragraph.elementsByTagName("TEXT").item(0).firstChild();
00427 QDomText currentText=temp.toText();
00428 if (temp.isNull()) { kdDebug(30503) << "no text" << endl; return; }
00429 QString oldtext=currentText.data();
00430 int oldLength=oldtext.length();
00431 if (keep_formatting) {
00432 if (oldLength) {
00433 ++oldLength;
00434 oldtext.append('\n');
00435 }
00436 } else {
00437 if (oldLength)
00438 ++oldLength;
00439 text=text.simplifyWhiteSpace();
00440 }
00441 QString newtext;
00442 if (keep_formatting)
00443 newtext=oldtext + text;
00444 else {
00445 newtext=oldtext + " " + text;
00446 newtext=newtext.simplifyWhiteSpace();
00447 }
00448 currentText.setData(newtext);
00449 int newLength=text.length();
00450 QDomElement lastformat=currentFormat(paragraph,true);
00451 if (lastformat.attribute("id").isEmpty())
00452 lastformat.setAttribute("id",format_id);
00453 lastformat.setAttribute("pos",QString("%1").arg(oldLength));
00454 lastformat.setAttribute("len",QString("%1").arg(newLength));
00455 }
00456
00457 QString KWDWriter::getText(QDomElement paragraph) {
00458 QDomNode temp=paragraph.elementsByTagName("TEXT").item(0).firstChild();
00459 QDomText currentText=temp.toText();
00460 if (temp.isNull()) { kdWarning(30503) << "no text" << endl; }
00461 return currentText.data();
00462 }
00463
00464
00465 QDomElement KWDWriter::startFormat(QDomElement paragraph) {
00466 if (paragraph.isNull()) { kdWarning(30503) << "startFormat on empty paragraph" << endl; }
00467 QDomElement format=_doc->createElement("FORMAT");
00468 paragraph.elementsByTagName("FORMATS").item(0).appendChild(format);
00469 return format;
00470 }
00471
00472
00473 QDomElement KWDWriter::startFormat(QDomElement paragraph, QDomElement formatToClone) {
00474 QDomElement format=formatToClone.cloneNode().toElement();
00475 if (format.isNull()) { kdWarning(30503) << "startFormat: null format cloned" << endl; }
00476 if (paragraph.isNull()) { kdWarning(30503) << "startFormat on empty paragraph" << endl; }
00477
00478 format.removeAttribute("len");
00479 format.removeAttribute("pos");
00480 format.removeAttribute("id");
00481 for (QDomElement a=format.firstChild().toElement();!a.isNull();a=a.nextSibling().toElement()) {
00482 if (a.tagName() == "ANCHOR") {
00483 format.removeChild(a);
00484 }
00485 }
00486 paragraph.elementsByTagName("FORMATS").item(0).appendChild(format);
00487 return format;
00488 }
00489
00490 QDomElement KWDWriter::currentFormat(QDomElement paragraph, bool start_new_one) {
00491
00492 QDomElement e=paragraph.elementsByTagName("FORMATS").item(0).lastChild().toElement();
00493 if (e.isNull()) {
00494
00495 if (start_new_one) return startFormat(paragraph);
00496 else { kdWarning(30503) << "warning: returning null format" << endl; }
00497 }
00498 if (!e.attribute("len").isNull()) {
00499
00500 if (start_new_one) return startFormat(paragraph,e);
00501 }
00502 return e;
00503 }
00504
00505
00506 void KWDWriter::cleanUpParagraph(QDomElement paragraph) {
00507 QDomElement e=paragraph.elementsByTagName("FORMATS").item(0).toElement();
00508 if (e.isNull()) { kdWarning(30503) << "cleanup : no valid paragraph" << endl; return; }
00509 for (QDomElement k=e.firstChild().toElement();!k.isNull();k=k.nextSibling().toElement()) {
00510 if (k.attribute("len",QString::null).isNull()) {
00511 e.removeChild(k);
00512 cleanUpParagraph(paragraph);
00513 return;
00514 }
00515 }
00516 }
00517
00518
00519 QDomElement KWDWriter::addFrame(QDomElement frameset, QRect rect, int runaround, int copy,
00520 int newFrameBehaviour, int runaroundGap
00521 ) {
00522 QDomElement frame = _doc->createElement("FRAME");
00523 frameset.appendChild(frame);
00524 frame.setAttribute("runaround",runaround);
00525 frame.setAttribute("copy",copy);
00526 frame.setAttribute("newFrameBehaviour",newFrameBehaviour);
00527 frame.setAttribute("runaroundGap",runaroundGap);
00528 addRect(frame,rect);
00529 return frame;
00530 }
00531
00532 QDomElement KWDWriter::docroot() {
00533 return _doc->elementsByTagName("DOC").item(0).toElement();
00534 }
00535
00536 bool KWDWriter::writeDoc() {
00537 QCString str=_doc->toCString();
00538 kdWarning(30503) << str << endl;
00539
00540 if (!_store->open("root")) {
00541 return false;
00542 } else {
00543 _store->write((const char *)str, str.length());
00544 _store->close();
00545 }
00546
00547 if (!_store->open("documentinfo.xml")) {
00548 kdWarning(30503) << "WARNING: unable to write out doc info. continuing anyway" << endl;
00549 } else {
00550 str=_docinfo->toCString();
00551 _store->write((const char *)str, str.length());
00552 _store->close();
00553 }
00554
00555 return true;
00556 }
00557
00558
00559 QDomElement KWDWriter::mainFrameset() {
00560 return _mainFrameset;
00561 }
00562
00563
00564 void KWDWriter::addRect(QDomElement e,QRect rect) {
00565 e.setAttribute("top",_zoomhandler->pixelYToPt( rect.top()));
00566 e.setAttribute("left",_zoomhandler->pixelXToPt(rect.left()));
00567 e.setAttribute("bottom",_zoomhandler->pixelYToPt(rect.bottom()));
00568 e.setAttribute("right",_zoomhandler->pixelXToPt(rect.right()));
00569 }
00570
00571
00572
00573
00574
00575 KWDWriter::~KWDWriter(){
00576 delete(_zoomhandler);
00577 }