rtfdocvisitor.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: $
00004  *
00005  *
00006  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00007  *
00008  * Permission to use, copy, modify, and distribute this software and its
00009  * documentation under the terms of the GNU General Public License is hereby 
00010  * granted. No representations are made about the suitability of this software 
00011  * for any purpose. It is provided "as is" without express or implied warranty.
00012  * See the GNU General Public License for more details.
00013  *
00014  * Documents produced by Doxygen are derivative works derived from the
00015  * input used in their production; they are not affected by this license.
00016  *
00017  */
00018 
00019 #include "rtfdocvisitor.h"
00020 #include "docparser.h"
00021 #include "language.h"
00022 #include "doxygen.h"
00023 #include "outputgen.h"
00024 #include "dot.h"
00025 #include "util.h"
00026 #include "rtfstyle.h"
00027 #include "message.h"
00028 #include <qfileinfo.h> 
00029 #include "parserintf.h"
00030 #include "msc.h"
00031 
00032 
00033 //#define DBG_RTF(x) m_t << x
00034 #define DBG_RTF(x) do {} while(0)
00035 
00036 RTFDocVisitor::RTFDocVisitor(QTextStream &t,CodeOutputInterface &ci,
00037                              const char *langExt) 
00038   : DocVisitor(DocVisitor_RTF), m_t(t), m_ci(ci), m_insidePre(FALSE), 
00039     m_hide(FALSE), m_indentLevel(0), m_lastIsPara(FALSE), m_langExt(langExt)
00040 {
00041 }
00042 
00043 QString RTFDocVisitor::getStyle(const char *name)
00044 {
00045   QString n;
00046   n.sprintf("%s%d",name,m_indentLevel);
00047   StyleData *sd = rtf_Style[n];
00048   ASSERT(sd!=0);
00049   return sd->reference;
00050 }
00051 
00052 void RTFDocVisitor::incIndentLevel()
00053 {
00054   if (m_indentLevel<rtf_maxIndentLevels-1) m_indentLevel++;
00055 }
00056 
00057 void RTFDocVisitor::decIndentLevel()
00058 {
00059   if (m_indentLevel>0) m_indentLevel--;
00060 }
00061 
00062   //--------------------------------------
00063   // visitor functions for leaf nodes
00064   //--------------------------------------
00065 
00066 void RTFDocVisitor::visit(DocWord *w)
00067 {
00068   if (m_hide) return;
00069   DBG_RTF("{\\comment RTFDocVisitor::visit(DocWord)}\n");
00070   filter(w->word());
00071   m_lastIsPara=FALSE;
00072 }
00073 
00074 void RTFDocVisitor::visit(DocLinkedWord *w)
00075 {
00076   if (m_hide) return;
00077   DBG_RTF("{\\comment RTFDocVisitor::visit(DocLinkedWord)}\n");
00078   startLink(w->ref(),w->file(),w->anchor());
00079   filter(w->word());
00080   endLink(w->ref());
00081   m_lastIsPara=FALSE;
00082 }
00083 
00084 void RTFDocVisitor::visit(DocWhiteSpace *w)
00085 {
00086   if (m_hide) return;
00087   DBG_RTF("{\\comment RTFDocVisitor::visit(DocWhiteSpace)}\n");
00088   if (m_insidePre)
00089   {
00090     m_t << w->chars();
00091   }
00092   else
00093   {
00094     m_t << " ";
00095   }
00096   m_lastIsPara=FALSE;
00097 }
00098 
00099 void RTFDocVisitor::visit(DocSymbol *s)
00100 {
00101   if (m_hide) return;
00102   DBG_RTF("{\\comment RTFDocVisitor::visit(DocSymbol)}\n");
00103   switch(s->symbol())
00104   {
00105     case DocSymbol::BSlash:  m_t << "\\\\"; break;
00106     case DocSymbol::At:      m_t << "@"; break;
00107     case DocSymbol::Less:    m_t << "<"; break;
00108     case DocSymbol::Greater: m_t << ">"; break;
00109     case DocSymbol::Amp:     m_t << "&"; break;
00110     case DocSymbol::Dollar:  m_t << "$"; break;
00111     case DocSymbol::Hash:    m_t << "#"; break;
00112     case DocSymbol::Percent: m_t << "%"; break;
00113     case DocSymbol::Copy:    m_t << "(C)"; break;
00114     case DocSymbol::Tm:      m_t << "(TM)"; break;
00115     case DocSymbol::Reg:     m_t << "(R)"; break;
00116     case DocSymbol::Apos:    m_t << "'"; break;
00117     case DocSymbol::Quot:    m_t << "\""; break;
00118     case DocSymbol::Lsquo:   m_t << "`"; break;
00119     case DocSymbol::Rsquo:   m_t << "'"; break;
00120     case DocSymbol::Ldquo:   m_t << "\""; break;
00121     case DocSymbol::Rdquo:   m_t << "\""; break;
00122     case DocSymbol::Ndash:   m_t << "-"; break;
00123     case DocSymbol::Mdash:   m_t << "--"; break;
00124     case DocSymbol::Uml:     switch(s->letter())
00125                              {
00126                                case 'A' : m_t << '\304'; break;
00127                                case 'E' : m_t << '\313'; break;
00128                                case 'I' : m_t << '\317'; break;
00129                                case 'O' : m_t << '\326'; break;
00130                                case 'U' : m_t << '\334'; break;
00131                                case 'Y' : m_t << 'Y';    break;
00132                                case 'a' : m_t << '\344'; break;
00133                                case 'e' : m_t << '\353'; break;
00134                                case 'i' : m_t << '\357'; break;
00135                                case 'o' : m_t << '\366'; break;
00136                                case 'u' : m_t << '\374'; break;
00137                                case 'y' : m_t << '\377'; break;
00138                                default: m_t << '?'; break;
00139                              }
00140                              break;
00141     case DocSymbol::Acute:   switch(s->letter())
00142                              {
00143                                case 'A' : m_t << '\301'; break;
00144                                case 'E' : m_t << '\311'; break;
00145                                case 'I' : m_t << '\315'; break;
00146                                case 'O' : m_t << '\323'; break;
00147                                case 'U' : m_t << '\332'; break;
00148                                case 'Y' : m_t << '\335'; break;
00149                                case 'a' : m_t << '\341'; break;
00150                                case 'e' : m_t << '\351'; break;
00151                                case 'i' : m_t << '\355'; break;
00152                                case 'o' : m_t << '\363'; break;
00153                                case 'u' : m_t << '\372'; break;
00154                                case 'y' : m_t << '\375'; break;
00155                                default: m_t << '?'; break;
00156                              }
00157                              break;
00158     case DocSymbol::Grave:   switch(s->letter())
00159                              {
00160                                case 'A' : m_t << '\300'; break;
00161                                case 'E' : m_t << '\310'; break;
00162                                case 'I' : m_t << '\314'; break;
00163                                case 'O' : m_t << '\322'; break;
00164                                case 'U' : m_t << '\331'; break;
00165                                case 'a' : m_t << '\340'; break;
00166                                case 'e' : m_t << '\350'; break;
00167                                case 'i' : m_t << '\354'; break;
00168                                case 'o' : m_t << '\362'; break;
00169                                case 'u' : m_t << '\371'; break;
00170                                default: m_t << '?'; break;
00171                              }
00172                              break;
00173     case DocSymbol::Circ:    switch(s->letter())
00174                              {
00175                                case 'A' : m_t << '\302'; break;
00176                                case 'E' : m_t << '\312'; break;
00177                                case 'I' : m_t << '\316'; break;
00178                                case 'O' : m_t << '\324'; break;
00179                                case 'U' : m_t << '\333'; break;
00180                                case 'a' : m_t << '\342'; break;
00181                                case 'e' : m_t << '\352'; break;
00182                                case 'i' : m_t << '\356'; break;
00183                                case 'o' : m_t << '\364'; break;
00184                                case 'u' : m_t << '\373'; break;
00185                                default: m_t << '?'; break;
00186                              }
00187                              break;
00188     case DocSymbol::Tilde:   switch(s->letter())
00189                              {
00190                                case 'A' : m_t << '\303'; break;
00191                                case 'N' : m_t << '\321'; break;
00192                                case 'O' : m_t << '\325'; break;
00193                                case 'a' : m_t << '\343'; break;
00194                                case 'n' : m_t << '\361'; break;
00195                                case 'o' : m_t << '\365'; break;
00196                                default: m_t << '?'; break;
00197                              }
00198                              break;
00199     case DocSymbol::Cedil:   switch(s->letter())
00200                              {
00201                                case 'C' : m_t << '\307'; break;
00202                                case 'c' : m_t << '\347'; break;
00203                                default: m_t << '?'; break;
00204                              }
00205                              break;
00206     case DocSymbol::Slash:   switch(s->letter())
00207                              {
00208                                case 'O' : m_t << '\330'; break;
00209                                case 'o' : m_t << '\370'; break;
00210                                default: m_t << '?'; break;
00211                              }
00212                              break;
00213     case DocSymbol::Ring:    switch(s->letter())
00214                              {
00215                                case 'A' : m_t << '\305'; break;
00216                                case 'a' : m_t << '\345'; break;
00217                                default: m_t << '?'; break;
00218                              }
00219                              break;
00220     case DocSymbol::Szlig:   m_t << "\337"; break;
00221     case DocSymbol::Nbsp:    m_t << "\\~ "; break;
00222     default:
00223                              err("Error: unknown symbol found\n");
00224   }
00225   m_lastIsPara=FALSE;
00226 }
00227 
00228 void RTFDocVisitor::visit(DocURL *u)
00229 {
00230   if (m_hide) return;
00231   DBG_RTF("{\\comment RTFDocVisitor::visit(DocURL)}\n");
00232   if (Config_getBool("RTF_HYPERLINKS"))
00233   {
00234     m_t << "{\\field "
00235              "{\\*\\fldinst "
00236                "{ HYPERLINK  \\\\l \"";
00237     if (u->isEmail()) m_t << "mailto:";
00238     m_t << u->url();
00239     m_t <<  "\" }"
00240                "{}";
00241     m_t <<   "}"
00242              "{\\fldrslt "
00243                "{\\cs37\\ul\\cf2 ";
00244     filter(u->url());
00245     m_t <<     "}"
00246              "}"
00247            "}" << endl;
00248   }
00249   else
00250   {
00251     m_t << "{\\f2 ";
00252     filter(u->url());
00253     m_t << "}";
00254   }
00255   m_lastIsPara=FALSE;
00256 }
00257 
00258 void RTFDocVisitor::visit(DocLineBreak *)
00259 {
00260   if (m_hide) return;
00261   DBG_RTF("{\\comment RTFDocVisitor::visit(DocLineBreak)}\n");
00262   m_t << "\\par";
00263   m_lastIsPara=TRUE;
00264 }
00265 
00266 void RTFDocVisitor::visit(DocHorRuler *)
00267 {
00268   if (m_hide) return;
00269   DBG_RTF("{\\comment RTFDocVisitor::visit(DocHorRuler)}\n");
00270   m_t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl;
00271   m_lastIsPara=TRUE;
00272 }
00273 
00274 void RTFDocVisitor::visit(DocStyleChange *s)
00275 {
00276   if (m_hide) return;
00277   m_lastIsPara=FALSE;
00278   DBG_RTF("{\\comment RTFDocVisitor::visit(DocStyleChange)}\n");
00279   switch (s->style())
00280   {
00281     case DocStyleChange::Bold:
00282       if (s->enable()) m_t << "{\\b ";      else m_t << "} ";
00283       break;
00284     case DocStyleChange::Italic:
00285       if (s->enable()) m_t << "{\\i ";     else m_t << "} ";
00286       break;
00287     case DocStyleChange::Code:
00288       if (s->enable()) m_t << "{\\f2 ";   else m_t << "} ";
00289       break;
00290     case DocStyleChange::Subscript:
00291       if (s->enable()) m_t << "{\\sub ";    else m_t << "} ";
00292       break;
00293     case DocStyleChange::Superscript:
00294       if (s->enable()) m_t << "{\\super ";    else m_t << "} ";
00295       break;
00296     case DocStyleChange::Center:
00297       if (s->enable()) m_t << "{\\qc "; else m_t << "} ";
00298       break;
00299     case DocStyleChange::Small:
00300       if (s->enable()) m_t << "{\\sub ";  else m_t << "} ";
00301       break;
00302     case DocStyleChange::Preformatted:
00303       if (s->enable())
00304       {
00305         m_t << "{" << endl;
00306         m_t << "\\par" << endl;
00307         m_t << rtf_Style_Reset << getStyle("CodeExample");
00308         m_insidePre=TRUE;
00309       }
00310       else
00311       {
00312         m_insidePre=FALSE;
00313         m_t << "\\par";
00314         m_t << "}" << endl;
00315       }
00316       m_lastIsPara=TRUE;
00317       break;
00318     case DocStyleChange::Div:  /* HTML only */ break;
00319     case DocStyleChange::Span: /* HTML only */ break;
00320   }
00321 }
00322 
00323 void RTFDocVisitor::visit(DocVerbatim *s)
00324 {
00325   if (m_hide) return;
00326   DBG_RTF("{\\comment RTFDocVisitor::visit(DocVerbatim)}\n");
00327   switch(s->type())
00328   {
00329     case DocVerbatim::Code: // fall though
00330       m_t << "{" << endl;
00331       m_t << "\\par" << endl;
00332       m_t << rtf_Style_Reset << getStyle("CodeExample");
00333       Doxygen::parserManager->getParser(m_langExt)
00334                             ->parseCode(m_ci,s->context(),s->text().latin1(),
00335                                         s->isExample(),s->exampleFile());
00336       //m_t << "\\par" << endl; 
00337       m_t << "}" << endl;
00338       break;
00339     case DocVerbatim::Verbatim: 
00340       m_t << "{" << endl;
00341       m_t << "\\par" << endl;
00342       m_t << rtf_Style_Reset << getStyle("CodeExample");
00343       filter(s->text(),TRUE);
00344       //m_t << "\\par" << endl; 
00345       m_t << "}" << endl;
00346       break;
00347     case DocVerbatim::HtmlOnly: 
00348     case DocVerbatim::LatexOnly: 
00349     case DocVerbatim::XmlOnly: 
00350     case DocVerbatim::ManOnly: 
00351       /* nothing */
00352       break;
00353     case DocVerbatim::Dot: 
00354       {
00355         static int dotindex = 1;
00356         QCString fileName(4096);
00357 
00358         fileName.sprintf("%s%d%s", 
00359             (Config_getString("RTF_OUTPUT")+"/inline_dotgraph_").data(), 
00360             dotindex++,
00361             ".dot"
00362            );
00363         QFile file(fileName);
00364         if (!file.open(IO_WriteOnly))
00365         {
00366           err("Could not open file %s for writing\n",fileName.data());
00367         }
00368         file.writeBlock( s->text(), s->text().length() );
00369         file.close();
00370         m_t << "\\par{\\qc "; // center picture
00371         writeDotFile(fileName);
00372         m_t << "} ";
00373         if (Config_getBool("DOT_CLEANUP")) file.remove();
00374       }
00375       break;
00376     case DocVerbatim::Msc: 
00377       {
00378         static int mscindex = 1;
00379         QCString baseName(4096);
00380 
00381         baseName.sprintf("%s%d", 
00382             (Config_getString("RTF_OUTPUT")+"/inline_mscgraph_").data(), 
00383             mscindex++
00384            );
00385         QFile file(baseName+".msc");
00386         if (!file.open(IO_WriteOnly))
00387         {
00388           err("Could not open file %s for writing\n",baseName.data());
00389         }
00390         QCString text = "msc {";
00391         text+=s->text();
00392         text+="}";
00393         file.writeBlock( text, text.length() );
00394         file.close();
00395         m_t << "\\par{\\qc "; // center picture
00396         writeMscFile(baseName);
00397         m_t << "} ";
00398         if (Config_getBool("DOT_CLEANUP")) file.remove();
00399       }
00400       break;
00401   }
00402   m_lastIsPara=FALSE;
00403 }
00404 
00405 void RTFDocVisitor::visit(DocAnchor *anc)
00406 {
00407   if (m_hide) return;
00408   DBG_RTF("{\\comment RTFDocVisitor::visit(DocAnchor)}\n");
00409   QString anchor;
00410   if (!anc->file().isEmpty())
00411   {
00412     anchor+=anc->file();
00413   }
00414   if (!anc->file().isEmpty() && !anc->anchor().isEmpty())
00415   {
00416     anchor+="_";
00417   }
00418   if (!anc->anchor().isEmpty())
00419   {
00420     anchor+=anc->anchor();
00421   }
00422   m_t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
00423   m_t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
00424   m_lastIsPara=FALSE;
00425 }
00426 
00427 void RTFDocVisitor::visit(DocInclude *inc)
00428 {
00429   if (m_hide) return;
00430   DBG_RTF("{\\comment RTFDocVisitor::visit(DocInclude)}\n");
00431   switch(inc->type())
00432   {
00433    case DocInclude::IncWithLines:
00434       { 
00435          m_t << "{" << endl;
00436          m_t << "\\par" << endl;
00437          m_t << rtf_Style_Reset << getStyle("CodeExample");
00438          QFileInfo cfi( inc->file() );
00439          FileDef fd( cfi.dirPath(), cfi.fileName() );
00440          Doxygen::parserManager->getParser(inc->extension())
00441                                ->parseCode(m_ci,inc->context(),
00442                                            inc->text().latin1(),
00443                                            inc->isExample(),
00444                                            inc->exampleFile(), &fd);
00445          m_t << "\\par";
00446          m_t << "}" << endl;
00447       }
00448       break;
00449    case DocInclude::Include: 
00450       m_t << "{" << endl;
00451       m_t << "\\par" << endl;
00452       m_t << rtf_Style_Reset << getStyle("CodeExample");
00453       Doxygen::parserManager->getParser(inc->extension())
00454                             ->parseCode(m_ci,inc->context(),
00455                                         inc->text().latin1(),inc->isExample(),
00456                                         inc->exampleFile());
00457       m_t << "\\par";
00458       m_t << "}" << endl;
00459       break;
00460     case DocInclude::DontInclude: 
00461       break;
00462     case DocInclude::HtmlInclude: 
00463       break;
00464     case DocInclude::VerbInclude: 
00465       m_t << "{" << endl;
00466       m_t << "\\par" << endl;
00467       m_t << rtf_Style_Reset << getStyle("CodeExample");
00468       filter(inc->text());
00469       m_t << "\\par";
00470       m_t << "}" << endl;
00471       break;
00472   }
00473   m_lastIsPara=TRUE;
00474 }
00475 
00476 void RTFDocVisitor::visit(DocIncOperator *op)
00477 {
00478   //printf("DocIncOperator: type=%d first=%d, last=%d text=`%s'\n",
00479   //    op->type(),op->isFirst(),op->isLast(),op->text().data());
00480   DBG_RTF("{\\comment RTFDocVisitor::visit(DocIncOperator)}\n");
00481   if (op->isFirst()) 
00482   {
00483     if (!m_hide)
00484     {
00485       m_t << "{" << endl;
00486       m_t << "\\par" << endl;
00487       m_t << rtf_Style_Reset << getStyle("CodeExample");
00488     }
00489     pushEnabled();
00490     m_hide = TRUE;
00491   }
00492   if (op->type()!=DocIncOperator::Skip) 
00493   {
00494     popEnabled();
00495     if (!m_hide) 
00496     {
00497       Doxygen::parserManager->getParser(m_langExt)
00498                             ->parseCode(m_ci,op->context(),op->text().latin1(),
00499                                         op->isExample(),op->exampleFile());
00500     }
00501     pushEnabled();
00502     m_hide=TRUE;
00503   }
00504   if (op->isLast())  
00505   {
00506     popEnabled();
00507     if (!m_hide)
00508     {
00509       m_t << "\\par";
00510       m_t << "}" << endl;
00511     }
00512     m_lastIsPara=TRUE;
00513   }
00514   else
00515   {
00516     if (!m_hide) m_t << endl;
00517     m_lastIsPara=FALSE;
00518   }
00519 }
00520 
00521 void RTFDocVisitor::visit(DocFormula *f)
00522 {
00523   if (m_hide) return;
00524   // TODO: do something sensible here, like including a bitmap
00525   DBG_RTF("{\\comment RTFDocVisitor::visit(DocFormula)}\n");
00526   m_t << f->text();
00527   m_lastIsPara=FALSE;
00528 }
00529 
00530 void RTFDocVisitor::visit(DocIndexEntry *i)
00531 {
00532   if (m_hide) return;
00533   DBG_RTF("{\\comment RTFDocVisitor::visit(DocIndexEntry)}\n");
00534   m_t << "{\\xe \\v " << i->entry() << "}" << endl;
00535   m_lastIsPara=FALSE;
00536 }
00537 
00538 //--------------------------------------
00539 // visitor functions for compound nodes
00540 //--------------------------------------
00541 
00542 void RTFDocVisitor::visitPre(DocAutoList *l)
00543 {
00544   if (m_hide) return;
00545   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocAutoList)}\n");
00546   m_t << "{" << endl;
00547   rtf_listItemInfo[m_indentLevel].isEnum = l->isEnumList();
00548   rtf_listItemInfo[m_indentLevel].number = 1;
00549   m_lastIsPara=FALSE;
00550 }
00551 
00552 void RTFDocVisitor::visitPost(DocAutoList *)
00553 {
00554   if (m_hide) return;
00555   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoList)}\n");
00556   m_t << "\\par";
00557   m_t << "}" << endl;
00558   m_lastIsPara=TRUE;
00559 }
00560 
00561 void RTFDocVisitor::visitPre(DocAutoListItem *)
00562 {
00563   if (m_hide) return;
00564   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocAutoListItem)}\n");
00565   if (!m_lastIsPara) m_t << "\\par" << endl;
00566   m_t << rtf_Style_Reset;
00567   if (rtf_listItemInfo[m_indentLevel].isEnum)
00568   {
00569     m_t << getStyle("ListEnum") << endl;
00570     m_t << rtf_listItemInfo[m_indentLevel].number << ".\\tab ";
00571     rtf_listItemInfo[m_indentLevel].number++;
00572   }
00573   else
00574   {
00575     m_t << getStyle("ListBullet") << endl;
00576   }
00577   incIndentLevel();
00578   m_lastIsPara=FALSE;
00579 }
00580 
00581 void RTFDocVisitor::visitPost(DocAutoListItem *) 
00582 {
00583   decIndentLevel();
00584   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocAutoListItem)}\n");
00585 }
00586 
00587 void RTFDocVisitor::visitPre(DocPara *) 
00588 {
00589   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n");
00590 }
00591 
00592 void RTFDocVisitor::visitPost(DocPara *p)
00593 {
00594   if (m_hide) return;
00595   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocPara)}\n");
00596   if (!m_lastIsPara &&
00597       !p->isLast() &&            // omit <p> for last paragraph
00598       !(p->parent() &&           // and for parameters & sections
00599         p->parent()->kind()==DocNode::Kind_ParamSect
00600        )
00601      ) 
00602   {
00603     m_t << "\\par" << endl;
00604     m_lastIsPara=TRUE;
00605   }
00606 }
00607 
00608 void RTFDocVisitor::visitPre(DocRoot *r)
00609 {
00610   if (m_hide) return;
00611   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocRoot)}\n");
00612   if (r->indent()) incIndentLevel();
00613   m_t << "{" << rtf_Style["BodyText"]->reference << endl;
00614 }
00615 
00616 void RTFDocVisitor::visitPost(DocRoot *r)
00617 {
00618   if (m_hide) return;
00619   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocRoot)}\n");
00620   if (!m_lastIsPara && !r->singleLine()) m_t << "\\par" << endl;
00621   m_t << "}";
00622   m_lastIsPara=TRUE;
00623   if (r->indent()) decIndentLevel();
00624 }
00625 
00626 void RTFDocVisitor::visitPre(DocSimpleSect *s)
00627 {
00628   if (m_hide) return;
00629   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleSect)}\n");
00630   if (!m_lastIsPara) m_t << "\\par" << endl;
00631   m_t << "{"; // start desc
00632   //m_t << "{\\b "; // start bold
00633   m_t << "{" << rtf_Style["Heading5"]->reference << endl;
00634   switch(s->type())
00635   {
00636     case DocSimpleSect::See: 
00637       m_t << theTranslator->trSeeAlso(); break;
00638     case DocSimpleSect::Return: 
00639       m_t << theTranslator->trReturns(); break;
00640     case DocSimpleSect::Author: 
00641       m_t << theTranslator->trAuthor(TRUE,TRUE); break;
00642     case DocSimpleSect::Authors: 
00643       m_t << theTranslator->trAuthor(TRUE,FALSE); break;
00644     case DocSimpleSect::Version: 
00645       m_t << theTranslator->trVersion(); break;
00646     case DocSimpleSect::Since: 
00647       m_t << theTranslator->trSince(); break;
00648     case DocSimpleSect::Date: 
00649       m_t << theTranslator->trDate(); break;
00650     case DocSimpleSect::Note: 
00651       m_t << theTranslator->trNote(); break;
00652     case DocSimpleSect::Warning:
00653       m_t << theTranslator->trWarning(); break;
00654     case DocSimpleSect::Pre:
00655       m_t << theTranslator->trPrecondition(); break;
00656     case DocSimpleSect::Post:
00657       m_t << theTranslator->trPostcondition(); break;
00658     case DocSimpleSect::Invar:
00659       m_t << theTranslator->trInvariant(); break;
00660     case DocSimpleSect::Remark:
00661       m_t << theTranslator->trRemarks(); break;
00662     case DocSimpleSect::Attention:
00663       m_t << theTranslator->trAttention(); break;
00664     case DocSimpleSect::User: break;
00665     case DocSimpleSect::Rcs: break;
00666     case DocSimpleSect::Unknown:  break;
00667   }
00668 
00669   // special case 1: user defined title
00670   if (s->type()!=DocSimpleSect::User && s->type()!=DocSimpleSect::Rcs)
00671   {
00672     m_t << ":";
00673     m_t << "\\par";
00674     m_t << "}"; // end bold
00675     incIndentLevel();
00676     m_t << rtf_Style_Reset << getStyle("DescContinue");
00677   }
00678   m_lastIsPara=FALSE;
00679 }
00680 
00681 void RTFDocVisitor::visitPost(DocSimpleSect *)
00682 {
00683   if (m_hide) return;
00684   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleSect)}\n");
00685   if (!m_lastIsPara) m_t << "\\par" << endl;
00686   decIndentLevel();
00687   m_t << "}"; // end desc
00688   m_lastIsPara=TRUE;
00689 }
00690 
00691 void RTFDocVisitor::visitPre(DocTitle *)
00692 {
00693   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocTitle)}\n");
00694 }
00695 
00696 void RTFDocVisitor::visitPost(DocTitle *)
00697 {
00698   if (m_hide) return;
00699   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocTitle)}\n");
00700   m_t << "\\par" << endl;
00701   m_t << "}"; // end bold
00702   incIndentLevel();
00703   m_t << rtf_Style_Reset << getStyle("DescContinue");
00704   m_lastIsPara=FALSE;
00705 }
00706 
00707 void RTFDocVisitor::visitPre(DocSimpleList *)
00708 {
00709   if (m_hide) return;
00710   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleSect)}\n");
00711   m_t << "{" << endl;
00712   rtf_listItemInfo[m_indentLevel].isEnum = FALSE;
00713   m_lastIsPara=FALSE;
00714 }
00715 
00716 void RTFDocVisitor::visitPost(DocSimpleList *)
00717 {
00718   if (m_hide) return;
00719   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleSect)}\n");
00720   if (!m_lastIsPara) m_t << "\\par" << endl;
00721   m_t << "}" << endl;
00722   m_lastIsPara=TRUE;
00723 }
00724 
00725 void RTFDocVisitor::visitPre(DocSimpleListItem *)
00726 {
00727   if (m_hide) return;
00728   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSimpleListItem)}\n");
00729   m_t << "\\par" << rtf_Style_Reset << getStyle("ListBullet") << endl;
00730   m_lastIsPara=FALSE;
00731   incIndentLevel();
00732 }
00733 
00734 void RTFDocVisitor::visitPost(DocSimpleListItem *) 
00735 {
00736   decIndentLevel();
00737   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSimpleListItem)}\n");
00738 }
00739 
00740 void RTFDocVisitor::visitPre(DocSection *s)
00741 {
00742   if (m_hide) return;
00743   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSection)}\n");
00744   if (!m_lastIsPara) m_t << "\\par" << endl;
00745   m_t << "{{" // start section
00746       << rtf_Style_Reset;
00747   QString heading;
00748   int level = QMIN(s->level()+1,4);
00749   heading.sprintf("Heading%d",level);
00750   // set style
00751   m_t << rtf_Style[heading]->reference << endl;
00752   // make table of contents entry
00753   filter(s->title());
00754   m_t << endl << "\\par" << "}" << endl;
00755   m_t << "{\\tc\\tcl" << level << " \\v ";
00756   filter(s->title());
00757   m_t << "}" << endl;
00758   m_lastIsPara=TRUE;
00759 }
00760 
00761 void RTFDocVisitor::visitPost(DocSection *) 
00762 {
00763   if (m_hide) return;
00764   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSection)}\n");
00765   m_t << "\\par}" << endl; // end section
00766   m_lastIsPara=TRUE;
00767 }
00768 
00769 void RTFDocVisitor::visitPre(DocHtmlList *l)
00770 {
00771   if (m_hide) return;
00772   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlList)}\n");
00773   m_t << "{" << endl;
00774   rtf_listItemInfo[m_indentLevel].isEnum = l->type()==DocHtmlList::Ordered; 
00775   rtf_listItemInfo[m_indentLevel].number = 1;
00776   m_lastIsPara=FALSE;
00777 }
00778 
00779 void RTFDocVisitor::visitPost(DocHtmlList *) 
00780 {
00781   if (m_hide) return;
00782   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlList)}\n");
00783   m_t << "\\par" << "}" << endl;
00784   m_lastIsPara=TRUE;
00785 }
00786 
00787 void RTFDocVisitor::visitPre(DocHtmlListItem *)
00788 {
00789   if (m_hide) return;
00790   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlListItem)}\n");
00791   m_t << "\\par" << endl;
00792   m_t << rtf_Style_Reset;
00793   if (rtf_listItemInfo[m_indentLevel].isEnum)
00794   {
00795     m_t << getStyle("ListEnum") << endl;
00796     m_t << rtf_listItemInfo[m_indentLevel].number << ".\\tab ";
00797     rtf_listItemInfo[m_indentLevel].number++;
00798   }
00799   else
00800   {
00801     m_t << getStyle("ListBullet") << endl;
00802   }
00803   incIndentLevel();
00804   m_lastIsPara=FALSE;
00805 }
00806 
00807 void RTFDocVisitor::visitPost(DocHtmlListItem *) 
00808 {
00809   decIndentLevel();
00810   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlListItem)}\n");
00811 }
00812 
00813 void RTFDocVisitor::visitPre(DocHtmlDescList *)
00814 {
00815   if (m_hide) return;
00816   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescList)}\n");
00817   //m_t << "{" << endl;
00818   //m_t << rtf_Style_Reset << getStyle("ListContinue");
00819   //m_lastIsPara=FALSE;
00820 }
00821 
00822 void RTFDocVisitor::visitPost(DocHtmlDescList *) 
00823 {
00824   if (m_hide) return;
00825   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescList)}\n");
00826   //m_t << "}" << endl;
00827   //m_t << "\\par" << endl;
00828   //m_lastIsPara=TRUE;
00829 }
00830 
00831 void RTFDocVisitor::visitPre(DocHtmlDescTitle *)
00832 {
00833   if (m_hide) return;
00834   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescTitle)}\n");
00835   //m_t << "\\par" << endl;
00836   //m_t << "{\\b ";
00837   m_t << "{" << rtf_Style["Heading5"]->reference << endl;
00838   m_lastIsPara=FALSE;
00839 }
00840 
00841 void RTFDocVisitor::visitPost(DocHtmlDescTitle *) 
00842 {
00843   if (m_hide) return;
00844   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescTitle)}\n");
00845   m_t << "\\par" << endl;
00846   m_t << "}" << endl;
00847   m_lastIsPara=TRUE;
00848 }
00849 
00850 void RTFDocVisitor::visitPre(DocHtmlDescData *)
00851 {
00852   if (m_hide) return;
00853   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlDescData)}\n");
00854   incIndentLevel();
00855   m_t << "{" << rtf_Style_Reset << getStyle("DescContinue");
00856 }
00857 
00858 void RTFDocVisitor::visitPost(DocHtmlDescData *) 
00859 {
00860   if (m_hide) return;
00861   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlDescData)}\n");
00862   m_t << "\\par";
00863   m_t << "}" << endl;
00864   decIndentLevel();
00865   m_lastIsPara=TRUE;
00866 }
00867 
00868 void RTFDocVisitor::visitPre(DocHtmlTable *)
00869 {
00870   if (m_hide) return;
00871   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlTable)}\n");
00872   if (!m_lastIsPara) m_t << "\\par" << endl;
00873   m_lastIsPara=TRUE;
00874 }
00875 
00876 void RTFDocVisitor::visitPost(DocHtmlTable *) 
00877 {
00878   if (m_hide) return;
00879   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlTable)}\n");
00880   m_t << "\\pard" << endl;
00881   m_lastIsPara=TRUE;
00882 }
00883 
00884 void RTFDocVisitor::visitPre(DocHtmlCaption *)
00885 {
00886   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlCaption)}\n");
00887 }
00888 
00889 void RTFDocVisitor::visitPost(DocHtmlCaption *) 
00890 {
00891   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCaption)}\n");
00892 }
00893 
00894 void RTFDocVisitor::visitPre(DocHtmlRow *r)
00895 {
00896   if (m_hide) return;
00897   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlRow)}\n");
00898   uint i,columnWidth=rtf_pageWidth/r->numCells();
00899   m_t << "\\trowd \\trgaph108\\trleft-108"
00900          "\\trbrdrt\\brdrs\\brdrw10 "
00901          "\\trbrdrl\\brdrs\\brdrw10 "
00902          "\\trbrdrb\\brdrs\\brdrw10 "
00903          "\\trbrdrr\\brdrs\\brdrw10 "
00904          "\\trbrdrh\\brdrs\\brdrw10 "
00905          "\\trbrdrv\\brdrs\\brdrw10 "<< endl;
00906   for (i=0;i<r->numCells();i++)
00907   {
00908     m_t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 "
00909            "\\clbrdrl\\brdrs\\brdrw10 "
00910            "\\clbrdrb\\brdrs\\brdrw10 "
00911            "\\clbrdrr \\brdrs\\brdrw10 "
00912            "\\cltxlrtb "
00913            "\\cellx" << ((i+1)*columnWidth) << endl;
00914   }
00915   m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
00916   m_lastIsPara=FALSE;
00917 }
00918 
00919 void RTFDocVisitor::visitPost(DocHtmlRow *) 
00920 {
00921   if (m_hide) return;
00922   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlRow)}\n");
00923   m_t << endl;
00924   m_t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
00925   m_t << "{\\row }" << endl;
00926   m_lastIsPara=FALSE;
00927 }
00928 
00929 void RTFDocVisitor::visitPre(DocHtmlCell *)
00930 {
00931   if (m_hide) return;
00932   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlCell)}\n");
00933   m_t << "{";
00934   m_lastIsPara=FALSE;
00935 }
00936 
00937 void RTFDocVisitor::visitPost(DocHtmlCell *) 
00938 {
00939   if (m_hide) return;
00940   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlCell)}\n");
00941   m_t << "\\cell }";
00942   m_lastIsPara=FALSE;
00943 }
00944 
00945 void RTFDocVisitor::visitPre(DocInternal *)
00946 {
00947   if (m_hide) return;
00948   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocInternal)}\n");
00949   m_t << "{"; // start desc
00950   m_t << "{\\b "; // start bold
00951   m_t << theTranslator->trForInternalUseOnly();
00952   m_t << "}"; // end bold
00953   m_t << "\\par" << endl;
00954   incIndentLevel();
00955   m_t << rtf_Style_Reset << getStyle("DescContinue");
00956   m_lastIsPara=FALSE;
00957 }
00958 
00959 void RTFDocVisitor::visitPost(DocInternal *) 
00960 {
00961   if (m_hide) return;
00962   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternal)}\n");
00963   m_t << "\\par";
00964   decIndentLevel();
00965   m_t << "}"; // end desc
00966   m_lastIsPara=TRUE;
00967 }
00968 
00969 void RTFDocVisitor::visitPre(DocHRef *href)
00970 {
00971   if (m_hide) return;
00972   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHRef)}\n");
00973   if (Config_getBool("RTF_HYPERLINKS"))
00974   {
00975     m_t << "{\\field "
00976              "{\\*\\fldinst "
00977                "{ HYPERLINK  \\\\l \"" << href->url() << "\" "
00978                "}{}"
00979              "}"
00980              "{\\fldrslt "
00981                "{\\cs37\\ul\\cf2 ";
00982 
00983   }
00984   else
00985   {
00986     m_t << "{\\f2 ";
00987   }
00988   m_lastIsPara=FALSE;
00989 }
00990 
00991 void RTFDocVisitor::visitPost(DocHRef *) 
00992 {
00993   if (m_hide) return;
00994   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHRef)}\n");
00995   if (Config_getBool("RTF_HYPERLINKS"))
00996   { 
00997     m_t <<     "}"
00998              "}"
00999            "}";
01000   }
01001   else
01002   {
01003     m_t << "}";
01004   }
01005   m_lastIsPara=FALSE;
01006 }
01007 
01008 void RTFDocVisitor::visitPre(DocHtmlHeader *header)
01009 {
01010   if (m_hide) return;
01011   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocHtmlHeader)}\n");
01012   m_t << "{" // start section
01013       << rtf_Style_Reset;
01014   QString heading;
01015   int level = QMIN(header->level()+2,4);
01016   heading.sprintf("Heading%d",level);
01017   // set style
01018   m_t << rtf_Style[heading]->reference;
01019   // make table of contents entry
01020   m_t << "{\\tc\\tcl \\v " << level << "}";
01021   m_lastIsPara=FALSE;
01022   
01023 }
01024 
01025 void RTFDocVisitor::visitPost(DocHtmlHeader *) 
01026 {
01027   if (m_hide) return;
01028   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocHtmlHeader)}\n");
01029   m_t << "\\par";
01030   m_t << "}" << endl; // end section
01031   m_lastIsPara=TRUE;
01032 }
01033 
01034 void RTFDocVisitor::visitPre(DocImage *img)
01035 {
01036   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocImage)}\n");
01037   if (img->type()==DocImage::Rtf)
01038   {
01039     m_t << "\\par" << endl;
01040     m_t << "{" << endl;
01041     m_t << rtf_Style_Reset << endl;
01042     m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
01043     m_t << img->name();
01044     m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
01045     m_t << "}" << endl;
01046     m_lastIsPara=TRUE;
01047   }
01048   else // other format -> skip
01049   {
01050   }
01051   // hide caption since it is not supported at the moment
01052   pushEnabled();
01053   m_hide=TRUE;
01054 }
01055 
01056 void RTFDocVisitor::visitPost(DocImage *) 
01057 {
01058   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocImage)}\n");
01059   popEnabled();
01060 }
01061 
01062 void RTFDocVisitor::visitPre(DocDotFile *df)
01063 {
01064   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocDotFile)}\n");
01065   writeDotFile(df->file());
01066 
01067   // hide caption since it is not supported at the moment
01068   pushEnabled();
01069   m_hide=TRUE;
01070 }
01071 
01072 void RTFDocVisitor::visitPost(DocDotFile *) 
01073 {
01074   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocDotFile)}\n");
01075   popEnabled();
01076 }
01077 
01078 void RTFDocVisitor::visitPre(DocLink *lnk)
01079 {
01080   if (m_hide) return;
01081   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocLink)}\n");
01082   startLink(lnk->ref(),lnk->file(),lnk->anchor());
01083 }
01084 
01085 void RTFDocVisitor::visitPost(DocLink *lnk) 
01086 {
01087   if (m_hide) return;
01088   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocLink)}\n");
01089   endLink(lnk->ref());
01090 }
01091 
01092 void RTFDocVisitor::visitPre(DocRef *ref)
01093 {
01094   if (m_hide) return;
01095   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocRef)}\n");
01096   if (!ref->file().isEmpty()) startLink(ref->ref(),ref->file(),ref->anchor());
01097   if (!ref->hasLinkText()) filter(ref->targetTitle());
01098 }
01099 
01100 void RTFDocVisitor::visitPost(DocRef *ref) 
01101 {
01102   if (m_hide) return;
01103   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocRef)}\n");
01104   if (!ref->file().isEmpty()) endLink(ref->ref());
01105   m_t << " ";
01106 }
01107 
01108 
01109 void RTFDocVisitor::visitPre(DocSecRefItem *)
01110 {
01111   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSecRefItem)}\n");
01112 }
01113 
01114 void RTFDocVisitor::visitPost(DocSecRefItem *) 
01115 {
01116   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefItem)}\n");
01117 }
01118 
01119 void RTFDocVisitor::visitPre(DocSecRefList *)
01120 {
01121   if (m_hide) return;
01122   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocSecRefList)}\n");
01123   m_t << "{" << endl;
01124   incIndentLevel();
01125   m_t << rtf_Style_Reset << getStyle("LatexTOC") << endl;
01126   m_t << "\\par" << endl;
01127   m_lastIsPara=TRUE;
01128 }
01129 
01130 void RTFDocVisitor::visitPost(DocSecRefList *) 
01131 {
01132   if (m_hide) return;
01133   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocSecRefList)}\n");
01134   decIndentLevel();
01135   m_t << "\\par";
01136   m_t << "}" << endl;
01137   m_lastIsPara=TRUE;
01138 }
01139 
01140 //void RTFDocVisitor::visitPre(DocLanguage *l)
01141 //{
01142 //  DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocLanguage)}\n");
01143 //  QString langId = Config_getEnum("OUTPUT_LANGUAGE");
01144 //  if (l->id().lower()!=langId.lower())
01145 //  {
01146 //    pushEnabled();
01147 //    m_hide = TRUE;
01148 //  }
01149 //}
01150 //
01151 //void RTFDocVisitor::visitPost(DocLanguage *l) 
01152 //{
01153 //  DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocLanguage)}\n");
01154 //  QString langId = Config_getEnum("OUTPUT_LANGUAGE");
01155 //  if (l->id().lower()!=langId.lower())
01156 //  {
01157 //    popEnabled();
01158 //  }
01159 //}
01160 
01161 void RTFDocVisitor::visitPre(DocParamSect *s)
01162 {
01163   if (m_hide) return;
01164   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamSect)}\n");
01165   m_t << "{"; // start param list
01166   if (!m_lastIsPara) m_t << "\\par" << endl;
01167   //m_t << "{\\b "; // start bold
01168   m_t << "{" << rtf_Style["Heading5"]->reference << endl;
01169   switch(s->type())
01170   {
01171     case DocParamSect::Param: 
01172       m_t << theTranslator->trParameters(); break;
01173     case DocParamSect::RetVal: 
01174       m_t << theTranslator->trReturnValues(); break;
01175     case DocParamSect::Exception: 
01176       m_t << theTranslator->trExceptions(); break;
01177     case DocParamSect::TemplateParam: 
01178       /* TODO: add this 
01179       m_t << theTranslator->trTemplateParam(); break;
01180       */
01181       m_t << "Template Parameters"; break;
01182     default:
01183       ASSERT(0);
01184   }
01185   m_t << ":";
01186   m_t << "\\par";
01187   m_t << "}" << endl;
01188   incIndentLevel();
01189   m_t << rtf_Style_Reset << getStyle("DescContinue");
01190   m_lastIsPara=TRUE;
01191 }
01192 
01193 void RTFDocVisitor::visitPost(DocParamSect *)
01194 {
01195   if (m_hide) return;
01196   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamSect)}\n");
01197   //m_t << "\\par" << endl;
01198   decIndentLevel();
01199   m_t << "}" << endl;
01200 }
01201 
01202 void RTFDocVisitor::visitPre(DocParamList *pl)
01203 {
01204   if (m_hide) return;
01205   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocParamList)}\n");
01206   m_t << "{\\i ";
01207   //QStrListIterator li(pl->parameters());
01208   //const char *s;
01209   QListIterator<DocNode> li(pl->parameters());
01210   DocNode *param;
01211   bool first=TRUE;
01212   for (li.toFirst();(param=li.current());++li)
01213   {
01214     if (!first) m_t << ","; else first=FALSE;
01215     if (param->kind()==DocNode::Kind_Word)
01216     {
01217       visit((DocWord*)param); 
01218     }
01219     else if (param->kind()==DocNode::Kind_LinkedWord)
01220     {
01221       visit((DocLinkedWord*)param); 
01222     }
01223   }
01224   m_t << "} ";
01225   m_lastIsPara=TRUE;
01226 }
01227 
01228 void RTFDocVisitor::visitPost(DocParamList *)
01229 {
01230   if (m_hide) return;
01231   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocParamList)}\n");
01232   m_t << "\\par" << endl;
01233   m_lastIsPara=TRUE;
01234 }
01235 
01236 void RTFDocVisitor::visitPre(DocXRefItem *x)
01237 {
01238   if (m_hide) return;
01239   bool anonymousEnum = x->file()=="@";
01240   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocXRefItem)}\n");
01241   m_t << "{"; // start param list
01242   //m_t << "{\\b "; // start bold
01243   m_t << "{" << rtf_Style["Heading5"]->reference << endl;
01244   if (Config_getBool("RTF_HYPERLINKS") && !anonymousEnum)
01245   {
01246     QString refName;
01247     if (!x->file().isEmpty())
01248     {
01249       refName+=x->file();
01250     }
01251     if (!x->file().isEmpty() && !x->anchor().isEmpty())
01252     {
01253       refName+="_";
01254     }
01255     if (!x->anchor().isEmpty())
01256     {
01257       refName+=x->anchor();
01258     }
01259 
01260     m_t << "{\\field "
01261              "{\\*\\fldinst "
01262                "{ HYPERLINK  \\\\l \"" << refName << "\" "
01263                "}{}"
01264              "}"
01265              "{\\fldrslt "
01266                "{\\cs37\\ul\\cf2 ";
01267     filter(x->title());
01268     m_t <<     "}"
01269              "}"
01270            "}";
01271   }
01272   else
01273   {
01274     filter(x->title());
01275   }
01276   m_t << ":";
01277   m_t << "\\par";
01278   m_t << "}"; // end bold
01279   incIndentLevel();
01280   m_t << rtf_Style_Reset << getStyle("DescContinue");
01281   m_lastIsPara=FALSE;
01282 }
01283 
01284 void RTFDocVisitor::visitPost(DocXRefItem *)
01285 {
01286   if (m_hide) return;
01287   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocXRefItem)}\n");
01288   m_t << "\\par" << endl;
01289   decIndentLevel();
01290   m_t << "}" << endl; // end xref item
01291   m_lastIsPara=TRUE;
01292 }
01293 
01294 void RTFDocVisitor::visitPre(DocInternalRef *ref)
01295 {
01296   if (m_hide) return;
01297   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocInternalRef)}\n");
01298   startLink("",ref->file(),ref->anchor());
01299 }
01300 
01301 void RTFDocVisitor::visitPost(DocInternalRef *) 
01302 {
01303   if (m_hide) return;
01304   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocInternalRef)}\n");
01305   endLink("");
01306   m_t << " ";
01307 }
01308 
01309 void RTFDocVisitor::visitPre(DocCopy *)
01310 {
01311   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocCopy)}\n");
01312 }
01313 
01314 void RTFDocVisitor::visitPost(DocCopy *)
01315 {
01316   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocCopy)}\n");
01317 }
01318 
01319 void RTFDocVisitor::visitPre(DocText *)
01320 {
01321   DBG_RTF("{\\comment RTFDocVisitor::visitPre(DocText)}\n");
01322 }
01323 
01324 void RTFDocVisitor::visitPost(DocText *)
01325 {
01326   DBG_RTF("{\\comment RTFDocVisitor::visitPost(DocText)}\n");
01327 }
01328 
01329 //static char* getMultiByte(int c)
01330 //{
01331 //    static char s[10];
01332 //    sprintf(s,"\\'%X",c);
01333 //    return s;
01334 //}
01335 
01336 void RTFDocVisitor::filter(const char *str,bool verbatim)
01337 { 
01338   if (str)
01339   {
01340     const unsigned char *p=(const unsigned char *)str;
01341     unsigned char c;
01342     unsigned char pc='\0';
01343     while (*p)
01344     {
01345       //static bool MultiByte = FALSE;
01346       c=*p++;
01347 
01348       //if ( MultiByte )
01349       //{
01350       //  m_t << getMultiByte( c );
01351       //  MultiByte = FALSE;
01352       //  continue;
01353       //}
01354       //if ( c >= 0x80 )
01355       //{
01356       //  MultiByte = TRUE;
01357       //  m_t << getMultiByte( c );
01358       //  continue;
01359       //}
01360 
01361       switch (c)
01362       {
01363         case '{':  m_t << "\\{";            break;
01364         case '}':  m_t << "\\}";            break;
01365         case '\\': m_t << "\\\\";           break;
01366         case '\n': if (verbatim)
01367                    {
01368                      m_t << "\\par" << endl; 
01369                    }
01370                    else
01371                    {
01372                      m_t << '\n';
01373                    }
01374                    break;
01375         default:   m_t << (char)c;
01376       }
01377       pc = c;
01378     }
01379   }
01380 }
01381 
01382 void RTFDocVisitor::startLink(const QString &ref,const QString &file,const QString &anchor)
01383 {
01384   if (ref.isEmpty() && Config_getBool("RTF_HYPERLINKS"))
01385   {
01386     QString refName;
01387     if (!file.isEmpty())
01388     {
01389       refName+=file;
01390     }
01391     if (anchor)
01392     {
01393       refName+='_';
01394       refName+=anchor;
01395     }
01396 
01397     m_t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
01398     m_t << rtfFormatBmkStr(refName);
01399     m_t << "\" }{}";
01400     m_t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
01401   }
01402   else
01403   {
01404     m_t << "{\\b ";
01405   }
01406   m_lastIsPara=FALSE;
01407 }
01408 
01409 void RTFDocVisitor::endLink(const QString &ref)
01410 {
01411   if (ref.isEmpty() && Config_getBool("RTF_HYPERLINKS"))
01412   {
01413     m_t << "}}}";
01414   }
01415   else
01416   {
01417     m_t << "}";
01418   }
01419   m_lastIsPara=FALSE;
01420 }
01421 
01422 void RTFDocVisitor::pushEnabled()
01423 {
01424   m_enabled.push(new bool(m_hide));
01425 }
01426 
01427 void RTFDocVisitor::popEnabled()
01428 {
01429   bool *v=m_enabled.pop();
01430   ASSERT(v!=0);
01431   m_hide = *v;
01432   delete v;
01433 }
01434 
01435 void RTFDocVisitor::writeDotFile(const QString &fileName)
01436 {
01437   QString baseName=fileName;
01438   int i;
01439   if ((i=baseName.findRev('/'))!=-1)
01440   {
01441     baseName=baseName.right(baseName.length()-i-1);
01442   } 
01443   QString outDir = Config_getString("RTF_OUTPUT");
01444   writeDotGraphFromFile(fileName,outDir,baseName,BITMAP);
01445   if (!m_lastIsPara) m_t << "\\par" << endl;
01446   m_t << "{" << endl;
01447   m_t << rtf_Style_Reset;
01448   m_t << "\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
01449   m_t << baseName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
01450   m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
01451   m_t << "}" << endl;
01452   m_lastIsPara=TRUE;
01453 }
01454 
01455 void RTFDocVisitor::writeMscFile(const QString &fileName)
01456 {
01457   QString baseName=fileName;
01458   int i;
01459   if ((i=baseName.findRev('/'))!=-1)
01460   {
01461     baseName=baseName.right(baseName.length()-i-1);
01462   } 
01463   QString outDir = Config_getString("RTF_OUTPUT");
01464   writeMscGraphFromFile(fileName,outDir,baseName,MSC_BITMAP);
01465   if (!m_lastIsPara) m_t << "\\par" << endl;
01466   m_t << "{" << endl;
01467   m_t << rtf_Style_Reset;
01468   m_t << "\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
01469   m_t << baseName << ".png";
01470   m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
01471   m_t << "}" << endl;
01472   m_lastIsPara=TRUE;
01473 }
01474 



Generated on Mon Mar 31 10:58:42 2008 by  doxygen 1.5.1