filters

khtmlreader.cpp

00001 /***************************************************************************
00002                           khtmlreader.cpp  -  description
00003                              -------------------
00004     begin                : Sun Sep 9 2001
00005     copyright            : (C) 2001 by Frank Dekervel
00006     email                : Frank.Dekervel@student.kuleuven.ac.be
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU lesser General Public License as        *
00013  *   published by                                                          *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 
00019 #include "khtmlreader.h"
00020 
00021 #include "khtmlreader.moc"
00022 #include <kdebug.h>
00023 #include <dom/dom_text.h>
00024 #include <dom/dom2_views.h>
00025 #include <dom/dom_doc.h>
00026 #include <qcolor.h>
00027 #include <dom/dom_element.h>
00028 #include <dom/html_table.h>
00029 #include <khtmlview.h>
00030 #include <qwidget.h>
00031 #include <kapplication.h>
00032 #include <dom/html_misc.h>
00033 #include <qregexp.h>
00034 
00035 KHTMLReader::KHTMLReader(KWDWriter *w)
00036 {
00037     _html=new KHTMLPart();
00038     _writer=w;
00039     _it_worked=false;
00040 }
00041 
00042 // if a troll ever sees this, he can't kill me anyway. (and he should kill dfaure first)
00043 void qt_enter_modal( QWidget *widget );
00044 void qt_leave_modal( QWidget *widget );
00045 
00046 
00047 bool KHTMLReader::filter(KURL url) 
00048 {
00049     kdDebug(30503) << "KHTMLReader::filter" << endl;
00050     QObject::connect(_html,SIGNAL(completed()),this,SLOT(completed()));
00051 
00052     _state.clear();
00053     _list_depth=0;
00054 
00055     _html->view()->resize(600,530);
00056     _html->setAutoloadImages(false);
00057     _html->setJScriptEnabled(false);
00058     _html->setPluginsEnabled(false);
00059     _html->setJavaEnabled(false);
00060     _html->setMetaRefreshEnabled(false);
00061     if (_html->openURL(url) == false) 
00062         {
00063         kdWarning(30503) << "openURL returned false" << endl;
00064         return false;
00065     }
00066 
00067     //FIXME use synchronous IO instead of this hack if possible.
00068     QWidget dummy(0,0,WType_Dialog | WShowModal);
00069     qt_enter_modal(&dummy);
00070     qApp->enter_loop();
00071     qt_leave_modal(&dummy);
00072     return _it_worked;
00073 }
00074 
00075 HTMLReader_state *KHTMLReader::state() 
00076 {
00077     if (_state.count() == 0) 
00078         {
00079         HTMLReader_state *s=new HTMLReader_state;
00080         s->frameset=_writer->mainFrameset();
00081         s->paragraph = _writer->addParagraph(s->frameset);
00082         s->format=_writer->currentFormat(s->paragraph,true);
00083         s->layout=_writer->currentLayout(s->paragraph);
00084         s->in_pre_mode = false;
00085         _state.push(s);
00086     }
00087     return _state.top();
00088 }
00089 
00090 HTMLReader_state *KHTMLReader::pushNewState() 
00091 {
00092         HTMLReader_state *s=new HTMLReader_state;
00093         s->frameset=state()->frameset;
00094         s->paragraph=state()->paragraph;
00095         s->format=state()->format;
00096         s->layout=state()->layout;
00097     s->in_pre_mode=state()->in_pre_mode;
00098         _writer->cleanUpParagraph(s->paragraph);
00099         _state.push(s);
00100         return s;
00101 }
00102 
00103 
00104 void KHTMLReader::popState() 
00105 {
00106         kdDebug(30503) << "Entering popState" << endl;
00107 
00108     HTMLReader_state *s=_state.pop();
00109 
00118     if (s->frameset == state()->frameset)
00119     {
00120         state()->paragraph=s->paragraph;
00121         if ((state()->layout != s->layout)) 
00122                 {
00123                   if (_writer->getText(state()->paragraph).length()!=0) startNewLayout(false,state()->layout);
00124         }
00125         state()->format=_writer->startFormat(state()->paragraph, state()->format);
00126     }
00127     delete(s);
00128 }
00129 
00130 void KHTMLReader::startNewLayout(bool startNewFormat) 
00131 {
00132     QDomElement layout;
00133     startNewLayout(startNewFormat,layout);
00134 }
00135 
00136 void KHTMLReader::startNewLayout(bool startNewFormat, QDomElement layout) 
00137 {
00138         kdDebug() << "entering startNewLayout" << endl;
00139     startNewParagraph(startNewFormat,true);
00140     state()->layout=_writer->setLayout(state()->paragraph,layout);
00141 }
00142 
00143 void KHTMLReader::completed() 
00144 {
00145     kdDebug(30503) << "KHTMLReader::completed" << endl;
00146         qApp->exit_loop();
00147     DOM::Document doc=_html->document(); // FIXME parse <HEAD> too
00148     DOM::NodeList list=doc.getElementsByTagName("body");
00149     DOM::Node docbody=list.item(0);
00150 
00151     if (docbody.isNull()) 
00152         {
00153         kdWarning(30503) << "no <BODY>, giving up" << endl;
00154         _it_worked=false;
00155         return;
00156     }
00157 
00158 
00159     parseNode(docbody); // start here (keyword: main)
00160 
00161     list = doc.getElementsByTagName("head");
00162     DOM::Node dochead=list.item(0);
00163     if (!dochead.isNull())
00164         parse_head(dochead);
00165     else
00166         kdWarning(30503) << "WARNING: no html <HEAD> section" << endl;
00167 
00168     _writer->cleanUpParagraph(state()->paragraph);
00169         _it_worked=_writer->writeDoc();
00170 }
00171 
00172 
00173 void KHTMLReader::parseNode(DOM::Node node) 
00174 {
00175     kdDebug(30503) << "Entering parseNode" << endl;
00176         // check if this is a text node.
00177     DOM::Text t=node;
00178     if (!t.isNull()) 
00179         {
00180        _writer->addText(state()->paragraph,t.data().string(),1,state()->in_pre_mode);
00181        return; // no children anymore...
00182     }
00183 
00184     // is this really needed ? it can't do harm anyway.
00185     state()->format=_writer->currentFormat(state()->paragraph,true);
00186     state()->layout=_writer->currentLayout(state()->paragraph);
00187     pushNewState();
00188 
00189     DOM::Element e=node;
00190 
00191     bool go_recursive=true;
00192 
00193     if (!e.isNull()) 
00194         {
00195                 // get the CSS information
00196                 parseStyle(e);
00197             // get the tag information
00198             go_recursive=parseTag(e);
00199     }
00200     if (go_recursive) 
00201         {
00202         for (DOM::Node q=node.firstChild(); !q.isNull(); q=q.nextSibling()) 
00203                 {
00204             parseNode(q);
00205         }
00206     } 
00207     popState();
00208 }
00209 
00210 void KHTMLReader::parse_head(DOM::Element e) 
00211 {
00212     for (DOM::Element items=e.firstChild();!items.isNull();items=items.nextSibling()) {
00213         if (items.tagName().string().lower() == "title") {
00214             DOM::Text t=items.firstChild();
00215             if (!t.isNull()) {
00216                 _writer->createDocInfo("HTML import filter",t.data().string());
00217             }
00218         }
00219     }
00220 }
00221 
00222 #define _PF(x,a,b,c) { \
00223     if (e.tagName().lower() == #x) \
00224         { \
00225              _writer->formatAttribute(state()->paragraph, #a,#b,#c); \
00226              return true; \
00227         } \
00228     }
00229 
00230 // the state->layout=_writer->setLayout is meant to tell popState something changed in the layout, and a new
00231 // layout should probably be started after closing.
00232 
00233 #define _PL(x,a,b,c) { \
00234         if (e.tagName().lower() == #x) \
00235             { \
00236                 state()->layout=_writer->setLayout(state()->paragraph,state()->layout);\
00237                 if (!(_writer->getText(state()->paragraph).isEmpty())) \
00238                     startNewParagraph(false,false); \
00239                 _writer->layoutAttribute(state()->paragraph, #a,#b,#c); \
00240                 return true; \
00241             } \
00242         }
00243 
00244 
00245 bool KHTMLReader::parseTag(DOM::Element e) 
00246 {
00247   kdDebug(30503) << "Entering parseTag for " << e.tagName().lower() << endl;
00248   if (e.tagName().lower()=="a") { return parse_a(e); }
00249   if (e.tagName().lower()=="p") { return parse_p(e); }
00250   if (e.tagName().lower()=="br") { return parse_br(e); }
00251   if (e.tagName().lower()=="ul") { return parse_ul(e); }
00252   if (e.tagName().lower()=="ol") { return parse_ol(e); }
00253   if (e.tagName().lower()=="hr") { return parse_hr(e); }
00254   if (e.tagName().lower()=="pre") { return parse_pre(e); }
00255   if (e.tagName().lower()=="font") { return parse_font(e); }
00256   if (e.tagName().lower()=="table") { return parse_table(e); }
00257 
00258   // FIXME we can get rid of these, make things tons more simple
00259   // when khtml finally implements getComputedStyle
00260   _PF(b,WEIGHT,value,75);
00261   _PF(strong,WEIGHT,value,75);
00262   _PF(u,UNDERLINE,value,1);
00263   _PF(i,ITALIC,value,1);
00264 
00265   _PL(center,FLOW,align,center);
00266   _PL(right,FLOW,align,right);
00267   _PL(left,FLOW,align,left);
00268 
00269   _PL(h1,NAME,value,h1);
00270   _PL(h2,NAME,value,h2);
00271   _PL(h3,NAME,value,h3);
00272   _PL(h4,NAME,value,h4);
00273   _PL(h5,NAME,value,h5);
00274   _PL(h6,NAME,value,h6);
00275   kdDebug(30503) << "Leaving parseTag" << endl;
00276 
00277   // Don't handle the content of comment- or script-nodes.
00278   if(e.nodeType() == DOM::Node::COMMENT_NODE || e.tagName().lower() == "script") 
00279   {
00280     return false;
00281   }
00282 
00283   return true;
00284 }
00285 
00286 void KHTMLReader::startNewParagraph(bool startnewformat, bool startnewlayout) 
00287 {
00288         kdDebug() << "Entering startNewParagraph" << endl;
00289 
00290     QDomElement qf=state()->format;
00291     QDomElement ql=state()->layout;
00292 
00293     _writer->cleanUpParagraph(state()->paragraph);
00294 
00295         if ((startnewlayout==true) || ql.isNull())
00296             {state()->paragraph=_writer->addParagraph(state()->frameset);}
00297         else
00298             {state()->paragraph=
00299                 _writer->addParagraph(state()->frameset,state()->layout);}
00300 
00301 
00302 
00303         if (qf.isNull() || (startnewformat==true)) 
00304         {
00305             state()->format=_writer->startFormat(state()->paragraph/*,state()->format*/);
00306     }  
00307         else 
00308         {
00309         state()->format=_writer->startFormat(state()->paragraph,qf);
00310     }
00311 
00317     QString ct=_writer->getLayoutAttribute(state()->paragraph,"COUNTER","type");
00318     if ((!ct.isNull()) && (ct != "0")) 
00319         {
00320         _writer->layoutAttribute(state()->paragraph,"COUNTER","type","0");
00321         _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","0");
00322         _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext","");
00323         int currdepth=(_writer->getLayoutAttribute(state()->paragraph,"COUNTER","depth")).toInt();
00324         _writer->layoutAttribute(state()->paragraph,"COUNTER","depth",QString("%1").arg(currdepth+1));
00325     }
00326 }
00327 
00328 KHTMLReader::~KHTMLReader(){
00329     delete _html;
00330 }
00331 
00332 
00333 
00334 
00335 
00336 
00337 //==============================================================
00338 //                          tag parsing
00339 //==============================================================
00340 
00341 
00342 bool KHTMLReader::parse_CommonAttributes(DOM::Element e) 
00343 {
00344   kdDebug(30503) << "entering KHTMLReader::parse_CommonAttributes" << endl;
00345   kdDebug(30503) << "tagName is " << e.tagName().string() << endl;
00346   QString s=e.getAttribute("align").string();
00347   if (!s.isEmpty()) 
00348   {
00349     _writer->formatAttribute(state()->paragraph,"FLOW","align",s);
00350   }
00351   QRegExp rx( "h[0-9]+" );
00352   if ( 0 == rx.search( e.getAttribute("class").string() ) )
00353   // example: <p class="h1" style="text-align:left; ">
00354   {
00355     kdDebug(30503) << "laying out with " << e.getAttribute("class").string() << endl;
00356     _writer->layoutAttribute(state()->paragraph,"NAME","value",e.getAttribute("class").string());
00357   }
00358   if ( e.getAttribute("class").string()=="Standard" )
00359   {
00360     kdDebug(30503) << "laying out with " << e.getAttribute("class").string() << endl;
00361     _writer->layoutAttribute(state()->paragraph,"NAME","value",e.getAttribute("class").string());
00362   }  
00363   kdDebug(30503) << "leaving parse_CommonAttributes" << endl;
00364   return true;
00365 }
00366 
00367 bool KHTMLReader::parse_a(DOM::Element e) {
00368         QString url = e.getAttribute("href").string();
00369         if (!url.isEmpty()) 
00370         {
00371         QString linkName;
00372         DOM::Text t = e.firstChild();
00373         if (t.isNull()) {
00374             /* Link without text -> just drop it*/
00375             return false; /* stop parsing recursively */
00376         }
00377         linkName = t.data().string().simplifyWhiteSpace();
00378         t.setData(DOM::DOMString("#")); // replace with '#'
00379         _writer->createLink(state()->paragraph, linkName, url);
00380         }
00381     return true; /* stop parsing recursively */
00382 }
00383 
00384 bool KHTMLReader::parse_p(DOM::Element e) 
00385 {
00386         // For every starting paragraph, a line break has to be inserted.
00387         // exception: the first paragraph, e.g. if the <body> starts with a <p>.
00388         kdDebug() << "entering parse_p" << endl;
00389         if (!(_writer->getText(state()->paragraph).isEmpty())) 
00390           startNewParagraph(false,false); 
00391     parse_CommonAttributes(e);
00392         kdDebug() << "leaving parse_p" << endl;
00393     return true;
00394 }
00395 
00396 bool KHTMLReader::parse_hr(DOM::Element /*e*/) 
00397 {
00398     startNewParagraph();
00399     _writer->createHR(state()->paragraph);
00400     startNewParagraph();
00401     return true;
00402 }
00403 
00404 bool KHTMLReader::parse_br(DOM::Element /*e*/) 
00405 {
00406     startNewParagraph(false,false); //keep the current format and layout
00407     return false; // a BR tag has no childs.
00408 }
00409 
00410 static const QColor parsecolor(const QString& colorstring) 
00411 {
00412       QColor color;
00413       if (colorstring[0]=='#') 
00414       {
00415             color.setRgb(
00416             colorstring.mid(1,2).toInt(0,16),
00417             colorstring.mid(3,2).toInt(0,16),
00418             colorstring.mid(5,2).toInt(0,16)
00419             );
00420       } 
00421       else 
00422       {
00423             QString colorlower=colorstring.lower();
00424             // Grays
00425             if (colorlower=="black")
00426                   color.setRgb(0,0,0);
00427             else if (colorlower=="white")
00428                   color.setRgb(255,255,255);
00429             else if (colorlower=="silver")
00430                   color.setRgb(0xc0,0xc0,0xc0);
00431             else if (colorlower=="gray")
00432                   color.setRgb(128,128,128);
00433             // "full" colors
00434             else if (colorlower=="red")
00435                   color.setRgb(255,0,0);
00436             else if (colorlower=="lime")
00437                   color.setRgb(0,255,0);
00438             else if (colorlower=="blue")
00439                   color.setRgb(0,0,255);
00440             else if (colorlower=="yellow")
00441                   color.setRgb(255,255,0);
00442             else if (colorlower=="fuchsia")
00443                   color.setRgb(255,0,255);
00444             else if (colorlower=="aqua")
00445                   color.setRgb(0,255,255);
00446             // "half" colors
00447             else if (colorlower=="maroon")
00448                   color.setRgb(128,0,0);
00449             else if (colorlower=="green")
00450                   color.setRgb(0,128,0);
00451             else if (colorlower=="navy")
00452                   color.setRgb(0,0,128);
00453             else if (colorlower=="olive")
00454                   color.setRgb(128,128,0);
00455             else if (colorlower=="purple")
00456                   color.setRgb(128,0,128);
00457             else if (colorlower=="teal")
00458                   color.setRgb(0,128,128);
00459             else 
00460             {
00461                   // H'm, we have still not found the color!
00462                   // Let us see if QT can do better!
00463                   color.setNamedColor(colorstring);
00464             }
00465       }
00466       return colorstring;
00467 }
00468 
00469 void KHTMLReader::parseStyle(DOM::Element e) 
00470 {
00471   // styles are broken broken broken broken broken broken.
00472   //FIXME: wait until getComputedStyle is more than
00473   // 'return 0' in khtml
00474   kdDebug(30503) << "entering parseStyle" << endl;
00475   DOM::CSSStyleDeclaration s1=e.style();
00476   DOM::Document doc=_html->document();
00477   DOM::CSSStyleDeclaration s2=doc.defaultView().getComputedStyle(e,"");
00478   kdDebug(30503) << "font-weight=" << s1.getPropertyValue("font-weight").string() << endl;
00479   if ( s1.getPropertyValue("font-weight").string() == "bolder" )
00480   {
00481     _writer->formatAttribute(state()->paragraph,"WEIGHT","value","75");
00482   }
00483   if ( s1.getPropertyValue("font-weight").string() == "bold" )
00484   {
00485     _writer->formatAttribute(state()->paragraph,"WEIGHT","value","75");
00486   }
00487      
00488   // process e.g. <style="color: #ffffff">
00489     if ( s1.getPropertyValue("color").string() != QString() )
00490     {
00491       QColor c=parsecolor(s1.getPropertyValue("color").string());
00492       _writer->formatAttribute(state()->paragraph,"COLOR","red",QString::number(c.red()));
00493       _writer->formatAttribute(state()->paragraph,"COLOR","green",QString::number(c.green()));
00494       _writer->formatAttribute(state()->paragraph,"COLOR","blue",QString::number(c.blue()));
00495     }
00496   // done
00497   // process e.g. <style="font-size: 42">
00498     if ( s1.getPropertyValue("font-size").string() != QString() )
00499     {
00500       QString size=s1.getPropertyValue("font-size").string();
00501       if (size.endsWith("pt"))
00502       {
00503         size=size.left(size.length()-2);
00504       }
00505       _writer->formatAttribute(state()->paragraph,"SIZE","value",size);
00506     }
00507   // done
00508   // process e.g. <style="text-align: center">this is in the center</style>
00509     if ( s1.getPropertyValue("text-align").string() != QString() && s1.getPropertyValue("text-align").string() != QString("left") )
00510     {
00511       state()->layout=_writer->setLayout(state()->paragraph,state()->layout);
00512       _writer->layoutAttribute(state()->paragraph, "FLOW","align",s1.getPropertyValue("text-align").string());
00513     }
00514   // done
00515 
00516      /*if (DOM::PROPV("font-weight") == "bolder")
00517     _writer->formatAttribute(state()->paragraph,"WEIGHT","value","75");
00518      */
00519 /*
00520      // debugging code.
00521      kdDebug(30503) << "e.style()" << endl;
00522      for (unsigned int i=0;i<s1.length();i++) {
00523         kdDebug(30503) << QString("%1: %2").arg(s1.item(i).string()).arg(s1.getPropertyValue(s1.item(i)).string()) << endl;
00524      }
00525      kdDebug(30503) << "override style" << endl;
00526      for (unsigned int i=0;i<s2.length();i++) {
00527         kdDebug(30503) << QString("%1: %2").arg(s2.item(i).string()).arg(s2.getPropertyValue(s2.item(i)).string()) << endl;
00528      }
00529 */
00530 }
00531 
00532 bool KHTMLReader::parse_table(DOM::Element e) 
00533 {
00534     if(_writer->isInTable()) {
00535         // We are already inside of a table. Tables in tables are not supported
00536         // yet. So, just add that table-content as text.
00537         for (DOM::Node rows=e.firstChild().firstChild();!rows.isNull();rows=rows.nextSibling())
00538             if (!rows.isNull() && rows.nodeName().string().lower() == "tr")
00539                 for (DOM::Node cols=rows.firstChild();!cols.isNull();cols=cols.nextSibling())
00540                     if (!cols.isNull())
00541                         parseNode(cols);
00542         return false;
00543     }
00544 
00545     DOM::Element table_body=e.firstChild();
00546     if(table_body.isNull()) {
00547         // If the table_body is empty, we don't continue cause else
00548         // KHTML will throw a DOM::DOMException if we try to access
00549         // the null element.
00550         return true;
00551     }
00552 
00553     int tableno=_writer->createTable();
00554     int nrow=0;
00555     int ncol=0;
00556     bool has_borders=false;
00557     QColor bgcolor=parsecolor("#FFFFFF");
00558 
00559     if (!table_body.getAttribute("bgcolor").string().isEmpty())
00560            bgcolor=parsecolor(table_body.getAttribute("bgcolor").string());
00561     if ((e.getAttribute("border").string().toInt() > 0))
00562         has_borders=true;
00563 
00564     // fixme rewrite this proper
00565     //(maybe using computed sizes from khtml if thats once exported)
00566     for (DOM::Node rowsnode=table_body.firstChild();!rowsnode.isNull();rowsnode=rowsnode.nextSibling()) {
00567     DOM::Element rows = rowsnode;
00568     if (!rows.isNull() && rows.tagName().string().lower() == "tr") {
00569         QColor obgcolor=bgcolor;
00570         if (!rows.getAttribute("bgcolor").string().isEmpty())
00571             bgcolor=parsecolor(rows.getAttribute("bgcolor").string());
00572 
00573         ncol=0;
00574         for (DOM::Node colsnode=rows.firstChild();!colsnode.isNull();colsnode=colsnode.nextSibling()) {
00575                 DOM::Element cols = colsnode;
00576                         const QString nodename = cols.isNull() ? QString::null : cols.nodeName().string().lower();
00577                 if (nodename == "td" || nodename == "th") {
00578                      QColor bbgcolor=bgcolor;
00579                 if (!cols.getAttribute("bgcolor").string().isEmpty())
00580                     bgcolor=parsecolor(cols.getAttribute("bgcolor").string());
00581 
00582                     pushNewState();
00583                         QRect colrect=cols.getRect();
00584                         state()->frameset=_writer->createTableCell(tableno,nrow,ncol,1,colrect);
00585                         state()->frameset.firstChild().toElement().setAttribute("bkRed",bgcolor.red());
00586                         state()->frameset.firstChild().toElement().setAttribute("bkGreen",bgcolor.green());
00587                         state()->frameset.firstChild().toElement().setAttribute("bkBlue",bgcolor.blue());
00588                         if (has_borders) {
00589                             state()->frameset.firstChild().toElement().setAttribute("lWidth",1);
00590                             state()->frameset.firstChild().toElement().setAttribute("rWidth",1);
00591                             state()->frameset.firstChild().toElement().setAttribute("bWidth",1);
00592                             state()->frameset.firstChild().toElement().setAttribute("tWidth",1);
00593                         }
00594 
00595                 // fixme don't guess. get it right.
00596                         state()->paragraph=_writer->addParagraph(state()->frameset);
00597                         parseNode(cols);
00598                 _writer->cleanUpParagraph(state()->paragraph);
00599                     popState();
00600                 ncol++;
00601                 bgcolor=bbgcolor;
00602             }
00603         }
00604         nrow++;
00605         bgcolor=obgcolor;
00606           }
00607     }
00608     _writer->finishTable(tableno/*,0,0,r.right()-r.left(),r.bottom()-r.top()*/); // FIXME find something better.
00609     startNewParagraph(false,false);
00610     _writer->createInline(state()->paragraph,_writer->fetchTableCell(tableno,0,0));
00611     startNewParagraph(false,false);
00612     return false; // we do our own recursion
00613 }
00614 
00615 bool KHTMLReader::parse_img(DOM::Element /*e*/) 
00616 {
00617         //QRect e=e.getRect();
00618     return true;
00619 }
00620 
00621 bool KHTMLReader::parse_pre(DOM::Element e) 
00622 {
00623 #if 0 // see Bug #74601 (normal): kword doesn't recognize PRE-tags in HTML
00624     //pushNewState();
00626     DOM::HTMLElement htmlelement(e);
00627     if(! htmlelement.isNull())
00628         _writer->addText(state()->paragraph,htmlelement.innerHTML().string(),1);
00629     startNewParagraph();
00630     //popState();
00631     return false; // children are already handled.
00632 #else
00633     pushNewState();
00634     state()->in_pre_mode=true;
00635         QString face=e.getAttribute("face").string();
00636         _writer->formatAttribute(state()->paragraph,"FONT","name",QString("Courier"));
00637     for (DOM::Node q=e.firstChild(); !q.isNull(); q=q.nextSibling()) 
00638         {
00639         parseNode(q); // parse everything...
00640     }
00641     popState();
00642         _writer->formatAttribute(state()->paragraph,"FONT","name",face);
00643     return false; // children are already handled.
00644 #endif
00645 }
00646 
00647 bool KHTMLReader::parse_ol(DOM::Element e) 
00648 {
00649   return parse_ul(e);
00650 }
00651 
00652 bool KHTMLReader::parse_font(DOM::Element e) 
00653 {
00654   kdDebug(30503) << "Entering parse_font" << endl;
00655   // fixme don't hardcode 12 font size ...
00656   QString face=e.getAttribute("face").string();
00657   QColor color=parsecolor("#000000");
00658   if (!e.getAttribute("color").string().isEmpty())
00659     color=parsecolor(e.getAttribute("color").string());
00660   QString size=e.getAttribute("size").string();
00661   int isize=-1;
00662   if (size.startsWith("+"))
00663     isize=12+size.right(size.length()-1).toInt();
00664   else if (size.startsWith("-"))
00665     isize=12-size.right(size.length()-1).toInt();
00666   else
00667     isize=12+size.toInt();
00668 
00669   _writer->formatAttribute(state()->paragraph,"FONT","name",face);
00670   if ((isize>=0) && (isize != 12))
00671     _writer->formatAttribute(state()->paragraph,"SIZE","value",QString("%1").arg(isize));
00672 
00673   _writer->formatAttribute(state()->paragraph,"COLOR","red",QString("%1").arg(color.red()));
00674   _writer->formatAttribute(state()->paragraph,"COLOR","green",QString("%1").arg(color.green()));
00675   _writer->formatAttribute(state()->paragraph,"COLOR","blue",QString("%1").arg(color.blue()));
00676   return true;
00677 }
00678 
00679 bool KHTMLReader::parse_ul(DOM::Element e) 
00680 {
00681 // Parse the tag ul and all its subnodes. Take special care for the li tag.
00682   kdDebug(30503) << "Entering KHTMLReader::parse_ul" << endl;
00683   kdDebug(30503) << "_writer->getText(state()->paragraph)=" << _writer->getText(state()->paragraph) << endl;
00684   _list_depth++;
00685   if (e.firstChild().nodeName().string().lower() == "#text")  // e.g. <ul>this is indented<li>first listitem</li></ul>
00686   {
00687     _writer->layoutAttribute(state()->paragraph,"COUNTER","depth",QString("%1").arg(_list_depth-1)); // indent
00688     startNewLayout();
00689   }
00690   for (DOM::Node items=e.firstChild();!items.isNull();items=items.nextSibling()) 
00691   {
00692     if (items.nodeName().string().lower() == "li") 
00693     {
00694       if (!(_writer->getText(state()->paragraph).isEmpty())) startNewLayout();
00695       _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","1");
00696       _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext",".");
00697       if (e.tagName().string().lower() == "ol")
00698       {
00699     _writer->layoutAttribute(state()->paragraph,"COUNTER","type","1");
00700     _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","1");
00701         _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext",".");
00702       }
00703       else
00704       {
00705     _writer->layoutAttribute(state()->paragraph,"COUNTER","type","10");
00706     _writer->layoutAttribute(state()->paragraph,"COUNTER","numberingtype","");
00707         _writer->layoutAttribute(state()->paragraph,"COUNTER","righttext","");
00708       }
00709       _writer->layoutAttribute(state()->paragraph,"COUNTER","depth",QString("%1").arg(_list_depth-1)); // indent
00710     }
00711     parseNode(items);
00712   }
00713   _list_depth--;
00714   kdDebug(30503) << "Leaving KHTMLReader::parse_ul" << endl;
00715   return false;
00716 }
00717 
KDE Home | KDE Accessibility Home | Description of Access Keys