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.
34 #include "docparser.h"
35 #include "htmldocvisitor.h"
36 #include "searchindex.h"
40 #include "vhdldocgen.h"
45 #include "resourcemgr.h"
48 //#define DBG_HTML(x) x;
51 static QCString g_header;
52 static QCString g_footer;
53 static QCString g_mathjax_code;
56 // note: this is only active if DISABLE_INDEX=YES, if DISABLE_INDEX is disabled, this
57 // part will be rendered inside menu.js
58 static void writeClientSearchBox(FTextStream &t,const char *relPath)
60 t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
61 t << " <span class=\"left\">\n";
62 t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n";
63 t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
64 t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
66 t << " <input type=\"text\" id=\"MSearchField\" value=\""
67 << theTranslator->trSearch() << "\" accesskey=\"S\"\n";
68 t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
69 t << " onblur=\"searchBox.OnSearchFieldFocus(false)\" \n";
70 t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
71 t << " </span><span class=\"right\">\n";
72 t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
73 << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n";
78 // note: this is only active if DISABLE_INDEX=YES. if DISABLE_INDEX is disabled, this
79 // part will be rendered inside menu.js
80 static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch)
82 static bool externalSearch = Config_getBool(EXTERNAL_SEARCH);
83 t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
84 t << " <div class=\"left\">\n";
85 t << " <form id=\"FSearchBox\" action=\"" << relPath;
88 t << "search" << Doxygen::htmlFileExtension;
94 t << "\" method=\"get\">\n";
95 t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n";
98 t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\""
99 << theTranslator->trSearch() << "\" size=\"20\" accesskey=\"S\" \n";
100 t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
101 t << " onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
103 t << " </div><div class=\"right\"></div>\n";
108 //------------------------------------------------------------------------
110 /// Clear a text block \a s from \a begin to \a end markers
111 QCString clearBlock(const char *s,const char *begin,const char *end)
113 if (s==0 || begin==0 || end==0) return s;
115 int beginLen = qstrlen(begin);
116 int endLen = qstrlen(end);
118 for (p=s; (q=strstr(p,begin))!=0; p=q+endLen)
122 if ((q=strstr(p,end))==0)
129 // resLen is the length of the string without the marked block
131 QCString result(resLen+1);
133 for (r=result.rawData(), p=s; (q=strstr(p,begin))!=0; p=q+endLen)
139 if ((q=strstr(p,end))==0)
141 memcpy(r,begin,beginLen);
149 //----------------------------------------------------------------------
151 QCString selectBlock(const QCString& s,const QCString &name,bool enable)
153 // TODO: this is an expensive function that is called a lot -> optimize it
154 const QCString begin = "<!--BEGIN " + name + "-->";
155 const QCString end = "<!--END " + name + "-->";
156 const QCString nobegin = "<!--BEGIN !" + name + "-->";
157 const QCString noend = "<!--END !" + name + "-->";
162 result = substitute(result, begin, "");
163 result = substitute(result, end, "");
164 result = clearBlock(result, nobegin, noend);
168 result = substitute(result, nobegin, "");
169 result = substitute(result, noend, "");
170 result = clearBlock(result, begin, end);
176 static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
179 FTextStream t(&result);
182 writeServerSearchBox(t, relPath, highlightSearch);
186 writeClientSearchBox(t, relPath);
188 return QCString(result);
191 static QCString removeEmptyLines(const QCString &s)
193 BufStr out(s.length()+1);
194 const char *p=s.data();
203 while (*e==' ' || *e=='\t') e++;
217 //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data());
221 static QCString substituteHtmlKeywords(const QCString &s,
222 const QCString &title,
223 const QCString &relPath,
224 const QCString &navPath=QCString())
226 // Build CSS/Javascript tags depending on treeview, search engine settings
228 QStrList extraCssFile;
229 QCString generatedBy;
230 QCString treeViewCssJs;
231 QCString searchCssJs;
234 QCString extraCssText;
236 static QCString projectName = Config_getString(PROJECT_NAME);
237 static bool timeStamp = Config_getBool(HTML_TIMESTAMP);
238 static bool treeView = Config_getBool(GENERATE_TREEVIEW);
239 static bool searchEngine = Config_getBool(SEARCHENGINE);
240 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
241 static bool mathJax = Config_getBool(USE_MATHJAX);
242 static QCString mathJaxFormat = Config_getEnum(MATHJAX_FORMAT);
243 static bool disableIndex = Config_getBool(DISABLE_INDEX);
244 static bool hasProjectName = !projectName.isEmpty();
245 static bool hasProjectNumber = !Config_getString(PROJECT_NUMBER).isEmpty();
246 static bool hasProjectBrief = !Config_getString(PROJECT_BRIEF).isEmpty();
247 static bool hasProjectLogo = !Config_getString(PROJECT_LOGO).isEmpty();
248 static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine));
250 cssFile = Config_getString(HTML_STYLESHEET);
251 if (cssFile.isEmpty())
253 cssFile = "doxygen.css";
257 QFileInfo cssfi(cssFile);
260 cssFile = cssfi.fileName().utf8();
264 cssFile = "doxygen.css";
269 extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
270 for (uint i=0; i<extraCssFile.count(); ++i)
272 QCString fileName(extraCssFile.at(i));
273 if (!fileName.isEmpty())
275 QFileInfo fi(fileName);
278 extraCssText += "<link href=\"$relpath^"+stripPath(fileName)+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
285 generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), convertToHtml(Config_getString(PROJECT_NAME)));
289 generatedBy = theTranslator->trGeneratedBy();
294 treeViewCssJs = "<link href=\"$relpath^navtree.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
295 "<script type=\"text/javascript\" src=\"$relpath^resize.js\"></script>\n"
296 "<script type=\"text/javascript\" src=\"$relpath^navtreedata.js\"></script>\n"
297 "<script type=\"text/javascript\" src=\"$relpath^navtree.js\"></script>\n"
298 "<script type=\"text/javascript\">\n"
299 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
300 " $(document).ready(initResizable);\n"
307 searchCssJs = "<link href=\"$relpath^search/search.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
308 if (!serverBasedSearch)
310 searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/searchdata.js\"></script>\n";
312 searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/search.js\"></script>\n";
314 if (!serverBasedSearch)
316 if (disableIndex || !Config_getBool(HTML_DYNAMIC_MENUS))
318 searchCssJs += "<script type=\"text/javascript\">\n"
319 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
320 " $(document).ready(function() { init_search(); });\n"
321 "/* @license-end */\n"
327 if (disableIndex || !Config_getBool(HTML_DYNAMIC_MENUS))
329 searchCssJs += "<script type=\"text/javascript\">\n"
330 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
331 " $(document).ready(function() {\n"
332 " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
334 " /* @license-end */\n"
338 // OPENSEARCH_PROVIDER {
339 searchCssJs += "<link rel=\"search\" href=\"" + relPath +
340 "search_opensearch.php?v=opensearch.xml\" "
341 "type=\"application/opensearchdescription+xml\" title=\"" +
342 (hasProjectName ? projectName : QCString("Doxygen")) +
344 // OPENSEARCH_PROVIDER }
346 searchBox = getSearchBox(serverBasedSearch, relPath, FALSE);
351 QCString path = Config_getString(MATHJAX_RELPATH);
352 if (path.isEmpty() || path.left(2)=="..") // relative path
354 path.prepend(relPath);
356 mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
357 " MathJax.Hub.Config({\n"
358 " extensions: [\"tex2jax.js\"";
359 QStrList &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
360 const char *s = mathJaxExtensions.first();
363 mathJaxJs+= ", \""+QCString(s)+".js\"";
364 s = mathJaxExtensions.next();
366 if (mathJaxFormat.isEmpty())
368 mathJaxFormat = "HTML-CSS";
371 " jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n"
373 if (!g_mathjax_code.isEmpty())
375 mathJaxJs += g_mathjax_code;
378 mathJaxJs += "</script>";
379 mathJaxJs += "<script type=\"text/javascript\" async=\"async\" src=\"" + path + "MathJax.js\"></script>\n";
382 // first substitute generic keywords
383 QCString result = substituteKeywords(s,title,
384 convertToHtml(Config_getString(PROJECT_NAME)),
385 convertToHtml(Config_getString(PROJECT_NUMBER)),
386 convertToHtml(Config_getString(PROJECT_BRIEF)));
388 // additional HTML only keywords
389 result = substitute(result,"$navpath",navPath);
390 result = substitute(result,"$stylesheet",cssFile);
391 result = substitute(result,"$treeview",treeViewCssJs);
392 result = substitute(result,"$searchbox",searchBox);
393 result = substitute(result,"$search",searchCssJs);
394 result = substitute(result,"$mathjax",mathJaxJs);
395 result = substitute(result,"$generatedby",generatedBy);
396 result = substitute(result,"$extrastylesheet",extraCssText);
397 result = substitute(result,"$relpath$",relPath); //<-- obsolete: for backwards compatibility only
398 result = substitute(result,"$relpath^",relPath); //<-- must be last
400 // additional HTML only conditional blocks
401 result = selectBlock(result,"DISABLE_INDEX",disableIndex);
402 result = selectBlock(result,"GENERATE_TREEVIEW",treeView);
403 result = selectBlock(result,"SEARCHENGINE",searchEngine);
404 result = selectBlock(result,"TITLEAREA",titleArea);
405 result = selectBlock(result,"PROJECT_NAME",hasProjectName);
406 result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber);
407 result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief);
408 result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo);
410 result = removeEmptyLines(result);
415 //--------------------------------------------------------------------------
417 HtmlCodeGenerator::HtmlCodeGenerator()
418 : m_streamSet(FALSE), m_col(0)
422 HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath)
423 : m_col(0), m_relPath(relPath)
428 void HtmlCodeGenerator::setTextStream(FTextStream &t)
430 m_streamSet = t.device()!=0;
431 m_t.setDevice(t.device());
434 void HtmlCodeGenerator::setRelativePath(const QCString &path)
439 void HtmlCodeGenerator::codify(const char *str)
441 static int tabSize = Config_getInt(TAB_SIZE);
442 if (str && m_streamSet)
446 int spacesToNextTabStop;
452 case '\t': spacesToNextTabStop =
453 tabSize - (m_col%tabSize);
454 m_t << Doxygen::spaces.left(spacesToNextTabStop);
455 m_col+=spacesToNextTabStop;
457 case '\n': m_t << "\n"; m_col=0;
460 case '<': m_t << "<"; m_col++;
462 case '>': m_t << ">"; m_col++;
464 case '&': m_t << "&"; m_col++;
466 case '\'': m_t << "'"; m_col++; // ' is not valid XHTML
468 case '"': m_t << """; m_col++;
472 { m_t << "<"; p++; }
474 { m_t << ">"; p++; }
479 default: p=writeUtf8Char(m_t,p-1);
487 void HtmlCodeGenerator::docify(const char *str)
489 m_t << getHtmlDirEmbedingChar(getTextDirByConfig(str));
491 if (str && m_streamSet)
500 case '<': m_t << "<"; break;
501 case '>': m_t << ">"; break;
502 case '&': m_t << "&"; break;
503 case '"': m_t << """; break;
506 { m_t << "<"; p++; }
508 { m_t << ">"; p++; }
518 void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename,
519 const char *anchor,int l)
521 if (!m_streamSet) return;
522 const int maxLineNrStr = 10;
523 char lineNumber[maxLineNrStr];
524 char lineAnchor[maxLineNrStr];
525 qsnprintf(lineNumber,maxLineNrStr,"%5d",l);
526 qsnprintf(lineAnchor,maxLineNrStr,"l%05d",l);
528 m_t << "<div class=\"line\">";
529 m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">";
532 _writeCodeLink("line",ref,filename,anchor,lineNumber,0);
542 void HtmlCodeGenerator::writeCodeLink(const char *ref,const char *f,
543 const char *anchor, const char *name,
546 if (!m_streamSet) return;
547 //printf("writeCodeLink(ref=%s,f=%s,anchor=%s,name=%s,tooltip=%s)\n",ref,f,anchor,name,tooltip);
548 _writeCodeLink("code",ref,f,anchor,name,tooltip);
551 void HtmlCodeGenerator::_writeCodeLink(const char *className,
552 const char *ref,const char *f,
553 const char *anchor, const char *name,
558 m_t << "<a class=\"" << className << "Ref\" ";
559 m_t << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
563 m_t << "<a class=\"" << className << "\" ";
566 m_t << externalRef(m_relPath,ref,TRUE);
567 if (f) m_t << f << Doxygen::htmlFileExtension;
568 if (anchor) m_t << "#" << anchor;
570 if (tooltip) m_t << " title=\"" << convertToHtml(tooltip) << "\"";
574 m_col+=qstrlen(name);
577 void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo,
578 const char *decl, const char *desc,
579 const SourceLinkInfo &defInfo,
580 const SourceLinkInfo &declInfo)
582 m_t << "<div class=\"ttc\" id=\"" << id << "\">";
583 m_t << "<div class=\"ttname\">";
584 if (!docInfo.url.isEmpty())
587 m_t << externalRef(m_relPath,docInfo.ref,TRUE);
588 m_t << docInfo.url << Doxygen::htmlFileExtension;
589 if (!docInfo.anchor.isEmpty())
591 m_t << "#" << docInfo.anchor;
595 docify(docInfo.name);
596 if (!docInfo.url.isEmpty())
603 m_t << "<div class=\"ttdeci\">";
609 m_t << "<div class=\"ttdoc\">";
613 if (!defInfo.file.isEmpty())
615 m_t << "<div class=\"ttdef\"><b>Definition:</b> ";
616 if (!defInfo.url.isEmpty())
619 m_t << externalRef(m_relPath,defInfo.ref,TRUE);
620 m_t << defInfo.url << Doxygen::htmlFileExtension;
621 if (!defInfo.anchor.isEmpty())
623 m_t << "#" << defInfo.anchor;
627 m_t << defInfo.file << ":" << defInfo.line;
628 if (!defInfo.url.isEmpty())
634 if (!declInfo.file.isEmpty())
636 m_t << "<div class=\"ttdecl\"><b>Declaration:</b> ";
637 if (!declInfo.url.isEmpty())
640 m_t << externalRef(m_relPath,declInfo.ref,TRUE);
641 m_t << declInfo.url << Doxygen::htmlFileExtension;
642 if (!declInfo.anchor.isEmpty())
644 m_t << "#" << declInfo.anchor;
648 m_t << declInfo.file << ":" << declInfo.line;
649 if (!declInfo.url.isEmpty())
655 m_t << "</div>" << endl;
659 void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers)
663 if (!hasLineNumbers) m_t << "<div class=\"line\">";
668 void HtmlCodeGenerator::endCodeLine()
670 if (m_streamSet) m_t << "</div>";
673 void HtmlCodeGenerator::startFontClass(const char *s)
675 if (m_streamSet) m_t << "<span class=\"" << s << "\">";
678 void HtmlCodeGenerator::endFontClass()
680 if (m_streamSet) m_t << "</span>";
683 void HtmlCodeGenerator::writeCodeAnchor(const char *anchor)
685 if (m_streamSet) m_t << "<a name=\"" << anchor << "\"></a>";
688 //--------------------------------------------------------------------------
690 HtmlGenerator::HtmlGenerator() : OutputGenerator()
692 dir=Config_getString(HTML_OUTPUT);
693 m_emptySection=FALSE;
697 HtmlGenerator::~HtmlGenerator()
699 //printf("HtmlGenerator::~HtmlGenerator()\n");
702 void HtmlGenerator::init()
704 QCString dname=Config_getString(HTML_OUTPUT);
706 if (!d.exists() && !d.mkdir(dname))
708 err("Could not create output directory %s\n",dname.data());
712 if (!Config_getString(HTML_HEADER).isEmpty())
714 g_header=fileToString(Config_getString(HTML_HEADER));
715 //printf("g_header='%s'\n",g_header.data());
719 g_header = ResourceMgr::instance().getAsString("header.html");
722 if (!Config_getString(HTML_FOOTER).isEmpty())
724 g_footer=fileToString(Config_getString(HTML_FOOTER));
725 //printf("g_footer='%s'\n",g_footer.data());
729 g_footer = ResourceMgr::instance().getAsString("footer.html");
732 if (Config_getBool(USE_MATHJAX))
734 if (!Config_getString(MATHJAX_CODEFILE).isEmpty())
736 g_mathjax_code=fileToString(Config_getString(MATHJAX_CODEFILE));
737 //printf("g_mathjax_code='%s'\n",g_mathjax_code.data());
742 ResourceMgr &mgr = ResourceMgr::instance();
743 if (Config_getBool(HTML_DYNAMIC_MENUS))
745 mgr.copyResourceAs("tabs.css",dname,"tabs.css");
747 else // stylesheet for the 'old' static tabs
749 mgr.copyResourceAs("fixed_tabs.css",dname,"tabs.css");
751 mgr.copyResource("jquery.js",dname);
752 if (Config_getBool(INTERACTIVE_SVG))
754 mgr.copyResource("svgpan.js",dname);
756 if (!Config_getBool(DISABLE_INDEX) && Config_getBool(HTML_DYNAMIC_MENUS))
758 mgr.copyResource("menu.js",dname);
762 QFile f(dname+"/dynsections.js");
763 if (f.open(IO_WriteOnly))
766 t << mgr.getAsString("dynsections.js");
767 if (Config_getBool(SOURCE_BROWSER) && Config_getBool(SOURCE_TOOLTIPS))
770 "$(document).ready(function() {\n"
771 " $('.code,.codeRef').each(function() {\n"
772 " $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n"
773 " $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n"
781 /// Additional initialization after indices have been created
782 void HtmlGenerator::writeTabData()
784 Doxygen::indexList->addStyleSheetFile("tabs.css");
785 QCString dname=Config_getString(HTML_OUTPUT);
786 ResourceMgr &mgr = ResourceMgr::instance();
787 //writeColoredImgData(dname,colored_tab_data);
788 mgr.copyResource("tab_a.lum",dname);
789 mgr.copyResource("tab_b.lum",dname);
790 mgr.copyResource("tab_h.lum",dname);
791 mgr.copyResource("tab_s.lum",dname);
792 mgr.copyResource("nav_h.lum",dname);
793 mgr.copyResource("nav_f.lum",dname);
794 mgr.copyResource("bc_s.luma",dname);
795 mgr.copyResource("doxygen.luma",dname);
796 mgr.copyResource("closed.luma",dname);
797 mgr.copyResource("open.luma",dname);
798 mgr.copyResource("bdwn.luma",dname);
799 mgr.copyResource("sync_on.luma",dname);
800 mgr.copyResource("sync_off.luma",dname);
803 // unsigned char shadow[6] = { 5, 5, 5, 5, 5, 5 };
804 // unsigned char shadow_alpha[6] = { 80, 60, 40, 20, 10, 0 };
805 // ColoredImage img(1,6,shadow,shadow_alpha,0,0,100);
806 // img.save(dname+"/nav_g.png");
808 mgr.copyResource("nav_g.png",dname);
811 void HtmlGenerator::writeSearchData(const char *dir)
813 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
814 //writeImgData(dir,serverBasedSearch ? search_server_data : search_client_data);
815 ResourceMgr &mgr = ResourceMgr::instance();
817 mgr.copyResource("search_l.png",dir);
818 Doxygen::indexList->addImageFile("search/search_l.png");
819 mgr.copyResource("search_m.png",dir);
820 Doxygen::indexList->addImageFile("search/search_m.png");
821 mgr.copyResource("search_r.png",dir);
822 Doxygen::indexList->addImageFile("search/search_r.png");
823 if (serverBasedSearch)
825 mgr.copyResource("mag.png",dir);
826 Doxygen::indexList->addImageFile("search/mag.png");
830 mgr.copyResource("close.png",dir);
831 Doxygen::indexList->addImageFile("search/close.png");
832 mgr.copyResource("mag_sel.png",dir);
833 Doxygen::indexList->addImageFile("search/mag_sel.png");
836 QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
837 QFile f(searchDirName+"/search.css");
838 if (f.open(IO_WriteOnly))
842 if (Config_getBool(DISABLE_INDEX))
844 searchCss = mgr.getAsString("search_nomenu.css");
846 else if (!Config_getBool(HTML_DYNAMIC_MENUS))
848 searchCss = mgr.getAsString("search_fixedtabs.css");
852 searchCss = mgr.getAsString("search.css");
854 searchCss = substitute(replaceColorMarkers(searchCss),"$doxygenversion",versionString);
856 Doxygen::indexList->addStyleSheetFile("search/search.css");
860 void HtmlGenerator::writeStyleSheetFile(QFile &file)
862 FTextStream t(&file);
863 t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString));
866 void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/)
868 FTextStream t(&file);
869 t << "<!-- HTML header for doxygen " << versionString << "-->" << endl;
870 t << ResourceMgr::instance().getAsString("header.html");
873 void HtmlGenerator::writeFooterFile(QFile &file)
875 FTextStream t(&file);
876 t << "<!-- HTML footer for doxygen " << versionString << "-->" << endl;
877 t << ResourceMgr::instance().getAsString("footer.html");
880 void HtmlGenerator::startFile(const char *name,const char *,
883 //printf("HtmlGenerator::startFile(%s)\n",name);
884 QCString fileName=name;
886 relPath = relativePathToRoot(fileName);
888 if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension)
890 fileName+=Doxygen::htmlFileExtension;
892 startPlainFile(fileName);
893 m_codeGen.setTextStream(t);
894 m_codeGen.setRelativePath(relPath);
895 Doxygen::indexList->addIndexFile(fileName);
898 t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath);
900 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
901 << versionString << " -->" << endl;
902 //static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
903 static bool searchEngine = Config_getBool(SEARCHENGINE);
904 if (searchEngine /*&& !generateTreeView*/)
906 t << "<script type=\"text/javascript\">\n";
907 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
908 t << "var searchBox = new SearchBox(\"searchBox\", \""
909 << relPath<< "search\",false,'" << theTranslator->trSearch() << "');\n";
910 t << "/* @license-end */\n";
913 //generateDynamicSections(t,relPath);
917 void HtmlGenerator::writeSearchInfo(FTextStream &t,const QCString &relPath)
919 static bool searchEngine = Config_getBool(SEARCHENGINE);
920 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
921 if (searchEngine && !serverBasedSearch)
924 t << "<!-- window showing the filter options -->\n";
925 t << "<div id=\"MSearchSelectWindow\"\n";
926 t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
927 t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
928 t << " onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
931 t << "<!-- iframe showing the search results (closed by default) -->\n";
932 t << "<div id=\"MSearchResultsWindow\">\n";
933 t << "<iframe src=\"javascript:void(0)\" frameborder=\"0\" \n";
934 t << " name=\"MSearchResults\" id=\"MSearchResults\">\n";
941 void HtmlGenerator::writeSearchInfo()
943 writeSearchInfo(t,relPath);
947 QCString HtmlGenerator::writeLogoAsString(const char *path)
949 static bool timeStamp = Config_getBool(HTML_TIMESTAMP);
953 result += theTranslator->trGeneratedAt(
955 Config_getString(PROJECT_NAME)
960 result += theTranslator->trGeneratedBy();
962 result += " \n<a href=\"http://www.doxygen.org/index.html\">\n"
963 "<img class=\"footer\" src=\"";
965 result += "doxygen.png\" alt=\"doxygen\"/></a> ";
966 result += versionString;
971 void HtmlGenerator::writeLogo()
973 t << writeLogoAsString(relPath);
976 void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle,
977 const QCString &relPath,const QCString &navPath)
979 t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath);
982 void HtmlGenerator::writeFooter(const char *navPath)
984 writePageFooter(t,lastTitle,relPath,navPath);
987 void HtmlGenerator::endFile()
992 void HtmlGenerator::startProjectNumber()
994 t << "<h3 class=\"version\">";
997 void HtmlGenerator::endProjectNumber()
1002 void HtmlGenerator::writeStyleInfo(int part)
1004 //printf("writeStyleInfo(%d)\n",part);
1007 if (Config_getString(HTML_STYLESHEET).isEmpty()) // write default style sheet
1009 //printf("write doxygen.css\n");
1010 startPlainFile("doxygen.css");
1012 // alternative, cooler looking titles
1013 //t << "H1 { text-align: center; border-width: thin none thin none;" << endl;
1014 //t << " border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl;
1016 t << replaceColorMarkers(substitute(ResourceMgr::instance().getAsString("doxygen.css"),"$doxygenversion",versionString));
1018 Doxygen::indexList->addStyleSheetFile("doxygen.css");
1020 else // write user defined style sheet
1022 QCString cssname=Config_getString(HTML_STYLESHEET);
1023 QFileInfo cssfi(cssname);
1024 if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
1026 err("style sheet %s does not exist or is not readable!", Config_getString(HTML_STYLESHEET).data());
1030 // convert style sheet to string
1031 QCString fileStr = fileToString(cssname);
1032 // write the string into the output dir
1033 startPlainFile(cssfi.fileName().utf8());
1037 Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8());
1039 static QStrList extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
1040 for (uint i=0; i<extraCssFile.count(); ++i)
1042 QCString fileName(extraCssFile.at(i));
1043 if (!fileName.isEmpty())
1045 QFileInfo fi(fileName);
1048 Doxygen::indexList->addStyleSheetFile(fi.fileName().utf8());
1053 Doxygen::indexList->addStyleSheetFile("jquery.js");
1054 Doxygen::indexList->addStyleSheetFile("dynsections.js");
1055 if (Config_getBool(INTERACTIVE_SVG))
1057 Doxygen::indexList->addStyleSheetFile("svgpan.js");
1062 void HtmlGenerator::startDoxyAnchor(const char *,const char *,
1063 const char *anchor, const char *,
1066 t << "<a id=\"" << anchor << "\"></a>";
1069 void HtmlGenerator::endDoxyAnchor(const char *,const char *)
1073 //void HtmlGenerator::newParagraph()
1075 // t << endl << "<p>" << endl;
1078 void HtmlGenerator::startParagraph(const char *classDef)
1081 t << endl << "<p class=\"" << classDef << "\">";
1086 void HtmlGenerator::endParagraph()
1088 t << "</p>" << endl;
1091 void HtmlGenerator::writeString(const char *text)
1096 void HtmlGenerator::startIndexListItem()
1101 void HtmlGenerator::endIndexListItem()
1103 t << "</li>" << endl;
1106 void HtmlGenerator::startIndexItem(const char *ref,const char *f)
1108 //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
1113 t << "<a class=\"elRef\" ";
1114 t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1118 t << "<a class=\"el\" ";
1121 t << externalRef(relPath,ref,TRUE);
1122 if (f) t << f << Doxygen::htmlFileExtension;
1131 void HtmlGenerator::endIndexItem(const char *ref,const char *f)
1133 //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
1144 void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
1145 const char *path,const char *name)
1148 if (path) docify(path);
1149 t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">";
1154 void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
1155 const char *anchor, const char *name)
1159 t << "<a class=\"elRef\" ";
1160 t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1164 t << "<a class=\"el\" ";
1167 t << externalRef(relPath,ref,TRUE);
1168 if (f) t << f << Doxygen::htmlFileExtension;
1169 if (anchor) t << "#" << anchor;
1175 void HtmlGenerator::startTextLink(const char *f,const char *anchor)
1178 if (f) t << relPath << f << Doxygen::htmlFileExtension;
1179 if (anchor) t << "#" << anchor;
1183 void HtmlGenerator::endTextLink()
1188 void HtmlGenerator::startHtmlLink(const char *url)
1190 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
1192 if (generateTreeView) t << "target=\"top\" ";
1198 void HtmlGenerator::endHtmlLink()
1203 void HtmlGenerator::startGroupHeader(int extraIndentLevel)
1205 if (extraIndentLevel==2)
1207 t << "<h4 class=\"groupheader\">";
1209 else if (extraIndentLevel==1)
1211 t << "<h3 class=\"groupheader\">";
1213 else // extraIndentLevel==0
1215 t << "<h2 class=\"groupheader\">";
1219 void HtmlGenerator::endGroupHeader(int extraIndentLevel)
1221 if (extraIndentLevel==2)
1223 t << "</h4>" << endl;
1225 else if (extraIndentLevel==1)
1227 t << "</h3>" << endl;
1231 t << "</h2>" << endl;
1235 void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
1239 case SectionInfo::Page: t << "\n\n<h1>"; break;
1240 case SectionInfo::Section: t << "\n\n<h2>"; break;
1241 case SectionInfo::Subsection: t << "\n\n<h3>"; break;
1242 case SectionInfo::Subsubsection: t << "\n\n<h4>"; break;
1243 case SectionInfo::Paragraph: t << "\n\n<h5>"; break;
1244 default: ASSERT(0); break;
1246 t << "<a id=\"" << lab << "\"></a>";
1249 void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
1253 case SectionInfo::Page: t << "</h1>"; break;
1254 case SectionInfo::Section: t << "</h2>"; break;
1255 case SectionInfo::Subsection: t << "</h3>"; break;
1256 case SectionInfo::Subsubsection: t << "</h4>"; break;
1257 case SectionInfo::Paragraph: t << "</h5>"; break;
1258 default: ASSERT(0); break;
1262 void HtmlGenerator::docify(const char *str)
1267 void HtmlGenerator::docify(const char *str,bool inHtmlComment)
1278 case '<': t << "<"; break;
1279 case '>': t << ">"; break;
1280 case '&': t << "&"; break;
1281 case '"': t << """; break;
1282 case '-': if (inHtmlComment) t << "-"; else t << "-"; break;
1285 { t << "<"; p++; }
1287 { t << ">"; p++; }
1297 void HtmlGenerator::writeChar(char c)
1305 //--- helper function for dynamic sections -------------------------
1307 static void startSectionHeader(FTextStream &t,
1308 const QCString &relPath,int sectionCount)
1310 //t << "<!-- startSectionHeader -->";
1311 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1312 if (dynamicSections)
1314 t << "<div id=\"dynsection-" << sectionCount << "\" "
1315 "onclick=\"return toggleVisibility(this)\" "
1316 "class=\"dynheader closed\" "
1317 "style=\"cursor:pointer;\">" << endl;
1318 t << " <img id=\"dynsection-" << sectionCount << "-trigger\" src=\""
1319 << relPath << "closed.png\" alt=\"+\"/> ";
1323 t << "<div class=\"dynheader\">" << endl;
1327 static void endSectionHeader(FTextStream &t)
1329 //t << "<!-- endSectionHeader -->";
1330 t << "</div>" << endl;
1333 static void startSectionSummary(FTextStream &t,int sectionCount)
1335 //t << "<!-- startSectionSummary -->";
1336 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1337 if (dynamicSections)
1339 t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
1340 "class=\"dynsummary\" "
1341 "style=\"display:block;\">" << endl;
1345 static void endSectionSummary(FTextStream &t)
1347 //t << "<!-- endSectionSummary -->";
1348 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1349 if (dynamicSections)
1351 t << "</div>" << endl;
1355 static void startSectionContent(FTextStream &t,int sectionCount)
1357 //t << "<!-- startSectionContent -->";
1358 static bool dynamicSections = Config_getBool(HTML_DYNAMIC_SECTIONS);
1359 if (dynamicSections)
1361 t << "<div id=\"dynsection-" << sectionCount << "-content\" "
1362 "class=\"dyncontent\" "
1363 "style=\"display:none;\">" << endl;
1367 t << "<div class=\"dyncontent\">" << endl;
1371 static void endSectionContent(FTextStream &t)
1373 //t << "<!-- endSectionContent -->";
1374 t << "</div>" << endl;
1377 //----------------------------
1379 void HtmlGenerator::startClassDiagram()
1381 startSectionHeader(t,relPath,m_sectionCount);
1384 void HtmlGenerator::endClassDiagram(const ClassDiagram &d,
1385 const char *fileName,const char *name)
1388 FTextStream tt(&result);
1390 endSectionHeader(t);
1391 startSectionSummary(t,m_sectionCount);
1392 endSectionSummary(t);
1393 startSectionContent(t,m_sectionCount);
1394 d.writeImage(tt,dir,relPath,fileName);
1395 if (!result.isEmpty())
1397 t << " <div class=\"center\">" << endl;
1398 t << " <img src=\"";
1399 t << relPath << fileName << ".png\" usemap=\"#" << convertToId(name);
1400 t << "_map\" alt=\"\"/>" << endl;
1401 t << " <map id=\"" << convertToId(name);
1402 t << "_map\" name=\"" << convertToId(name);
1403 t << "_map\">" << endl;
1405 t << " </map>" << endl;
1410 t << " <div class=\"center\">" << endl;
1411 t << " <img src=\"";
1412 t << relPath << fileName << ".png\" alt=\"\"/>" << endl;
1415 endSectionContent(t);
1420 void HtmlGenerator::startMemberList()
1422 DBG_HTML(t << "<!-- startMemberList -->" << endl)
1425 void HtmlGenerator::endMemberList()
1427 DBG_HTML(t << "<!-- endMemberList -->" << endl)
1431 // 0 = single column right aligned
1432 // 1 = double column left aligned
1433 // 2 = single column left aligned
1434 void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char *inheritId)
1436 DBG_HTML(t << "<!-- startMemberItem() -->" << endl)
1439 t << "<table class=\"memberdecls\">" << endl;
1440 m_emptySection=FALSE;
1442 t << "<tr class=\"memitem:" << anchor;
1445 t << " inherit " << inheritId;
1448 insertMemberAlignLeft(annoType, true);
1451 void HtmlGenerator::endMemberItem()
1457 void HtmlGenerator::startMemberTemplateParams()
1461 void HtmlGenerator::endMemberTemplateParams(const char *anchor,const char *inheritId)
1463 t << "</td></tr>" << endl;
1464 t << "<tr class=\"memitem:" << anchor;
1467 t << " inherit " << inheritId;
1469 t << "\"><td class=\"memTemplItemLeft\" align=\"right\" valign=\"top\">";
1473 void HtmlGenerator::insertMemberAlign(bool templ)
1475 DBG_HTML(t << "<!-- insertMemberAlign -->" << endl)
1476 QCString className = templ ? "memTemplItemRight" : "memItemRight";
1477 t << " </td><td class=\"" << className << "\" valign=\"bottom\">";
1480 void HtmlGenerator::insertMemberAlignLeft(int annoType, bool initTag)
1482 if (!initTag) t << " </td>";
1485 case 0: t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
1486 case 1: t << "<td class=\"memItemLeft\" >"; break;
1487 case 2: t << "<td class=\"memItemLeft\" valign=\"top\">"; break;
1488 default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
1492 void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId, bool typ)
1494 DBG_HTML(t << "<!-- startMemberDescription -->" << endl)
1497 t << "<table class=\"memberdecls\">" << endl;
1498 m_emptySection=FALSE;
1500 t << "<tr class=\"memdesc:" << anchor;
1503 t << " inherit " << inheritId;
1506 t << "<td class=\"mdescLeft\"> </td>";
1507 if (typ) t << "<td class=\"mdescLeft\"> </td>";
1508 t << "<td class=\"mdescRight\">";;
1511 void HtmlGenerator::endMemberDescription()
1513 DBG_HTML(t << "<!-- endMemberDescription -->" << endl)
1514 t << "<br /></td></tr>" << endl;
1517 void HtmlGenerator::startMemberSections()
1519 DBG_HTML(t << "<!-- startMemberSections -->" << endl)
1520 m_emptySection=TRUE; // we postpone writing <table> until we actually
1521 // write a row to prevent empty tables, which
1522 // are not valid XHTML!
1525 void HtmlGenerator::endMemberSections()
1527 DBG_HTML(t << "<!-- endMemberSections -->" << endl)
1528 if (!m_emptySection)
1530 t << "</table>" << endl;
1534 void HtmlGenerator::startMemberHeader(const char *anchor, int typ)
1536 DBG_HTML(t << "<!-- startMemberHeader -->" << endl)
1537 if (!m_emptySection)
1540 m_emptySection=TRUE;
1544 t << "<table class=\"memberdecls\">" << endl;
1545 m_emptySection=FALSE;
1547 t << "<tr class=\"heading\"><td colspan=\"" << typ << "\"><h2 class=\"groupheader\">";
1550 t << "<a name=\"" << anchor << "\"></a>" << endl;
1554 void HtmlGenerator::endMemberHeader()
1556 DBG_HTML(t << "<!-- endMemberHeader -->" << endl)
1557 t << "</h2></td></tr>" << endl;
1560 void HtmlGenerator::startMemberSubtitle()
1562 DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl)
1563 t << "<tr><td class=\"ititle\" colspan=\"2\">";
1566 void HtmlGenerator::endMemberSubtitle()
1568 DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl)
1569 t << "</td></tr>" << endl;
1572 void HtmlGenerator::startIndexList()
1574 t << "<table>" << endl;
1577 void HtmlGenerator::endIndexList()
1579 t << "</table>" << endl;
1582 void HtmlGenerator::startIndexKey()
1584 // inserted 'class = ...', 02 jan 2002, jh
1585 t << " <tr><td class=\"indexkey\">";
1588 void HtmlGenerator::endIndexKey()
1593 void HtmlGenerator::startIndexValue(bool)
1595 // inserted 'class = ...', 02 jan 2002, jh
1596 t << "<td class=\"indexvalue\">";
1599 void HtmlGenerator::endIndexValue(const char *,bool)
1601 t << "</td></tr>" << endl;
1604 void HtmlGenerator::startMemberDocList()
1606 DBG_HTML(t << "<!-- startMemberDocList -->" << endl;)
1609 void HtmlGenerator::endMemberDocList()
1611 DBG_HTML(t << "<!-- endMemberDocList -->" << endl;)
1614 void HtmlGenerator::startMemberDoc( const char *clName, const char *memName,
1615 const char *anchor, const char *title,
1616 int memCount, int memTotal, bool showInline)
1618 DBG_HTML(t << "<!-- startMemberDoc -->" << endl;)
1619 t << "\n<h2 class=\"memtitle\">"
1620 << "<span class=\"permalink\"><a href=\"#" << anchor << "\">◆ </a></span>";
1624 t << " <span class=\"overload\">[" << memCount << "/" << memTotal <<"]</span>";
1628 t << "\n<div class=\"memitem\">" << endl;
1629 t << "<div class=\"memproto\">" << endl;
1632 void HtmlGenerator::startMemberDocPrefixItem()
1634 DBG_HTML(t << "<!-- startMemberDocPrefixItem -->" << endl;)
1635 t << "<div class=\"memtemplate\">" << endl;
1638 void HtmlGenerator::endMemberDocPrefixItem()
1640 DBG_HTML(t << "<!-- endMemberDocPrefixItem -->" << endl;)
1641 t << "</div>" << endl;
1644 void HtmlGenerator::startMemberDocName(bool /*align*/)
1646 DBG_HTML(t << "<!-- startMemberDocName -->" << endl;)
1648 t << " <table class=\"memname\">" << endl;
1650 t << " <tr>" << endl;
1651 t << " <td class=\"memname\">";
1654 void HtmlGenerator::endMemberDocName()
1656 DBG_HTML(t << "<!-- endMemberDocName -->" << endl;)
1657 t << "</td>" << endl;
1660 void HtmlGenerator::startParameterList(bool openBracket)
1662 DBG_HTML(t << "<!-- startParameterList -->" << endl;)
1664 if (openBracket) t << "(";
1665 t << "</td>" << endl;
1668 void HtmlGenerator::startParameterType(bool first,const char *key)
1672 DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
1673 t << " <td class=\"paramtype\">";
1677 DBG_HTML(t << "<!-- startParameterType -->" << endl;)
1678 t << " <tr>" << endl;
1679 t << " <td class=\"paramkey\">";
1681 t << "</td>" << endl;
1682 t << " <td></td>" << endl;
1683 t << " <td class=\"paramtype\">";
1687 void HtmlGenerator::endParameterType()
1689 DBG_HTML(t << "<!-- endParameterType -->" << endl;)
1690 t << " </td>" << endl;
1693 void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
1695 DBG_HTML(t << "<!-- startParameterName -->" << endl;)
1696 t << " <td class=\"paramname\">";
1699 void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket)
1701 DBG_HTML(t << "<!-- endParameterName -->" << endl;)
1706 if (closeBracket) t << "</td><td>)";
1707 t << "</td>" << endl;
1712 t << " </td>" << endl;
1713 t << " </tr>" << endl;
1714 t << " <tr>" << endl;
1715 t << " <td></td>" << endl;
1717 if (closeBracket) t << ")";
1718 t << "</td>" << endl;
1719 t << " <td></td><td>";
1724 t << "</td>" << endl;
1725 t << " </tr>" << endl;
1729 void HtmlGenerator::endParameterList()
1731 DBG_HTML(t << "<!-- endParameterList -->" << endl;)
1732 t << "</td>" << endl;
1733 t << " </tr>" << endl;
1736 void HtmlGenerator::exceptionEntry(const char* prefix,bool closeBracket)
1738 DBG_HTML(t << "<!-- exceptionEntry -->" << endl;)
1739 t << "</td>" << endl;
1740 t << " </tr>" << endl;
1741 t << " <tr>" << endl;
1742 t << " <td align=\"right\">";
1743 // colspan 2 so it gets both parameter type and parameter name columns
1745 t << prefix << "</td><td>(</td><td colspan=\"2\">";
1746 else if (closeBracket)
1747 t << "</td><td>)</td><td></td><td>";
1749 t << "</td><td></td><td colspan=\"2\">";
1752 void HtmlGenerator::endMemberDoc(bool hasArgs)
1754 DBG_HTML(t << "<!-- endMemberDoc -->" << endl;)
1757 t << " </tr>" << endl;
1759 t << " </table>" << endl;
1760 // t << "</div>" << endl;
1763 void HtmlGenerator::startDotGraph()
1765 startSectionHeader(t,relPath,m_sectionCount);
1768 void HtmlGenerator::endDotGraph(const DotClassGraph &g)
1770 bool generateLegend = Config_getBool(GENERATE_LEGEND);
1771 bool umlLook = Config_getBool(UML_LOOK);
1772 endSectionHeader(t);
1773 startSectionSummary(t,m_sectionCount);
1774 endSectionSummary(t);
1775 startSectionContent(t,m_sectionCount);
1777 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,TRUE,m_sectionCount);
1778 if (generateLegend && !umlLook)
1780 t << "<center><span class=\"legend\">[";
1781 startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension);
1782 t << theTranslator->trLegend();
1784 t << "]</span></center>";
1787 endSectionContent(t);
1791 void HtmlGenerator::startInclDepGraph()
1793 startSectionHeader(t,relPath,m_sectionCount);
1796 void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g)
1798 endSectionHeader(t);
1799 startSectionSummary(t,m_sectionCount);
1800 endSectionSummary(t);
1801 startSectionContent(t,m_sectionCount);
1803 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1805 endSectionContent(t);
1809 void HtmlGenerator::startGroupCollaboration()
1811 startSectionHeader(t,relPath,m_sectionCount);
1814 void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
1816 endSectionHeader(t);
1817 startSectionSummary(t,m_sectionCount);
1818 endSectionSummary(t);
1819 startSectionContent(t,m_sectionCount);
1821 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1823 endSectionContent(t);
1827 void HtmlGenerator::startCallGraph()
1829 startSectionHeader(t,relPath,m_sectionCount);
1832 void HtmlGenerator::endCallGraph(const DotCallGraph &g)
1834 endSectionHeader(t);
1835 startSectionSummary(t,m_sectionCount);
1836 endSectionSummary(t);
1837 startSectionContent(t,m_sectionCount);
1839 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1841 endSectionContent(t);
1845 void HtmlGenerator::startDirDepGraph()
1847 startSectionHeader(t,relPath,m_sectionCount);
1850 void HtmlGenerator::endDirDepGraph(const DotDirDeps &g)
1852 endSectionHeader(t);
1853 startSectionSummary(t,m_sectionCount);
1854 endSectionSummary(t);
1855 startSectionContent(t,m_sectionCount);
1857 g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);
1859 endSectionContent(t);
1863 void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g)
1865 g.writeGraph(t,dir,fileName);
1868 void HtmlGenerator::startMemberGroupHeader(bool)
1870 t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
1873 void HtmlGenerator::endMemberGroupHeader()
1875 t << "</div></td></tr>" << endl;
1878 void HtmlGenerator::startMemberGroupDocs()
1880 t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
1883 void HtmlGenerator::endMemberGroupDocs()
1885 t << "</div></td></tr>" << endl;
1888 void HtmlGenerator::startMemberGroup()
1892 void HtmlGenerator::endMemberGroup(bool)
1896 void HtmlGenerator::startIndent()
1898 DBG_HTML(t << "<!-- startIndent -->" << endl;)
1900 t << "<div class=\"memdoc\">\n";
1903 void HtmlGenerator::endIndent()
1905 DBG_HTML(t << "<!-- endIndent -->" << endl;)
1906 t << endl << "</div>" << endl << "</div>" << endl;
1909 void HtmlGenerator::addIndexItem(const char *,const char *)
1913 void HtmlGenerator::writeNonBreakableSpace(int n)
1922 void HtmlGenerator::startDescTable(const char *title)
1924 t << "<table class=\"fieldtable\">" << endl
1925 << "<tr><th colspan=\"2\">" << title << "</th></tr>";
1927 void HtmlGenerator::endDescTable()
1929 t << "</table>" << endl;
1932 void HtmlGenerator::startDescTableRow()
1937 void HtmlGenerator::endDescTableRow()
1939 t << "</tr>" << endl;
1942 void HtmlGenerator::startDescTableTitle()
1944 t << "<td class=\"fieldname\">";
1947 void HtmlGenerator::endDescTableTitle()
1952 void HtmlGenerator::startDescTableData()
1954 t << "<td class=\"fielddoc\">";
1957 void HtmlGenerator::endDescTableData()
1962 void HtmlGenerator::startExamples()
1964 t << "<dl class=\"section examples\"><dt>";
1965 docify(theTranslator->trExamples());
1969 void HtmlGenerator::endExamples()
1971 t << "</dl>" << endl;
1974 void HtmlGenerator::startParamList(ParamListTypes,
1982 void HtmlGenerator::endParamList()
1987 void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
1989 HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx);
1994 //---------------- helpers for index generation -----------------------------
1996 static void startQuickIndexList(FTextStream &t,bool compact,bool topLevel=TRUE)
2002 t << " <div id=\"navrow1\" class=\"tabs\">\n";
2006 t << " <div id=\"navrow2\" class=\"tabs2\">\n";
2008 t << " <ul class=\"tablist\">\n";
2016 static void endQuickIndexList(FTextStream &t,bool compact)
2029 static void startQuickIndexItem(FTextStream &t,const char *l,
2030 bool hl,bool /*compact*/,
2031 const QCString &relPath)
2036 t << " class=\"current\"";
2039 if (l) t << "<a href=\"" << correctURL(l,relPath) << "\">";
2043 static void endQuickIndexItem(FTextStream &t,const char *l)
2050 static bool quickLinkVisible(LayoutNavEntry::Kind kind)
2052 static bool showFiles = Config_getBool(SHOW_FILES);
2053 static bool showNamespaces = Config_getBool(SHOW_NAMESPACES);
2056 case LayoutNavEntry::MainPage: return TRUE;
2057 case LayoutNavEntry::User: return TRUE;
2058 case LayoutNavEntry::UserGroup: return TRUE;
2059 case LayoutNavEntry::Pages: return indexedPages>0;
2060 case LayoutNavEntry::Modules: return documentedGroups>0;
2061 case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces;
2062 case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces;
2063 case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0;
2064 case LayoutNavEntry::Classes: return annotatedClasses>0;
2065 case LayoutNavEntry::ClassList: return annotatedClasses>0;
2066 case LayoutNavEntry::ClassIndex: return annotatedClasses>0;
2067 case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0;
2068 case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0;
2069 case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles;
2070 case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles;
2071 case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0;
2072 case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0;
2073 case LayoutNavEntry::Interfaces: return annotatedInterfaces>0;
2074 case LayoutNavEntry::InterfaceList: return annotatedInterfaces>0;
2075 case LayoutNavEntry::InterfaceIndex: return annotatedInterfaces>0;
2076 case LayoutNavEntry::InterfaceHierarchy: return hierarchyInterfaces>0;
2077 case LayoutNavEntry::Structs: return annotatedStructs>0;
2078 case LayoutNavEntry::StructList: return annotatedStructs>0;
2079 case LayoutNavEntry::StructIndex: return annotatedStructs>0;
2080 case LayoutNavEntry::Exceptions: return annotatedExceptions>0;
2081 case LayoutNavEntry::ExceptionList: return annotatedExceptions>0;
2082 case LayoutNavEntry::ExceptionIndex: return annotatedExceptions>0;
2083 case LayoutNavEntry::ExceptionHierarchy: return hierarchyExceptions>0;
2084 case LayoutNavEntry::None: // should never happen, means not properly initialized
2085 assert(kind != LayoutNavEntry::None);
2091 static void renderQuickLinksAsTree(FTextStream &t,const QCString &relPath,LayoutNavEntry *root)
2094 QListIterator<LayoutNavEntry> li(root->children());
2095 LayoutNavEntry *entry;
2097 for (li.toFirst();(entry=li.current());++li)
2099 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2101 if (count>0) // at least one item is visible
2103 startQuickIndexList(t,FALSE);
2104 for (li.toFirst();(entry=li.current());++li)
2106 if (entry->visible() && quickLinkVisible(entry->kind()))
2108 QCString url = entry->url();
2109 t << "<li><a href=\"" << relPath << url << "\"><span>";
2110 t << fixSpaces(entry->title());
2111 t << "</span></a>\n";
2112 // recursive into child list
2113 renderQuickLinksAsTree(t,relPath,entry);
2117 endQuickIndexList(t,FALSE);
2122 static void renderQuickLinksAsTabs(FTextStream &t,const QCString &relPath,
2123 LayoutNavEntry *hlEntry,LayoutNavEntry::Kind kind,
2124 bool highlightParent,bool highlightSearch)
2126 if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
2128 renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
2130 if (hlEntry->parent() && hlEntry->parent()->children().count()>0) // draw tabs for row containing hlEntry
2132 bool topLevel = hlEntry->parent()->parent()==0;
2133 QListIterator<LayoutNavEntry> li(hlEntry->parent()->children());
2134 LayoutNavEntry *entry;
2137 for (li.toFirst();(entry=li.current());++li)
2139 if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2141 if (count>0) // at least one item is visible
2143 startQuickIndexList(t,TRUE,topLevel);
2144 for (li.toFirst();(entry=li.current());++li)
2146 if (entry->visible() && quickLinkVisible(entry->kind()))
2148 QCString url = entry->url();
2149 startQuickIndexItem(t,url,
2151 (entry->children().count()>0 ||
2152 (entry->kind()==kind && !highlightParent)
2155 t << fixSpaces(entry->title());
2156 endQuickIndexItem(t,url);
2159 if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
2161 static bool searchEngine = Config_getBool(SEARCHENGINE);
2162 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2166 if (!serverBasedSearch) // pure client side search
2168 writeClientSearchBox(t,relPath);
2171 else // server based search
2173 writeServerSearchBox(t,relPath,highlightSearch);
2174 if (!highlightSearch)
2180 if (!highlightSearch) // on the search page the index will be ended by the
2183 endQuickIndexList(t,TRUE);
2186 else // normal case for other rows than first one
2188 endQuickIndexList(t,TRUE);
2194 static void writeDefaultQuickLinks(FTextStream &t,bool compact,
2195 HighlightedItem hli,
2197 const QCString &relPath)
2199 static bool serverBasedSearch = Config_getBool(SERVER_BASED_SEARCH);
2200 static bool searchEngine = Config_getBool(SEARCHENGINE);
2201 static bool externalSearch = Config_getBool(EXTERNAL_SEARCH);
2202 LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry();
2203 LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1;
2204 LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file
2205 bool highlightParent=FALSE;
2206 switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
2208 case HLI_Main: kind = LayoutNavEntry::MainPage; break;
2209 case HLI_Modules: kind = LayoutNavEntry::Modules; break;
2210 //case HLI_Directories: kind = LayoutNavEntry::Dirs; break;
2211 case HLI_Namespaces: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces; break;
2212 case HLI_ClassHierarchy: kind = LayoutNavEntry::ClassHierarchy; break;
2213 case HLI_InterfaceHierarchy: kind = LayoutNavEntry::InterfaceHierarchy; break;
2214 case HLI_ExceptionHierarchy: kind = LayoutNavEntry::ExceptionHierarchy; break;
2215 case HLI_Classes: kind = LayoutNavEntry::ClassIndex; altKind = LayoutNavEntry::Classes; break;
2216 case HLI_Interfaces: kind = LayoutNavEntry::InterfaceIndex; altKind = LayoutNavEntry::Interfaces; break;
2217 case HLI_Structs: kind = LayoutNavEntry::StructIndex; altKind = LayoutNavEntry::Structs; break;
2218 case HLI_Exceptions: kind = LayoutNavEntry::ExceptionIndex; altKind = LayoutNavEntry::Exceptions; break;
2219 case HLI_AnnotatedClasses: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes; break;
2220 case HLI_AnnotatedInterfaces: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces; break;
2221 case HLI_AnnotatedStructs: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs; break;
2222 case HLI_AnnotatedExceptions: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions; break;
2223 case HLI_Files: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files; break;
2224 case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
2225 case HLI_Functions: kind = LayoutNavEntry::ClassMembers; break;
2226 case HLI_Globals: kind = LayoutNavEntry::FileGlobals; break;
2227 case HLI_Pages: kind = LayoutNavEntry::Pages; break;
2228 case HLI_Examples: kind = LayoutNavEntry::Examples; break;
2229 case HLI_UserGroup: kind = LayoutNavEntry::UserGroup; break;
2230 case HLI_ClassVisible: kind = LayoutNavEntry::ClassList; altKind = LayoutNavEntry::Classes;
2231 highlightParent = TRUE; break;
2232 case HLI_InterfaceVisible: kind = LayoutNavEntry::InterfaceList; altKind = LayoutNavEntry::Interfaces;
2233 highlightParent = TRUE; break;
2234 case HLI_StructVisible: kind = LayoutNavEntry::StructList; altKind = LayoutNavEntry::Structs;
2235 highlightParent = TRUE; break;
2236 case HLI_ExceptionVisible: kind = LayoutNavEntry::ExceptionList; altKind = LayoutNavEntry::Exceptions;
2237 highlightParent = TRUE; break;
2238 case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList; altKind = LayoutNavEntry::Namespaces;
2239 highlightParent = TRUE; break;
2240 case HLI_FileVisible: kind = LayoutNavEntry::FileList; altKind = LayoutNavEntry::Files;
2241 highlightParent = TRUE; break;
2242 case HLI_None: break;
2243 case HLI_Search: break;
2246 if (compact && Config_getBool(HTML_DYNAMIC_MENUS))
2248 QCString searchPage;
2251 searchPage = "search" + Doxygen::htmlFileExtension;
2255 searchPage = "search.php";
2257 t << "<script type=\"text/javascript\" src=\"" << relPath << "menudata.js\"></script>" << endl;
2258 t << "<script type=\"text/javascript\" src=\"" << relPath << "menu.js\"></script>" << endl;
2259 t << "<script type=\"text/javascript\">" << endl;
2260 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2261 t << "$(function() {" << endl;
2262 t << " initMenu('" << relPath << "',"
2263 << (searchEngine?"true":"false") << ","
2264 << (serverBasedSearch?"true":"false") << ",'"
2265 << searchPage << "','"
2266 << theTranslator->trSearch() << "');" << endl;
2267 if (Config_getBool(SEARCHENGINE))
2269 if (!serverBasedSearch)
2271 t << " $(document).ready(function() { init_search(); });\n";
2275 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2276 t << " $(document).ready(function() {\n"
2277 << " if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
2282 t << "/* @license-end */";
2283 t << "</script>" << endl;
2284 t << "<div id=\"main-nav\"></div>" << endl;
2286 else if (compact) // && !Config_getBool(HTML_DYNAMIC_MENUS)
2288 // find highlighted index item
2289 LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : 0);
2290 if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; }
2291 if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
2293 highlightParent=TRUE;
2294 hlEntry = root->children().getFirst();
2297 return; // argl, empty index!
2300 if (kind==LayoutNavEntry::UserGroup)
2302 LayoutNavEntry *e = hlEntry->children().getFirst();
2308 renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HLI_Search);
2312 renderQuickLinksAsTree(t,relPath,root);
2316 void HtmlGenerator::endQuickIndices()
2318 t << "</div><!-- top -->" << endl;
2321 QCString HtmlGenerator::writeSplitBarAsString(const char *name,const char *relpath)
2323 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2326 if (generateTreeView)
2329 "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n"
2330 " <div id=\"nav-tree\">\n"
2331 " <div id=\"nav-tree-contents\">\n"
2332 " <div id=\"nav-sync\" class=\"sync\"></div>\n"
2335 " <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
2336 " class=\"ui-resizable-handle\">\n"
2339 "<script type=\"text/javascript\">\n"
2340 "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n"
2341 "$(document).ready(function(){initNavTree('") +
2342 QCString(name) + Doxygen::htmlFileExtension +
2343 QCString("','") + relpath +
2345 "/* @license-end */\n"
2347 "<div id=\"doc-content\">\n");
2352 void HtmlGenerator::writeSplitBar(const char *name)
2354 t << writeSplitBarAsString(name,relPath);
2357 void HtmlGenerator::writeNavigationPath(const char *s)
2359 t << substitute(s,"$relpath^",relPath);
2362 void HtmlGenerator::startContents()
2364 t << "<div class=\"contents\">" << endl;
2367 void HtmlGenerator::endContents()
2369 t << "</div><!-- contents -->" << endl;
2372 void HtmlGenerator::startPageDoc(const char *pageTitle)
2374 t << "<div" << getDirHtmlClassOfPage(pageTitle) << ">";
2377 void HtmlGenerator::endPageDoc()
2379 t << "</div><!-- PageDoc -->" << endl;
2382 void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
2384 writeDefaultQuickLinks(t,compact,hli,file,relPath);
2387 // PHP based search script
2388 void HtmlGenerator::writeSearchPage()
2390 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2391 static bool disableIndex = Config_getBool(DISABLE_INDEX);
2392 static QCString projectName = Config_getString(PROJECT_NAME);
2393 static QCString htmlOutput = Config_getString(HTML_OUTPUT);
2395 // OPENSEARCH_PROVIDER {
2396 QCString configFileName = htmlOutput+"/search_config.php";
2397 QFile cf(configFileName);
2398 if (cf.open(IO_WriteOnly))
2402 t << "$config = array(\n";
2403 t << " 'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
2404 t << " 'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
2405 t << " 'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
2407 t << "$translator = array(\n";
2408 t << " 'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
2409 t << " 'search_results' => array(\n";
2410 t << " 0 => \"" << theTranslator->trSearchResults(0) << "\",\n";
2411 t << " 1 => \"" << theTranslator->trSearchResults(1) << "\",\n";
2412 t << " 2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";
2414 t << " 'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
2415 t << " 'search' => \"" << theTranslator->trSearch() << "\",\n";
2416 t << " 'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n";
2417 t << " 'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
2422 ResourceMgr::instance().copyResource("search_functions.php",htmlOutput);
2423 ResourceMgr::instance().copyResource("search_opensearch.php",htmlOutput);
2424 // OPENSEARCH_PROVIDER }
2426 QCString fileName = htmlOutput+"/search.php";
2428 if (f.open(IO_WriteOnly))
2431 t << substituteHtmlKeywords(g_header,"Search","");
2433 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
2434 << versionString << " -->" << endl;
2435 t << "<script type=\"text/javascript\">\n";
2436 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2437 t << "var searchBox = new SearchBox(\"searchBox\", \""
2438 << "search\",false,'" << theTranslator->trSearch() << "');\n";
2439 t << "/* @license-end */\n";
2441 if (!Config_getBool(DISABLE_INDEX))
2443 writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
2447 t << "</div>" << endl;
2451 t << "require_once \"search_functions.php\";\n";
2455 // Write empty navigation path, to make footer connect properly
2456 if (generateTreeView)
2458 t << "</div><!-- doc-content -->\n";
2461 writePageFooter(t,"Search","","");
2463 QCString scriptName = htmlOutput+"/search/search.js";
2464 QFile sf(scriptName);
2465 if (sf.open(IO_WriteOnly))
2468 t << ResourceMgr::instance().getAsString("extsearch.js");
2472 err("Failed to open file '%s' for writing...\n",scriptName.data());
2476 void HtmlGenerator::writeExternalSearchPage()
2478 static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2479 static bool disableIndex = Config_getBool(DISABLE_INDEX);
2480 QCString fileName = Config_getString(HTML_OUTPUT)+"/search"+Doxygen::htmlFileExtension;
2482 if (f.open(IO_WriteOnly))
2485 t << substituteHtmlKeywords(g_header,"Search","");
2487 t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen "
2488 << versionString << " -->" << endl;
2489 t << "<script type=\"text/javascript\">\n";
2490 t << "/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */\n";
2491 t << "var searchBox = new SearchBox(\"searchBox\", \""
2492 << "search\",false,'" << theTranslator->trSearch() << "');\n";
2493 t << "/* @license-end */\n";
2495 if (!Config_getBool(DISABLE_INDEX))
2497 writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
2498 t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
2500 t << " </div><div class=\"right\"></div>\n";
2509 t << "</div>" << endl;
2511 t << writeSplitBarAsString("search","");
2512 t << "<div class=\"header\">" << endl;
2513 t << " <div class=\"headertitle\">" << endl;
2514 t << " <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>" << endl;
2515 t << " </div>" << endl;
2516 t << "</div>" << endl;
2517 t << "<div class=\"contents\">" << endl;
2519 t << "<div id=\"searchresults\"></div>" << endl;
2520 t << "</div>" << endl;
2522 if (generateTreeView)
2524 t << "</div><!-- doc-content -->" << endl;
2527 writePageFooter(t,"Search","","");
2530 QCString scriptName = Config_getString(HTML_OUTPUT)+"/search/search.js";
2531 QFile sf(scriptName);
2532 if (sf.open(IO_WriteOnly))
2535 t << "var searchResultsText=["
2536 << "\"" << theTranslator->trSearchResults(0) << "\","
2537 << "\"" << theTranslator->trSearchResults(1) << "\","
2538 << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl;
2539 t << "var serverUrl=\"" << Config_getString(SEARCHENGINE_URL) << "\";" << endl;
2540 t << "var tagMap = {" << endl;
2542 // add search mappings
2543 QStrList &extraSearchMappings = Config_getList(EXTRA_SEARCH_MAPPINGS);
2544 char *ml=extraSearchMappings.first();
2547 QCString mapLine = ml;
2548 int eqPos = mapLine.find('=');
2549 if (eqPos!=-1) // tag command contains a destination
2551 QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
2552 QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
2553 if (!tagName.isEmpty())
2555 if (!first) t << "," << endl;
2556 t << " \"" << tagName << "\": \"" << destName << "\"";
2560 ml=extraSearchMappings.next();
2562 if (!first) t << endl;
2563 t << "};" << endl << endl;
2564 t << ResourceMgr::instance().getAsString("extsearch.js");
2566 t << "$(document).ready(function() {" << endl;
2567 t << " var query = trim(getURLParameter('query'));" << endl;
2568 t << " if (query) {" << endl;
2569 t << " searchFor(query,0,20);" << endl;
2570 t << " } else {" << endl;
2571 t << " var results = $('#results');" << endl;
2572 t << " results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');" << endl;
2578 err("Failed to open file '%s' for writing...\n",scriptName.data());
2582 void HtmlGenerator::startConstraintList(const char *header)
2584 t << "<div class=\"typeconstraint\">" << endl;
2585 t << "<dl><dt><b>" << header << "</b></dt><dd>" << endl;
2586 t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
2589 void HtmlGenerator::startConstraintParam()
2591 t << "<tr><td valign=\"top\"><em>";
2594 void HtmlGenerator::endConstraintParam()
2599 void HtmlGenerator::startConstraintType()
2601 t << "<td> :</td><td valign=\"top\"><em>";
2604 void HtmlGenerator::endConstraintType()
2609 void HtmlGenerator::startConstraintDocs()
2614 void HtmlGenerator::endConstraintDocs()
2616 t << "</td></tr>" << endl;
2619 void HtmlGenerator::endConstraintList()
2621 t << "</table>" << endl;
2622 t << "</dd>" << endl;
2623 t << "</dl>" << endl;
2624 t << "</div>" << endl;
2627 void HtmlGenerator::lineBreak(const char *style)
2631 t << "<br class=\"" << style << "\" />" << endl;
2635 t << "<br />" << endl;
2639 void HtmlGenerator::startHeaderSection()
2641 t << "<div class=\"header\">" << endl;
2644 void HtmlGenerator::startTitleHead(const char *)
2646 t << " <div class=\"headertitle\">" << endl;
2650 void HtmlGenerator::endTitleHead(const char *,const char *)
2653 t << " </div>" << endl;
2656 void HtmlGenerator::endHeaderSection()
2658 t << "</div><!--header-->" << endl;
2661 void HtmlGenerator::startInlineHeader()
2665 t << "<table class=\"memberdecls\">" << endl;
2666 m_emptySection=FALSE;
2668 t << "<tr><td colspan=\"2\"><h3>";
2671 void HtmlGenerator::endInlineHeader()
2673 t << "</h3></td></tr>" << endl;
2676 void HtmlGenerator::startMemberDocSimple(bool isEnum)
2678 DBG_HTML(t << "<!-- startMemberDocSimple -->" << endl;)
2679 t << "<table class=\"fieldtable\">" << endl;
2680 t << "<tr><th colspan=\"" << (isEnum?"2":"3") << "\">";
2681 t << (isEnum? theTranslator->trEnumerationValues() :
2682 theTranslator->trCompoundMembers()) << "</th></tr>" << endl;
2685 void HtmlGenerator::endMemberDocSimple(bool)
2687 DBG_HTML(t << "<!-- endMemberDocSimple -->" << endl;)
2688 t << "</table>" << endl;
2691 void HtmlGenerator::startInlineMemberType()
2693 DBG_HTML(t << "<!-- startInlineMemberType -->" << endl;)
2694 t << "<tr><td class=\"fieldtype\">" << endl;
2697 void HtmlGenerator::endInlineMemberType()
2699 DBG_HTML(t << "<!-- endInlineMemberType -->" << endl;)
2700 t << "</td>" << endl;
2703 void HtmlGenerator::startInlineMemberName()
2705 DBG_HTML(t << "<!-- startInlineMemberName -->" << endl;)
2706 t << "<td class=\"fieldname\">" << endl;
2709 void HtmlGenerator::endInlineMemberName()
2711 DBG_HTML(t << "<!-- endInlineMemberName -->" << endl;)
2712 t << "</td>" << endl;
2715 void HtmlGenerator::startInlineMemberDoc()
2717 DBG_HTML(t << "<!-- startInlineMemberDoc -->" << endl;)
2718 t << "<td class=\"fielddoc\">" << endl;
2721 void HtmlGenerator::endInlineMemberDoc()
2723 DBG_HTML(t << "<!-- endInlineMemberDoc -->" << endl;)
2724 t << "</td></tr>" << endl;
2727 void HtmlGenerator::startLabels()
2729 DBG_HTML(t << "<!-- startLabels -->" << endl;)
2730 t << "<span class=\"mlabels\">";
2733 void HtmlGenerator::writeLabel(const char *l,bool /*isLast*/)
2735 DBG_HTML(t << "<!-- writeLabel(" << l << ") -->" << endl;)
2736 //t << "<tt>[" << l << "]</tt>";
2737 //if (!isLast) t << ", ";
2738 t << "<span class=\"mlabel\">" << l << "</span>";
2741 void HtmlGenerator::endLabels()
2743 DBG_HTML(t << "<!-- endLabels -->" << endl;)
2747 void HtmlGenerator::writeInheritedSectionTitle(
2748 const char *id, const char *ref,
2749 const char *file, const char *anchor,
2750 const char *title, const char *name)
2752 DBG_HTML(t << "<!-- writeInheritedSectionTitle -->" << endl;)
2753 QCString a = anchor;
2754 if (!a.isEmpty()) a.prepend("#");
2755 QCString classLink = QCString("<a class=\"el\" ");
2758 classLink+= externalLinkTarget();
2759 classLink += " href=\"";
2760 classLink+= externalRef(relPath,ref,TRUE);
2764 classLink += "href=\"";
2767 classLink+=file+Doxygen::htmlFileExtension+a;
2768 classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
2769 t << "<tr class=\"inherit_header " << id << "\">"
2770 << "<td colspan=\"2\" onclick=\"javascript:toggleInherit('" << id << "')\">"
2771 << "<img src=\"" << relPath << "closed.png\" alt=\"-\"/> "
2772 << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
2773 << "</td></tr>" << endl;
2776 void HtmlGenerator::writeSummaryLink(const char *file,const char *anchor,const char *title,bool first)
2780 t << " <div class=\"summary\">\n";
2789 t << relPath << file;
2790 t << Doxygen::htmlFileExtension;
2802 void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritId)
2804 t << "<tr class=\"separator:" << anchor;
2807 t << " inherit " << inheritId;
2809 t << "\"><td class=\"memSeparator\" colspan=\"2\"> </td></tr>\n";
2812 void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile)
2814 if (Doxygen::searchIndex)
2816 Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile);
2820 void HtmlGenerator::addWord(const char *word,bool hiPriority)
2822 if (Doxygen::searchIndex)
2824 Doxygen::searchIndex->addWord(word,hiPriority);