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