1 /******************************************************************************
5 * Copyright (C) 1997-2015 by Dimitri van Heesch.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
33 #include "docparser.h"
34 #include "htmldocvisitor.h"
35 #include "searchindex.h"
39 #include "vhdldocgen.h"
44 #include "resourcemgr.h"
47 //#define DBG_HTML(x) x;
50 static QCString g_header;
51 static QCString g_footer;
52 static QCString g_mathjax_code;
55 // note: this is only active if DISABLE_INDEX=YES, if DISABLE_INDEX is disabled, this
56 // part will be rendered inside menu.js
57 static void writeClientSearchBox(FTextStream &t,const char *relPath)
59 t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
60 t << " <span class=\"left\">\n";
61 t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n";
62 t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
63 t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
65 t << " <input type=\"text\" id=\"MSearchField\" value=\""
66 << theTranslator->trSearch() << "\" accesskey=\"S\"\n";
67 t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
68 t << " onblur=\"searchBox.OnSearchFieldFocus(false)\" \n";
69 t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
70 t << " </span><span class=\"right\">\n";
71 t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
72 << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n";
77 // note: this is only active if DISABLE_INDEX=YES. if DISABLE_INDEX is disabled, this
78 // part will be rendered inside menu.js
79 static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch)
81 static bool externalSearch = Config_getBool(EXTERNAL_SEARCH);
82 t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
83 t << " <div class=\"left\">\n";
84 t << " <form id=\"FSearchBox\" action=\"" << relPath;
87 t << "search" << Doxygen::htmlFileExtension;
93 t << "\" method=\"get\">\n";
94 t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n";
97 t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\""
98 << theTranslator->trSearch() << "\" size=\"20\" accesskey=\"S\" \n";
99 t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
100 t << " onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
102 t << " </div><div class=\"right\"></div>\n";
107 //------------------------------------------------------------------------
109 /// Clear a text block \a s from \a begin to \a end markers
110 QCString clearBlock(const char *s,const char *begin,const char *end)
112 if (s==0 || begin==0 || end==0) return s;
114 int beginLen = qstrlen(begin);
115 int endLen = qstrlen(end);
117 for (p=s; (q=strstr(p,begin))!=0; p=q+endLen)
121 if ((q=strstr(p,end))==0)
128 // resLen is the length of the string without the marked block
130 QCString result(resLen+1);
132 for (r=result.rawData(), p=s; (q=strstr(p,begin))!=0; p=q+endLen)
138 if ((q=strstr(p,end))==0)
140 memcpy(r,begin,beginLen);
148 //----------------------------------------------------------------------
150 QCString selectBlock(const QCString& s,const QCString &name,bool enable)
152 // TODO: this is an expensive function that is called a lot -> optimize it
153 const QCString begin = "<!--BEGIN " + name + "-->";
154 const QCString end = "<!--END " + name + "-->";
155 const QCString nobegin = "<!--BEGIN !" + name + "-->";
156 const QCString noend = "<!--END !" + name + "-->";
161 result = substitute(result, begin, "");
162 result = substitute(result, end, "");
163 result = clearBlock(result, nobegin, noend);
167 result = substitute(result, nobegin, "");
168 result = substitute(result, noend, "");
169 result = clearBlock(result, begin, end);
175 static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
178 FTextStream t(&result);
181 writeServerSearchBox(t, relPath, highlightSearch);
185 writeClientSearchBox(t, relPath);
187 return QCString(result);
190 static QCString removeEmptyLines(const QCString &s)
192 BufStr out(s.length()+1);
193 const char *p=s.data();
202 while (*e==' ' || *e=='\t') e++;
216 //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data());
220 static QCString substituteHtmlKeywords(const QCString &s,
221 const QCString &title,
222 const QCString &relPath,
223 const QCString &navPath=QCString())
225 // Build CSS/Javascript tags depending on treeview, search engine settings
227 QStrList extraCssFile;
228 QCString generatedBy;
229 QCString treeViewCssJs;
230 QCString searchCssJs;
233 QCString extraCssText;
235 static QCString projectName = Config_getString(PROJECT_NAME);
236 static bool timeStamp = Config_getBool(HTML_TIMESTAMP);
237 static bool treeView = Config_getBool(GENERATE_TREEVIEW);
238 static bool searchEngine = Config_getBool(SEARCHENGINE);
239 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
240 static bool mathJax = Config_getBool(USE_MATHJAX);
241 static QCString mathJaxFormat = Config_getEnum(MATHJAX_FORMAT);
242 static bool disableIndex = Config_getBool(DISABLE_INDEX);
243 static bool hasProjectName = !projectName.isEmpty();
244 static bool hasProjectNumber = !Config_getString(PROJECT_NUMBER).isEmpty();
245 static bool hasProjectBrief = !Config_getString(PROJECT_BRIEF).isEmpty();
246 static bool hasProjectLogo = !Config_getString(PROJECT_LOGO).isEmpty();
247 static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine));
249 cssFile = Config_getString(HTML_STYLESHEET);
250 if (cssFile.isEmpty())
252 cssFile = "doxygen.css";
256 QFileInfo cssfi(cssFile);
259 cssFile = cssfi.fileName().utf8();
263 cssFile = "doxygen.css";
268 extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
269 for (uint i=0; i<extraCssFile.count(); ++i)
271 QCString fileName(extraCssFile.at(i));
272 if (!fileName.isEmpty())
274 QFileInfo fi(fileName);
277 extraCssText += "<link href=\"$relpath^"+stripPath(fileName)+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
284 generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), convertToHtml(Config_getString(PROJECT_NAME)));
288 generatedBy = theTranslator->trGeneratedBy();
293 treeViewCssJs = "<link href=\"$relpath^navtree.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
294 "<script type=\"text/javascript\" src=\"$relpath^resize.js\"></script>\n"
295 "<script type=\"text/javascript\" src=\"$relpath^navtreedata.js\"></script>\n"
296 "<script type=\"text/javascript\" src=\"$relpath^navtree.js\"></script>\n"
297 "<script type=\"text/javascript\">\n"
298 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
299 " $(document).ready(initResizable);\n"
306 searchCssJs = "<link href=\"$relpath^search/search.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
307 if (!serverBasedSearch)
309 searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/searchdata.js\"></script>\n";
311 searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/search.js\"></script>\n";
313 if (!serverBasedSearch)
315 if (disableIndex || !Config_getBool(HTML_DYNAMIC_MENUS))
317 searchCssJs += "<script type=\"text/javascript\">\n"
318 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
319 " $(document).ready(function() { init_search(); });\n"
320 "/* @license-end */\n"
326 if (disableIndex || !Config_getBool(HTML_DYNAMIC_MENUS))
328 searchCssJs += "<script type=\"text/javascript\">\n"
329 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
330 " $(document).ready(function() {\n"
331 " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
333 " /* @license-end */\n"
337 // OPENSEARCH_PROVIDER {
338 searchCssJs += "<link rel=\"search\" href=\"" + relPath +
339 "search_opensearch.php?v=opensearch.xml\" "
340 "type=\"application/opensearchdescription+xml\" title=\"" +
341 (hasProjectName ? projectName : QCString("Doxygen")) +
343 // OPENSEARCH_PROVIDER }
345 searchBox = getSearchBox(serverBasedSearch, relPath, FALSE);
350 QCString path = Config_getString(MATHJAX_RELPATH);
351 if (path.isEmpty() || path.left(2)=="..") // relative path
353 path.prepend(relPath);
355 mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
356 " MathJax.Hub.Config({\n"
357 " extensions: [\"tex2jax.js\"";
358 QStrList &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
359 const char *s = mathJaxExtensions.first();
362 mathJaxJs+= ", \""+QCString(s)+".js\"";
363 s = mathJaxExtensions.next();
365 if (mathJaxFormat.isEmpty())
367 mathJaxFormat = "HTML-CSS";
370 " jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n"
372 if (!g_mathjax_code.isEmpty())
374 mathJaxJs += g_mathjax_code;
377 mathJaxJs += "</script>";
378 mathJaxJs += "<script type=\"text/javascript\" async src=\"" + path + "MathJax.js\"></script>\n";
381 // first substitute generic keywords
382 QCString result = substituteKeywords(s,title,
383 convertToHtml(Config_getString(PROJECT_NAME)),
384 convertToHtml(Config_getString(PROJECT_NUMBER)),
385 convertToHtml(Config_getString(PROJECT_BRIEF)));
387 // additional HTML only keywords
388 result = substitute(result,"$navpath",navPath);
389 result = substitute(result,"$stylesheet",cssFile);
390 result = substitute(result,"$treeview",treeViewCssJs);
391 result = substitute(result,"$searchbox",searchBox);
392 result = substitute(result,"$search",searchCssJs);
393 result = substitute(result,"$mathjax",mathJaxJs);
394 result = substitute(result,"$generatedby",generatedBy);
395 result = substitute(result,"$extrastylesheet",extraCssText);
396 result = substitute(result,"$relpath$",relPath); //<-- obsolete: for backwards compatibility only
397 result = substitute(result,"$relpath^",relPath); //<-- must be last
399 // additional HTML only conditional blocks
400 result = selectBlock(result,"DISABLE_INDEX",disableIndex);
401 result = selectBlock(result,"GENERATE_TREEVIEW",treeView);
402 result = selectBlock(result,"SEARCHENGINE",searchEngine);
403 result = selectBlock(result,"TITLEAREA",titleArea);
404 result = selectBlock(result,"PROJECT_NAME",hasProjectName);
405 result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber);
406 result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief);
407 result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo);
409 result = removeEmptyLines(result);
414 //--------------------------------------------------------------------------
416 HtmlCodeGenerator::HtmlCodeGenerator()
417 : m_streamSet(FALSE), m_col(0)
421 HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath)
422 : m_col(0), m_relPath(relPath)
427 void HtmlCodeGenerator::setTextStream(FTextStream &t)
429 m_streamSet = t.device()!=0;
430 m_t.setDevice(t.device());
433 void HtmlCodeGenerator::setRelativePath(const QCString &path)
438 void HtmlCodeGenerator::codify(const char *str)
440 static int tabSize = Config_getInt(TAB_SIZE);
441 if (str && m_streamSet)
445 int spacesToNextTabStop;
451 case '\t': spacesToNextTabStop =
452 tabSize - (m_col%tabSize);
453 m_t << Doxygen::spaces.left(spacesToNextTabStop);
454 m_col+=spacesToNextTabStop;
456 case '\n': m_t << "\n"; m_col=0;
459 case '<': m_t << "<"; m_col++;
461 case '>': m_t << ">"; m_col++;
463 case '&': m_t << "&"; m_col++;
465 case '\'': m_t << "'"; m_col++; // ' is not valid XHTML
467 case '"': m_t << """; m_col++;
471 { m_t << "<"; p++; }
473 { m_t << ">"; p++; }
478 default: p=writeUtf8Char(m_t,p-1);
486 void HtmlCodeGenerator::docify(const char *str)
488 if (str && m_streamSet)
497 case '<': m_t << "<"; break;
498 case '>': m_t << ">"; break;
499 case '&': m_t << "&"; break;
500 case '"': m_t << """; break;
503 { m_t << "<"; p++; }
505 { m_t << ">"; p++; }
515 void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename,
516 const char *anchor,int l)
518 if (!m_streamSet) return;
519 const int maxLineNrStr = 10;
520 char lineNumber[maxLineNrStr];
521 char lineAnchor[maxLineNrStr];
522 qsnprintf(lineNumber,maxLineNrStr,"%5d",l);
523 qsnprintf(lineAnchor,maxLineNrStr,"l%05d",l);
525 m_t << "<div class=\"line\">";
526 m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">";
529 _writeCodeLink("line",ref,filename,anchor,lineNumber,0);
539 void HtmlCodeGenerator::writeCodeLink(const char *ref,const char *f,
540 const char *anchor, const char *name,
543 if (!m_streamSet) return;
544 //printf("writeCodeLink(ref=%s,f=%s,anchor=%s,name=%s,tooltip=%s)\n",ref,f,anchor,name,tooltip);
545 _writeCodeLink("code",ref,f,anchor,name,tooltip);
548 void HtmlCodeGenerator::_writeCodeLink(const char *className,
549 const char *ref,const char *f,
550 const char *anchor, const char *name,
555 m_t << "<a class=\"" << className << "Ref\" ";
556 m_t << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
560 m_t << "<a class=\"" << className << "\" ";
563 m_t << externalRef(m_relPath,ref,TRUE);
564 if (f) m_t << f << Doxygen::htmlFileExtension;
565 if (anchor) m_t << "#" << anchor;
567 if (tooltip) m_t << " title=\"" << convertToHtml(tooltip) << "\"";
571 m_col+=qstrlen(name);
574 void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo,
575 const char *decl, const char *desc,
576 const SourceLinkInfo &defInfo,
577 const SourceLinkInfo &declInfo)
579 m_t << "<div class=\"ttc\" id=\"" << id << "\">";
580 m_t << "<div class=\"ttname\">";
581 if (!docInfo.url.isEmpty())
584 m_t << externalRef(m_relPath,docInfo.ref,TRUE);
585 m_t << docInfo.url << Doxygen::htmlFileExtension;
586 if (!docInfo.anchor.isEmpty())
588 m_t << "#" << docInfo.anchor;
592 docify(docInfo.name);
593 if (!docInfo.url.isEmpty())
600 m_t << "<div class=\"ttdeci\">";
606 m_t << "<div class=\"ttdoc\">";
607 docify(desc); // desc is already HTML escaped; but there are still < and > signs
610 if (!defInfo.file.isEmpty())
612 m_t << "<div class=\"ttdef\"><b>Definition:</b> ";
613 if (!defInfo.url.isEmpty())
616 m_t << externalRef(m_relPath,defInfo.ref,TRUE);
617 m_t << defInfo.url << Doxygen::htmlFileExtension;
618 if (!defInfo.anchor.isEmpty())
620 m_t << "#" << defInfo.anchor;
624 m_t << defInfo.file << ":" << defInfo.line;
625 if (!defInfo.url.isEmpty())
631 if (!declInfo.file.isEmpty())
633 m_t << "<div class=\"ttdecl\"><b>Declaration:</b> ";
634 if (!declInfo.url.isEmpty())
637 m_t << externalRef(m_relPath,declInfo.ref,TRUE);
638 m_t << declInfo.url << Doxygen::htmlFileExtension;
639 if (!declInfo.anchor.isEmpty())
641 m_t << "#" << declInfo.anchor;
645 m_t << declInfo.file << ":" << declInfo.line;
646 if (!declInfo.url.isEmpty())
652 m_t << "</div>" << endl;
656 void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers)
660 if (!hasLineNumbers) m_t << "<div class=\"line\">";
665 void HtmlCodeGenerator::endCodeLine()
667 if (m_streamSet) m_t << "</div>";
670 void HtmlCodeGenerator::startFontClass(const char *s)
672 if (m_streamSet) m_t << "<span class=\"" << s << "\">";
675 void HtmlCodeGenerator::endFontClass()
677 if (m_streamSet) m_t << "</span>";
680 void HtmlCodeGenerator::writeCodeAnchor(const char *anchor)
682 if (m_streamSet) m_t << "<a name=\"" << anchor << "\"></a>";
685 //--------------------------------------------------------------------------
687 HtmlGenerator::HtmlGenerator() : OutputGenerator()
689 dir=Config_getString(HTML_OUTPUT);
690 m_emptySection=FALSE;
693 HtmlGenerator::~HtmlGenerator()
695 //printf("HtmlGenerator::~HtmlGenerator()\n");
698 void HtmlGenerator::init()
700 QCString dname=Config_getString(HTML_OUTPUT);
702 if (!d.exists() && !d.mkdir(dname))
704 err("Could not create output directory %s\n",dname.data());
708 if (!Config_getString(HTML_HEADER).isEmpty())
710 g_header=fileToString(Config_getString(HTML_HEADER));
711 //printf("g_header='%s'\n",g_header.data());
715 g_header = ResourceMgr::instance().getAsString("header.html");
718 if (!Config_getString(HTML_FOOTER).isEmpty())
720 g_footer=fileToString(Config_getString(HTML_FOOTER));
721 //printf("g_footer='%s'\n",g_footer.data());
725 g_footer = ResourceMgr::instance().getAsString("footer.html");
728 if (Config_getBool(USE_MATHJAX))
730 if (!Config_getString(MATHJAX_CODEFILE).isEmpty())
732 g_mathjax_code=fileToString(Config_getString(MATHJAX_CODEFILE));
733 //printf("g_mathjax_code='%s'\n",g_mathjax_code.data());
738 ResourceMgr &mgr = ResourceMgr::instance();
739 if (Config_getBool(HTML_DYNAMIC_MENUS))
741 mgr.copyResourceAs("tabs.css",dname,"tabs.css");
743 else // stylesheet for the 'old' static tabs
745 mgr.copyResourceAs("fixed_tabs.css",dname,"tabs.css");
747 mgr.copyResource("jquery.js",dname);
748 if (Config_getBool(INTERACTIVE_SVG))
750 mgr.copyResource("svgpan.js",dname);
752 if (!Config_getBool(DISABLE_INDEX) && Config_getBool(HTML_DYNAMIC_MENUS))
754 mgr.copyResource("menu.js",dname);
758 QFile f(dname+"/dynsections.js");
759 if (f.open(IO_WriteOnly))
762 t << mgr.getAsString("dynsections.js");
763 if (Config_getBool(SOURCE_BROWSER) && Config_getBool(SOURCE_TOOLTIPS))
766 "$(document).ready(function() {\n"
767 " $('.code,.codeRef').each(function() {\n"
768 " $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n"
769 " $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n"
777 /// Additional initialization after indices have been created
778 void HtmlGenerator::writeTabData()
780 Doxygen::indexList->addStyleSheetFile("tabs.css");
781 QCString dname=Config_getString(HTML_OUTPUT);
782 ResourceMgr &mgr = ResourceMgr::instance();
783 //writeColoredImgData(dname,colored_tab_data);
784 mgr.copyResource("tab_a.lum",dname);
785 mgr.copyResource("tab_b.lum",dname);
786 mgr.copyResource("tab_h.lum",dname);
787 mgr.copyResource("tab_s.lum",dname);
788 mgr.copyResource("nav_h.lum",dname);
789 mgr.copyResource("nav_f.lum",dname);
790 mgr.copyResource("bc_s.luma",dname);
791 mgr.copyResource("doxygen.luma",dname);
792 mgr.copyResource("closed.luma",dname);
793 mgr.copyResource("open.luma",dname);
794 mgr.copyResource("bdwn.luma",dname);
795 mgr.copyResource("sync_on.luma",dname);
796 mgr.copyResource("sync_off.luma",dname);
799 // unsigned char shadow[6] = { 5, 5, 5, 5, 5, 5 };
800 // unsigned char shadow_alpha[6] = { 80, 60, 40, 20, 10, 0 };
801 // ColoredImage img(1,6,shadow,shadow_alpha,0,0,100);
802 // img.save(dname+"/nav_g.png");
804 mgr.copyResource("nav_g.png",dname);
807 void HtmlGenerator::writeSearchData(const char *dir)
809 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
810 //writeImgData(dir,serverBasedSearch ? search_server_data : search_client_data);
811 ResourceMgr &mgr = ResourceMgr::instance();
813 mgr.copyResource("search_l.png",dir);
814 Doxygen::indexList->addImageFile("search/search_l.png");
815 mgr.copyResource("search_m.png",dir);
816 Doxygen::indexList->addImageFile("search/search_m.png");
817 mgr.copyResource("search_r.png",dir);
818 Doxygen::indexList->addImageFile("search/search_r.png");
819 if (serverBasedSearch)
821 mgr.copyResource("mag.png",dir);
822 Doxygen::indexList->addImageFile("search/mag.png");
826 mgr.copyResource("close.png",dir);
827 Doxygen::indexList->addImageFile("search/close.png");
828 mgr.copyResource("mag_sel.png",dir);
829 Doxygen::indexList->addImageFile("search/mag_sel.png");
832 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
833 QFile f(searchDirName+"/search.css");
834 if (f.open(IO_WriteOnly))
838 if (Config_getBool(DISABLE_INDEX))
840 searchCss = mgr.getAsString("search_nomenu.css");
842 else if (!Config_getBool(HTML_DYNAMIC_MENUS))
844 searchCss = mgr.getAsString("search_fixedtabs.css");
848 searchCss = mgr.getAsString("search.css");
850 searchCss = substitute(replaceColorMarkers(searchCss),"$doxygenversion",versionString);
852 Doxygen::indexList->addStyleSheetFile("search/search.css");
856 void HtmlGenerator::writeStyleSheetFile(QFile &file)
858 FTextStream t(&file);
859 t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString));
862 void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/)
864 FTextStream t(&file);
865 t << "<!-- HTML header for doxygen " << versionString << "-->" << endl;
866 t << ResourceMgr::instance().getAsString("header.html");
869 void HtmlGenerator::writeFooterFile(QFile &file)
871 FTextStream t(&file);
872 t << "<!-- HTML footer for doxygen " << versionString << "-->" << endl;
873 t << ResourceMgr::instance().getAsString("footer.html");
876 void HtmlGenerator::startFile(const char *name,const char *,
879 //printf("HtmlGenerator::startFile(%s)\n",name);
880 QCString fileName=name;
882 relPath = relativePathToRoot(fileName);
884 if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension)
886 fileName+=Doxygen::htmlFileExtension;
888 startPlainFile(fileName);
889 m_codeGen.setTextStream(t);
890 m_codeGen.setRelativePath(relPath);
891 Doxygen::indexList->addIndexFile(fileName);
894 t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath);
896 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
897 << versionString << " -->" << endl;
898 //static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
899 static bool searchEngine = Config_getBool(SEARCHENGINE);
900 if (searchEngine /*&& !generateTreeView*/)
902 t << "<script type=\"text/javascript\">\n";
903 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
904 t << "var searchBox = new SearchBox(\"searchBox\", \""
905 << relPath<< "search\",false,'" << theTranslator->trSearch() << "');\n";
906 t << "/* @license-end */\n";
909 //generateDynamicSections(t,relPath);
913 void HtmlGenerator::writeSearchInfo(FTextStream &t,const QCString &relPath)
915 static bool searchEngine = Config_getBool(SEARCHENGINE);
916 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
917 if (searchEngine && !serverBasedSearch)
920 t << "<!-- window showing the filter options -->\n";
921 t << "<div id=\"MSearchSelectWindow\"\n";
922 t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
923 t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
924 t << " onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
927 t << "<!-- iframe showing the search results (closed by default) -->\n";
928 t << "<div id=\"MSearchResultsWindow\">\n";
929 t << "<iframe src=\"javascript:void(0)\" frameborder=\"0\" \n";
930 t << " name=\"MSearchResults\" id=\"MSearchResults\">\n";
937 void HtmlGenerator::writeSearchInfo()
939 writeSearchInfo(t,relPath);
943 QCString HtmlGenerator::writeLogoAsString(const char *path)
945 static bool timeStamp = Config_getBool(HTML_TIMESTAMP);
949 result += theTranslator->trGeneratedAt(
951 Config_getString(PROJECT_NAME)
956 result += theTranslator->trGeneratedBy();
958 result += " \n<a href=\"http://www.doxygen.org/index.html\">\n"
959 "<img class=\"footer\" src=\"";
961 result += "doxygen.png\" alt=\"doxygen\"/></a> ";
962 result += versionString;
967 void HtmlGenerator::writeLogo()
969 t << writeLogoAsString(relPath);
972 void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle,
973 const QCString &relPath,const QCString &navPath)
975 t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath);
978 void HtmlGenerator::writeFooter(const char *navPath)
980 writePageFooter(t,lastTitle,relPath,navPath);
983 void HtmlGenerator::endFile()
988 void HtmlGenerator::startProjectNumber()
990 t << "<h3 class=\"version\">";
993 void HtmlGenerator::endProjectNumber()
998 void HtmlGenerator::writeStyleInfo(int part)
1000 //printf("writeStyleInfo(%d)\n",part);
1003 if (Config_getString(HTML_STYLESHEET).isEmpty()) // write default style sheet
1005 //printf("write doxygen.css\n");
1006 startPlainFile("doxygen.css");
1008 // alternative, cooler looking titles
1009 //t << "H1 { text-align: center; border-width: thin none thin none;" << endl;
1010 //t << " border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl;
1012 t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString));
1014 Doxygen::indexList->addStyleSheetFile("doxygen.css");
1016 else // write user defined style sheet
1018 QCString cssname=Config_getString(HTML_STYLESHEET);
1019 QFileInfo cssfi(cssname);
1020 if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
1022 err("style sheet %s does not exist or is not readable!", Config_getString(HTML_STYLESHEET).data());
1026 // convert style sheet to string
1027 QCString fileStr = fileToString(cssname);
1028 // write the string into the output dir
1029 startPlainFile(cssfi.fileName().utf8());
1033 Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8());
1035 static QStrList extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
1036 for (uint i=0; i<extraCssFile.count(); ++i)
1038 QCString fileName(extraCssFile.at(i));
1039 if (!fileName.isEmpty())
1041 QFileInfo fi(fileName);
1044 Doxygen::indexList->addStyleSheetFile(fi.fileName().utf8());
1049 Doxygen::indexList->addStyleSheetFile("jquery.js");
1050 Doxygen::indexList->addStyleSheetFile("dynsections.js");
1051 if (Config_getBool(INTERACTIVE_SVG))
1053 Doxygen::indexList->addStyleSheetFile("svgpan.js");
1058 void HtmlGenerator::startDoxyAnchor(const char *,const char *,
1059 const char *anchor, const char *,
1062 t << "<a id=\"" << anchor << "\"></a>";
1065 void HtmlGenerator::endDoxyAnchor(const char *,const char *)
1069 //void HtmlGenerator::newParagraph()
1071 // t << endl << "<p>" << endl;
1074 void HtmlGenerator::startParagraph(const char *classDef)
1077 t << endl << "<p class=\"" << classDef << "\">";
1082 void HtmlGenerator::endParagraph()
1084 t << "</p>" << endl;
1087 void HtmlGenerator::writeString(const char *text)
1092 void HtmlGenerator::startIndexListItem()
1097 void HtmlGenerator::endIndexListItem()
1099 t << "</li>" << endl;
1102 void HtmlGenerator::startIndexItem(const char *ref,const char *f)
1104 //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
1109 t << "<a class=\"elRef\" ";
1110 t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1114 t << "<a class=\"el\" ";
1117 t << externalRef(relPath,ref,TRUE);
1118 if (f) t << f << Doxygen::htmlFileExtension << "\">";
1126 void HtmlGenerator::endIndexItem(const char *ref,const char *f)
1128 //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
1139 void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
1140 const char *path,const char *name)
1143 if (path) docify(path);
1144 t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">";
1149 void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
1150 const char *anchor, const char *name)
1154 t << "<a class=\"elRef\" ";
1155 t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1159 t << "<a class=\"el\" ";
1162 t << externalRef(relPath,ref,TRUE);
1163 if (f) t << f << Doxygen::htmlFileExtension;
1164 if (anchor) t << "#" << anchor;
1170 void HtmlGenerator::startTextLink(const char *f,const char *anchor)
1173 if (f) t << relPath << f << Doxygen::htmlFileExtension;
1174 if (anchor) t << "#" << anchor;
1178 void HtmlGenerator::endTextLink()
1183 void HtmlGenerator::startHtmlLink(const char *url)
1185 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
1187 if (generateTreeView) t << "target=\"top\" ";
1193 void HtmlGenerator::endHtmlLink()
1198 void HtmlGenerator::startGroupHeader(int extraIndentLevel)
1200 if (extraIndentLevel==2)
1202 t << "<h4 class=\"groupheader\">";
1204 else if (extraIndentLevel==1)
1206 t << "<h3 class=\"groupheader\">";
1208 else // extraIndentLevel==0
1210 t << "<h2 class=\"groupheader\">";
1214 void HtmlGenerator::endGroupHeader(int extraIndentLevel)
1216 if (extraIndentLevel==2)
1218 t << "</h4>" << endl;
1220 else if (extraIndentLevel==1)
1222 t << "</h3>" << endl;
1226 t << "</h2>" << endl;
1230 void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
1234 case SectionInfo::Page: t << "\n\n<h1>"; break;
1235 case SectionInfo::Section: t << "\n\n<h2>"; break;
1236 case SectionInfo::Subsection: t << "\n\n<h3>"; break;
1237 case SectionInfo::Subsubsection: t << "\n\n<h4>"; break;
1238 case SectionInfo::Paragraph: t << "\n\n<h5>"; break;
1239 default: ASSERT(0); break;
1241 t << "<a id=\"" << lab << "\"></a>";
1244 void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
1248 case SectionInfo::Page: t << "</h1>"; break;
1249 case SectionInfo::Section: t << "</h2>"; break;
1250 case SectionInfo::Subsection: t << "</h3>"; break;
1251 case SectionInfo::Subsubsection: t << "</h4>"; break;
1252 case SectionInfo::Paragraph: t << "</h5>"; break;
1253 default: ASSERT(0); break;
1257 void HtmlGenerator::docify(const char *str)
1262 void HtmlGenerator::docify(const char *str,bool inHtmlComment)
1273 case '<': t << "<"; break;
1274 case '>': t << ">"; break;
1275 case '&': t << "&"; break;
1276 case '"': t << """; break;
1277 case '-': if (inHtmlComment) t << "-"; else t << "-"; break;
1280 { t << "<"; p++; }
1282 { t << ">"; p++; }
1292 void HtmlGenerator::writeChar(char c)
1300 //--- helper function for dynamic sections -------------------------
1302 static void startSectionHeader(FTextStream &t,
1303 const QCString &relPath,int sectionCount)
1305 //t << "<!-- startSectionHeader -->";
1306 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1307 if (dynamicSections)
1309 t << "<div id=\"dynsection-" << sectionCount << "\" "
1310 "onclick=\"return toggleVisibility(this)\" "
1311 "class=\"dynheader closed\" "
1312 "style=\"cursor:pointer;\">" << endl;
1313 t << " <img id=\"dynsection-" << sectionCount << "-trigger\" src=\""
1314 << relPath << "closed.png\" alt=\"+\"/> ";
1318 t << "<div class=\"dynheader\">" << endl;
1322 static void endSectionHeader(FTextStream &t)
1324 //t << "<!-- endSectionHeader -->";
1325 t << "</div>" << endl;
1328 static void startSectionSummary(FTextStream &t,int sectionCount)
1330 //t << "<!-- startSectionSummary -->";
1331 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1332 if (dynamicSections)
1334 t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
1335 "class=\"dynsummary\" "
1336 "style=\"display:block;\">" << endl;
1340 static void endSectionSummary(FTextStream &t)
1342 //t << "<!-- endSectionSummary -->";
1343 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1344 if (dynamicSections)
1346 t << "</div>" << endl;
1350 static void startSectionContent(FTextStream &t,int sectionCount)
1352 //t << "<!-- startSectionContent -->";
1353 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1354 if (dynamicSections)
1356 t << "<div id=\"dynsection-" << sectionCount << "-content\" "
1357 "class=\"dyncontent\" "
1358 "style=\"display:none;\">" << endl;
1362 t << "<div class=\"dyncontent\">" << endl;
1366 static void endSectionContent(FTextStream &t)
1368 //t << "<!-- endSectionContent -->";
1369 t << "</div>" << endl;
1372 //----------------------------
1374 void HtmlGenerator::startClassDiagram()
1376 startSectionHeader(t,relPath,m_sectionCount);
1379 void HtmlGenerator::endClassDiagram(const ClassDiagram &d,
1380 const char *fileName,const char *name)
1382 endSectionHeader(t);
1383 startSectionSummary(t,m_sectionCount);
1384 endSectionSummary(t);
1385 startSectionContent(t,m_sectionCount);
1386 t << " <div class=\"center\">" << endl;
1387 t << " <img src=\"";
1388 t << relPath << fileName << ".png\" usemap=\"#" << convertToId(name);
1389 t << "_map\" alt=\"\"/>" << endl;
1390 t << " <map id=\"" << convertToId(name);
1391 t << "_map\" name=\"" << convertToId(name);
1392 t << "_map\">" << endl;
1394 d.writeImage(t,dir,relPath,fileName);
1396 endSectionContent(t);
1401 void HtmlGenerator::startMemberList()
1403 DBG_HTML(t << "<!-- startMemberList -->" << endl)
1406 void HtmlGenerator::endMemberList()
1408 DBG_HTML(t << "<!-- endMemberList -->" << endl)
1412 // 0 = single column right aligned
1413 // 1 = double column left aligned
1414 // 2 = single column left aligned
1415 void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char *inheritId)
1417 DBG_HTML(t << "<!-- startMemberItem() -->" << endl)
1420 t << "<table class=\"memberdecls\">" << endl;
1421 m_emptySection=FALSE;
1423 t << "<tr class=\"memitem:" << anchor;
1426 t << " inherit " << inheritId;
1431 case 0: t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
1432 case 1: t << "<td class=\"memItemLeft\" >"; break;
1433 case 2: t << "<td class=\"memItemLeft\" valign=\"top\">"; break;
1434 default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
1438 void HtmlGenerator::endMemberItem()
1444 void HtmlGenerator::startMemberTemplateParams()
1448 void HtmlGenerator::endMemberTemplateParams(const char *anchor,const char *inheritId)
1450 t << "</td></tr>" << endl;
1451 t << "<tr class=\"memitem:" << anchor;
1454 t << " inherit " << inheritId;
1456 t << "\"><td class=\"memTemplItemLeft\" align=\"right\" valign=\"top\">";
1460 void HtmlGenerator::insertMemberAlign(bool templ)
1462 DBG_HTML(t << "<!-- insertMemberAlign -->" << endl)
1463 QCString className = templ ? "memTemplItemRight" : "memItemRight";
1464 t << " </td><td class=\"" << className << "\" valign=\"bottom\">";
1467 void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId)
1469 DBG_HTML(t << "<!-- startMemberDescription -->" << endl)
1472 t << "<table class=\"memberdecls\">" << endl;
1473 m_emptySection=FALSE;
1475 t << "<tr class=\"memdesc:" << anchor;
1478 t << " inherit " << inheritId;
1480 t << "\"><td class=\"mdescLeft\"> </td><td class=\"mdescRight\">";
1483 void HtmlGenerator::endMemberDescription()
1485 DBG_HTML(t << "<!-- endMemberDescription -->" << endl)
1486 t << "<br /></td></tr>" << endl;
1489 void HtmlGenerator::startMemberSections()
1491 DBG_HTML(t << "<!-- startMemberSections -->" << endl)
1492 m_emptySection=TRUE; // we postpone writing <table> until we actually
1493 // write a row to prevent empty tables, which
1494 // are not valid XHTML!
1497 void HtmlGenerator::endMemberSections()
1499 DBG_HTML(t << "<!-- endMemberSections -->" << endl)
1500 if (!m_emptySection)
1502 t << "</table>" << endl;
1506 void HtmlGenerator::startMemberHeader(const char *anchor)
1508 DBG_HTML(t << "<!-- startMemberHeader -->" << endl)
1509 if (!m_emptySection)
1512 m_emptySection=TRUE;
1516 t << "<table class=\"memberdecls\">" << endl;
1517 m_emptySection=FALSE;
1519 t << "<tr class=\"heading\"><td colspan=\"2\"><h2 class=\"groupheader\">";
1522 t << "<a name=\"" << anchor << "\"></a>" << endl;
1526 void HtmlGenerator::endMemberHeader()
1528 DBG_HTML(t << "<!-- endMemberHeader -->" << endl)
1529 t << "</h2></td></tr>" << endl;
1532 void HtmlGenerator::startMemberSubtitle()
1534 DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl)
1535 t << "<tr><td class=\"ititle\" colspan=\"2\">";
1538 void HtmlGenerator::endMemberSubtitle()
1540 DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl)
1541 t << "</td></tr>" << endl;
1544 void HtmlGenerator::startIndexList()
1546 t << "<table>" << endl;
1549 void HtmlGenerator::endIndexList()
1551 t << "</table>" << endl;
1554 void HtmlGenerator::startIndexKey()
1556 // inserted 'class = ...', 02 jan 2002, jh
1557 t << " <tr><td class=\"indexkey\">";
1560 void HtmlGenerator::endIndexKey()
1565 void HtmlGenerator::startIndexValue(bool)
1567 // inserted 'class = ...', 02 jan 2002, jh
1568 t << "<td class=\"indexvalue\">";
1571 void HtmlGenerator::endIndexValue(const char *,bool)
1573 t << "</td></tr>" << endl;
1576 void HtmlGenerator::startMemberDocList()
1578 DBG_HTML(t << "<!-- startMemberDocList -->" << endl;)
1581 void HtmlGenerator::endMemberDocList()
1583 DBG_HTML(t << "<!-- endMemberDocList -->" << endl;)
1586 void HtmlGenerator::startMemberDoc( const char *clName, const char *memName,
1587 const char *anchor, const char *title,
1588 int memCount, int memTotal, bool showInline)
1590 DBG_HTML(t << "<!-- startMemberDoc -->" << endl;)
1591 t << "\n<h2 class=\"memtitle\">"
1592 << "<span class=\"permalink\"><a href=\"#" << anchor << "\">◆ </a></span>";
1596 t << " <span class=\"overload\">[" << memCount << "/" << memTotal <<"]</span>";
1600 t << "\n<div class=\"memitem\">" << endl;
1601 t << "<div class=\"memproto\">" << endl;
1604 void HtmlGenerator::startMemberDocPrefixItem()
1606 DBG_HTML(t << "<!-- startMemberDocPrefixItem -->" << endl;)
1607 t << "<div class=\"memtemplate\">" << endl;
1610 void HtmlGenerator::endMemberDocPrefixItem()
1612 DBG_HTML(t << "<!-- endMemberDocPrefixItem -->" << endl;)
1613 t << "</div>" << endl;
1616 void HtmlGenerator::startMemberDocName(bool /*align*/)
1618 DBG_HTML(t << "<!-- startMemberDocName -->" << endl;)
1620 t << " <table class=\"memname\">" << endl;
1622 t << " <tr>" << endl;
1623 t << " <td class=\"memname\">";
1626 void HtmlGenerator::endMemberDocName()
1628 DBG_HTML(t << "<!-- endMemberDocName -->" << endl;)
1629 t << "</td>" << endl;
1632 void HtmlGenerator::startParameterList(bool openBracket)
1634 DBG_HTML(t << "<!-- startParameterList -->" << endl;)
1636 if (openBracket) t << "(";
1637 t << "</td>" << endl;
1640 void HtmlGenerator::startParameterType(bool first,const char *key)
1644 DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
1645 t << " <td class=\"paramtype\">";
1649 DBG_HTML(t << "<!-- startParameterType -->" << endl;)
1650 t << " <tr>" << endl;
1651 t << " <td class=\"paramkey\">";
1653 t << "</td>" << endl;
1654 t << " <td></td>" << endl;
1655 t << " <td class=\"paramtype\">";
1659 void HtmlGenerator::endParameterType()
1661 DBG_HTML(t << "<!-- endParameterType -->" << endl;)
1662 t << " </td>" << endl;
1665 void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
1667 DBG_HTML(t << "<!-- startParameterName -->" << endl;)
1668 t << " <td class=\"paramname\">";
1671 void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket)
1673 DBG_HTML(t << "<!-- endParameterName -->" << endl;)
1678 if (closeBracket) t << "</td><td>)";
1679 t << "</td>" << endl;
1684 t << " </td>" << endl;
1685 t << " </tr>" << endl;
1686 t << " <tr>" << endl;
1687 t << " <td></td>" << endl;
1689 if (closeBracket) t << ")";
1690 t << "</td>" << endl;
1691 t << " <td></td><td>";
1696 t << "</td>" << endl;
1697 t << " </tr>" << endl;
1701 void HtmlGenerator::endParameterList()
1703 DBG_HTML(t << "<!-- endParameterList -->" << endl;)
1704 t << "</td>" << endl;
1705 t << " </tr>" << endl;
1708 void HtmlGenerator::exceptionEntry(const char* prefix,bool closeBracket)
1710 DBG_HTML(t << "<!-- exceptionEntry -->" << endl;)
1711 t << "</td>" << endl;
1712 t << " </tr>" << endl;
1713 t << " <tr>" << endl;
1714 t << " <td align=\"right\">";
1715 // colspan 2 so it gets both parameter type and parameter name columns
1717 t << prefix << "</td><td>(</td><td colspan=\"2\">";
1718 else if (closeBracket)
1719 t << "</td><td>)</td><td></td><td>";
1721 t << "</td><td></td><td colspan=\"2\">";
1724 void HtmlGenerator::endMemberDoc(bool hasArgs)
1726 DBG_HTML(t << "<!-- endMemberDoc -->" << endl;)
1729 t << " </tr>" << endl;
1731 t << " </table>" << endl;
1732 // t << "</div>" << endl;
1735 void HtmlGenerator::startDotGraph()
1737 startSectionHeader(t,relPath,m_sectionCount);
1740 void HtmlGenerator::endDotGraph(const DotClassGraph &g)
1742 bool generateLegend = Config_getBool(GENERATE_LEGEND);
1743 bool umlLook = Config_getBool(UML_LOOK);
1744 endSectionHeader(t);
1745 startSectionSummary(t,m_sectionCount);
1746 endSectionSummary(t);
1747 startSectionContent(t,m_sectionCount);
1749 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,TRUE,m_sectionCount);
1750 if (generateLegend && !umlLook)
1752 t << "<center><span class=\"legend\">[";
1753 startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension);
1754 t << theTranslator->trLegend();
1756 t << "]</span></center>";
1759 endSectionContent(t);
1763 void HtmlGenerator::startInclDepGraph()
1765 startSectionHeader(t,relPath,m_sectionCount);
1768 void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g)
1770 endSectionHeader(t);
1771 startSectionSummary(t,m_sectionCount);
1772 endSectionSummary(t);
1773 startSectionContent(t,m_sectionCount);
1775 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1777 endSectionContent(t);
1781 void HtmlGenerator::startGroupCollaboration()
1783 startSectionHeader(t,relPath,m_sectionCount);
1786 void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
1788 endSectionHeader(t);
1789 startSectionSummary(t,m_sectionCount);
1790 endSectionSummary(t);
1791 startSectionContent(t,m_sectionCount);
1793 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1795 endSectionContent(t);
1799 void HtmlGenerator::startCallGraph()
1801 startSectionHeader(t,relPath,m_sectionCount);
1804 void HtmlGenerator::endCallGraph(const DotCallGraph &g)
1806 endSectionHeader(t);
1807 startSectionSummary(t,m_sectionCount);
1808 endSectionSummary(t);
1809 startSectionContent(t,m_sectionCount);
1811 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1813 endSectionContent(t);
1817 void HtmlGenerator::startDirDepGraph()
1819 startSectionHeader(t,relPath,m_sectionCount);
1822 void HtmlGenerator::endDirDepGraph(const DotDirDeps &g)
1824 endSectionHeader(t);
1825 startSectionSummary(t,m_sectionCount);
1826 endSectionSummary(t);
1827 startSectionContent(t,m_sectionCount);
1829 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1831 endSectionContent(t);
1835 void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g)
1837 g.writeGraph(t,dir,fileName);
1840 void HtmlGenerator::startMemberGroupHeader(bool)
1842 t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
1845 void HtmlGenerator::endMemberGroupHeader()
1847 t << "</div></td></tr>" << endl;
1850 void HtmlGenerator::startMemberGroupDocs()
1852 t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
1855 void HtmlGenerator::endMemberGroupDocs()
1857 t << "</div></td></tr>" << endl;
1860 void HtmlGenerator::startMemberGroup()
1864 void HtmlGenerator::endMemberGroup(bool)
1868 void HtmlGenerator::startIndent()
1870 DBG_HTML(t << "<!-- startIndent -->" << endl;)
1872 t << "<div class=\"memdoc\">\n";
1875 void HtmlGenerator::endIndent()
1877 DBG_HTML(t << "<!-- endIndent -->" << endl;)
1878 t << endl << "</div>" << endl << "</div>" << endl;
1881 void HtmlGenerator::addIndexItem(const char *,const char *)
1885 void HtmlGenerator::writeNonBreakableSpace(int n)
1894 void HtmlGenerator::startDescTable(const char *title)
1896 t << "<table class=\"fieldtable\">" << endl
1897 << "<tr><th colspan=\"2\">" << title << "</th></tr>";
1899 void HtmlGenerator::endDescTable()
1901 t << "</table>" << endl;
1904 void HtmlGenerator::startDescTableRow()
1909 void HtmlGenerator::endDescTableRow()
1911 t << "</tr>" << endl;
1914 void HtmlGenerator::startDescTableTitle()
1916 t << "<td class=\"fieldname\">";
1919 void HtmlGenerator::endDescTableTitle()
1924 void HtmlGenerator::startDescTableData()
1926 t << "<td class=\"fielddoc\">";
1929 void HtmlGenerator::endDescTableData()
1934 void HtmlGenerator::startSimpleSect(SectionTypes,
1935 const char *filename,const char *anchor,
1941 writeObjectLink(0,filename,anchor,title);
1950 void HtmlGenerator::endSimpleSect()
1955 void HtmlGenerator::startParamList(ParamListTypes,
1963 void HtmlGenerator::endParamList()
1968 void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
1970 HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx);
1975 //---------------- helpers for index generation -----------------------------
1977 static void startQuickIndexList(FTextStream &t,bool compact,bool topLevel=TRUE)
1983 t << " <div id=\"navrow1\" class=\"tabs\">\n";
1987 t << " <div id=\"navrow2\" class=\"tabs2\">\n";
1989 t << " <ul class=\"tablist\">\n";
1997 static void endQuickIndexList(FTextStream &t,bool compact)
2010 static void startQuickIndexItem(FTextStream &t,const char *l,
2011 bool hl,bool /*compact*/,
2012 const QCString &relPath)
2017 t << " class=\"current\"";
2020 if (l) t << "<a href=\"" << correctURL(l,relPath) << "\">";
2024 static void endQuickIndexItem(FTextStream &t,const char *l)
2031 static bool quickLinkVisible(LayoutNavEntry::Kind kind)
2033 static bool showFiles = Config_getBool(SHOW_FILES);
2034 static bool showNamespaces = Config_getBool(SHOW_NAMESPACES);
2037 case LayoutNavEntry::MainPage: return TRUE;
2038 case LayoutNavEntry::User: return TRUE;
2039 case LayoutNavEntry::UserGroup: return TRUE;
2040 case LayoutNavEntry::Pages: return indexedPages>0;
2041 case LayoutNavEntry::Modules: return documentedGroups>0;
2042 case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces;
2043 case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces;
2044 case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0;
2045 case LayoutNavEntry::Classes: return annotatedClasses>0;
2046 case LayoutNavEntry::ClassList: return annotatedClasses>0;
2047 case LayoutNavEntry::ClassIndex: return annotatedClasses>0;
2048 case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0;
2049 case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0;
2050 case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles;
2051 case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles;
2052 case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0;
2053 //case LayoutNavEntry::Dirs: return documentedDirs>0;
2054 case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0;
2059 static void renderQuickLinksAsTree(FTextStream &t,const QCString &relPath,LayoutNavEntry *root)
2062 QListIterator<LayoutNavEntry> li(root->children());
2063 LayoutNavEntry *entry;
2065 for (li.toFirst();(entry=li.current());++li)
2067 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2069 if (count>0) // at least one item is visible
2071 startQuickIndexList(t,FALSE);
2072 for (li.toFirst();(entry=li.current());++li)
2074 if (entry->visible() && quickLinkVisible(entry->kind()))
2076 QCString url = entry->url();
2077 t << "<li><a href=\"" << relPath << url << "\"><span>";
2078 t << fixSpaces(entry->title());
2079 t << "</span></a>\n";
2080 // recursive into child list
2081 renderQuickLinksAsTree(t,relPath,entry);
2085 endQuickIndexList(t,FALSE);
2090 static void renderQuickLinksAsTabs(FTextStream &t,const QCString &relPath,
2091 LayoutNavEntry *hlEntry,LayoutNavEntry::Kind kind,
2092 bool highlightParent,bool highlightSearch)
2094 if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
2096 renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
2098 if (hlEntry->parent() && hlEntry->parent()->children().count()>0) // draw tabs for row containing hlEntry
2100 bool topLevel = hlEntry->parent()->parent()==0;
2101 QListIterator<LayoutNavEntry> li(hlEntry->parent()->children());
2102 LayoutNavEntry *entry;
2105 for (li.toFirst();(entry=li.current());++li)
2107 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2109 if (count>0) // at least one item is visible
2111 startQuickIndexList(t,TRUE,topLevel);
2112 for (li.toFirst();(entry=li.current());++li)
2114 if (entry->visible() && quickLinkVisible(entry->kind()))
2116 QCString url = entry->url();
2117 startQuickIndexItem(t,url,
2119 (entry->children().count()>0 ||
2120 (entry->kind()==kind && !highlightParent)
2123 t << fixSpaces(entry->title());
2124 endQuickIndexItem(t,url);
2127 if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
2129 static bool searchEngine = Config_getBool(SEARCHENGINE);
2130 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2134 if (!serverBasedSearch) // pure client side search
2136 writeClientSearchBox(t,relPath);
2139 else // server based search
2141 writeServerSearchBox(t,relPath,highlightSearch);
2142 if (!highlightSearch)
2148 if (!highlightSearch) // on the search page the index will be ended by the
2151 endQuickIndexList(t,TRUE);
2154 else // normal case for other rows than first one
2156 endQuickIndexList(t,TRUE);
2162 static void writeDefaultQuickLinks(FTextStream &t,bool compact,
2163 HighlightedItem hli,
2165 const QCString &relPath)
2167 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2168 static bool searchEngine = Config_getBool(SEARCHENGINE);
2169 static bool externalSearch = Config_getBool(EXTERNAL_SEARCH);
2170 LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry();
2171 LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1;
2172 LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file
2173 bool highlightParent=FALSE;
2174 switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
2176 case HLI_Main: kind = LayoutNavEntry::MainPage; break;
2177 case HLI_Modules: kind = LayoutNavEntry::Modules; break;
2178 //case HLI_Directories: kind = LayoutNavEntry::Dirs; break;
2179 case HLI_Namespaces: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; break;
2180 case HLI_Hierarchy: kind = LayoutNavEntry::ClassHierarchy; break;
2181 case HLI_Classes: kind = LayoutNavEntry::ClassIndex; altKind = LayoutNavEntry::Classes; break;
2182 case HLI_Annotated: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break;
2183 case HLI_Files: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; break;
2184 case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
2185 case HLI_Functions: kind = LayoutNavEntry::ClassMembers; break;
2186 case HLI_Globals: kind = LayoutNavEntry::FileGlobals; break;
2187 case HLI_Pages: kind = LayoutNavEntry::Pages; break;
2188 case HLI_Examples: kind = LayoutNavEntry::Examples; break;
2189 case HLI_UserGroup: kind = LayoutNavEntry::UserGroup; break;
2190 case HLI_ClassVisible: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes;
2191 highlightParent = TRUE; break;
2192 case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces;
2193 highlightParent = TRUE; break;
2194 case HLI_FileVisible: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files;
2195 highlightParent = TRUE; break;
2196 case HLI_None: break;
2197 case HLI_Search: break;
2200 if (compact && Config_getBool(HTML_DYNAMIC_MENUS))
2202 QCString searchPage;
2205 searchPage = "search" + Doxygen::htmlFileExtension;
2209 searchPage = "search.php";
2211 t << "<script type=\"text/javascript\" src=\"" << relPath << "menudata.js\"></script>" << endl;
2212 t << "<script type=\"text/javascript\" src=\"" << relPath << "menu.js\"></script>" << endl;
2213 t << "<script type=\"text/javascript\">" << endl;
2214 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2215 t << "$(function() {" << endl;
2216 t << " initMenu('" << relPath << "',"
2217 << (searchEngine?"true":"false") << ","
2218 << (serverBasedSearch?"true":"false") << ",'"
2219 << searchPage << "','"
2220 << theTranslator->trSearch() << "');" << endl;
2221 if (Config_getBool(SEARCHENGINE))
2223 if (!serverBasedSearch)
2225 t << " $(document).ready(function() { init_search(); });\n";
2229 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2230 t << " $(document).ready(function() {\n"
2231 << " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
2236 t << "/* @license-end */";
2237 t << "</script>" << endl;
2238 t << "<div id=\"main-nav\"></div>" << endl;
2240 else if (compact) // && !Config_getBool(HTML_DYNAMIC_MENUS)
2242 // find highlighted index item
2243 LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : 0);
2244 if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; }
2245 if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
2247 highlightParent=TRUE;
2248 hlEntry = root->children().getFirst();
2251 return; // argl, empty index!
2254 if (kind==LayoutNavEntry::UserGroup)
2256 LayoutNavEntry *e = hlEntry->children().getFirst();
2262 renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HLI_Search);
2266 renderQuickLinksAsTree(t,relPath,root);
2270 void HtmlGenerator::endQuickIndices()
2272 t << "</div><!-- top -->" << endl;
2275 QCString HtmlGenerator::writeSplitBarAsString(const char *name,const char *relpath)
2277 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2280 if (generateTreeView)
2283 "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n"
2284 " <div id=\"nav-tree\">\n"
2285 " <div id=\"nav-tree-contents\">\n"
2286 " <div id=\"nav-sync\" class=\"sync\"></div>\n"
2289 " <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
2290 " class=\"ui-resizable-handle\">\n"
2293 "<script type=\"text/javascript\">\n"
2294 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
2295 "$(document).ready(function(){initNavTree('") +
2296 QCString(name) + Doxygen::htmlFileExtension +
2297 QCString("','") + relpath +
2299 "/* @license-end */\n"
2301 "<div id=\"doc-content\">\n");
2306 void HtmlGenerator::writeSplitBar(const char *name)
2308 t << writeSplitBarAsString(name,relPath);
2311 void HtmlGenerator::writeNavigationPath(const char *s)
2313 t << substitute(s,"$relpath^",relPath);
2316 void HtmlGenerator::startContents()
2318 t << "<div class=\"contents\">" << endl;
2321 void HtmlGenerator::endContents()
2323 t << "</div><!-- contents -->" << endl;
2326 void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
2328 writeDefaultQuickLinks(t,compact,hli,file,relPath);
2331 // PHP based search script
2332 void HtmlGenerator::writeSearchPage()
2334 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2335 static bool disableIndex = Config_getBool(DISABLE_INDEX);
2336 static QCString projectName = Config_getString(PROJECT_NAME);
2337 static QCString htmlOutput = Config_getString(HTML_OUTPUT);
2339 // OPENSEARCH_PROVIDER {
2340 QCString configFileName = htmlOutput+"/search_config.php";
2341 QFile cf(configFileName);
2342 if (cf.open(IO_WriteOnly))
2345 t << "<script language=\"php\">\n\n";
2346 t << "$config = array(\n";
2347 t << " 'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
2348 t << " 'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
2349 t << " 'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
2351 t << "$translator = array(\n";
2352 t << " 'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
2353 t << " 'search_results' => array(\n";
2354 t << " 0 => \"" << theTranslator->trSearchResults(0) << "\",\n";
2355 t << " 1 => \"" << theTranslator->trSearchResults(1) << "\",\n";
2356 t << " 2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";
2358 t << " 'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
2359 t << " 'search' => \"" << theTranslator->trSearch() << "\",\n";
2360 t << " 'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n";
2361 t << " 'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
2366 ResourceMgr::instance().copyResource("search_functions.php",htmlOutput);
2367 ResourceMgr::instance().copyResource("search_opensearch.php",htmlOutput);
2368 // OPENSEARCH_PROVIDER }
2370 QCString fileName = htmlOutput+"/search.php";
2372 if (f.open(IO_WriteOnly))
2375 t << substituteHtmlKeywords(g_header,"Search","");
2377 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
2378 << versionString << " -->" << endl;
2379 t << "<script type=\"text/javascript\">\n";
2380 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2381 t << "var searchBox = new SearchBox(\"searchBox\", \""
2382 << "search\",false,'" << theTranslator->trSearch() << "');\n";
2383 t << "/* @license-end */\n";
2385 if (!Config_getBool(DISABLE_INDEX))
2387 writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
2391 t << "</div>" << endl;
2394 t << "<script language=\"php\">\n";
2395 t << "require_once \"search_functions.php\";\n";
2399 // Write empty navigation path, to make footer connect properly
2400 if (generateTreeView)
2402 t << "</div><!-- doc-content -->\n";
2405 writePageFooter(t,"Search","","");
2407 QCString scriptName = htmlOutput+"/search/search.js";
2408 QFile sf(scriptName);
2409 if (sf.open(IO_WriteOnly))
2412 t << ResourceMgr::instance().getAsString("extsearch.js");
2416 err("Failed to open file '%s' for writing...\n",scriptName.data());
2420 void HtmlGenerator::writeExternalSearchPage()
2422 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2423 static bool disableIndex = Config_getBool(DISABLE_INDEX);
2424 QCString fileName = Config_getString(HTML_OUTPUT)+"/search"+Doxygen::htmlFileExtension;
2426 if (f.open(IO_WriteOnly))
2429 t << substituteHtmlKeywords(g_header,"Search","");
2431 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
2432 << versionString << " -->" << endl;
2433 t << "<script type=\"text/javascript\">\n";
2434 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2435 t << "var searchBox = new SearchBox(\"searchBox\", \""
2436 << "search\",false,'" << theTranslator->trSearch() << "');\n";
2437 t << "/* @license-end */\n";
2439 if (!Config_getBool(DISABLE_INDEX))
2441 writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
2442 t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
2444 t << " </div><div class=\"right\"></div>\n";
2453 t << "</div>" << endl;
2455 t << writeSplitBarAsString("search","");
2456 t << "<div class=\"header\">" << endl;
2457 t << " <div class=\"headertitle\">" << endl;
2458 t << " <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>" << endl;
2459 t << " </div>" << endl;
2460 t << "</div>" << endl;
2461 t << "<div class=\"contents\">" << endl;
2463 t << "<div id=\"searchresults\"></div>" << endl;
2464 t << "</div>" << endl;
2466 if (generateTreeView)
2468 t << "</div><!-- doc-content -->" << endl;
2471 writePageFooter(t,"Search","","");
2474 QCString scriptName = Config_getString(HTML_OUTPUT)+"/search/search.js";
2475 QFile sf(scriptName);
2476 if (sf.open(IO_WriteOnly))
2479 t << "var searchResultsText=["
2480 << "\"" << theTranslator->trSearchResults(0) << "\","
2481 << "\"" << theTranslator->trSearchResults(1) << "\","
2482 << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl;
2483 t << "var serverUrl=\"" << Config_getString(SEARCHENGINE_URL) << "\";" << endl;
2484 t << "var tagMap = {" << endl;
2486 // add search mappings
2487 QStrList &extraSearchMappings = Config_getList(EXTRA_SEARCH_MAPPINGS);
2488 char *ml=extraSearchMappings.first();
2491 QCString mapLine = ml;
2492 int eqPos = mapLine.find('=');
2493 if (eqPos!=-1) // tag command contains a destination
2495 QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
2496 QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
2497 if (!tagName.isEmpty())
2499 if (!first) t << "," << endl;
2500 t << " \"" << tagName << "\": \"" << destName << "\"";
2504 ml=extraSearchMappings.next();
2506 if (!first) t << endl;
2507 t << "};" << endl << endl;
2508 t << ResourceMgr::instance().getAsString("extsearch.js");
2510 t << "$(document).ready(function() {" << endl;
2511 t << " var query = trim(getURLParameter('query'));" << endl;
2512 t << " if (query) {" << endl;
2513 t << " searchFor(query,0,20);" << endl;
2514 t << " } else {" << endl;
2515 t << " var results = $('#results');" << endl;
2516 t << " results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');" << endl;
2522 err("Failed to open file '%s' for writing...\n",scriptName.data());
2526 void HtmlGenerator::startConstraintList(const char *header)
2528 t << "<div class=\"typeconstraint\">" << endl;
2529 t << "<dl><dt><b>" << header << "</b></dt><dd>" << endl;
2530 t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
2533 void HtmlGenerator::startConstraintParam()
2535 t << "<tr><td valign=\"top\"><em>";
2538 void HtmlGenerator::endConstraintParam()
2543 void HtmlGenerator::startConstraintType()
2545 t << "<td> :</td><td valign=\"top\"><em>";
2548 void HtmlGenerator::endConstraintType()
2553 void HtmlGenerator::startConstraintDocs()
2558 void HtmlGenerator::endConstraintDocs()
2560 t << "</td></tr>" << endl;
2563 void HtmlGenerator::endConstraintList()
2565 t << "</table>" << endl;
2566 t << "</dd>" << endl;
2567 t << "</dl>" << endl;
2568 t << "</div>" << endl;
2571 void HtmlGenerator::lineBreak(const char *style)
2575 t << "<br class=\"" << style << "\" />" << endl;
2579 t << "<br />" << endl;
2583 void HtmlGenerator::startHeaderSection()
2585 t << "<div class=\"header\">" << endl;
2588 void HtmlGenerator::startTitleHead(const char *)
2590 t << " <div class=\"headertitle\">" << endl;
2594 void HtmlGenerator::endTitleHead(const char *,const char *)
2597 t << " </div>" << endl;
2600 void HtmlGenerator::endHeaderSection()
2602 t << "</div><!--header-->" << endl;
2605 void HtmlGenerator::startInlineHeader()
2609 t << "<table class=\"memberdecls\">" << endl;
2610 m_emptySection=FALSE;
2612 t << "<tr><td colspan=\"2\"><h3>";
2615 void HtmlGenerator::endInlineHeader()
2617 t << "</h3></td></tr>" << endl;
2620 void HtmlGenerator::startMemberDocSimple(bool isEnum)
2622 DBG_HTML(t << "<!-- startMemberDocSimple -->" << endl;)
2623 t << "<table class=\"fieldtable\">" << endl;
2624 t << "<tr><th colspan=\"" << (isEnum?"2":"3") << "\">";
2625 t << (isEnum? theTranslator->trEnumerationValues() :
2626 theTranslator->trCompoundMembers()) << "</th></tr>" << endl;
2629 void HtmlGenerator::endMemberDocSimple(bool)
2631 DBG_HTML(t << "<!-- endMemberDocSimple -->" << endl;)
2632 t << "</table>" << endl;
2635 void HtmlGenerator::startInlineMemberType()
2637 DBG_HTML(t << "<!-- startInlineMemberType -->" << endl;)
2638 t << "<tr><td class=\"fieldtype\">" << endl;
2641 void HtmlGenerator::endInlineMemberType()
2643 DBG_HTML(t << "<!-- endInlineMemberType -->" << endl;)
2644 t << "</td>" << endl;
2647 void HtmlGenerator::startInlineMemberName()
2649 DBG_HTML(t << "<!-- startInlineMemberName -->" << endl;)
2650 t << "<td class=\"fieldname\">" << endl;
2653 void HtmlGenerator::endInlineMemberName()
2655 DBG_HTML(t << "<!-- endInlineMemberName -->" << endl;)
2656 t << "</td>" << endl;
2659 void HtmlGenerator::startInlineMemberDoc()
2661 DBG_HTML(t << "<!-- startInlineMemberDoc -->" << endl;)
2662 t << "<td class=\"fielddoc\">" << endl;
2665 void HtmlGenerator::endInlineMemberDoc()
2667 DBG_HTML(t << "<!-- endInlineMemberDoc -->" << endl;)
2668 t << "</td></tr>" << endl;
2671 void HtmlGenerator::startLabels()
2673 DBG_HTML(t << "<!-- startLabels -->" << endl;)
2674 t << "<span class=\"mlabels\">";
2677 void HtmlGenerator::writeLabel(const char *l,bool /*isLast*/)
2679 DBG_HTML(t << "<!-- writeLabel(" << l << ") -->" << endl;)
2680 //t << "<tt>[" << l << "]</tt>";
2681 //if (!isLast) t << ", ";
2682 t << "<span class=\"mlabel\">" << l << "</span>";
2685 void HtmlGenerator::endLabels()
2687 DBG_HTML(t << "<!-- endLabels -->" << endl;)
2691 void HtmlGenerator::writeInheritedSectionTitle(
2692 const char *id, const char *ref,
2693 const char *file, const char *anchor,
2694 const char *title, const char *name)
2696 DBG_HTML(t << "<!-- writeInheritedSectionTitle -->" << endl;)
2697 QCString a = anchor;
2698 if (!a.isEmpty()) a.prepend("#");
2699 QCString classLink = QCString("<a class=\"el\" href=\"");
2702 classLink+= externalLinkTarget() + externalRef(relPath,ref,TRUE);
2708 classLink+=file+Doxygen::htmlFileExtension+a;
2709 classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
2710 t << "<tr class=\"inherit_header " << id << "\">"
2711 << "<td colspan=\"2\" onclick=\"javascript:toggleInherit('" << id << "')\">"
2712 << "<img src=\"" << relPath << "closed.png\" alt=\"-\"/> "
2713 << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
2714 << "</td></tr>" << endl;
2717 void HtmlGenerator::writeSummaryLink(const char *file,const char *anchor,const char *title,bool first)
2721 t << " <div class=\"summary\">\n";
2730 t << relPath << file;
2731 t << Doxygen::htmlFileExtension;
2743 void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritId)
2745 t << "<tr class=\"separator:" << anchor;
2748 t << " inherit " << inheritId;
2750 t << "\"><td class=\"memSeparator\" colspan=\"2\"> </td></tr>\n";
2753 void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile)
2755 if (Doxygen::searchIndex)
2757 Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile);
2761 void HtmlGenerator::addWord(const char *word,bool hiPriority)
2763 if (Doxygen::searchIndex)
2765 Doxygen::searchIndex->addWord(word,hiPriority);