Doxygen
ftvhelp.cpp
浏览该文件的文档.
1 /******************************************************************************
2  * ftvhelp.cpp,v 1.0 2000/09/06 16:09:00
3  *
4  * Copyright (C) 1997-2015 by Dimitri van Heesch.
5  *
6  * Permission to use, copy, modify, and distribute this software and its
7  * documentation under the terms of the GNU General Public License is hereby
8  * granted. No representations are made about the suitability of this software
9  * for any purpose. It is provided "as is" without express or implied warranty.
10  * See the GNU General Public License for more details.
11  *
12  * Documents produced by Doxygen are derivative works derived from the
13  * input used in their production; they are not affected by this license.
14  *
15  * Original version contributed by Kenney Wong <kwong@ea.com>
16  * Modified by Dimitri van Heesch
17  *
18  * Folder Tree View for offline help on browsers that do not support HTML Help.
19  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <algorithm>
24 
25 #include "ftvhelp.h"
26 #include "config.h"
27 #include "message.h"
28 #include "doxygen.h"
29 #include "language.h"
30 #include "htmlgen.h"
31 #include "layout.h"
32 #include "pagedef.h"
33 #include "docparser.h"
34 #include "htmldocvisitor.h"
35 #include "filedef.h"
36 #include "classdef.h"
37 #include "util.h"
38 #include "resourcemgr.h"
39 
40 static int folderId=1;
41 
42 const char *JAVASCRIPT_LICENSE_TEXT = R"LIC(/*
43  @licstart The following is the entire license notice for the JavaScript code in this file.
44 
45  The MIT License (MIT)
46 
47  Copyright (C) 1997-2020 by Dimitri van Heesch
48 
49  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
50  and associated documentation files (the "Software"), to deal in the Software without restriction,
51  including without limitation the rights to use, copy, modify, merge, publish, distribute,
52  sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
53  furnished to do so, subject to the following conditions:
54 
55  The above copyright notice and this permission notice shall be included in all copies or
56  substantial portions of the Software.
57 
58  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
59  BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
60  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
61  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
63 
64  @licend The above is the entire license notice for the JavaScript code in this file
65 */
66 )LIC";
67 
68 struct FTVNode
69 {
70  FTVNode(bool dir,const QCString &r,const QCString &f,const QCString &a,
71  const QCString &n,bool sepIndex,bool navIndex,const Definition *df)
72  : isLast(TRUE), isDir(dir),ref(r),file(f),anchor(a),name(n), index(0),
73  parent(0), separateIndex(sepIndex), addToNavIndex(navIndex),
74  def(df) {}
75  ~FTVNode() { for (const auto &child : children) delete child; }
76  int computeTreeDepth(int level) const;
77  int numNodesAtLevel(int level,int maxLevel) const;
78  bool isLast;
79  bool isDir;
84  int index;
85  std::vector<FTVNode*> children;
89  const Definition *def;
90 };
91 
92 int FTVNode::computeTreeDepth(int level) const
93 {
94  int maxDepth=level;
95  for (const auto &n : children)
96  {
97  if (!n->children.empty())
98  {
99  int d = n->computeTreeDepth(level+1);
100  if (d>maxDepth) maxDepth=d;
101  }
102  }
103  return maxDepth;
104 }
105 
106 int FTVNode::numNodesAtLevel(int level,int maxLevel) const
107 {
108  int num=0;
109  if (level<maxLevel)
110  {
111  num++; // this node
112  for (const auto &n : children)
113  {
114  num+=n->numNodesAtLevel(level+1,maxLevel);
115  }
116  }
117  return num;
118 }
119 
120 //----------------------------------------------------------------------------
121 
122 /*! Constructs an ftv help object.
123  * The object has to be \link initialize() initialized\endlink before it can
124  * be used.
125  */
127 {
128  /* initial depth */
129  m_indentNodes.resize(1);
130  m_indent=0;
131  m_topLevelIndex = TLI;
132 }
133 
134 /*! Destroys the ftv help object. */
136 {
137  for (auto &idx : m_indentNodes)
138  {
139  for (auto &n : idx)
140  {
141  delete n;
142  }
143  idx.clear();
144  }
145  m_indentNodes.clear();
146 }
147 
148 /*! This will create a folder tree view table of contents file (tree.js).
149  * \sa finalize()
150  */
152 {
153 }
154 
155 /*! Finalizes the FTV help. This will finish and close the
156  * contents file (index.js).
157  * \sa initialize()
158  */
160 {
162 }
163 
164 /*! Increase the level of the contents hierarchy.
165  * This will start a new sublist in contents file.
166  * \sa decContentsDepth()
167  */
169 {
170  //printf("%p: incContentsDepth() indent=%d\n",this,m_indent);
171  m_indent++;
172  m_indentNodes.resize(m_indent+1);
173 }
174 
175 /*! Decrease the level of the contents hierarchy.
176  * This will end the current sublist.
177  * \sa incContentsDepth()
178  */
180 {
181  //printf("%p: decContentsDepth() indent=%d\n",this,m_indent);
182  ASSERT(m_indent>0);
183  if (m_indent>0)
184  {
185  m_indent--;
186  std::vector<FTVNode*> &nl = m_indentNodes[m_indent];
187  if (!nl.empty())
188  {
189  FTVNode *parent = nl.back();
190  std::vector<FTVNode*> &children = m_indentNodes[m_indent+1];
191  for (const auto &child : children)
192  {
193  parent->children.push_back(child);
194  }
195  children.clear();
196  }
197  }
198 }
199 
200 /*! Add a list item to the contents file.
201  * \param isDir TRUE if the item is a directory, FALSE if it is a text
202  * \param name the name of the item.
203  * \param ref the URL of to the item.
204  * \param file the file containing the definition of the item
205  * \param anchor the anchor within the file.
206  * \param separateIndex put the entries in a separate index file
207  * \param addToNavIndex add this entry to the quick navigation index
208  * \param def Definition corresponding to this entry
209  */
210 void FTVHelp::addContentsItem(bool isDir,
211  const QCString &name,
212  const QCString &ref,
213  const QCString &file,
214  const QCString &anchor,
215  bool separateIndex,
216  bool addToNavIndex,
217  const Definition *def
218  )
219 {
220  //printf("%p: m_indent=%d addContentsItem(%s,%s,%s,%s)\n",this,m_indent,name,ref,file,anchor);
221  std::vector<FTVNode*> &nl = m_indentNodes[m_indent];
222  FTVNode *newNode = new FTVNode(isDir,ref,file,anchor,name,separateIndex,addToNavIndex,def);
223  if (!nl.empty())
224  {
225  nl.back()->isLast=FALSE;
226  }
227  nl.push_back(newNode);
228  newNode->index = static_cast<int>(nl.size()-1);
229  if (m_indent>0)
230  {
231  std::vector<FTVNode*> &pnl = m_indentNodes[m_indent-1];
232  if (!pnl.empty())
233  {
234  newNode->parent = pnl.back();
235  }
236  }
237 }
238 
239 static QCString node2URL(const FTVNode *n,bool overruleFile=FALSE,bool srcLink=FALSE)
240 {
241  QCString url = n->file;
242  if (!url.isEmpty() && url.at(0)=='!') // relative URL
243  {
244  // remove leading !
245  url = url.mid(1);
246  }
247  else if (!url.isEmpty() && url.at(0)=='^') // absolute URL
248  {
249  // skip, keep ^ in the output
250  }
251  else // local file (with optional anchor)
252  {
253  if (overruleFile && n->def && n->def->definitionType()==Definition::TypeFile)
254  {
255  const FileDef *fd = toFileDef(n->def);
256  if (srcLink)
257  {
258  url = fd->getSourceFileBase();
259  }
260  else
261  {
262  url = fd->getOutputFileBase();
263  }
264  }
265  url = addHtmlExtensionIfMissing(url);
266  if (!n->anchor.isEmpty()) url+="#"+n->anchor;
267  }
268  return url;
269 }
270 
272 {
273  QCString result;
274  if (n->parent)
275  {
276  result=generateIndentLabel(n->parent,level+1);
277  }
278  result+=QCString().setNum(n->index)+"_";
279  return result;
280 }
281 
283 {
284  int indent=0;
285  FTVNode *p = n->parent;
286  while (p) { indent++; p=p->parent; }
287  if (n->isDir)
288  {
289  QCString dir = opened ? "&#9660;" : "&#9658;";
290  t << "<span style=\"width:" << (indent*16) << "px;display:inline-block;\">&#160;</span>"
291  << "<span id=\"arr_" << generateIndentLabel(n,0) << "\" class=\"arrow\" ";
292  t << "onclick=\"toggleFolder('" << generateIndentLabel(n,0) << "')\"";
293  t << ">" << dir
294  << "</span>";
295  }
296  else
297  {
298  t << "<span style=\"width:" << ((indent+1)*16) << "px;display:inline-block;\">&#160;</span>";
299  }
300 }
301 
303 {
304  //printf("FTVHelp::generateLink(ref=%s,file=%s,anchor=%s\n",
305  // qPrint(n->ref),qPrint(n->file),qPrint(n->anchor));
306  bool setTarget = FALSE;
307  if (n->file.isEmpty()) // no link
308  {
309  t << "<b>" << convertToHtml(n->name) << "</b>";
310  }
311  else // link into other frame
312  {
313  if (!n->ref.isEmpty()) // link to entity imported via tag file
314  {
315  t << "<a class=\"elRef\" ";
316  QCString result = externalLinkTarget();
317  if (result != "") setTarget = TRUE;
318  t << result;
319  }
320  else // local link
321  {
322  t << "<a class=\"el\" ";
323  }
324  t << "href=\"";
325  t << externalRef("",n->ref,TRUE);
326  t << node2URL(n);
327  if (!setTarget)
328  {
329  if (m_topLevelIndex)
330  t << "\" target=\"basefrm\">";
331  else
332  t << "\" target=\"_self\">";
333  }
334  else
335  {
336  t << "\">";
337  }
338  t << convertToHtml(n->name);
339  t << "</a>";
340  if (!n->ref.isEmpty())
341  {
342  t << "&#160;[external]";
343  }
344  }
345 }
346 
347 static void generateBriefDoc(TextStream &t,const Definition *def)
348 {
349  QCString brief = def->briefDescription(TRUE);
350  //printf("*** %p: generateBriefDoc(%s)='%s'\n",def,qPrint(def->name()),qPrint(brief));
351  if (!brief.isEmpty())
352  {
353  std::unique_ptr<IDocParser> parser { createDocParser() };
354  std::unique_ptr<DocRoot> root { validatingParseDoc(*parser.get(),
355  def->briefFile(),def->briefLine(),
356  def,0,brief,FALSE,FALSE,
357  QCString(),TRUE,TRUE,Config_getBool(MARKDOWN_SUPPORT)) };
359  HtmlCodeGenerator htmlGen(t,relPath);
360  auto visitor = std::make_unique<HtmlDocVisitor>(t,htmlGen,def);
361  root->accept(visitor.get());
362  }
363 }
364 
365 static char compoundIcon(const ClassDef *cd)
366 {
367  char icon='C';
368  if (cd->getLanguage() == SrcLangExt_Slice)
369  {
371  {
372  icon='I';
373  }
374  else if (cd->compoundType()==ClassDef::Struct)
375  {
376  icon='S';
377  }
378  else if (cd->compoundType()==ClassDef::Exception)
379  {
380  icon='E';
381  }
382  }
383  return icon;
384 }
385 
386 void FTVHelp::generateTree(TextStream &t, const std::vector<FTVNode*> &nl,int level,int maxLevel,int &index)
387 {
388  for (const auto &n : nl)
389  {
390  t << "<tr id=\"row_" << generateIndentLabel(n,0) << "\"";
391  if ((index&1)==0) // even row
392  t << " class=\"even\"";
393  if (level>=maxLevel) // item invisible by default
394  t << " style=\"display:none;\"";
395  else // item visible by default
396  index++;
397  t << "><td class=\"entry\">";
398  bool nodeOpened = level+1<maxLevel;
399  generateIndent(t,n,nodeOpened);
400  if (n->isDir)
401  {
402  if (n->def && n->def->definitionType()==Definition::TypeGroup)
403  {
404  // no icon
405  }
406  else if (n->def && n->def->definitionType()==Definition::TypePage)
407  {
408  // no icon
409  }
410  else if (n->def && n->def->definitionType()==Definition::TypeNamespace)
411  {
412  if (n->def->getLanguage() == SrcLangExt_Slice)
413  {
414  t << "<span class=\"icona\"><span class=\"icon\">M</span></span>";
415  }
416  else
417  {
418  t << "<span class=\"icona\"><span class=\"icon\">N</span></span>";
419  }
420  }
421  else if (n->def && n->def->definitionType()==Definition::TypeClass)
422  {
423  char icon=compoundIcon(toClassDef(n->def));
424  t << "<span class=\"icona\"><span class=\"icon\">" << icon << "</span></span>";
425  }
426  else
427  {
428  t << "<span id=\"img_" << generateIndentLabel(n,0)
429  << "\" class=\"iconf"
430  << (nodeOpened?"open":"closed")
431  << "\" onclick=\"toggleFolder('" << generateIndentLabel(n,0)
432  << "')\">&#160;</span>";
433  }
434  generateLink(t,n);
435  t << "</td><td class=\"desc\">";
436  if (n->def)
437  {
438  generateBriefDoc(t,n->def);
439  }
440  t << "</td></tr>\n";
441  folderId++;
442  generateTree(t,n->children,level+1,maxLevel,index);
443  }
444  else // leaf node
445  {
446  const FileDef *srcRef=0;
447  if (n->def && n->def->definitionType()==Definition::TypeFile &&
448  (toFileDef(n->def))->generateSourceFile())
449  {
450  srcRef = toFileDef(n->def);
451  }
452  if (srcRef)
453  {
454  t << "<a href=\"" << addHtmlExtensionIfMissing(srcRef->getSourceFileBase())
455  << "\">";
456  }
457  if (n->def && n->def->definitionType()==Definition::TypeGroup)
458  {
459  // no icon
460  }
461  else if (n->def && n->def->definitionType()==Definition::TypePage)
462  {
463  // no icon
464  }
465  else if (n->def && n->def->definitionType()==Definition::TypeNamespace)
466  {
467  if (n->def->getLanguage() == SrcLangExt_Slice)
468  {
469  t << "<span class=\"icona\"><span class=\"icon\">M</span></span>";
470  }
471  else
472  {
473  t << "<span class=\"icona\"><span class=\"icon\">N</span></span>";
474  }
475  }
476  else if (n->def && n->def->definitionType()==Definition::TypeClass)
477  {
478  char icon=compoundIcon(toClassDef(n->def));
479  t << "<span class=\"icona\"><span class=\"icon\">" << icon << "</span></span>";
480  }
481  else if (n->def && n->def->definitionType()==Definition::TypeConcept)
482  {
483  t << "<span class=\"icona\"><span class=\"icon\">R</span></span>";
484  }
485  else if (n->def && n->def->definitionType()==Definition::TypeDir)
486  {
487  t << "<span class=\"iconfclosed\"></span>";
488  }
489  else
490  {
491  t << "<span class=\"icondoc\"></span>";
492  }
493  if (srcRef)
494  {
495  t << "</a>";
496  }
497  generateLink(t,n);
498  t << "</td><td class=\"desc\">";
499  if (n->def)
500  {
501  generateBriefDoc(t,n->def);
502  }
503  t << "</td></tr>\n";
504  }
505  }
506 }
507 
508 //-----------------------------------------------------------
509 
511 {
512  NavIndexEntry(const QCString &u,const QCString &p) : url(u), path(p) {}
515 };
516 
517 class NavIndexEntryList : public std::vector<NavIndexEntry>
518 {
519 };
520 
521 static QCString pathToNode(const FTVNode *leaf,const FTVNode *n)
522 {
523  QCString result;
524  if (n->parent)
525  {
526  result+=pathToNode(leaf,n->parent);
527  }
528  result+=QCString().setNum(n->index);
529  if (leaf!=n) result+=",";
530  return result;
531 }
532 
533 static bool dupOfParent(const FTVNode *n)
534 {
535  if (n->parent==0) return FALSE;
536  if (n->file==n->parent->file) return TRUE;
537  return FALSE;
538 }
539 
540 static void generateJSLink(TextStream &t,const FTVNode *n)
541 {
542  if (n->file.isEmpty()) // no link
543  {
544  t << "\"" << convertToJSString(n->name) << "\", null, ";
545  }
546  else // link into other page
547  {
548  t << "\"" << convertToJSString(n->name) << "\", \"";
549  t << externalRef("",n->ref,TRUE);
550  t << node2URL(n);
551  t << "\", ";
552  }
553 }
554 
555 static QCString convertFileId2Var(const QCString &fileId)
556 {
557  QCString varId = fileId;
558  int i=varId.findRev('/');
559  if (i>=0) varId = varId.mid(i+1);
560  return substitute(varId,"-","_");
561 }
562 
563 static bool generateJSTree(NavIndexEntryList &navIndex,TextStream &t,
564  const std::vector<FTVNode*> &nl,int level,bool &first)
565 {
566  static QCString htmlOutput = Config_getString(HTML_OUTPUT);
567  QCString indentStr;
568  indentStr.fill(' ',level*2);
569  bool found=FALSE;
570  for (const auto &n : nl)
571  {
572  // terminate previous entry
573  if (!first) t << ",\n";
574  first=FALSE;
575 
576  // start entry
577  if (!found)
578  {
579  t << "[\n";
580  }
581  found=TRUE;
582 
583  if (n->addToNavIndex) // add entry to the navigation index
584  {
585  if (n->def && n->def->definitionType()==Definition::TypeFile)
586  {
587  const FileDef *fd = toFileDef(n->def);
588  bool doc,src;
589  doc = fileVisibleInIndex(fd,src);
590  if (doc)
591  {
592  navIndex.emplace_back(node2URL(n,TRUE,FALSE),pathToNode(n,n));
593  }
594  if (src)
595  {
596  navIndex.emplace_back(node2URL(n,TRUE,TRUE),pathToNode(n,n));
597  }
598  }
599  else
600  {
601  navIndex.emplace_back(node2URL(n),pathToNode(n,n));
602  }
603  }
604 
605  if (n->separateIndex) // store items in a separate file for dynamic loading
606  {
607  bool firstChild=TRUE;
608  t << indentStr << " [ ";
609  generateJSLink(t,n);
610  if (!n->children.empty()) // write children to separate file for dynamic loading
611  {
612  QCString fileId = n->file;
613  if (!n->anchor.isEmpty())
614  {
615  fileId+="_"+n->anchor;
616  }
617  if (dupOfParent(n))
618  {
619  fileId+="_dup";
620  }
621  QCString fileName = htmlOutput+"/"+fileId+".js";
622  std::ofstream f(fileName.str(),std::ofstream::out | std::ofstream::binary);
623  if (f.is_open())
624  {
625  TextStream tt(&f);
626  tt << "var " << convertFileId2Var(fileId) << " =\n";
627  generateJSTree(navIndex,tt,n->children,1,firstChild);
628  tt << "\n];";
629  }
630  f.close();
631  t << "\"" << fileId << "\" ]";
632  }
633  else // no children
634  {
635  t << "null ]";
636  }
637  }
638  else // show items in this file
639  {
640  bool firstChild=TRUE;
641  t << indentStr << " [ ";
642  generateJSLink(t,n);
643  bool emptySection = !generateJSTree(navIndex,t,n->children,level+1,firstChild);
644  if (emptySection)
645  t << "null ]";
646  else
647  t << "\n" << indentStr << " ] ]";
648  }
649  }
650  return found;
651 }
652 
653 static void generateJSNavTree(const std::vector<FTVNode*> &nodeList)
654 {
655  QCString htmlOutput = Config_getString(HTML_OUTPUT);
656  std::ofstream f(htmlOutput.str()+"/navtreedata.js",std::ofstream::out | std::ofstream::binary);
657  NavIndexEntryList navIndex;
658  if (f.is_open())
659  {
660  TextStream t(&f);
661  //TextStream tidx(&fidx);
662  //tidx << "var NAVTREEINDEX =\n";
663  //tidx << "{\n";
665  t << "var NAVTREE =\n";
666  t << "[\n";
667  t << " [ ";
668  QCString projName = Config_getString(PROJECT_NAME);
669  if (projName.isEmpty())
670  {
671  if (mainPageHasTitle()) // Use title of main page as root
672  {
673  t << "\"" << convertToJSString(Doxygen::mainPage->title()) << "\", ";
674  }
675  else // Use default section title as root
676  {
678  t << "\"" << convertToJSString(lne->title()) << "\", ";
679  }
680  }
681  else // use PROJECT_NAME as root tree element
682  {
683  t << "\"" << convertToJSString(projName) << "\", ";
684  }
685  t << "\"index" << Doxygen::htmlFileExtension << "\", ";
686 
687  // add special entry for index page
688  navIndex.emplace_back("index"+Doxygen::htmlFileExtension,"");
689  // related page index is written as a child of index.html, so add this as well
690  navIndex.emplace_back("pages"+Doxygen::htmlFileExtension,"");
691 
692  bool first=TRUE;
693  generateJSTree(navIndex,t,nodeList,1,first);
694 
695  if (first)
696  t << "]\n";
697  else
698  t << "\n ] ]\n";
699  t << "];\n\n";
700 
701  // write the navigation index (and sub-indices)
702  std::sort(navIndex.begin(),navIndex.end(),[](const auto &n1,const auto &n2)
703  { return !n1.url.isEmpty() && (n2.url.isEmpty() || (n1.url<n2.url)); });
704 
705  int subIndex=0;
706  int elemCount=0;
707  const int maxElemCount=250;
708  std::ofstream tsidx(htmlOutput.str()+"/navtreeindex0.js",std::ofstream::out | std::ofstream::binary);
709  if (tsidx.is_open())
710  {
711  t << "var NAVTREEINDEX =\n";
712  t << "[\n";
713  tsidx << "var NAVTREEINDEX" << subIndex << " =\n";
714  tsidx << "{\n";
715  first=TRUE;
716  auto it = navIndex.begin();
717  while (it!=navIndex.end())
718  {
719  const NavIndexEntry &e = *it;
720  if (elemCount==0)
721  {
722  if (!first)
723  {
724  t << ",\n";
725  }
726  else
727  {
728  first=FALSE;
729  }
730  t << "\"" << e.url << "\"";
731  }
732  tsidx << "\"" << e.url << "\":[" << e.path << "]";
733  ++it;
734  if (it!=navIndex.end() && elemCount<maxElemCount-1) tsidx << ","; // not last entry
735  tsidx << "\n";
736 
737  elemCount++;
738  if (it!=navIndex.end() && elemCount>=maxElemCount) // switch to new sub-index
739  {
740  tsidx << "};\n";
741  elemCount=0;
742  tsidx.close();
743  subIndex++;
744  QCString fileName = htmlOutput+"/navtreeindex"+QCString().setNum(subIndex)+".js";
745  tsidx.open(fileName.str(),std::ofstream::out | std::ofstream::binary);
746  if (!tsidx.is_open()) break;
747  tsidx << "var NAVTREEINDEX" << subIndex << " =\n";
748  tsidx << "{\n";
749  }
750  }
751  tsidx << "};\n";
752  t << "\n];\n";
753  }
754  t << "\nvar SYNCONMSG = '" << theTranslator->trPanelSynchronisationTooltip(FALSE) << "';";
755  t << "\nvar SYNCOFFMSG = '" << theTranslator->trPanelSynchronisationTooltip(TRUE) << "';";
756  }
757  ResourceMgr::instance().copyResource("navtree.js",htmlOutput);
758 }
759 
760 //-----------------------------------------------------------
761 
762 // new style images
764 {
765  QCString dname=Config_getString(HTML_OUTPUT);
766  const ResourceMgr &rm = ResourceMgr::instance();
767  rm.copyResource("doc.luma",dname);
768  rm.copyResource("folderopen.luma",dname);
769  rm.copyResource("folderclosed.luma",dname);
770  rm.copyResource("splitbar.lum",dname);
771 }
772 
773 // new style scripts
775 {
776  QCString htmlOutput = Config_getString(HTML_OUTPUT);
777 
778  // generate navtree.js & navtreeindex.js
780 
781  // copy resize.js & navtree.css
782  ResourceMgr::instance().copyResource("resize.js",htmlOutput);
783  ResourceMgr::instance().copyResource("navtree.css",htmlOutput);
784 }
785 
786 // write tree inside page
788 {
789  int preferredNumEntries = Config_getInt(HTML_INDEX_NUM_ENTRIES);
790  t << "<div class=\"directory\">\n";
791  int d=1, depth=1;
792  for (const auto &n : m_indentNodes[0])
793  {
794  if (!n->children.empty())
795  {
796  d = n->computeTreeDepth(2);
797  if (d>depth) depth=d;
798  }
799  }
800  int preferredDepth = depth;
801  // write level selector
802  if (depth>1)
803  {
804  t << "<div class=\"levels\">[";
806  t << " ";
807  for (int i=1;i<=depth;i++)
808  {
809  t << "<span onclick=\"javascript:toggleLevel(" << i << ");\">" << i << "</span>";
810  }
811  t << "]</div>";
812 
813  if (preferredNumEntries>0)
814  {
815  preferredDepth=1;
816  for (int i=1;i<=depth;i++)
817  {
818  int num=0;
819  for (const auto &n : m_indentNodes[0])
820  {
821  num+=n->numNodesAtLevel(0,i);
822  }
823  if (num<=preferredNumEntries)
824  {
825  preferredDepth=i;
826  }
827  else
828  {
829  break;
830  }
831  }
832  }
833  }
834  //printf("preferred depth=%d\n",preferredDepth);
835 
836  if (!m_indentNodes[0].empty())
837  {
838  t << "<table class=\"directory\">\n";
839  int index=0;
840  generateTree(t,m_indentNodes[0],0,preferredDepth,index);
841  t << "</table>\n";
842  }
843 
844  t << "</div><!-- directory -->\n";
845 }
846 
847 // write old style index.html and tree.html
849 {
852 }
ResourceMgr::copyResource
bool copyResource(const QCString &name, const QCString &targetDir) const
Copies a registered resource to a given target directory
Definition: resourcemgr.cpp:180
ResourceMgr::instance
static ResourceMgr & instance()
Returns the one and only instance of this class
Definition: resourcemgr.cpp:32
FTVNode::~FTVNode
~FTVNode()
Definition: ftvhelp.cpp:75
LayoutNavEntry
Base class for the layout of a navigation item at the top of the HTML pages.
Definition: layout.h:125
NavIndexEntryList
Definition: ftvhelp.cpp:517
FTVHelp::FTVHelp
FTVHelp(bool LTI)
Definition: ftvhelp.cpp:126
FileDef::getSourceFileBase
virtual QCString getSourceFileBase() const =0
LayoutDocManager::rootNavEntry
LayoutNavEntry * rootNavEntry() const
returns the (invisible) root of the navigation tree.
Definition: layout.cpp:1585
Doxygen::mainPage
static std::unique_ptr< PageDef > mainPage
Definition: doxygen.h:83
generateJSLink
static void generateJSLink(TextStream &t, const FTVNode *n)
Definition: ftvhelp.cpp:540
Translator::trDetailLevel
virtual QCString trDetailLevel()=0
Definition
The common base class of all entity definitions found in the sources.
Definition: definition.h:76
relativePathToRoot
QCString relativePathToRoot(const QCString &name)
Definition: util.cpp:3656
FTVNode::parent
FTVNode * parent
Definition: ftvhelp.cpp:86
NavIndexEntry::path
QCString path
Definition: ftvhelp.cpp:514
compoundIcon
static char compoundIcon(const ClassDef *cd)
Definition: ftvhelp.cpp:365
pathToNode
static QCString pathToNode(const FTVNode *leaf, const FTVNode *n)
Definition: ftvhelp.cpp:521
pagedef.h
FTVNode::isDir
bool isDir
Definition: ftvhelp.cpp:79
QCString::findRev
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition: qcstring.cpp:86
QCString::isEmpty
bool isEmpty() const
Returns TRUE iff the string is empty
Definition: qcstring.h:144
LayoutNavEntry::find
LayoutNavEntry * find(LayoutNavEntry::Kind k, const QCString &file=QCString()) const
Definition: layout.cpp:107
dupOfParent
static bool dupOfParent(const FTVNode *n)
Definition: ftvhelp.cpp:533
FTVHelp::generateTree
void generateTree(TextStream &t, const std::vector< FTVNode * > &nl, int level, int maxLevel, int &index)
Definition: ftvhelp.cpp:386
Definition::TypePage
@ TypePage
Definition: definition.h:93
ClassDef::Interface
@ Interface
Definition: classdef.h:110
FTVHelp::addContentsItem
void addContentsItem(bool isDir, const QCString &name, const QCString &ref, const QCString &file, const QCString &anchor, bool separateIndex, bool addToNavIndex, const Definition *def)
Definition: ftvhelp.cpp:210
FTVHelp::incContentsDepth
void incContentsDepth()
Definition: ftvhelp.cpp:168
QCString::str
std::string str() const
Definition: qcstring.h:442
FTVHelp::decContentsDepth
void decContentsDepth()
Definition: ftvhelp.cpp:179
Definition::TypeGroup
@ TypeGroup
Definition: definition.h:91
htmldocvisitor.h
FTVHelp::generateTreeViewInline
void generateTreeViewInline(TextStream &t)
Definition: ftvhelp.cpp:787
QCString::at
char & at(size_t i)
Returns a reference to the character at index i.
Definition: qcstring.h:477
TextStream
Text streaming class that buffers data.
Definition: textstream.h:33
Definition::briefLine
virtual int briefLine() const =0
Definition::getLanguage
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
mainPageHasTitle
bool mainPageHasTitle()
Definition: util.cpp:7027
FTVHelp::generateIndentLabel
QCString generateIndentLabel(FTVNode *n, int level)
Definition: ftvhelp.cpp:271
NavIndexEntry::NavIndexEntry
NavIndexEntry(const QCString &u, const QCString &p)
Definition: ftvhelp.cpp:512
FTVNode::file
QCString file
Definition: ftvhelp.cpp:81
generateJSTree
static bool generateJSTree(NavIndexEntryList &navIndex, TextStream &t, const std::vector< FTVNode * > &nl, int level, bool &first)
Definition: ftvhelp.cpp:563
FTVNode::FTVNode
FTVNode(bool dir, const QCString &r, const QCString &f, const QCString &a, const QCString &n, bool sepIndex, bool navIndex, const Definition *df)
Definition: ftvhelp.cpp:70
addHtmlExtensionIfMissing
QCString addHtmlExtensionIfMissing(const QCString &fName)
Definition: util.cpp:5275
FTVHelp::initialize
void initialize()
Definition: ftvhelp.cpp:151
FTVNode::isLast
bool isLast
Definition: ftvhelp.cpp:78
FTVHelp::generateLink
void generateLink(TextStream &t, FTVNode *n)
Definition: ftvhelp.cpp:302
Definition::TypeNamespace
@ TypeNamespace
Definition: definition.h:89
ClassDef
A abstract class representing of a compound symbol.
Definition: classdef.h:103
Config_getInt
#define Config_getInt(name)
Definition: config.h:34
fileVisibleInIndex
bool fileVisibleInIndex(const FileDef *fd, bool &genSourceFile)
Definition: util.cpp:6712
message.h
generateBriefDoc
static void generateBriefDoc(TextStream &t, const Definition *def)
Definition: ftvhelp.cpp:347
FTVHelp::m_topLevelIndex
bool m_topLevelIndex
Definition: ftvhelp.h:68
Definition::TypeFile
@ TypeFile
Definition: definition.h:88
FTVNode::anchor
QCString anchor
Definition: ftvhelp.cpp:82
FTVNode::ref
QCString ref
Definition: ftvhelp.cpp:80
theTranslator
Translator * theTranslator
Definition: language.cpp:156
resourcemgr.h
doxygen.h
FTVHelp::generateTreeView
void generateTreeView()
Definition: ftvhelp.cpp:848
JAVASCRIPT_LICENSE_TEXT
const char * JAVASCRIPT_LICENSE_TEXT
Definition: ftvhelp.cpp:42
FTVNode::name
QCString name
Definition: ftvhelp.cpp:83
Definition::TypeConcept
@ TypeConcept
Definition: definition.h:95
language.h
validatingParseDoc
DocRoot * validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
Definition: docparser.cpp:7495
FTVNode::index
int index
Definition: ftvhelp.cpp:84
generateJSNavTree
static void generateJSNavTree(const std::vector< FTVNode * > &nodeList)
Definition: ftvhelp.cpp:653
docparser.h
NavIndexEntry::url
QCString url
Definition: ftvhelp.cpp:513
Definition::briefDescription
virtual QCString briefDescription(bool abbreviate=FALSE) const =0
TRUE
#define TRUE
Definition: qcstring.h:36
Definition::TypeDir
@ TypeDir
Definition: definition.h:94
Definition::getOutputFileBase
virtual QCString getOutputFileBase() const =0
FTVNode::numNodesAtLevel
int numNodesAtLevel(int level, int maxLevel) const
Definition: ftvhelp.cpp:106
filedef.h
ClassDef::Struct
@ Struct
Definition: classdef.h:108
toClassDef
ClassDef * toClassDef(Definition *d)
Definition: classdef.cpp:4907
HtmlCodeGenerator
Definition: htmlgen.h:21
QCString::fill
bool fill(char c, int len=-1)
Fills a string with a predefined character
Definition: qcstring.h:175
Definition::TypeClass
@ TypeClass
Definition: definition.h:87
Definition::definitionType
virtual DefType definitionType() const =0
Definition::briefFile
virtual QCString briefFile() const =0
externalLinkTarget
QCString externalLinkTarget(const bool parent)
Definition: util.cpp:6323
ClassDef::compoundType
virtual CompoundType compoundType() const =0
Returns the type of compound this is, i.e.
QCString::setNum
QCString & setNum(short n)
Definition: qcstring.h:372
node2URL
static QCString node2URL(const FTVNode *n, bool overruleFile=FALSE, bool srcLink=FALSE)
Definition: ftvhelp.cpp:239
FTVHelp::generateTreeViewImages
static void generateTreeViewImages()
Definition: ftvhelp.cpp:763
FTVHelp::finalize
void finalize()
Definition: ftvhelp.cpp:159
classdef.h
QCString::mid
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition: qcstring.h:224
substitute
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition: qcstring.cpp:465
Config_getBool
#define Config_getBool(name)
Definition: config.h:33
layout.h
Doxygen::htmlFileExtension
static QCString htmlFileExtension
Definition: doxygen.h:103
htmlgen.h
ResourceMgr
Singleton for managing resources compiled into an executable
Definition: resourcemgr.h:35
LayoutDocManager::instance
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition: layout.cpp:1574
FTVNode::addToNavIndex
bool addToNavIndex
Definition: ftvhelp.cpp:88
Translator::trPanelSynchronisationTooltip
virtual QCString trPanelSynchronisationTooltip(bool enable)=0
FTVNode::children
std::vector< FTVNode * > children
Definition: ftvhelp.cpp:85
Config_getString
#define Config_getString(name)
Definition: config.h:32
folderId
static int folderId
Definition: ftvhelp.cpp:40
config.h
ASSERT
#define ASSERT(x)
Definition: qcstring.h:44
FileDef
A model of a file symbol.
Definition: filedef.h:73
LayoutNavEntry::title
QCString title() const
Definition: layout.h:172
convertToJSString
QCString convertToJSString(const QCString &s)
Definition: util.cpp:4123
FTVHelp::generateTreeViewScripts
void generateTreeViewScripts()
Definition: ftvhelp.cpp:774
toFileDef
FileDef * toFileDef(Definition *d)
Definition: filedef.cpp:1778
FTVHelp::m_indentNodes
std::vector< std::vector< FTVNode * > > m_indentNodes
Definition: ftvhelp.h:66
FTVNode::def
const Definition * def
Definition: ftvhelp.cpp:89
NavIndexEntry
Definition: ftvhelp.cpp:510
ftvhelp.h
externalRef
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition: util.cpp:6334
ClassDef::Exception
@ Exception
Definition: classdef.h:113
FileDef::getOutputFileBase
virtual QCString getOutputFileBase() const =0
util.h
A bunch of utility functions.
FTVNode::computeTreeDepth
int computeTreeDepth(int level) const
Definition: ftvhelp.cpp:92
FTVNode
Definition: ftvhelp.cpp:68
LayoutNavEntry::MainPage
@ MainPage
Definition: layout.h:130
FTVNode::separateIndex
bool separateIndex
Definition: ftvhelp.cpp:87
FTVHelp::generateIndent
void generateIndent(TextStream &t, FTVNode *n, bool opened)
Definition: ftvhelp.cpp:282
convertToHtml
QCString convertToHtml(const QCString &s, bool keepEntities)
Definition: util.cpp:4063
convertFileId2Var
static QCString convertFileId2Var(const QCString &fileId)
Definition: ftvhelp.cpp:555
createDocParser
std::unique_ptr< IDocParser > createDocParser()
Definition: docparser.cpp:179
FTVHelp::m_indent
int m_indent
Definition: ftvhelp.h:67
FTVHelp::~FTVHelp
~FTVHelp()
Definition: ftvhelp.cpp:135
FALSE
#define FALSE
Definition: qcstring.h:33
SrcLangExt_Slice
@ SrcLangExt_Slice
Definition: types.h:59
QCString
This is an alternative implementation of QCString.
Definition: qcstring.h:108