Imported Upstream version 1.8.8
[platform/upstream/doxygen.git] / src / context.cpp
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2014 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15
16 #include <qdir.h>
17
18 #include "context.h"
19 #include "config.h"
20 #include "index.h"
21 #include "classlist.h"
22 #include "doxygen.h"
23 #include "namespacedef.h"
24 #include "filedef.h"
25 #include "pagedef.h"
26 #include "groupdef.h"
27 #include "util.h"
28 #include "version.h"
29 #include "language.h"
30 #include "message.h"
31 #include "vhdldocgen.h"
32 #include "filename.h"
33 #include "dirdef.h"
34 #include "docparser.h"
35 #include "htmlgen.h"
36 #include "htmldocvisitor.h"
37 #include "dot.h"
38 #include "diagram.h"
39 #include "example.h"
40 #include "membername.h"
41 #include "parserintf.h"
42 #include "portable.h"
43 #include "arguments.h"
44 #include "groupdef.h"
45
46 // TODO: pass the current file to Dot*::writeGraph, so the user can put dot graphs in other
47 //       files as well
48
49 #define ADD_PROPERTY(name) addProperty(#name,this,&Private::name);
50
51 struct ContextGlobals
52 {
53   enum OutputFormat
54   {
55     Html,
56     LateX,
57     Rtf,
58     ManPage,
59     DocBook,
60     Xml,
61     TagFile
62   };
63   int          dynSectionId;
64   QCString     outputDir;
65   OutputFormat outputFormat;
66 } g_globals;
67
68 /** @brief Scoped smart pointer */
69 template<class T> class ScopedPtr
70 {
71   private:
72     T *m_ptr;
73     ScopedPtr(const ScopedPtr &);
74     ScopedPtr &operator=(const ScopedPtr &);
75     void operator==(const ScopedPtr &) const;
76     void operator!=(const ScopedPtr &) const;
77
78   public:
79     typedef T Type;
80     explicit ScopedPtr(T *p=0) : m_ptr(p) {}
81     ~ScopedPtr() { delete m_ptr; };
82     T &operator*() const { return *m_ptr; }
83     T *operator->() const { return m_ptr; }
84     T *get() const { return m_ptr; }
85     operator bool() const { return m_ptr!=0; }
86     void reset(T *p=0) { if (p!=m_ptr) { delete m_ptr; m_ptr = p; } }
87 };
88
89 /** @brief Reference counting smart pointer */
90 template<class T> class SharedPtr
91 {
92   private:
93     T *m_ptr;
94     SharedPtr(const SharedPtr &);
95     SharedPtr &operator=(const SharedPtr &p);
96     void operator==(const SharedPtr &) const;
97     void operator!=(const SharedPtr &) const;
98
99   public:
100     typedef T Type;
101     explicit SharedPtr(T *p=0) : m_ptr(p) { if (m_ptr) m_ptr->addRef(); }
102     ~SharedPtr() { if (m_ptr) m_ptr->release(); };
103     T &operator*() const { return *m_ptr; }
104     T *operator->() const { return m_ptr; }
105     T *get() const { return m_ptr; }
106     operator bool() const { return m_ptr!=0; }
107     void reset(T *p=0)
108     {
109       if (p) p->addRef();
110       if (m_ptr) m_ptr->release();
111       m_ptr = p;
112     }
113 };
114
115 /** @brief Template List iterator support */
116 class GenericConstIterator : public TemplateListIntf::ConstIterator
117 {
118   public:
119     GenericConstIterator(const QList<TemplateVariant> &list)
120       : m_it(list) { }
121     virtual ~GenericConstIterator() {}
122     void toFirst()
123     {
124       m_it.toFirst();
125     }
126     void toLast()
127     {
128       m_it.toLast();
129     }
130     void toNext()
131     {
132       if (m_it.current()) ++m_it;
133     }
134     void toPrev()
135     {
136       if (m_it.current()) --m_it;
137     }
138     bool current(TemplateVariant &v) const
139     {
140       if (m_it.current())
141       {
142         v = *m_it.current();
143         return TRUE;
144       }
145       else
146       {
147         v = TemplateVariant();
148         return FALSE;
149       }
150     }
151   private:
152     QListIterator<TemplateVariant> m_it;
153 };
154
155 //------------------------------------------------------------------------
156
157 /** @brief standard template list implementation */
158 class GenericNodeListContext : public TemplateListIntf
159 {
160   public:
161     GenericNodeListContext() : m_refCount(0)
162     {
163       m_children.setAutoDelete(TRUE);
164     }
165     static GenericNodeListContext *alloc()
166     {
167       return new GenericNodeListContext;
168     }
169
170     // TemplateListIntf methods
171     int count() const
172     {
173       return (int)m_children.count();
174     }
175     TemplateVariant at(int index) const
176     {
177       TemplateVariant result;
178       if (index>=0 && index<count())
179       {
180         result = *m_children.at(index);
181       }
182       return result;
183     }
184     TemplateListIntf::ConstIterator *createIterator() const
185     {
186       return new GenericConstIterator(m_children);
187     }
188
189     void append(const TemplateVariant &ctn)
190     {
191       m_children.append(new TemplateVariant(ctn));
192     }
193     bool isEmpty() const
194     {
195       return m_children.isEmpty();
196     }
197     int addRef()
198     {
199       return ++m_refCount;
200     }
201     int release()
202     {
203       int count = --m_refCount;
204       if (count<=0)
205       {
206         delete this;
207       }
208       return count;
209     }
210   private:
211     mutable QList<TemplateVariant> m_children;
212     int m_refCount;
213 };
214
215 //------------------------------------------------------------------------
216
217 /** @brief Helper class to map a property name to a handler member function */
218 class PropertyMapper 
219 {
220   private:
221     struct PropertyFuncIntf
222     {
223       virtual ~PropertyFuncIntf() {}
224       virtual TemplateVariant operator()() const = 0;
225     };
226     template<typename T>
227     struct PropertyFunc : public PropertyFuncIntf
228     {
229       typedef TemplateVariant (T::*Handler)() const;
230       PropertyFunc(const T *o,Handler h) : obj(o), handler(h) {}
231       TemplateVariant operator()() const
232       {
233         return (obj->*handler)();
234       }
235       const T *obj;
236       Handler handler;
237     };
238
239   public:
240     PropertyMapper() { m_map.setAutoDelete(TRUE); }
241
242     /** Add a property to the map
243      *  @param[in] name   The name of the property to add.
244      *  @param[in] obj    The object handling access to the property.
245      *  @param[in] handle The method to call when the property is accessed.
246      */
247     template<typename T>
248     void addProperty(const char *name,const T* obj,
249                      typename PropertyFunc<T>::Handler handle)
250     {
251       if (m_map.find(name))
252       {
253         err("Error: adding property '%s' more than once",name);
254       }
255       else
256       {
257         m_map.insert(name,new PropertyFunc<T>(obj,handle));
258       }
259     }
260
261     /** Gets the value of a property.
262      *  @param[in] name The name of the property.
263      *  @returns A variant representing the properties value or an
264      *  invalid variant if it was not found.
265      */
266     TemplateVariant get(const char *name) const
267     {
268       //printf("PropertyMapper::get(%s)\n",name);
269       TemplateVariant result;
270       PropertyFuncIntf *func = m_map.find(name);
271       if (func)
272       {
273         result = (*func)();
274       }
275       return result;
276     }
277
278   private:
279     QDict<PropertyFuncIntf> m_map;
280 };
281
282
283 //------------------------------------------------------------------------
284
285 //%% struct Config : configuration options
286 //%% {
287 class ConfigContext::Private
288 {
289   public:
290     Private() { m_cachedLists.setAutoDelete(TRUE); }
291     virtual ~Private() { }
292     TemplateVariant fetchList(const QCString &name,const QStrList *list)
293     {
294       TemplateVariant *v = m_cachedLists.find(name);
295       if (v==0)
296       {
297         TemplateList *tlist = TemplateList::alloc();
298         m_cachedLists.insert(name,new TemplateVariant(tlist));
299         QStrListIterator li(*list);
300         char *s;
301         for (li.toFirst();(s=li.current());++li)
302         {
303           tlist->append(s);
304         }
305         return tlist;
306       }
307       else
308       {
309         return *v;
310       }
311     }
312   private:
313     QDict<TemplateVariant> m_cachedLists;
314 };
315 //%% }
316
317 ConfigContext::ConfigContext() : RefCountedContext("ConfigContext")
318 {
319   p = new Private;
320 }
321
322 ConfigContext::~ConfigContext()
323 {
324   delete p;
325 }
326
327 TemplateVariant ConfigContext::get(const char *name) const
328 {
329   TemplateVariant result;
330   if (name)
331   {
332     ConfigOption *option = Config::instance()->get(name);
333     if (option)
334     {
335       switch (option->kind())
336       {
337         case ConfigOption::O_Bool:
338           return TemplateVariant(*((ConfigBool*)option)->valueRef());
339         case ConfigOption::O_Int:
340           return TemplateVariant(*((ConfigInt*)option)->valueRef());
341         case ConfigOption::O_Enum:
342           return TemplateVariant(*((ConfigEnum*)option)->valueRef());
343         case ConfigOption::O_String:
344           return TemplateVariant(*((ConfigString*)option)->valueRef());
345         case ConfigOption::O_List:
346           return p->fetchList(name,((ConfigList*)option)->valueRef());
347           break;
348         default:
349           break;
350       }
351     }
352   }
353   return result;
354 }
355
356 //------------------------------------------------------------------------
357
358 //%% struct Doxygen: global information
359 //%% {
360 class DoxygenContext::Private : public PropertyMapper
361 {
362   public:
363     TemplateVariant version() const
364     {
365       return versionString;
366     }
367     TemplateVariant date() const
368     {
369       return TemplateVariant(dateToString(TRUE));
370     }
371     Private()
372     {
373       //%% string version
374       addProperty("version",this,&Private::version); //makeProperty(this,&Private::version));
375       //%% string date
376       addProperty("date",   this,&Private::date);
377     }
378 };
379 //%% }
380
381 DoxygenContext::DoxygenContext() : RefCountedContext("DoxygenContext")
382 {
383   p = new Private;
384 }
385
386 DoxygenContext::~DoxygenContext()
387 {
388   delete p;
389 }
390
391 TemplateVariant DoxygenContext::get(const char *n) const
392 {
393   return p->get(n);
394 }
395
396 //------------------------------------------------------------------------
397
398 //%% struct Translator: translation methods
399 //%% {
400 class TranslateContext::Private : public PropertyMapper
401 {
402   public:
403
404     TemplateVariant handleGeneratedAt(const QValueList<TemplateVariant> &args) const
405     {
406       if (args.count()==2)
407       {
408         return theTranslator->trGeneratedAt(args[0].toString(),args[1].toString());
409       }
410       else
411       {
412         err("tr.generateAt should take two arguments, got %d!\n",args.count());
413       }
414       return TemplateVariant();
415     }
416     TemplateVariant handleInheritanceDiagramFor(const QValueList<TemplateVariant> &args) const
417     {
418       if (args.count()==1)
419       {
420         return theTranslator->trClassDiagram(args[0].toString());
421       }
422       else
423       {
424         err("tr.inheritanceDiagramFor should take one argument, got %d!\n",args.count());
425       }
426       return TemplateVariant();
427     }
428     TemplateVariant handleCollaborationDiagramFor(const QValueList<TemplateVariant> &args) const
429     {
430       if (args.count()==1)
431       {
432         return theTranslator->trCollaborationDiagram(args[0].toString());
433       }
434       else
435       {
436         err("tr.collaborationDiagramFor should take one argument, got %d!\n",args.count());
437       }
438       return TemplateVariant();
439     }
440     TemplateVariant handleInheritsList(const QValueList<TemplateVariant> &args) const
441     {
442       if (args.count()==1)
443       {
444         return theTranslator->trInheritsList(args[0].toInt());
445       }
446       else
447       {
448         err("tr.inheritsList should take one integer argument, got %d!\n",args.count());
449       }
450       return TemplateVariant();
451     }
452     TemplateVariant handleInheritedByList(const QValueList<TemplateVariant> &args) const
453     {
454       if (args.count()==1)
455       {
456         return theTranslator->trInheritedByList(args[0].toInt());
457       }
458       else
459       {
460         err("tr.inheritedByList should take one integer argument, got %d!\n",args.count());
461       }
462       return TemplateVariant();
463     }
464     TemplateVariant handleWriteList(const QValueList<TemplateVariant> &args) const
465     {
466       if (args.count()==1)
467       {
468         return theTranslator->trWriteList(args[0].toInt());
469       }
470       else
471       {
472         err("tr.*List should take one integer argument, got %d!\n",args.count());
473       }
474       return TemplateVariant();
475     }
476     TemplateVariant handleImplementedBy(const QValueList<TemplateVariant> &args) const
477     {
478       if (args.count()==1)
479       {
480         return theTranslator->trImplementedInList(args[0].toInt());
481       }
482       else
483       {
484         err("tr.implementedBy should take one integer argument, got %d!\n",args.count());
485       }
486       return TemplateVariant();
487     }
488     TemplateVariant handleReimplementedBy(const QValueList<TemplateVariant> &args) const
489     {
490       if (args.count()==1)
491       {
492         return theTranslator->trReimplementedInList(args[0].toInt());
493       }
494       else
495       {
496         err("tr.reimplementedBy should take one integer argument, got %d!\n",args.count());
497       }
498       return TemplateVariant();
499     }
500     TemplateVariant handleSourceRefs(const QValueList<TemplateVariant> &args) const
501     {
502       if (args.count()==1)
503       {
504         return theTranslator->trReferences()+" "+theTranslator->trWriteList(args[0].toInt())+".";
505       }
506       else
507       {
508         err("tr.sourceRefs should take one integer argument, got %d\n",args.count());
509       }
510       return TemplateVariant();
511     }
512     TemplateVariant handleSourceRefBys(const QValueList<TemplateVariant> &args) const
513     {
514       if (args.count()==1)
515       {
516         return theTranslator->trReferencedBy()+" "+theTranslator->trWriteList(args[0].toInt())+".";
517       }
518       else
519       {
520         err("tr.sourceRefBys should take one integer argument, got %d\n",args.count());
521       }
522       return TemplateVariant();
523     }
524     TemplateVariant handleIncludeDependencyGraph(const QValueList<TemplateVariant> &args) const
525     {
526       if (args.count()==1)
527       {
528         return theTranslator->trInclDepGraph(args[0].toString());
529       }
530       else
531       {
532         err("tr.includeDependencyGraph should take one string argument, got %d\n",args.count());
533       }
534       return TemplateVariant();
535     }
536
537
538
539     TemplateVariant generatedBy() const
540     {
541       return theTranslator->trGeneratedBy();
542     }
543     TemplateVariant generatedAt() const
544     {
545       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleGeneratedAt>(this);
546     }
547     TemplateVariant inheritanceDiagramFor() const
548     {
549       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritanceDiagramFor>(this);
550     }
551     TemplateVariant collaborationDiagramFor() const
552     {
553       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleCollaborationDiagramFor>(this);
554     }
555     TemplateVariant search() const
556     {
557       return theTranslator->trSearch();
558     }
559     TemplateVariant mainPage() const
560     {
561       return theTranslator->trMainPage();
562     }
563     TemplateVariant classes() const
564     {
565       return theTranslator->trClasses();
566       // TODO: VHDL: trVhdlType(VhdlDocGen::ENTITY,FALSE)
567       // TODO: Fortran: trDataTypes()
568     }
569     TemplateVariant classList() const
570     {
571       return theTranslator->trCompoundList();
572     }
573     TemplateVariant classListDescription() const
574     {
575       return theTranslator->trCompoundListDescription();
576     }
577     TemplateVariant classIndex() const
578     {
579       return theTranslator->trCompoundIndex();
580     }
581     TemplateVariant classHierarchy() const
582     {
583       return theTranslator->trClassHierarchy();
584     }
585     TemplateVariant classMembers() const
586     {
587       return theTranslator->trCompoundMembers();
588     }
589     TemplateVariant modules() const
590     {
591       return theTranslator->trModules();
592     }
593     TemplateVariant namespaces() const
594     {
595       if (m_javaOpt || m_vhdlOpt)
596       {
597         return theTranslator->trPackages();
598       }
599       else if (m_fortranOpt)
600       {
601         return theTranslator->trModules();
602       }
603       else
604       {
605         return theTranslator->trNamespaces();
606       }
607     }
608     TemplateVariant files() const
609     {
610       return theTranslator->trFile(TRUE,FALSE);
611     }
612     TemplateVariant pages() const
613     {
614       return theTranslator->trRelatedPages();
615     }
616     TemplateVariant examples() const
617     {
618       return theTranslator->trExamples();
619     }
620     TemplateVariant namespaceList() const
621     {
622       if (m_javaOpt || m_vhdlOpt)
623       {
624         return theTranslator->trPackages();
625       }
626       else if (m_fortranOpt)
627       {
628         return theTranslator->trModulesList();
629       }
630       else
631       {
632         return theTranslator->trNamespaceList();
633       }
634     }
635     TemplateVariant namespaceMembers() const
636     {
637       if (m_javaOpt || m_vhdlOpt)
638       {
639         return theTranslator->trPackageMembers();
640       }
641       else if (m_fortranOpt)
642       {
643         return theTranslator->trModulesMembers();
644       }
645       else
646       {
647         return theTranslator->trNamespaceMembers();
648       }
649     }
650     TemplateVariant fileList() const
651     {
652       return theTranslator->trFileList();
653     }
654     TemplateVariant fileMembers() const
655     {
656       return theTranslator->trFileMembers();
657     }
658     TemplateVariant fileMembersDescription() const
659     {
660       static bool extractAll = Config_getBool("EXTRACT_ALL");
661       return theTranslator->trFileMembersDescription(extractAll);
662     }
663     TemplateVariant namespaceMembersDescription() const
664     {
665       static bool extractAll = Config_getBool("EXTRACT_ALL");
666       return theTranslator->trNamespaceMemberDescription(extractAll);
667     }
668     TemplateVariant classMembersDescription() const
669     {
670       static bool extractAll = Config_getBool("EXTRACT_ALL");
671       static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
672       if (fortranOpt)
673       {
674         return theTranslator->trCompoundMembersDescriptionFortran(extractAll);
675       }
676       else
677       {
678         return theTranslator->trCompoundMembersDescription(extractAll);
679       }
680     }
681     TemplateVariant relatedPagesDesc() const
682     {
683       return theTranslator->trRelatedPagesDescription();
684     }
685     TemplateVariant more() const
686     {
687       return theTranslator->trMore();
688     }
689     TemplateVariant detailedDesc() const
690     {
691       return theTranslator->trDetailedDescription();
692     }
693     TemplateVariant inheritsList() const
694     {
695       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritsList>(this);
696     }
697     TemplateVariant inheritedByList() const
698     {
699       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleInheritedByList>(this);
700     }
701     TemplateVariant definedAtLineInSourceFile() const
702     {
703       return theTranslator->trDefinedAtLineInSourceFile();
704     }
705     TemplateVariant typeConstraints() const
706     {
707       return theTranslator->trTypeConstraints();
708     }
709     TemplateVariant exampleList() const
710     {
711       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleWriteList>(this);
712     }
713     TemplateVariant listOfAllMembers() const
714     {
715       return theTranslator->trListOfAllMembers();
716     }
717     TemplateVariant memberList() const
718     {
719       return theTranslator->trMemberList();
720     }
721     TemplateVariant theListOfAllMembers() const
722     {
723       return theTranslator->trThisIsTheListOfAllMembers();
724     }
725     TemplateVariant incInheritedMembers() const
726     {
727       return theTranslator->trIncludingInheritedMembers();
728     }
729     TemplateVariant defineValue() const
730     {
731       return theTranslator->trDefineValue();
732     }
733     TemplateVariant initialValue() const
734     {
735       return theTranslator->trInitialValue();
736     }
737     TemplateVariant enumerationValues() const
738     {
739       return theTranslator->trEnumerationValues();
740     }
741     TemplateVariant implements() const
742     {
743       return theTranslator->trImplementedFromList(1);
744     }
745     TemplateVariant reimplements() const
746     {
747       return theTranslator->trReimplementedFromList(1);
748     }
749     TemplateVariant implementedBy() const
750     {
751       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleImplementedBy>(this);
752     }
753     TemplateVariant reimplementedBy() const
754     {
755       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleReimplementedBy>(this);
756     }
757     TemplateVariant sourceRefs() const
758     {
759       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleSourceRefs>(this);
760     }
761     TemplateVariant sourceRefBys() const
762     {
763       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleSourceRefBys>(this);
764     }
765     TemplateVariant callGraph() const
766     {
767       return theTranslator->trCallGraph();
768     }
769     TemplateVariant callerGraph() const
770     {
771       return theTranslator->trCallerGraph();
772     }
773     TemplateVariant inheritedFrom() const
774     {
775       return theTranslator->trInheritedFrom("@0","@1");
776     }
777     TemplateVariant additionalInheritedMembers() const
778     {
779       return theTranslator->trAdditionalInheritedMembers();
780     }
781     TemplateVariant includeDependencyGraph() const
782     {
783       return TemplateVariant::Delegate::fromMethod<Private,&Private::handleIncludeDependencyGraph>(this);
784     }
785     TemplateVariant includedByDependencyGraph() const
786     {
787       return theTranslator->trInclByDepGraph();
788     }
789     TemplateVariant gotoSourceCode() const
790     {
791       return theTranslator->trGotoSourceCode();
792     }
793     TemplateVariant gotoDocumentation() const
794     {
795       return theTranslator->trGotoDocumentation();
796     }
797     TemplateVariant constantgroups() const
798     {
799       return theTranslator->trConstantGroups();
800     }
801     TemplateVariant classDocumentation() const
802     {
803       return theTranslator->trClassDocumentation();
804     }
805     TemplateVariant compoundMembers() const
806     {
807       return theTranslator->trCompoundMembers();
808     }
809     TemplateVariant detailLevel() const
810     {
811       return theTranslator->trDetailLevel();
812     }
813     TemplateVariant fileListDescription() const
814     {
815       bool extractAll = Config_getBool("EXTRACT_ALL");
816       return theTranslator->trFileListDescription(extractAll);
817     }
818     TemplateVariant modulesDescription() const
819     {
820       bool extractAll = Config_getBool("EXTRACT_ALL");
821       return theTranslator->trModulesListDescription(extractAll);
822     }
823     TemplateVariant namespaceListDescription() const
824     {
825       bool extractAll = Config_getBool("EXTRACT_ALL");
826       return theTranslator->trNamespaceListDescription(extractAll);
827     }
828     TemplateVariant directories() const
829     {
830       return theTranslator->trDirectories();
831     }
832     TemplateVariant all() const
833     {
834       return theTranslator->trAll();
835     }
836     TemplateVariant functions() const
837     {
838       static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
839       static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
840       return fortranOpt ? theTranslator->trSubprograms() :
841              vhdlOpt    ? VhdlDocGen::trFunctionAndProc() :
842                           theTranslator->trFunctions();
843     }
844     TemplateVariant variables() const
845     {
846       return theTranslator->trVariables();
847     }
848     TemplateVariant typedefs() const
849     {
850       return theTranslator->trTypedefs();
851     }
852     TemplateVariant enums() const
853     {
854       return theTranslator->trEnumerations();
855     }
856     TemplateVariant properties() const
857     {
858       return theTranslator->trProperties();
859     }
860     TemplateVariant events() const
861     {
862       return theTranslator->trEvents();
863     }
864     TemplateVariant related() const
865     {
866       return theTranslator->trRelatedFunctions();
867     }
868     TemplateVariant macros() const
869     {
870       return theTranslator->trDefines();
871     }
872     Private()
873     {
874       //%% string generatedBy
875       addProperty("generatedby",       this,&Private::generatedBy);
876       //%% string generatedAt
877       addProperty("generatedAt",       this,&Private::generatedAt);
878       //%% string search
879       addProperty("search",            this,&Private::search);
880       //%% string mainPage
881       addProperty("mainPage",          this,&Private::mainPage);
882       //%% string classes
883       addProperty("classes",           this,&Private::classes);
884       //%% string classList
885       addProperty("classList",         this,&Private::classList);
886       //%% string classListDescription
887       addProperty("classListDescription", this,&Private::classListDescription);
888       //%% string classIndex
889       addProperty("classIndex",        this,&Private::classIndex);
890       //%% string classHierarchy
891       addProperty("classHierarchy",    this,&Private::classHierarchy);
892       //%% string classMembers
893       addProperty("classMembers",      this,&Private::classMembers);
894       //%% string classMembersDescription
895       addProperty("classMembersDescription",this,&Private::classMembersDescription);
896       //%% string modules
897       addProperty("modules",           this,&Private::modules);
898       //%% string namespaces
899       addProperty("namespaces",        this,&Private::namespaces);
900       //%% string files
901       addProperty("files",             this,&Private::files);
902       //%% string pages
903       addProperty("pages",             this,&Private::pages);
904       //%% string examples
905       addProperty("examples",          this,&Private::examples);
906       //%% string namespaceList
907       addProperty("namespaceList",     this,&Private::namespaceList);
908       //%% string namespaceMembers
909       addProperty("namespaceMembers",  this,&Private::namespaceMembers);
910       //%% srting fileList
911       addProperty("fileList",          this,&Private::fileList);
912       //%% string fileMembers
913       addProperty("fileMembers",       this,&Private::fileMembers);
914       //%% string fileMembersDescription
915       addProperty("fileMembersDescription", this,&Private::fileMembersDescription);
916       //%% string relatedPagesDescripiton
917       addProperty("relatedPagesDesc",  this,&Private::relatedPagesDesc);
918       //%% string more
919       addProperty("more",              this,&Private::more);
920       //%% string detailedDescription
921       addProperty("detailedDesc",      this,&Private::detailedDesc);
922       //%% string inheritanceDiagramFor
923       addProperty("inheritanceDiagramFor", this,&Private::inheritanceDiagramFor);
924       //%% string collaborationDiagramFor
925       addProperty("collaborationDiagramFor", this,&Private::collaborationDiagramFor);
926       //%% markerstring inheritsList
927       addProperty("inheritsList",      this,&Private::inheritsList);
928       //%% markerstring inheritedByList
929       addProperty("inheritedByList",   this,&Private::inheritedByList);
930       //%% markerstring definedAtLineInSourceFile
931       addProperty("definedAtLineInSourceFile", this,&Private::definedAtLineInSourceFile);
932       //%% string typeConstraints
933       addProperty("typeConstraints",   this,&Private::typeConstraints);
934       //%% string exampleList
935       addProperty("exampleList",       this,&Private::exampleList);
936       //%% string listOfAllMembers
937       addProperty("listOfAllMembers",  this,&Private::listOfAllMembers);
938       //%% string memberList
939       addProperty("memberList",        this,&Private::memberList);
940       //%% string theListOfAllMembers
941       addProperty("theListOfAllMembers",this,&Private::theListOfAllMembers);
942       //%% string incInheritedMembers
943       addProperty("incInheritedMembers",this,&Private::incInheritedMembers);
944       //%% string defineValue
945       addProperty("defineValue",        this,&Private::defineValue);
946       //%% string initialValue
947       addProperty("initialValue",       this,&Private::initialValue);
948       //%% markerstring implements
949       addProperty("implements",         this,&Private::implements);
950       //%% markerstring reimplements
951       addProperty("reimplements",       this,&Private::reimplements);
952       //%% markerstring implementedBy
953       addProperty("implementedBy",      this,&Private::implementedBy);
954       //%% markerstring reimplementedBy
955       addProperty("reimplementedBy",    this,&Private::reimplementedBy);
956       //%% markerstring sourceRefs
957       addProperty("sourceRefs",         this,&Private::sourceRefs);
958       //%% markerstring sourceRefBys
959       addProperty("sourceRefBys",       this,&Private::sourceRefBys);
960       //%% string callGraph
961       addProperty("callGraph",          this,&Private::callGraph);
962       //%% string callerGraph
963       addProperty("callerGraph",        this,&Private::callerGraph);
964       //%% markerstring inheritedFrom
965       addProperty("inheritedFrom",      this,&Private::inheritedFrom);
966       //%% string addtionalInheritedMembers
967       addProperty("additionalInheritedMembers",this,&Private::additionalInheritedMembers);
968       //%% string includeDependencyGraph:container_name
969       addProperty("includeDependencyGraph",this,&Private::includeDependencyGraph);
970       //%% string includedByDependencyGraph
971       addProperty("includedByDependencyGraph",this,&Private::includedByDependencyGraph);
972       //%% string gotoSourceCode
973       addProperty("gotoSourceCode",     this,&Private::gotoSourceCode);
974       //%% string gotoDocumentation
975       addProperty("gotoDocumentation",  this,&Private::gotoDocumentation);
976       //%% string constantgroups
977       addProperty("constantgroups",     this,&Private::constantgroups);
978       //%% string classDocumentation
979       addProperty("classDocumentation", this,&Private::classDocumentation);
980       //%% string compoundMembers
981       addProperty("compoundMembers",    this,&Private::compoundMembers);
982       //%% string detailLevel
983       addProperty("detailLevel",        this,&Private::detailLevel);
984       //%% string fileListDescription
985       addProperty("fileListDescription",this,&Private::fileListDescription);
986       //%% string namespaceListDescription
987       addProperty("namespaceListDescription",this,&Private::namespaceListDescription);
988       //%% string directories
989       addProperty("directories",        this,&Private::directories);
990       //%% string moduleDescript
991       addProperty("modulesDescription", this,&Private::modulesDescription);
992       //%% string all
993       addProperty("all",                this,&Private::all);
994       //%% string functions
995       addProperty("functions",          this,&Private::functions);
996       //%% string variables
997       addProperty("variables",          this,&Private::variables);
998       //%% string typedefs
999       addProperty("typedefs",           this,&Private::typedefs);
1000       //%% string enums
1001       addProperty("enums",              this,&Private::enums);
1002       //%% string enumValues
1003       addProperty("enumValues",         this,&Private::enumerationValues);
1004       //%% string properties
1005       addProperty("properties",         this,&Private::properties);
1006       //%% string events
1007       addProperty("events",             this,&Private::events);
1008       //%% string related
1009       addProperty("related",            this,&Private::related);
1010       //%% string macros
1011       addProperty("macros",             this,&Private::macros);
1012       //%% string namespaceMembersDescription
1013       addProperty("namespaceMembersDescription",this,&Private::namespaceMembersDescription);
1014
1015       m_javaOpt    = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
1016       m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
1017       m_vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1018     }
1019   private:
1020     bool m_javaOpt;
1021     bool m_fortranOpt;
1022     bool m_vhdlOpt;
1023 };
1024 //%% }
1025
1026 TranslateContext::TranslateContext() : RefCountedContext("TranslateContext")
1027 {
1028   p = new Private;
1029 }
1030
1031 TranslateContext::~TranslateContext()
1032 {
1033   delete p;
1034 }
1035
1036 TemplateVariant TranslateContext::get(const char *n) const
1037 {
1038   return p->get(n);
1039 }
1040
1041 static TemplateVariant parseDoc(Definition *def,const QCString &file,int line,
1042                                 const QCString &relPath,const QCString &docStr,bool isBrief)
1043 {
1044   TemplateVariant result;
1045   DocRoot *root = validatingParseDoc(file,line,def,0,docStr,TRUE,FALSE,0,isBrief,FALSE);
1046   QGString docs;
1047   {
1048     FTextStream ts(&docs);
1049     // TODO: support other generators
1050     HtmlCodeGenerator codeGen(ts,relPath);
1051     HtmlDocVisitor visitor(ts,codeGen,def);
1052     root->accept(&visitor);
1053   }
1054   bool isEmpty = root->isEmpty();
1055   if (isEmpty)
1056     result = "";
1057   else
1058     result = TemplateVariant(docs,TRUE);
1059   delete root;
1060   return result;
1061 }
1062
1063 static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const QCString &relPath,
1064                                  const QCString &code,int startLine=-1,int endLine=-1,bool showLineNumbers=FALSE)
1065 {
1066   ParserInterface *pIntf = Doxygen::parserManager->getParser(md->getDefFileExtension());
1067   pIntf->resetCodeParserState();
1068   QGString s;
1069   FTextStream t(&s);
1070   HtmlCodeGenerator codeGen(t,relPath);
1071   pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(),
1072                    startLine,endLine,TRUE,md,showLineNumbers,md);
1073   return TemplateVariant(s.data(),TRUE);
1074 }
1075
1076 static TemplateVariant parseCode(FileDef *fd,const QCString &relPath)
1077 {
1078   static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
1079   ParserInterface *pIntf = Doxygen::parserManager->getParser(fd->getDefFileExtension());
1080   pIntf->resetCodeParserState();
1081   QGString s;
1082   FTextStream t(&s);
1083   HtmlCodeGenerator codeGen(t,relPath);
1084   pIntf->parseCode(codeGen,0,
1085         fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources
1086         fd->getLanguage(),  // lang
1087         FALSE,              // isExampleBlock
1088         0,                  // exampleName
1089         fd,                 // fileDef
1090         -1,                 // startLine
1091         -1,                 // endLine
1092         FALSE,              // inlineFragment
1093         0,                  // memberDef
1094         TRUE,               // showLineNumbers
1095         0,                  // searchCtx
1096         TRUE                // collectXRefs, TODO: should become FALSE
1097         );
1098   return TemplateVariant(s.data(),TRUE);
1099 }
1100
1101 //------------------------------------------------------------------------
1102
1103 //%% struct Symbol: shared info for all symbols
1104 //%% {
1105 template<typename T>
1106 class DefinitionContext : public PropertyMapper
1107 {
1108   public:
1109     DefinitionContext(Definition *d) : m_def(d)
1110     {
1111       //%% string name: the name of the symbol
1112       addProperty("name",this,&DefinitionContext::name);
1113       //%% string bareName: the bare name of the symbol with scope info
1114       addProperty("bareName",this,&DefinitionContext::bareName);
1115       //%% string relPath: the relative path to the root of the output (CREATE_SUBDIRS)
1116       addProperty("relPath",this,&DefinitionContext::relPath);
1117       //%% string fileName: the file name of the output file associated with the symbol (without extension)
1118       addProperty("fileName",this,&DefinitionContext::fileName);
1119       //%% string anchor: anchor within the page
1120       addProperty("anchor",this,&DefinitionContext::anchor);
1121       //%% string details: the detailed documentation for this symbol
1122       addProperty("details",this,&DefinitionContext::details);
1123       //%% string brief: the brief description for this symbol
1124       addProperty("brief",this,&DefinitionContext::brief);
1125       //%% string inbodyDocs: the documentation found in the body
1126       addProperty("inbodyDocs",this,&DefinitionContext::inbodyDocs);
1127       //%% string sourceFileName: the file name of the source file (without extension)
1128       addProperty("sourceFileName",this,&DefinitionContext::sourceFileName);
1129       //%% bool isLinkable: can the symbol be linked to?
1130       addProperty("isLinkable",this,&DefinitionContext::isLinkable);
1131       //%% bool isLinkableInProject: can the symbol be linked within this project?
1132       addProperty("isLinkableInProject",this,&DefinitionContext::isLinkableInProject);
1133       //%% int dynSectionId: identifier that can be used for collapsable sections
1134       addProperty("dynSectionId",this,&DefinitionContext::dynSectionId);
1135       //%% string language: the programming language in which the symbol is written
1136       addProperty("language",this,&DefinitionContext::language);
1137       //%% string sourceDef: A link to the source definition
1138       addProperty("sourceDef",this,&DefinitionContext::sourceDef);
1139       //%% list[Definition] navigationPath: Breadcrumb navigation path to this item
1140       addProperty("navigationPath",this,&DefinitionContext::navigationPath);
1141
1142       m_cache.sourceDef.reset(TemplateList::alloc());
1143       m_cache.lineLink.reset(TemplateStruct::alloc());
1144       m_cache.fileLink.reset(TemplateStruct::alloc());
1145
1146       if (m_def && !m_def->getSourceFileBase().isEmpty())
1147       {
1148         m_cache.lineLink->set("text",m_def->getStartBodyLine());
1149         m_cache.lineLink->set("isLinkable",TRUE);
1150         m_cache.lineLink->set("fileName",m_def->getSourceFileBase());
1151         m_cache.lineLink->set("anchor",m_def->getSourceAnchor());
1152         if (m_def->definitionType()==Definition::TypeFile)
1153         {
1154           m_cache.fileLink->set("text",m_def->name());
1155         }
1156         else if (m_def->getBodyDef())
1157         {
1158           m_cache.fileLink->set("text",m_def->getBodyDef()->name());
1159         }
1160         else
1161         {
1162           m_cache.fileLink->set("text",name());
1163         }
1164         m_cache.fileLink->set("isLinkable",TRUE);
1165         m_cache.fileLink->set("fileName",m_def->getSourceFileBase());
1166         m_cache.fileLink->set("anchor",QCString());
1167         m_cache.sourceDef->append(m_cache.lineLink.get());
1168         m_cache.sourceDef->append(m_cache.fileLink.get());
1169       }
1170     }
1171     TemplateVariant fileName() const
1172     {
1173       return m_def->getOutputFileBase();
1174     }
1175     TemplateVariant anchor() const
1176     {
1177       return m_def->anchor();
1178     }
1179     TemplateVariant sourceFileName() const
1180     {
1181       return m_def->getSourceFileBase();
1182     }
1183     TemplateVariant isLinkable() const
1184     {
1185       return m_def->isLinkable();
1186     }
1187     TemplateVariant isLinkableInProject() const
1188     {
1189       return m_def->isLinkableInProject();
1190     }
1191     TemplateVariant name() const
1192     {
1193       return m_def->displayName(TRUE);
1194     }
1195     TemplateVariant bareName() const
1196     {
1197       return m_def->displayName(FALSE);
1198     }
1199     QCString relPathAsString() const
1200     {
1201       static bool createSubdirs = Config_getBool("CREATE_SUBDIRS");
1202       return createSubdirs ? QCString("../../") : QCString("");
1203     }
1204     virtual TemplateVariant relPath() const
1205     {
1206       return relPathAsString();
1207     }
1208     TemplateVariant details() const
1209     {
1210       if (!m_cache.details)
1211       {
1212         m_cache.details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(),
1213                                             relPathAsString(),m_def->documentation(),FALSE)));
1214       }
1215       return *m_cache.details;
1216     }
1217     TemplateVariant brief() const
1218     {
1219       if (!m_cache.brief)
1220       {
1221         if (m_def->hasBriefDescription())
1222         {
1223           m_cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(),
1224                              relPathAsString(),m_def->briefDescription(),TRUE)));
1225         }
1226         else
1227         {
1228           m_cache.brief.reset(new TemplateVariant(""));
1229         }
1230       }
1231       return *m_cache.brief;
1232     }
1233     TemplateVariant inbodyDocs() const
1234     {
1235       if (!m_cache.inbodyDocs)
1236       {
1237         if (!m_def->inbodyDocumentation().isEmpty())
1238         {
1239           m_cache.inbodyDocs.reset(new TemplateVariant(parseDoc(m_def,m_def->inbodyFile(),m_def->inbodyLine(),
1240                                            relPathAsString(),m_def->inbodyDocumentation(),FALSE)));
1241         }
1242         else
1243         {
1244           m_cache.inbodyDocs.reset(new TemplateVariant(""));
1245         }
1246       }
1247       return *m_cache.inbodyDocs;
1248     }
1249     TemplateVariant dynSectionId() const
1250     {
1251       return g_globals.dynSectionId;
1252     }
1253     TemplateVariant language() const
1254     {
1255       SrcLangExt lang = m_def->getLanguage();
1256       QCString result = "unknown";
1257       switch (lang)
1258       {
1259         case SrcLangExt_Unknown:  break;
1260         case SrcLangExt_IDL:      result="idl";      break;
1261         case SrcLangExt_Java:     result="java";     break;
1262         case SrcLangExt_CSharp:   result="csharp";   break;
1263         case SrcLangExt_D:        result="d";        break;
1264         case SrcLangExt_PHP:      result="php";      break;
1265         case SrcLangExt_ObjC:     result="objc";     break;
1266         case SrcLangExt_Cpp:      result="cpp";      break;
1267         case SrcLangExt_JS:       result="js";       break;
1268         case SrcLangExt_Python:   result="python";   break;
1269         case SrcLangExt_Fortran:  result="fortran";  break;
1270         case SrcLangExt_VHDL:     result="vhdl";     break;
1271         case SrcLangExt_XML:      result="xml";      break;
1272         case SrcLangExt_Tcl:      result="tcl";      break;
1273         case SrcLangExt_Markdown: result="markdown"; break;
1274       }
1275       return result;
1276     }
1277     TemplateVariant sourceDef() const
1278     {
1279       if (m_cache.sourceDef->count()==2)
1280       {
1281         return m_cache.sourceDef.get();
1282       }
1283       else
1284       {
1285         return FALSE;
1286       }
1287     }
1288     void fillPath(Definition *def,TemplateList *list) const
1289     {
1290       Definition *outerScope = def->getOuterScope();
1291       Definition::DefType type = def->definitionType();
1292       if (outerScope && outerScope!=Doxygen::globalScope)
1293       {
1294         fillPath(outerScope,list);
1295       }
1296       else if (type==Definition::TypeFile && ((const FileDef*)def)->getDirDef())
1297       {
1298         fillPath(((const FileDef*)def)->getDirDef(),list);
1299       }
1300       list->append(NavPathElemContext::alloc(def));
1301     }
1302     TemplateVariant navigationPath() const
1303     {
1304       if (!m_cache.navPath)
1305       {
1306         TemplateList *list = TemplateList::alloc();
1307         if (m_def->getOuterScope() && m_def->getOuterScope()!=Doxygen::globalScope)
1308         {
1309           fillPath(m_def->getOuterScope(),list);
1310         }
1311         else if (m_def->definitionType()==Definition::TypeFile && ((const FileDef *)m_def)->getDirDef())
1312         {
1313           fillPath(((const FileDef *)m_def)->getDirDef(),list);
1314         }
1315         m_cache.navPath.reset(list);
1316       }
1317       return m_cache.navPath.get();
1318     }
1319
1320   private:
1321     Definition      *m_def;
1322     struct Cachable
1323     {
1324       Cachable() { }
1325       ScopedPtr<TemplateVariant> details;
1326       ScopedPtr<TemplateVariant> brief;
1327       ScopedPtr<TemplateVariant> inbodyDocs;
1328       SharedPtr<TemplateList>    navPath;
1329       SharedPtr<TemplateList>    sourceDef;
1330       SharedPtr<TemplateStruct>  fileLink;
1331       SharedPtr<TemplateStruct>  lineLink;
1332     };
1333     mutable Cachable m_cache;
1334 };
1335 //%% }
1336
1337 //------------------------------------------------------------------------
1338
1339 //%% struct IncludeInfo: include file information
1340 //%% {
1341 class IncludeInfoContext::Private : public PropertyMapper
1342 {
1343   public:
1344     Private(const IncludeInfo *info,SrcLangExt lang) :
1345       m_info(info),
1346       m_lang(lang)
1347     {
1348       if (m_info)
1349       {
1350         addProperty("file",this,&Private::file);
1351         addProperty("name",this,&Private::name);
1352         addProperty("isImport",this,&Private::isImport);
1353         addProperty("isLocal",this,&Private::isLocal);
1354       }
1355     }
1356     TemplateVariant isLocal() const
1357     {
1358       bool isIDLorJava = m_lang==SrcLangExt_IDL || m_lang==SrcLangExt_Java;
1359       return m_info->local || isIDLorJava;
1360     }
1361     TemplateVariant isImport() const
1362     {
1363       return m_info->imported;
1364     }
1365     TemplateVariant file() const
1366     {
1367       if (!m_fileContext && m_info && m_info->fileDef)
1368       {
1369         m_fileContext.reset(FileContext::alloc(m_info->fileDef));
1370       }
1371       if (m_fileContext)
1372       {
1373         return m_fileContext.get();
1374       }
1375       else
1376       {
1377         return FALSE;
1378       }
1379     }
1380     TemplateVariant name() const
1381     {
1382       return m_info->includeName;
1383     }
1384   private:
1385     const IncludeInfo *m_info;
1386     mutable SharedPtr<FileContext> m_fileContext;
1387     SrcLangExt m_lang;
1388 };
1389
1390 IncludeInfoContext::IncludeInfoContext(const IncludeInfo *info,SrcLangExt lang) : RefCountedContext("IncludeContext")
1391 {
1392   p = new Private(info,lang);
1393 }
1394
1395 IncludeInfoContext::~IncludeInfoContext()
1396 {
1397   delete p;
1398 }
1399
1400 TemplateVariant IncludeInfoContext::get(const char *n) const
1401 {
1402   return p->get(n);
1403 }
1404 //%% }
1405
1406 //------------------------------------------------------------------------
1407
1408 //%% list IncludeInfoList[Class] : list of nested classes
1409 class IncludeInfoListContext::Private : public GenericNodeListContext
1410 {
1411   public:
1412     Private(const QList<IncludeInfo> &list,SrcLangExt lang)
1413     {
1414       QListIterator<IncludeInfo> li(list);
1415       IncludeInfo *ii;
1416       for (li.toFirst();(ii=li.current());++li)
1417       {
1418         if (!ii->indirect)
1419         {
1420           append(IncludeInfoContext::alloc(ii,lang));
1421         }
1422       }
1423     }
1424 };
1425
1426 IncludeInfoListContext::IncludeInfoListContext(const QList<IncludeInfo> &list,SrcLangExt lang) : RefCountedContext("IncludeListContext")
1427 {
1428   p = new Private(list,lang);
1429 }
1430
1431 IncludeInfoListContext::~IncludeInfoListContext()
1432 {
1433   delete p;
1434 }
1435
1436 // TemplateListIntf
1437 int IncludeInfoListContext::count() const
1438 {
1439   return p->count();
1440 }
1441
1442 TemplateVariant IncludeInfoListContext::at(int index) const
1443 {
1444   return p->at(index);
1445 }
1446
1447 TemplateListIntf::ConstIterator *IncludeInfoListContext::createIterator() const
1448 {
1449   return p->createIterator();
1450 }
1451
1452 //------------------------------------------------------------------------
1453
1454 //%% struct Class(Symbol): class information
1455 //%% {
1456 class ClassContext::Private : public DefinitionContext<ClassContext::Private>
1457 {
1458   public:
1459     Private(ClassDef *cd) : DefinitionContext<ClassContext::Private>(cd),
1460        m_classDef(cd)
1461     {
1462       addProperty("title",                     this,&Private::title);
1463       addProperty("highlight",                 this,&Private::highlight);
1464       addProperty("subhighlight",              this,&Private::subHighlight);
1465       addProperty("hasDetails",                this,&Private::hasDetails);
1466       addProperty("generatedFromFiles",        this,&Private::generatedFromFiles);
1467       addProperty("usedFiles",                 this,&Private::usedFiles);
1468       addProperty("hasInheritanceDiagram",     this,&Private::hasInheritanceDiagram);
1469       addProperty("inheritanceDiagram",        this,&Private::inheritanceDiagram);
1470       addProperty("hasCollaborationDiagram",   this,&Private::hasCollaborationDiagram);
1471       addProperty("collaborationDiagram",      this,&Private::collaborationDiagram);
1472       addProperty("includeInfo",               this,&Private::includeInfo);
1473       addProperty("inherits",                  this,&Private::inherits);
1474       addProperty("inheritedBy",               this,&Private::inheritedBy);
1475       addProperty("unoIDLServices",            this,&Private::unoIDLServices);
1476       addProperty("unoIDLInterfaces",          this,&Private::unoIDLInterfaces);
1477       addProperty("signals",                   this,&Private::signals);
1478       addProperty("publicTypes",               this,&Private::publicTypes);
1479       addProperty("publicMethods",             this,&Private::publicMethods);
1480       addProperty("publicStaticMethods",       this,&Private::publicStaticMethods);
1481       addProperty("publicAttributes",          this,&Private::publicAttributes);
1482       addProperty("publicStaticAttributes",    this,&Private::publicStaticAttributes);
1483       addProperty("publicSlots",               this,&Private::publicSlots);
1484       addProperty("protectedTypes",            this,&Private::protectedTypes);
1485       addProperty("protectedMethods",          this,&Private::protectedMethods);
1486       addProperty("protectedStaticMethods",    this,&Private::protectedStaticMethods);
1487       addProperty("protectedAttributes",       this,&Private::protectedAttributes);
1488       addProperty("protectedStaticAttributes", this,&Private::protectedStaticAttributes);
1489       addProperty("protectedSlots",            this,&Private::protectedSlots);
1490       addProperty("privateTypes",              this,&Private::privateTypes);
1491       addProperty("privateMethods",            this,&Private::privateMethods);
1492       addProperty("privateStaticMethods",      this,&Private::privateStaticMethods);
1493       addProperty("privateAttributes",         this,&Private::privateAttributes);
1494       addProperty("privateStaticAttributes",   this,&Private::privateStaticAttributes);
1495       addProperty("privateSlots",              this,&Private::privateSlots);
1496       addProperty("packageTypes",              this,&Private::packageTypes);
1497       addProperty("packageMethods",            this,&Private::packageMethods);
1498       addProperty("packageStaticMethods",      this,&Private::packageStaticMethods);
1499       addProperty("packageAttributes",         this,&Private::packageAttributes);
1500       addProperty("packageStaticAttributes",   this,&Private::packageStaticAttributes);
1501       addProperty("properties",                this,&Private::properties);
1502       addProperty("events",                    this,&Private::events);
1503       addProperty("friends",                   this,&Private::friends);
1504       addProperty("related",                   this,&Private::related);
1505       addProperty("detailedTypedefs",          this,&Private::detailedTypedefs);
1506       addProperty("detailedEnums",             this,&Private::detailedEnums);
1507       addProperty("detailedServices",          this,&Private::detailedServices);
1508       addProperty("detailedInterfaces",        this,&Private::detailedInterfaces);
1509       addProperty("detailedConstructors",      this,&Private::detailedConstructors);
1510       addProperty("detailedMethods",           this,&Private::detailedMethods);
1511       addProperty("detailedRelated",           this,&Private::detailedRelated);
1512       addProperty("detailedVariables",         this,&Private::detailedVariables);
1513       addProperty("detailedProperties",        this,&Private::detailedProperties);
1514       addProperty("detailedEvents",            this,&Private::detailedEvents);
1515       addProperty("classes",                   this,&Private::classes);
1516       addProperty("compoundType",              this,&Private::compoundType);
1517       addProperty("templateDecls",             this,&Private::templateDecls);
1518       addProperty("typeConstraints",           this,&Private::typeConstraints);
1519       addProperty("examples",                  this,&Private::examples);
1520       addProperty("members",                   this,&Private::members);
1521       addProperty("allMembersList",            this,&Private::allMembersList);
1522       addProperty("allMembersFileName",        this,&Private::allMembersFileName);
1523       addProperty("memberGroups",              this,&Private::memberGroups);
1524       addProperty("additionalInheritedMembers",this,&Private::additionalInheritedMembers);
1525     }
1526     virtual ~Private() {}
1527     TemplateVariant title() const
1528     {
1529       return TemplateVariant(m_classDef->title());
1530     }
1531     TemplateVariant highlight() const
1532     {
1533       return TemplateVariant("classes");
1534     }
1535     TemplateVariant subHighlight() const
1536     {
1537       return TemplateVariant("");
1538     }
1539     TemplateVariant hasDetails() const
1540     {
1541       return m_classDef->hasDetailedDescription();
1542     }
1543     TemplateVariant generatedFromFiles() const
1544     {
1545       return m_classDef->generatedFromFiles();
1546     }
1547     TemplateVariant usedFiles() const
1548     {
1549       if (!m_cache.usedFiles)
1550       {
1551         m_cache.usedFiles.reset(UsedFilesContext::alloc(m_classDef));
1552       }
1553       return m_cache.usedFiles.get();
1554     }
1555     DotClassGraph *getClassGraph() const
1556     {
1557       if (!m_cache.classGraph)
1558       {
1559         m_cache.classGraph.reset(new DotClassGraph(m_classDef,DotNode::Inheritance));
1560       }
1561       return m_cache.classGraph.get();
1562     }
1563     int numInheritanceNodes() const
1564     {
1565       if (m_cache.inheritanceNodes==-1)
1566       {
1567         m_cache.inheritanceNodes=m_classDef->countInheritanceNodes();
1568       }
1569       return m_cache.inheritanceNodes>0;
1570     }
1571     TemplateVariant hasInheritanceDiagram() const
1572     {
1573       bool result=FALSE;
1574       static bool haveDot       = Config_getBool("HAVE_DOT");
1575       static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS");
1576       static bool classGraph    = Config_getBool("CLASS_GRAPH");
1577       if (haveDot && (classDiagrams || classGraph))
1578       {
1579         DotClassGraph *cg = getClassGraph();
1580         result = !cg->isTrivial() && !cg->isTooBig();
1581       }
1582       else if (classDiagrams)
1583       {
1584         result = numInheritanceNodes()>0;
1585       }
1586       return result;
1587     }
1588     TemplateVariant inheritanceDiagram() const
1589     {
1590       QGString result;
1591       static bool haveDot       = Config_getBool("HAVE_DOT");
1592       static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS");
1593       static bool classGraph    = Config_getBool("CLASS_GRAPH");
1594       if (haveDot && (classDiagrams || classGraph))
1595       {
1596         DotClassGraph *cg = getClassGraph();
1597         FTextStream t(&result);
1598         cg->writeGraph(t,GOF_BITMAP,EOF_Html,
1599                        g_globals.outputDir,
1600                        g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension,
1601                        relPathAsString(),TRUE,TRUE,g_globals.dynSectionId
1602                       );
1603       }
1604       else if (classDiagrams)
1605       {
1606         ClassDiagram d(m_classDef);
1607         FTextStream t(&result);
1608         QCString name = convertToHtml(m_classDef->displayName());
1609         t << "<div class=\"center\">" << endl;
1610         t << "<img src=\"";
1611         t << relPathAsString() << m_classDef->getOutputFileBase();
1612         t << ".png\" usemap=\"#" << name << "_map\" alt=\"\"/>" << endl;
1613         t << "<map id=\"" << name << "_map\" name=\"" << name << "_map\">" << endl;
1614         d.writeImage(t,g_globals.outputDir,
1615                      relPathAsString(),
1616                      m_classDef->getOutputFileBase());
1617         t << "</div>";
1618       }
1619       g_globals.dynSectionId++;
1620       return TemplateVariant(result.data(),TRUE);
1621     }
1622     DotClassGraph *getCollaborationGraph() const
1623     {
1624       if (!m_cache.collaborationGraph)
1625       {
1626         m_cache.collaborationGraph.reset(new DotClassGraph(m_classDef,DotNode::Collaboration));
1627       }
1628       return m_cache.collaborationGraph.get();
1629     }
1630     TemplateVariant hasCollaborationDiagram() const
1631     {
1632       static bool haveDot = Config_getBool("HAVE_DOT");
1633       return haveDot && !getCollaborationGraph()->isTrivial();
1634     }
1635     TemplateVariant collaborationDiagram() const
1636     {
1637       static bool haveDot = Config_getBool("HAVE_DOT");
1638       QGString result;
1639       if (haveDot)
1640       {
1641         DotClassGraph *cg = getCollaborationGraph();
1642         FTextStream t(&result);
1643         cg->writeGraph(t,GOF_BITMAP,EOF_Html,
1644             g_globals.outputDir,
1645             g_globals.outputDir+portable_pathSeparator()+m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension,
1646             relPathAsString(),TRUE,TRUE,g_globals.dynSectionId
1647             );
1648       }
1649       g_globals.dynSectionId++;
1650       return TemplateVariant(result.data(),TRUE);
1651     }
1652
1653     TemplateVariant includeInfo() const
1654     {
1655       if (!m_cache.includeInfo && m_classDef->includeInfo())
1656       {
1657         m_cache.includeInfo.reset(IncludeInfoContext::alloc(m_classDef->includeInfo(),m_classDef->getLanguage()));
1658       }
1659       if (m_cache.includeInfo)
1660       {
1661         return m_cache.includeInfo.get();
1662       }
1663       else
1664       {
1665         return TemplateVariant(FALSE);
1666       }
1667     }
1668     TemplateVariant inherits() const
1669     {
1670       if (!m_cache.inheritsList)
1671       {
1672         m_cache.inheritsList.reset(InheritanceListContext::alloc(m_classDef->baseClasses(),TRUE));
1673       }
1674       return m_cache.inheritsList.get();
1675     }
1676     TemplateVariant inheritedBy() const
1677     {
1678       if (!m_cache.inheritedByList)
1679       {
1680         m_cache.inheritedByList.reset(InheritanceListContext::alloc(m_classDef->subClasses(),FALSE));
1681       }
1682       return m_cache.inheritedByList.get();
1683     }
1684     TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
1685                                   MemberListType type,const char *title,bool detailed=FALSE) const
1686     {
1687       if (!list)
1688       {
1689         MemberList *ml = m_classDef->getMemberList(type);
1690         if (ml)
1691         {
1692           list.reset(MemberListInfoContext::alloc(m_classDef,relPathAsString(),ml,title,detailed));
1693         }
1694       }
1695       if (list)
1696       {
1697         return list.get();
1698       }
1699       else
1700       {
1701         return TemplateVariant(FALSE);
1702       }
1703     }
1704     TemplateVariant unoIDLServices() const
1705     {
1706       return getMemberList(m_cache.unoIDLServices,MemberListType_services,theTranslator->trServices());
1707     }
1708     TemplateVariant unoIDLInterfaces() const
1709     {
1710       return getMemberList(m_cache.unoIDLInterfaces,MemberListType_interfaces,theTranslator->trInterfaces());
1711     }
1712     TemplateVariant signals() const
1713     {
1714       return getMemberList(m_cache.signals,MemberListType_signals,theTranslator->trSignals());
1715     }
1716     TemplateVariant publicTypes() const
1717     {
1718       return getMemberList(m_cache.publicTypes,MemberListType_pubTypes,theTranslator->trPublicTypes());
1719     }
1720     TemplateVariant publicMethods() const
1721     {
1722       return getMemberList(m_cache.publicMethods,MemberListType_pubMethods,
1723           m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods()
1724                                                      : theTranslator->trPublicMembers());
1725     }
1726     TemplateVariant publicStaticMethods() const
1727     {
1728       return getMemberList(m_cache.publicStaticMethods,MemberListType_pubStaticMethods,
1729           m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods()
1730                                                      : theTranslator->trStaticPublicMembers());
1731     }
1732     TemplateVariant publicAttributes() const
1733     {
1734       return getMemberList(m_cache.publicAttributes,MemberListType_pubAttribs,theTranslator->trPublicAttribs());
1735     }
1736     TemplateVariant publicStaticAttributes() const
1737     {
1738       return getMemberList(m_cache.publicStaticAttributes,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs());
1739     }
1740     TemplateVariant publicSlots() const
1741     {
1742       return getMemberList(m_cache.publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots());
1743     }
1744     TemplateVariant protectedTypes() const
1745     {
1746       return getMemberList(m_cache.protectedTypes,MemberListType_proTypes,theTranslator->trProtectedTypes());
1747     }
1748     TemplateVariant protectedMethods() const
1749     {
1750       return getMemberList(m_cache.protectedMethods,MemberListType_proMethods,theTranslator->trProtectedMembers());
1751     }
1752     TemplateVariant protectedStaticMethods() const
1753     {
1754       return getMemberList(m_cache.protectedStaticMethods,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers());
1755     }
1756     TemplateVariant protectedAttributes() const
1757     {
1758       return getMemberList(m_cache.protectedAttributes,MemberListType_proAttribs,theTranslator->trProtectedAttribs());
1759     }
1760     TemplateVariant protectedStaticAttributes() const
1761     {
1762       return getMemberList(m_cache.protectedStaticAttributes,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs());
1763     }
1764     TemplateVariant protectedSlots() const
1765     {
1766       return getMemberList(m_cache.protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots());
1767     }
1768     TemplateVariant privateTypes() const
1769     {
1770       return getMemberList(m_cache.privateTypes,MemberListType_priTypes,theTranslator->trPrivateTypes());
1771     }
1772     TemplateVariant privateSlots() const
1773     {
1774       return getMemberList(m_cache.privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots());
1775     }
1776     TemplateVariant privateMethods() const
1777     {
1778       return getMemberList(m_cache.privateMethods,MemberListType_priMethods,theTranslator->trPrivateMembers());
1779     }
1780     TemplateVariant privateStaticMethods() const
1781     {
1782       return getMemberList(m_cache.privateStaticMethods,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers());
1783     }
1784     TemplateVariant privateAttributes() const
1785     {
1786       return getMemberList(m_cache.privateAttributes,MemberListType_priAttribs,theTranslator->trPrivateAttribs());
1787     }
1788     TemplateVariant privateStaticAttributes() const
1789     {
1790       return getMemberList(m_cache.privateStaticAttributes,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs());
1791     }
1792     TemplateVariant packageTypes() const
1793     {
1794       return getMemberList(m_cache.packageTypes,MemberListType_pacTypes,theTranslator->trPackageTypes());
1795     }
1796     TemplateVariant packageMethods() const
1797     {
1798       return getMemberList(m_cache.packageMethods,MemberListType_pacMethods,theTranslator->trPackageMembers());
1799     }
1800     TemplateVariant packageStaticMethods() const
1801     {
1802       return getMemberList(m_cache.packageStaticMethods,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers());
1803     }
1804     TemplateVariant packageAttributes() const
1805     {
1806       return getMemberList(m_cache.packageAttributes,MemberListType_pacAttribs,theTranslator->trPackageAttribs());
1807     }
1808     TemplateVariant packageStaticAttributes() const
1809     {
1810       return getMemberList(m_cache.packageStaticAttributes,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs());
1811     }
1812     TemplateVariant properties() const
1813     {
1814       return getMemberList(m_cache.properties,MemberListType_properties,theTranslator->trProperties());
1815     }
1816     TemplateVariant events() const
1817     {
1818       return getMemberList(m_cache.events,MemberListType_events,theTranslator->trEvents());
1819     }
1820     TemplateVariant friends() const
1821     {
1822       return getMemberList(m_cache.friends,MemberListType_friends,theTranslator->trFriends());
1823     }
1824     TemplateVariant related() const
1825     {
1826       return getMemberList(m_cache.related,MemberListType_related,theTranslator->trRelatedFunctions());
1827     }
1828     TemplateVariant detailedTypedefs() const
1829     {
1830       return getMemberList(m_cache.detailedTypedefs,MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation(),TRUE);
1831     }
1832     TemplateVariant detailedEnums() const
1833     {
1834       return getMemberList(m_cache.detailedEnums,MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation(),TRUE);
1835     }
1836     TemplateVariant detailedServices() const
1837     {
1838       return getMemberList(m_cache.detailedServices,MemberListType_serviceMembers,theTranslator->trServices(),TRUE);
1839     }
1840     TemplateVariant detailedInterfaces() const
1841     {
1842       return getMemberList(m_cache.detailedInterfaces,MemberListType_interfaceMembers,theTranslator->trInterfaces(),TRUE);
1843     }
1844     TemplateVariant detailedConstructors() const
1845     {
1846       return getMemberList(m_cache.detailedConstructors,MemberListType_constructors,theTranslator->trConstructorDocumentation(),TRUE);
1847     }
1848     TemplateVariant detailedMethods() const
1849     {
1850       return getMemberList(m_cache.detailedMethods,MemberListType_functionMembers,theTranslator->trMemberFunctionDocumentation(),TRUE);
1851     }
1852     TemplateVariant detailedRelated() const
1853     {
1854       return getMemberList(m_cache.detailedRelated,MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation(),TRUE);
1855     }
1856     TemplateVariant detailedVariables() const
1857     {
1858       return getMemberList(m_cache.detailedVariables,MemberListType_variableMembers,theTranslator->trMemberDataDocumentation(),TRUE);
1859     }
1860     TemplateVariant detailedProperties() const
1861     {
1862       return getMemberList(m_cache.detailedProperties,MemberListType_propertyMembers,theTranslator->trPropertyDocumentation(),TRUE);
1863     }
1864     TemplateVariant detailedEvents() const
1865     {
1866       return getMemberList(m_cache.detailedEvents,MemberListType_eventMembers,theTranslator->trEventDocumentation(),TRUE);
1867     }
1868     TemplateVariant classes() const
1869     {
1870       if (!m_cache.classes)
1871       {
1872         TemplateList *classList = TemplateList::alloc();
1873         if (m_classDef->getClassSDict())
1874         {
1875           ClassSDict::Iterator sdi(*m_classDef->getClassSDict());
1876           ClassDef *cd;
1877           for (sdi.toFirst();(cd=sdi.current());++sdi)
1878           {
1879             if (cd->visibleInParentsDeclList())
1880             {
1881               classList->append(ClassContext::alloc(cd));
1882             }
1883           }
1884         }
1885         m_cache.classes.reset(classList);
1886       }
1887       return m_cache.classes.get();
1888     }
1889     TemplateVariant compoundType() const
1890     {
1891       return m_classDef->compoundTypeString();
1892     }
1893     void addTemplateDecls(Definition *d,TemplateList *tl) const
1894     {
1895       if (d->definitionType()==Definition::TypeClass)
1896       {
1897         Definition *parent = d->getOuterScope();
1898         if (parent)
1899         {
1900           addTemplateDecls(parent,tl);
1901         }
1902         ClassDef *cd=(ClassDef *)d;
1903         if (cd->templateArguments())
1904         {
1905           ArgumentListContext *al = ArgumentListContext::alloc(cd->templateArguments(),cd,relPathAsString());
1906           // since a TemplateVariant does take ownership of the object, we add it
1907           // a separate list just to be able to delete it and avoid a memory leak
1908           tl->append(al);
1909         }
1910       }
1911     }
1912     void addExamples(TemplateList *list) const
1913     {
1914       if (m_classDef->hasExamples())
1915       {
1916         ExampleSDict::Iterator it(*m_classDef->exampleList());
1917         Example *ex;
1918         for (it.toFirst();(ex=it.current());++it)
1919         {
1920           TemplateStruct *s = TemplateStruct::alloc();
1921           s->set("text",ex->name);
1922           s->set("isLinkable",TRUE);
1923           s->set("anchor",ex->anchor);
1924           s->set("fileName",ex->file);
1925           list->append(s);
1926         }
1927       }
1928     }
1929     TemplateVariant templateDecls() const
1930     {
1931       if (!m_cache.templateDecls)
1932       {
1933         TemplateList *tl = TemplateList::alloc();
1934         addTemplateDecls(m_classDef,tl);
1935         m_cache.templateDecls.reset(tl);
1936       }
1937       return m_cache.templateDecls.get();
1938     }
1939     TemplateVariant typeConstraints() const
1940     {
1941       if (!m_cache.typeConstraints && m_classDef->typeConstraints())
1942       {
1943         m_cache.typeConstraints.reset(ArgumentListContext::alloc(m_classDef->typeConstraints(),m_classDef,relPathAsString()));
1944       }
1945       else
1946       {
1947         m_cache.typeConstraints.reset(ArgumentListContext::alloc());
1948       }
1949       return m_cache.typeConstraints.get();
1950     }
1951     TemplateVariant examples() const
1952     {
1953       if (!m_cache.examples)
1954       {
1955         TemplateList *exampleList = TemplateList::alloc();
1956         addExamples(exampleList);
1957         m_cache.examples.reset(exampleList);
1958       }
1959       return m_cache.examples.get();
1960     }
1961     void addMembers(ClassDef *cd,MemberListType lt) const
1962     {
1963       MemberList *ml = cd->getMemberList(lt);
1964       if (ml)
1965       {
1966         MemberListIterator li(*ml);
1967         const MemberDef *md;
1968         for (li.toFirst();(md=li.current());++li)
1969         {
1970           if (md->isBriefSectionVisible())
1971           {
1972             m_cache.allMembers.append(md);
1973           }
1974         }
1975       }
1976     }
1977     TemplateVariant members() const
1978     {
1979       if (!m_cache.members)
1980       {
1981         addMembers(m_classDef,MemberListType_pubTypes);
1982         addMembers(m_classDef,MemberListType_services);
1983         addMembers(m_classDef,MemberListType_interfaces);
1984         addMembers(m_classDef,MemberListType_pubSlots);
1985         addMembers(m_classDef,MemberListType_signals);
1986         addMembers(m_classDef,MemberListType_pubMethods);
1987         addMembers(m_classDef,MemberListType_pubStaticMethods);
1988         addMembers(m_classDef,MemberListType_pubAttribs);
1989         addMembers(m_classDef,MemberListType_pubStaticAttribs);
1990         addMembers(m_classDef,MemberListType_proTypes);
1991         addMembers(m_classDef,MemberListType_proSlots);
1992         addMembers(m_classDef,MemberListType_proMethods);
1993         addMembers(m_classDef,MemberListType_proStaticMethods);
1994         addMembers(m_classDef,MemberListType_proAttribs);
1995         addMembers(m_classDef,MemberListType_proStaticAttribs);
1996         addMembers(m_classDef,MemberListType_pacTypes);
1997         addMembers(m_classDef,MemberListType_pacMethods);
1998         addMembers(m_classDef,MemberListType_pacStaticMethods);
1999         addMembers(m_classDef,MemberListType_pacAttribs);
2000         addMembers(m_classDef,MemberListType_pacStaticAttribs);
2001         addMembers(m_classDef,MemberListType_properties);
2002         addMembers(m_classDef,MemberListType_events);
2003         addMembers(m_classDef,MemberListType_priTypes);
2004         addMembers(m_classDef,MemberListType_priSlots);
2005         addMembers(m_classDef,MemberListType_priMethods);
2006         addMembers(m_classDef,MemberListType_priStaticMethods);
2007         addMembers(m_classDef,MemberListType_priAttribs);
2008         addMembers(m_classDef,MemberListType_priStaticAttribs);
2009         addMembers(m_classDef,MemberListType_related);
2010         m_cache.members.reset(MemberListContext::alloc(&m_cache.allMembers));
2011       }
2012       return m_cache.members.get();
2013     }
2014     TemplateVariant allMembersList() const
2015     {
2016       if (!m_cache.allMembersList)
2017       {
2018         if (m_classDef->memberNameInfoSDict())
2019         {
2020           AllMembersListContext *ml = AllMembersListContext::alloc(m_classDef->memberNameInfoSDict());
2021           m_cache.allMembersList.reset(ml);
2022         }
2023         else
2024         {
2025           m_cache.allMembersList.reset(AllMembersListContext::alloc());
2026         }
2027       }
2028       return m_cache.allMembersList.get();
2029     }
2030     TemplateVariant allMembersFileName() const
2031     {
2032       return m_classDef->getMemberListFileName();
2033     }
2034     TemplateVariant memberGroups() const
2035     {
2036       if (!m_cache.memberGroups)
2037       {
2038         if (m_classDef->getMemberGroupSDict())
2039         {
2040           m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_classDef,relPathAsString(),m_classDef->getMemberGroupSDict(),m_classDef->subGrouping()));
2041         }
2042         else
2043         {
2044           m_cache.memberGroups.reset(MemberGroupListContext::alloc());
2045         }
2046       }
2047       return m_cache.memberGroups.get();
2048     }
2049     TemplateVariant additionalInheritedMembers() const
2050     {
2051       if (!m_cache.additionalInheritedMembers)
2052       {
2053         InheritedMemberInfoListContext *ctx = InheritedMemberInfoListContext::alloc();
2054         ctx->addMemberList(m_classDef,MemberListType_pubTypes,theTranslator->trPublicTypes());
2055         ctx->addMemberList(m_classDef,MemberListType_services,theTranslator->trServices());
2056         ctx->addMemberList(m_classDef,MemberListType_interfaces,theTranslator->trInterfaces());
2057         ctx->addMemberList(m_classDef,MemberListType_pubSlots,theTranslator->trPublicSlots());
2058         ctx->addMemberList(m_classDef,MemberListType_signals,theTranslator->trSignals());
2059         ctx->addMemberList(m_classDef,MemberListType_pubMethods,
2060           m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods()
2061                                                      : theTranslator->trPublicMembers());
2062         ctx->addMemberList(m_classDef,MemberListType_pubStaticMethods,
2063           m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods()
2064                                                      : theTranslator->trStaticPublicMembers());
2065         ctx->addMemberList(m_classDef,MemberListType_pubAttribs,theTranslator->trPublicAttribs());
2066         ctx->addMemberList(m_classDef,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs());
2067         ctx->addMemberList(m_classDef,MemberListType_proTypes,theTranslator->trProtectedTypes());
2068         ctx->addMemberList(m_classDef,MemberListType_proSlots,theTranslator->trProtectedSlots());
2069         ctx->addMemberList(m_classDef,MemberListType_proMethods,theTranslator->trProtectedMembers());
2070         ctx->addMemberList(m_classDef,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers());
2071         ctx->addMemberList(m_classDef,MemberListType_proAttribs,theTranslator->trProtectedAttribs());
2072         ctx->addMemberList(m_classDef,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs());
2073         ctx->addMemberList(m_classDef,MemberListType_pacTypes,theTranslator->trPackageTypes());
2074         ctx->addMemberList(m_classDef,MemberListType_pacMethods,theTranslator->trPackageMembers());
2075         ctx->addMemberList(m_classDef,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers());
2076         ctx->addMemberList(m_classDef,MemberListType_pacAttribs,theTranslator->trPackageAttribs());
2077         ctx->addMemberList(m_classDef,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs());
2078         ctx->addMemberList(m_classDef,MemberListType_properties,theTranslator->trProperties());
2079         ctx->addMemberList(m_classDef,MemberListType_events,theTranslator->trEvents());
2080         ctx->addMemberList(m_classDef,MemberListType_priTypes,theTranslator->trPrivateTypes());
2081         ctx->addMemberList(m_classDef,MemberListType_priSlots,theTranslator->trPrivateSlots());
2082         ctx->addMemberList(m_classDef,MemberListType_priMethods,theTranslator->trPrivateMembers());
2083         ctx->addMemberList(m_classDef,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers());
2084         ctx->addMemberList(m_classDef,MemberListType_priAttribs,theTranslator->trPrivateAttribs());
2085         ctx->addMemberList(m_classDef,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs());
2086         ctx->addMemberList(m_classDef,MemberListType_related,theTranslator->trRelatedFunctions());
2087         m_cache.additionalInheritedMembers.reset(ctx);
2088       }
2089       return m_cache.additionalInheritedMembers.get();
2090     }
2091
2092   private:
2093     ClassDef *m_classDef;
2094     struct Cachable
2095     {
2096       Cachable() : inheritanceNodes(-1) { }
2097       SharedPtr<IncludeInfoContext>     includeInfo;
2098       SharedPtr<InheritanceListContext> inheritsList;
2099       SharedPtr<InheritanceListContext> inheritedByList;
2100       ScopedPtr<DotClassGraph>          classGraph;
2101       ScopedPtr<DotClassGraph>          collaborationGraph;
2102       SharedPtr<TemplateList>           classes;
2103       SharedPtr<MemberListInfoContext>  publicTypes;
2104       SharedPtr<MemberListInfoContext>  publicMethods;
2105       SharedPtr<MemberListInfoContext>  publicStaticMethods;
2106       SharedPtr<MemberListInfoContext>  publicAttributes;
2107       SharedPtr<MemberListInfoContext>  publicStaticAttributes;
2108       SharedPtr<MemberListInfoContext>  publicSlots;
2109       SharedPtr<MemberListInfoContext>  protectedTypes;
2110       SharedPtr<MemberListInfoContext>  protectedMethods;
2111       SharedPtr<MemberListInfoContext>  protectedStaticMethods;
2112       SharedPtr<MemberListInfoContext>  protectedAttributes;
2113       SharedPtr<MemberListInfoContext>  protectedStaticAttributes;
2114       SharedPtr<MemberListInfoContext>  protectedSlots;
2115       SharedPtr<MemberListInfoContext>  privateTypes;
2116       SharedPtr<MemberListInfoContext>  privateMethods;
2117       SharedPtr<MemberListInfoContext>  privateStaticMethods;
2118       SharedPtr<MemberListInfoContext>  privateAttributes;
2119       SharedPtr<MemberListInfoContext>  privateStaticAttributes;
2120       SharedPtr<MemberListInfoContext>  privateSlots;
2121       SharedPtr<MemberListInfoContext>  packageTypes;
2122       SharedPtr<MemberListInfoContext>  packageMethods;
2123       SharedPtr<MemberListInfoContext>  packageStaticMethods;
2124       SharedPtr<MemberListInfoContext>  packageAttributes;
2125       SharedPtr<MemberListInfoContext>  packageStaticAttributes;
2126       SharedPtr<MemberListInfoContext>  unoIDLServices;
2127       SharedPtr<MemberListInfoContext>  unoIDLInterfaces;
2128       SharedPtr<MemberListInfoContext>  signals;
2129       SharedPtr<MemberListInfoContext>  properties;
2130       SharedPtr<MemberListInfoContext>  events;
2131       SharedPtr<MemberListInfoContext>  friends;
2132       SharedPtr<MemberListInfoContext>  related;
2133       SharedPtr<MemberListInfoContext>  detailedTypedefs;
2134       SharedPtr<MemberListInfoContext>  detailedEnums;
2135       SharedPtr<MemberListInfoContext>  detailedServices;
2136       SharedPtr<MemberListInfoContext>  detailedInterfaces;
2137       SharedPtr<MemberListInfoContext>  detailedConstructors;
2138       SharedPtr<MemberListInfoContext>  detailedMethods;
2139       SharedPtr<MemberListInfoContext>  detailedRelated;
2140       SharedPtr<MemberListInfoContext>  detailedVariables;
2141       SharedPtr<MemberListInfoContext>  detailedProperties;
2142       SharedPtr<MemberListInfoContext>  detailedEvents;
2143       SharedPtr<MemberGroupListContext> memberGroups;
2144       SharedPtr<AllMembersListContext>  allMembersList;
2145       SharedPtr<ArgumentListContext>    typeConstraints;
2146       SharedPtr<TemplateList>           examples;
2147       SharedPtr<TemplateList>           templateDecls;
2148       SharedPtr<InheritedMemberInfoListContext> additionalInheritedMembers;
2149       SharedPtr<MemberListContext>      members;
2150       SharedPtr<UsedFilesContext>       usedFiles;
2151       SharedPtr<TemplateList>           exampleList;
2152       int                               inheritanceNodes;
2153       MemberList                        allMembers;
2154     };
2155     mutable Cachable m_cache;
2156 };
2157 //%% }
2158
2159 ClassContext::ClassContext(ClassDef *cd) : RefCountedContext("ClassContext")
2160 {
2161   //printf("ClassContext::ClassContext(%s)\n",cd?cd->name().data():"<none>");
2162   p = new Private(cd);
2163 }
2164
2165 ClassContext::~ClassContext()
2166 {
2167   delete p;
2168 }
2169
2170 TemplateVariant ClassContext::get(const char *n) const
2171 {
2172   return p->get(n);
2173 }
2174
2175 //------------------------------------------------------------------------
2176
2177 //%% struct Namespace(Symbol): namespace information
2178 //%% {
2179 class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Private>
2180 {
2181   public:
2182     Private(NamespaceDef *nd) : DefinitionContext<NamespaceContext::Private>(nd) , m_namespaceDef(nd)
2183     {
2184       addProperty("title",             this,&Private::title);
2185       addProperty("highlight",         this,&Private::highlight);
2186       addProperty("subhighlight",      this,&Private::subHighlight);
2187       addProperty("compoundType",      this,&Private::compoundType);
2188       addProperty("hasDetails",        this,&Private::hasDetails);
2189       addProperty("classes",           this,&Private::classes);
2190       addProperty("namespaces",        this,&Private::namespaces);
2191       addProperty("constantgroups",    this,&Private::constantgroups);
2192       addProperty("typedefs",          this,&Private::typedefs);
2193       addProperty("enums",             this,&Private::enums);
2194       addProperty("functions",         this,&Private::functions);
2195       addProperty("variables",         this,&Private::variables);
2196       addProperty("memberGroups",      this,&Private::memberGroups);
2197       addProperty("detailedTypedefs",  this,&Private::detailedTypedefs);
2198       addProperty("detailedEnums",     this,&Private::detailedEnums);
2199       addProperty("detailedFunctions", this,&Private::detailedFunctions);
2200       addProperty("detailedVariables", this,&Private::detailedVariables);
2201       addProperty("inlineClasses",     this,&Private::inlineClasses);
2202     }
2203     virtual ~Private() {}
2204     TemplateVariant title() const
2205     {
2206       return TemplateVariant(m_namespaceDef->title());
2207     }
2208     TemplateVariant highlight() const
2209     {
2210       return TemplateVariant("namespaces");
2211     }
2212     TemplateVariant subHighlight() const
2213     {
2214       return TemplateVariant("");
2215     }
2216     TemplateVariant compoundType() const
2217     {
2218       return m_namespaceDef->compoundTypeString();
2219     }
2220     TemplateVariant hasDetails() const
2221     {
2222       return m_namespaceDef->hasDetailedDescription();
2223     }
2224     TemplateVariant classes() const
2225     {
2226       if (!m_cache.classes)
2227       {
2228         TemplateList *classList = TemplateList::alloc();
2229         if (m_namespaceDef->getClassSDict())
2230         {
2231           ClassSDict::Iterator sdi(*m_namespaceDef->getClassSDict());
2232           ClassDef *cd;
2233           for (sdi.toFirst();(cd=sdi.current());++sdi)
2234           {
2235             if (cd->visibleInParentsDeclList())
2236             {
2237               classList->append(ClassContext::alloc(cd));
2238             }
2239           }
2240         }
2241         m_cache.classes.reset(classList);
2242       }
2243       return m_cache.classes.get();
2244     }
2245     TemplateVariant namespaces() const
2246     {
2247       if (!m_cache.namespaces)
2248       {
2249         TemplateList *namespaceList = TemplateList::alloc();
2250         if (m_namespaceDef->getNamespaceSDict())
2251         {
2252           NamespaceSDict::Iterator sdi(*m_namespaceDef->getNamespaceSDict());
2253           NamespaceDef *nd;
2254           for (sdi.toFirst();(nd=sdi.current());++sdi)
2255           {
2256             if (nd->isLinkable() && !nd->isConstantGroup())
2257             {
2258               namespaceList->append(NamespaceContext::alloc(nd));
2259             }
2260           }
2261         }
2262         m_cache.namespaces.reset(namespaceList);
2263       }
2264       return m_cache.namespaces.get();
2265     }
2266     TemplateVariant constantgroups() const
2267     {
2268       if (!m_cache.constantgroups)
2269       {
2270         TemplateList *namespaceList = TemplateList::alloc();
2271         if (m_namespaceDef->getNamespaceSDict())
2272         {
2273           NamespaceSDict::Iterator sdi(*m_namespaceDef->getNamespaceSDict());
2274           NamespaceDef *nd;
2275           for (sdi.toFirst();(nd=sdi.current());++sdi)
2276           {
2277             if (nd->isLinkable() && nd->isConstantGroup())
2278             {
2279               namespaceList->append(NamespaceContext::alloc(nd));
2280             }
2281           }
2282         }
2283         m_cache.constantgroups.reset(namespaceList);
2284       }
2285       return m_cache.constantgroups.get();
2286     }
2287     TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
2288                                   MemberListType type,const char *title,bool detailed=FALSE) const
2289     {
2290       if (!list)
2291       {
2292         MemberList *ml = m_namespaceDef->getMemberList(type);
2293         if (ml)
2294         {
2295           list.reset(MemberListInfoContext::alloc(m_namespaceDef,relPathAsString(),ml,title,detailed));
2296         }
2297       }
2298       if (list)
2299       {
2300         return list.get();
2301       }
2302       else
2303       {
2304         return TemplateVariant(FALSE);
2305       }
2306     }
2307     TemplateVariant typedefs() const
2308     {
2309       return getMemberList(m_cache.typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs());
2310     }
2311     TemplateVariant enums() const
2312     {
2313       return getMemberList(m_cache.enums,MemberListType_decEnumMembers,theTranslator->trEnumerations());
2314     }
2315     TemplateVariant functions() const
2316     {
2317       QCString title = theTranslator->trFunctions();
2318       SrcLangExt lang = m_namespaceDef->getLanguage();
2319       if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms();
2320       else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc();
2321       return getMemberList(m_cache.functions,MemberListType_decFuncMembers,title);
2322     }
2323     TemplateVariant variables() const
2324     {
2325       return getMemberList(m_cache.variables,MemberListType_decVarMembers,theTranslator->trVariables());
2326     }
2327     TemplateVariant memberGroups() const
2328     {
2329       if (!m_cache.memberGroups)
2330       {
2331         if (m_namespaceDef->getMemberGroupSDict())
2332         {
2333           m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_namespaceDef,relPathAsString(),m_namespaceDef->getMemberGroupSDict(),m_namespaceDef->subGrouping()));
2334         }
2335         else
2336         {
2337           m_cache.memberGroups.reset(MemberGroupListContext::alloc());
2338         }
2339       }
2340       return m_cache.memberGroups.get();
2341     }
2342     TemplateVariant detailedTypedefs() const
2343     {
2344       return getMemberList(m_cache.detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation());
2345     }
2346     TemplateVariant detailedEnums() const
2347     {
2348       return getMemberList(m_cache.detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation());
2349     }
2350     TemplateVariant detailedFunctions() const
2351     {
2352       QCString title = theTranslator->trFunctionDocumentation();
2353       SrcLangExt lang = m_namespaceDef->getLanguage();
2354       if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation();
2355       return getMemberList(m_cache.detailedFunctions,MemberListType_docFuncMembers,title);
2356     }
2357     TemplateVariant detailedVariables() const
2358     {
2359       return getMemberList(m_cache.detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation());
2360     }
2361     TemplateVariant inlineClasses() const
2362     {
2363       if (!m_cache.inlineClasses)
2364       {
2365         TemplateList *classList = TemplateList::alloc();
2366         if (m_namespaceDef->getClassSDict())
2367         {
2368           ClassSDict::Iterator sdi(*m_namespaceDef->getClassSDict());
2369           ClassDef *cd;
2370           for (sdi.toFirst();(cd=sdi.current());++sdi)
2371           {
2372             if (cd->name().find('@')==-1 &&
2373                 cd->isLinkableInProject() &&
2374                 cd->isEmbeddedInOuterScope() &&
2375                 cd->partOfGroups()==0)
2376             {
2377               classList->append(ClassContext::alloc(cd));
2378             }
2379           }
2380         }
2381         m_cache.inlineClasses.reset(classList);
2382       }
2383       return m_cache.inlineClasses.get();
2384     }
2385   private:
2386     NamespaceDef *m_namespaceDef;
2387     struct Cachable
2388     {
2389       SharedPtr<TemplateList>               classes;
2390       SharedPtr<TemplateList>               namespaces;
2391       SharedPtr<TemplateList>               constantgroups;
2392       SharedPtr<MemberListInfoContext>      typedefs;
2393       SharedPtr<MemberListInfoContext>      enums;
2394       SharedPtr<MemberListInfoContext>      functions;
2395       SharedPtr<MemberListInfoContext>      variables;
2396       SharedPtr<MemberGroupListContext>     memberGroups;
2397       SharedPtr<MemberListInfoContext>      detailedTypedefs;
2398       SharedPtr<MemberListInfoContext>      detailedEnums;
2399       SharedPtr<MemberListInfoContext>      detailedFunctions;
2400       SharedPtr<MemberListInfoContext>      detailedVariables;
2401       SharedPtr<TemplateList>               inlineClasses;
2402     };
2403     mutable Cachable m_cache;
2404 };
2405 //%% }
2406
2407 NamespaceContext::NamespaceContext(NamespaceDef *nd) : RefCountedContext("NamespaceContext")
2408 {
2409   p = new Private(nd);
2410 }
2411
2412 NamespaceContext::~NamespaceContext()
2413 {
2414   delete p;
2415 }
2416
2417 TemplateVariant NamespaceContext::get(const char *n) const
2418 {
2419   return p->get(n);
2420 }
2421
2422 //------------------------------------------------------------------------
2423
2424 //%% struct File(Symbol): file information
2425 //%% {
2426 class FileContext::Private : public DefinitionContext<FileContext::Private>
2427 {
2428   public:
2429     Private(FileDef *fd) : DefinitionContext<FileContext::Private>(fd) , m_fileDef(fd)
2430     {
2431       if (fd==0) abort();
2432       addProperty("title",                     this,&Private::title);
2433       addProperty("highlight",                 this,&Private::highlight);
2434       addProperty("subhighlight",              this,&Private::subHighlight);
2435       addProperty("versionInfo",               this,&Private::versionInfo);
2436       addProperty("includeList",               this,&Private::includeList);
2437       addProperty("hasIncludeGraph",           this,&Private::hasIncludeGraph);
2438       addProperty("hasIncludedByGraph",        this,&Private::hasIncludedByGraph);
2439       addProperty("includeGraph",              this,&Private::includeGraph);
2440       addProperty("includedByGraph",           this,&Private::includedByGraph);
2441       addProperty("hasDetails",                this,&Private::hasDetails);
2442       addProperty("hasSourceFile",             this,&Private::hasSourceFile);
2443       addProperty("sources",                   this,&Private::sources);
2444       addProperty("version",                   this,&Private::version);
2445       addProperty("classes",                   this,&Private::classes);
2446       addProperty("namespaces",                this,&Private::namespaces);
2447       addProperty("constantgroups",            this,&Private::constantgroups);
2448       addProperty("macros",                    this,&Private::macros);
2449       addProperty("typedefs",                  this,&Private::typedefs);
2450       addProperty("enums",                     this,&Private::enums);
2451       addProperty("functions",                 this,&Private::functions);
2452       addProperty("variables",                 this,&Private::variables);
2453       addProperty("memberGroups",              this,&Private::memberGroups);
2454       addProperty("detailedMacros",            this,&Private::detailedMacros);
2455       addProperty("detailedTypedefs",          this,&Private::detailedTypedefs);
2456       addProperty("detailedEnums",             this,&Private::detailedEnums);
2457       addProperty("detailedFunctions",         this,&Private::detailedFunctions);
2458       addProperty("detailedVariables",         this,&Private::detailedVariables);
2459       addProperty("inlineClasses",             this,&Private::inlineClasses);
2460       addProperty("compoundType",              this,&Private::compoundType);
2461     }
2462     virtual ~Private() {}
2463     TemplateVariant title() const
2464     {
2465       return m_fileDef->title();
2466     }
2467     TemplateVariant highlight() const
2468     {
2469       return TemplateVariant("files");
2470     }
2471     TemplateVariant subHighlight() const
2472     {
2473       return TemplateVariant("");
2474     }
2475     TemplateVariant versionInfo() const
2476     {
2477       return m_fileDef->getVersion();
2478     }
2479     TemplateVariant includeList() const
2480     {
2481       if (!m_cache.includeInfoList && m_fileDef->includeFileList())
2482       {
2483         m_cache.includeInfoList.reset(IncludeInfoListContext::alloc(
2484               *m_fileDef->includeFileList(),m_fileDef->getLanguage()));
2485       }
2486       if (m_cache.includeInfoList)
2487       {
2488         return m_cache.includeInfoList.get();
2489       }
2490       else
2491       {
2492         return TemplateVariant(FALSE);
2493       }
2494     }
2495     DotInclDepGraph *getIncludeGraph() const
2496     {
2497       if (!m_cache.includeGraph)
2498       {
2499         m_cache.includeGraph.reset(new DotInclDepGraph(m_fileDef,FALSE));
2500       }
2501       return m_cache.includeGraph.get();
2502     }
2503     TemplateVariant hasIncludeGraph() const
2504     {
2505       static bool haveDot = Config_getBool("HAVE_DOT");
2506       DotInclDepGraph *incGraph = getIncludeGraph();
2507       return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial());
2508     }
2509     TemplateVariant includeGraph() const
2510     {
2511       static bool haveDot = Config_getBool("HAVE_DOT");
2512       QGString result;
2513       if (haveDot)
2514       {
2515         DotInclDepGraph *cg = getIncludeGraph();
2516         FTextStream t(&result);
2517         cg->writeGraph(t,GOF_BITMAP,EOF_Html,
2518             g_globals.outputDir,
2519             g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension,
2520             relPathAsString(),TRUE,g_globals.dynSectionId
2521             );
2522       }
2523       g_globals.dynSectionId++;
2524       return TemplateVariant(result.data(),TRUE);
2525     }
2526     DotInclDepGraph *getIncludedByGraph() const
2527     {
2528       if (!m_cache.includedByGraph)
2529       {
2530         m_cache.includedByGraph.reset(new DotInclDepGraph(m_fileDef,TRUE));
2531       }
2532       return m_cache.includedByGraph.get();
2533     }
2534     TemplateVariant hasIncludedByGraph() const
2535     {
2536       static bool haveDot = Config_getBool("HAVE_DOT");
2537       DotInclDepGraph *incGraph = getIncludedByGraph();
2538       return (haveDot && !incGraph->isTooBig() && !incGraph->isTrivial());
2539     }
2540     TemplateVariant includedByGraph() const
2541     {
2542       static bool haveDot = Config_getBool("HAVE_DOT");
2543       QGString result;
2544       if (haveDot)
2545       {
2546         DotInclDepGraph *cg = getIncludedByGraph();
2547         FTextStream t(&result);
2548         cg->writeGraph(t,GOF_BITMAP,EOF_Html,
2549             g_globals.outputDir,
2550             g_globals.outputDir+portable_pathSeparator()+m_fileDef->getOutputFileBase()+Doxygen::htmlFileExtension,
2551             relPathAsString(),TRUE,g_globals.dynSectionId
2552             );
2553       }
2554       g_globals.dynSectionId++;
2555       return TemplateVariant(result.data(),TRUE);
2556     }
2557     TemplateVariant hasDetails() const
2558     {
2559       return m_fileDef->hasDetailedDescription();
2560     }
2561     TemplateVariant hasSourceFile() const
2562     {
2563       return m_fileDef->generateSourceFile();
2564     }
2565     TemplateVariant sources() const
2566     {
2567       if (!m_cache.sources)
2568       {
2569         if (m_fileDef->generateSourceFile())
2570         {
2571           m_cache.sources.reset(new TemplateVariant(parseCode(m_fileDef,relPathAsString())));
2572         }
2573         else
2574         {
2575           m_cache.sources.reset(new TemplateVariant(""));
2576         }
2577       }
2578       return *m_cache.sources;
2579     }
2580     TemplateVariant version() const
2581     {
2582       return m_fileDef->fileVersion();
2583     }
2584     TemplateVariant classes() const
2585     {
2586       if (!m_cache.classes)
2587       {
2588         TemplateList *classList = TemplateList::alloc();
2589         if (m_fileDef->getClassSDict())
2590         {
2591           ClassSDict::Iterator sdi(*m_fileDef->getClassSDict());
2592           ClassDef *cd;
2593           for (sdi.toFirst();(cd=sdi.current());++sdi)
2594           {
2595             if (cd->visibleInParentsDeclList())
2596             {
2597               classList->append(ClassContext::alloc(cd));
2598             }
2599           }
2600         }
2601         m_cache.classes.reset(classList);
2602       }
2603       return m_cache.classes.get();
2604     }
2605     TemplateVariant namespaces() const
2606     {
2607       if (!m_cache.namespaces)
2608       {
2609         TemplateList *namespaceList = TemplateList::alloc();
2610         if (m_fileDef->getNamespaceSDict())
2611         {
2612           NamespaceSDict::Iterator sdi(*m_fileDef->getNamespaceSDict());
2613           NamespaceDef *nd;
2614           for (sdi.toFirst();(nd=sdi.current());++sdi)
2615           {
2616             if (nd->isLinkable() && !nd->isConstantGroup())
2617             {
2618               namespaceList->append(NamespaceContext::alloc(nd));
2619             }
2620           }
2621         }
2622         m_cache.namespaces.reset(namespaceList);
2623       }
2624       return m_cache.namespaces.get();
2625     }
2626     TemplateVariant constantgroups() const
2627     {
2628       if (!m_cache.constantgroups)
2629       {
2630         TemplateList *namespaceList = TemplateList::alloc();
2631         if (m_fileDef->getNamespaceSDict())
2632         {
2633           NamespaceSDict::Iterator sdi(*m_fileDef->getNamespaceSDict());
2634           NamespaceDef *nd;
2635           for (sdi.toFirst();(nd=sdi.current());++sdi)
2636           {
2637             if (nd->isLinkable() && nd->isConstantGroup())
2638             {
2639               namespaceList->append(NamespaceContext::alloc(nd));
2640             }
2641           }
2642         }
2643         m_cache.constantgroups.reset(namespaceList);
2644       }
2645       return m_cache.constantgroups.get();
2646     }
2647     TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
2648                                   MemberListType type,const char *title,bool detailed=FALSE) const
2649     {
2650       if (!list)
2651       {
2652         MemberList *ml = m_fileDef->getMemberList(type);
2653         if (ml)
2654         {
2655           list.reset(MemberListInfoContext::alloc(m_fileDef,relPathAsString(),ml,title,detailed));
2656         }
2657       }
2658       if (list)
2659       {
2660         return list.get();
2661       }
2662       else
2663       {
2664         return TemplateVariant(FALSE);
2665       }
2666     }
2667     TemplateVariant macros() const
2668     {
2669       return getMemberList(m_cache.macros,MemberListType_decDefineMembers,theTranslator->trDefines());
2670     }
2671     TemplateVariant typedefs() const
2672     {
2673       return getMemberList(m_cache.typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs());
2674     }
2675     TemplateVariant enums() const
2676     {
2677       return getMemberList(m_cache.enums,MemberListType_decEnumMembers,theTranslator->trEnumerations());
2678     }
2679     TemplateVariant functions() const
2680     {
2681       QCString title = theTranslator->trFunctions();
2682       SrcLangExt lang = m_fileDef->getLanguage();
2683       if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms();
2684       else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc();
2685       return getMemberList(m_cache.functions,MemberListType_decFuncMembers,title);
2686     }
2687     TemplateVariant variables() const
2688     {
2689       return getMemberList(m_cache.variables,MemberListType_decVarMembers,theTranslator->trVariables());
2690     }
2691     TemplateVariant memberGroups() const
2692     {
2693       if (!m_cache.memberGroups)
2694       {
2695         if (m_fileDef->getMemberGroupSDict())
2696         {
2697           m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_fileDef,relPathAsString(),m_fileDef->getMemberGroupSDict(),m_fileDef->subGrouping()));
2698         }
2699         else
2700         {
2701           m_cache.memberGroups.reset(MemberGroupListContext::alloc());
2702         }
2703       }
2704       return m_cache.memberGroups.get();
2705     }
2706     TemplateVariant detailedMacros() const
2707     {
2708       return getMemberList(m_cache.detailedMacros,MemberListType_docDefineMembers,theTranslator->trDefineDocumentation());
2709     }
2710     TemplateVariant detailedTypedefs() const
2711     {
2712       return getMemberList(m_cache.detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation());
2713     }
2714     TemplateVariant detailedEnums() const
2715     {
2716       return getMemberList(m_cache.detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation());
2717     }
2718     TemplateVariant detailedFunctions() const
2719     {
2720       QCString title = theTranslator->trFunctionDocumentation();
2721       SrcLangExt lang = m_fileDef->getLanguage();
2722       if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation();
2723       return getMemberList(m_cache.detailedFunctions,MemberListType_docFuncMembers,title);
2724     }
2725     TemplateVariant detailedVariables() const
2726     {
2727       return getMemberList(m_cache.detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation());
2728     }
2729     TemplateVariant inlineClasses() const
2730     {
2731       if (!m_cache.inlineClasses)
2732       {
2733         TemplateList *classList = TemplateList::alloc();
2734         if (m_fileDef->getClassSDict())
2735         {
2736           ClassSDict::Iterator sdi(*m_fileDef->getClassSDict());
2737           ClassDef *cd;
2738           for (sdi.toFirst();(cd=sdi.current());++sdi)
2739           {
2740             if (cd->name().find('@')==-1 &&
2741                 cd->isLinkableInProject() &&
2742                 cd->isEmbeddedInOuterScope() &&
2743                 cd->partOfGroups()==0)
2744             {
2745               classList->append(ClassContext::alloc(cd));
2746             }
2747           }
2748         }
2749         m_cache.inlineClasses.reset(classList);
2750       }
2751       return m_cache.inlineClasses.get();
2752     }
2753     TemplateVariant compoundType() const
2754     {
2755       return theTranslator->trFile(FALSE,TRUE);
2756     }
2757
2758   private:
2759     FileDef *m_fileDef;
2760     struct Cachable
2761     {
2762       SharedPtr<IncludeInfoListContext>     includeInfoList;
2763       ScopedPtr<DotInclDepGraph>            includeGraph;
2764       ScopedPtr<DotInclDepGraph>            includedByGraph;
2765       ScopedPtr<TemplateVariant>            sources;
2766       SharedPtr<TemplateList>               classes;
2767       SharedPtr<TemplateList>               namespaces;
2768       SharedPtr<TemplateList>               constantgroups;
2769       SharedPtr<MemberListInfoContext>      macros;
2770       SharedPtr<MemberListInfoContext>      typedefs;
2771       SharedPtr<MemberListInfoContext>      enums;
2772       SharedPtr<MemberListInfoContext>      functions;
2773       SharedPtr<MemberListInfoContext>      variables;
2774       SharedPtr<MemberGroupListContext>     memberGroups;
2775       SharedPtr<MemberListInfoContext>      detailedMacros;
2776       SharedPtr<MemberListInfoContext>      detailedTypedefs;
2777       SharedPtr<MemberListInfoContext>      detailedEnums;
2778       SharedPtr<MemberListInfoContext>      detailedFunctions;
2779       SharedPtr<MemberListInfoContext>      detailedVariables;
2780       SharedPtr<TemplateList>               inlineClasses;
2781     };
2782     mutable Cachable m_cache;
2783 };
2784 //%% }
2785
2786 FileContext::FileContext(FileDef *fd) : RefCountedContext("FileContext")
2787 {
2788   p = new Private(fd);
2789 }
2790
2791 FileContext::~FileContext()
2792 {
2793   delete p;
2794 }
2795
2796 TemplateVariant FileContext::get(const char *n) const
2797 {
2798   return p->get(n);
2799 }
2800
2801 //------------------------------------------------------------------------
2802
2803 //%% struct Dir(Symbol): directory information
2804 //%% {
2805 class DirContext::Private : public DefinitionContext<DirContext::Private>
2806 {
2807   public:
2808     Private(DirDef *dd) : DefinitionContext<DirContext::Private>(dd) , m_dirDef(dd)
2809     {
2810       addProperty("title",         this,&Private::title);
2811       addProperty("highlight",     this,&Private::highlight);
2812       addProperty("subhighlight",  this,&Private::subHighlight);
2813       addProperty("dirName",       this,&Private::dirName);
2814       addProperty("dirs",          this,&Private::dirs);
2815       addProperty("files",         this,&Private::files);
2816       addProperty("hasDetails",    this,&Private::hasDetails);
2817       addProperty("compoundType",  this,&Private::compoundType);
2818     }
2819     virtual ~Private() {}
2820     TemplateVariant title() const
2821     {
2822       return TemplateVariant(m_dirDef->shortTitle());
2823     }
2824     TemplateVariant highlight() const
2825     {
2826       return TemplateVariant("files");
2827     }
2828     TemplateVariant subHighlight() const
2829     {
2830       return TemplateVariant("");
2831     }
2832     TemplateVariant dirName() const
2833     {
2834       return TemplateVariant(m_dirDef->shortName());
2835     }
2836     TemplateVariant dirs() const
2837     {
2838       if (!m_cache.dirs)
2839       {
2840         m_cache.dirs.reset(TemplateList::alloc());
2841         const DirList &subDirs = m_dirDef->subDirs();
2842         QListIterator<DirDef> it(subDirs);
2843         DirDef *dd;
2844         for (it.toFirst();(dd=it.current());++it)
2845         {
2846           DirContext *dc = new DirContext(dd);
2847           m_cache.dirs->append(dc);
2848         }
2849       }
2850       return m_cache.dirs.get();
2851     }
2852     TemplateVariant files() const
2853     {
2854       // FileList *list = m_dirDef->getFiles();
2855       if (!m_cache.files)
2856       {
2857         m_cache.files.reset(TemplateList::alloc());
2858         FileList *files = m_dirDef->getFiles();
2859         if (files)
2860         {
2861           QListIterator<FileDef> it(*files);
2862           FileDef *fd;
2863           for (it.toFirst();(fd=it.current());++it)
2864           {
2865             FileContext *fc = FileContext::alloc(fd);
2866             m_cache.files->append(fc);
2867           }
2868         }
2869       }
2870       return m_cache.files.get();
2871     }
2872     TemplateVariant hasDetails() const
2873     {
2874       return m_dirDef->hasDetailedDescription();
2875     }
2876     TemplateVariant compoundType() const
2877     {
2878       return theTranslator->trDir(FALSE,TRUE);
2879     }
2880     TemplateVariant relPath() const
2881     {
2882       return "";
2883     }
2884
2885   private:
2886     DirDef *m_dirDef;
2887     struct Cachable
2888     {
2889       Cachable() {}
2890       SharedPtr<TemplateList>  dirs;
2891       SharedPtr<TemplateList>  files;
2892     };
2893     mutable Cachable m_cache;
2894 };
2895 //%% }
2896
2897 DirContext::DirContext(DirDef *fd) : RefCountedContext("DirContext")
2898 {
2899   p = new Private(fd);
2900 }
2901
2902 DirContext::~DirContext()
2903 {
2904   delete p;
2905 }
2906
2907 TemplateVariant DirContext::get(const char *n) const
2908 {
2909   return p->get(n);
2910 }
2911
2912 //------------------------------------------------------------------------
2913
2914 //%% struct Page(Symbol): page information
2915 //%% {
2916 class PageContext::Private : public DefinitionContext<PageContext::Private>
2917 {
2918   public:
2919     Private(PageDef *pd,bool isMainPage)
2920       : DefinitionContext<PageContext::Private>(pd) , m_pageDef(pd), m_isMainPage(isMainPage)
2921     {
2922       addProperty("title",this,&Private::title);
2923       addProperty("highlight",this,&Private::highlight);
2924       addProperty("subhighlight",this,&Private::subHighlight);
2925     }
2926     virtual ~Private() {}
2927     TemplateVariant title() const
2928     {
2929       if (m_isMainPage)
2930       {
2931         if (mainPageHasTitle())
2932         {
2933           return m_pageDef->title();
2934         }
2935         else
2936         {
2937           return theTranslator->trMainPage();
2938         }
2939       }
2940       else
2941       {
2942         return m_pageDef->title();
2943       }
2944     }
2945     TemplateVariant relPath() const
2946     {
2947       if (m_pageDef==Doxygen::mainPage)
2948       {
2949         return "";
2950       }
2951       else
2952       {
2953         return DefinitionContext<PageContext::Private>::relPath();
2954       }
2955     }
2956     TemplateVariant highlight() const
2957     {
2958       if (m_pageDef==Doxygen::mainPage)
2959       {
2960         return "main";
2961       }
2962       else
2963       {
2964         return "pages";
2965       }
2966     }
2967     TemplateVariant subHighlight() const
2968     {
2969       return "";
2970     }
2971   private:
2972     PageDef *m_pageDef;
2973     bool m_isMainPage;
2974 };
2975 //%% }
2976
2977 PageContext::PageContext(PageDef *pd,bool isMainPage) : RefCountedContext("PageContext")
2978 {
2979   p = new Private(pd,isMainPage);
2980 }
2981
2982 PageContext::~PageContext()
2983 {
2984   delete p;
2985 }
2986
2987 TemplateVariant PageContext::get(const char *n) const
2988 {
2989   return p->get(n);
2990 }
2991
2992 //------------------------------------------------------------------------
2993
2994 class TextGeneratorHtml : public TextGeneratorIntf
2995 {
2996   public:
2997     TextGeneratorHtml(FTextStream &ts,const QCString &relPath)
2998        : m_ts(ts), m_relPath(relPath) {}
2999     void writeString(const char *s,bool keepSpaces) const
3000     {
3001       if (s==0) return;
3002       //printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces);
3003       if (keepSpaces)
3004       {
3005         const char *p=s;
3006         char c;
3007         while ((c=*p++))
3008         {
3009           switch(c)
3010           {
3011             case '<':  m_ts << "&lt;"; break;
3012             case '>':  m_ts << "&gt;"; break;
3013             case '\'': m_ts << "&#39;"; break;
3014             case '"':  m_ts << "&quot;"; break;
3015             case '&':  m_ts << "&amp;"; break;
3016             case ' ':  m_ts << "&#160;"; break;
3017           }
3018         }
3019       }
3020       else
3021       {
3022         m_ts << convertToHtml(s);
3023       }
3024     }
3025
3026     void writeBreak(int indent) const
3027     {
3028       m_ts << "<br />";
3029       for (int i=0;i<indent;i++)
3030       {
3031         m_ts << "&#160;";
3032       }
3033     }
3034
3035     void writeLink(const char *ref,const char *f,
3036                    const char *anchor,const char *name
3037                   ) const
3038     {
3039       if (ref)
3040       {
3041         m_ts << "<a class=\"elRef\" ";
3042         m_ts << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
3043       }
3044       else
3045       {
3046         m_ts << "<a class=\"el\" ";
3047       }
3048       m_ts << "href=\"";
3049       m_ts << externalRef(m_relPath,ref,TRUE);
3050       if (f) m_ts << f << Doxygen::htmlFileExtension;
3051       if (anchor) m_ts << "#" << anchor;
3052       m_ts << "\">";
3053       m_ts << convertToHtml(name);
3054       m_ts << "</a>";
3055     }
3056
3057   private:
3058     FTextStream &m_ts;
3059     QCString m_relPath;
3060 };
3061
3062 class TextGeneratorFactory
3063 {
3064   public:
3065     static TextGeneratorFactory *instance()
3066     {
3067       static TextGeneratorFactory *instance = 0;
3068       if (instance==0) instance = new TextGeneratorFactory;
3069       return instance;
3070     }
3071     TextGeneratorIntf *create(FTextStream &ts,const QCString &relPath)
3072     {
3073       switch (g_globals.outputFormat)
3074       {
3075         case ContextGlobals::Html:
3076           return new TextGeneratorHtml(ts,relPath);
3077           break;
3078         default:
3079           break;
3080       }
3081       return 0;
3082     }
3083   private:
3084     TextGeneratorFactory() {}
3085     virtual ~TextGeneratorFactory() {}
3086 };
3087
3088 TemplateVariant createLinkedText(Definition *def,const QCString &relPath,const QCString &text)
3089 {
3090   QGString s;
3091   FTextStream ts(&s);
3092   TextGeneratorIntf *tg = TextGeneratorFactory::instance()->create(ts,relPath);
3093   if (tg)
3094   {
3095     linkifyText(*tg,def->getOuterScope(),def->getBodyDef(),def,text);
3096     return TemplateVariant(s.data(),TRUE);
3097   }
3098   else
3099   {
3100     return text;
3101   }
3102 }
3103
3104 //%% struct Member(Symbol): member information
3105 //%% {
3106 class MemberContext::Private : public DefinitionContext<MemberContext::Private>
3107 {
3108   public:
3109     Private(MemberDef *md) : DefinitionContext<MemberContext::Private>(md) , m_memberDef(md)
3110     {
3111       addProperty("isSignal",            this,&Private::isSignal);
3112       addProperty("isSlot",              this,&Private::isSlot);
3113       addProperty("isVariable",          this,&Private::isVariable);
3114       addProperty("isEnumeration",       this,&Private::isEnumeration);
3115       addProperty("isEnumValue",         this,&Private::isEnumValue);
3116       addProperty("isTypedef",           this,&Private::isTypedef);
3117       addProperty("isFunction",          this,&Private::isFunction);
3118       addProperty("isFunctionPtr",       this,&Private::isFunctionPtr);
3119       addProperty("isDefine",            this,&Private::isDefine);
3120       addProperty("isFriend",            this,&Private::isFriend);
3121       addProperty("isProperty",          this,&Private::isProperty);
3122       addProperty("isEvent",             this,&Private::isEvent);
3123       addProperty("isRelated",           this,&Private::isRelated);
3124       addProperty("isForeign",           this,&Private::isForeign);
3125       addProperty("isStatic",            this,&Private::isStatic);
3126       addProperty("isInline",            this,&Private::isInline);
3127       addProperty("isExplicit",          this,&Private::isExplicit);
3128       addProperty("isMutable",           this,&Private::isMutable);
3129       addProperty("isGettable",          this,&Private::isGettable);
3130       addProperty("isPrivateGettable",   this,&Private::isPrivateGettable);
3131       addProperty("isProtectedGettable", this,&Private::isProtectedGettable);
3132       addProperty("isSettable",          this,&Private::isSettable);
3133       addProperty("isPrivateSettable",   this,&Private::isPrivateSettable);
3134       addProperty("isProtectedSettable", this,&Private::isProtectedSettable);
3135       addProperty("isReadable",          this,&Private::isReadable);
3136       addProperty("isWritable",          this,&Private::isWritable);
3137       addProperty("isAddable",           this,&Private::isAddable);
3138       addProperty("isRemovable",         this,&Private::isRemovable);
3139       addProperty("isRaisable",          this,&Private::isRaisable);
3140       addProperty("isFinal",             this,&Private::isFinal);
3141       addProperty("isAbstract",          this,&Private::isAbstract);
3142       addProperty("isOverride",          this,&Private::isOverride);
3143       addProperty("isInitonly",          this,&Private::isInitonly);
3144       addProperty("isOptional",          this,&Private::isOptional);
3145       addProperty("isRequired",          this,&Private::isRequired);
3146       addProperty("isNonAtomic",         this,&Private::isNonAtomic);
3147       addProperty("isCopy",              this,&Private::isCopy);
3148       addProperty("isAssign",            this,&Private::isAssign);
3149       addProperty("isRetain",            this,&Private::isRetain);
3150       addProperty("isWeak",              this,&Private::isWeak);
3151       addProperty("isStrong",            this,&Private::isStrong);
3152       addProperty("isUnretained",        this,&Private::isUnretained);
3153       addProperty("isNew",               this,&Private::isNew);
3154       addProperty("isSealed",            this,&Private::isSealed);
3155       addProperty("isImplementation",    this,&Private::isImplementation);
3156       addProperty("isExternal",          this,&Private::isExternal);
3157       addProperty("isAlias",             this,&Private::isAlias);
3158       addProperty("isDefault",           this,&Private::isDefault);
3159       addProperty("isDelete",            this,&Private::isDelete);
3160       addProperty("isNoExcept",          this,&Private::isNoExcept);
3161       addProperty("isAttribute",         this,&Private::isAttribute);
3162       addProperty("isUNOProperty",       this,&Private::isUNOProperty);
3163       addProperty("isReadonly",          this,&Private::isReadonly);
3164       addProperty("isBound",             this,&Private::isBound);
3165       addProperty("isConstrained",       this,&Private::isConstrained);
3166       addProperty("isTransient",         this,&Private::isTransient);
3167       addProperty("isMaybeVoid",         this,&Private::isMaybeVoid);
3168       addProperty("isMaybeDefault",      this,&Private::isMaybeDefault);
3169       addProperty("isMaybeAmbiguous",    this,&Private::isMaybeAmbiguous);
3170       addProperty("isPublished",         this,&Private::isPublished);
3171       addProperty("isTemplateSpecialization",this,&Private::isTemplateSpecialization);
3172       addProperty("isObjCMethod",        this,&Private::isObjCMethod);
3173       addProperty("isObjCProperty",      this,&Private::isObjCProperty);
3174       addProperty("isAnonymous",         this,&Private::isAnonymous);
3175       addProperty("declType",            this,&Private::declType);
3176       addProperty("declArgs",            this,&Private::declArgs);
3177       addProperty("anonymousType",       this,&Private::anonymousType);
3178       addProperty("anonymousMember",     this,&Private::anonymousMember);
3179       addProperty("hasDetails",          this,&Private::hasDetails);
3180       addProperty("exception",           this,&Private::exception);
3181       addProperty("bitfields",           this,&Private::bitfields);
3182       addProperty("initializer",         this,&Private::initializer);
3183       addProperty("initializerAsCode",   this,&Private::initializerAsCode);
3184       addProperty("hasOneLineInitializer",   this,&Private::hasOneLineInitializer);
3185       addProperty("hasMultiLineInitializer", this,&Private::hasMultiLineInitializer);
3186       addProperty("templateArgs",        this,&Private::templateArgs);
3187       addProperty("templateAlias",       this,&Private::templateAlias);
3188       addProperty("propertyAttrs",       this,&Private::propertyAttrs);
3189       addProperty("eventAttrs",          this,&Private::eventAttrs);
3190       addProperty("class",               this,&Private::getClass);
3191       addProperty("file",                this,&Private::getFile);
3192       addProperty("namespace",           this,&Private::getNamespace);
3193       addProperty("definition",          this,&Private::definition);
3194       addProperty("parameters",          this,&Private::parameters);
3195       addProperty("hasParameterList",    this,&Private::hasParameterList);
3196       addProperty("hasConstQualifier",   this,&Private::hasConstQualifier);
3197       addProperty("hasVolatileQualifier",this,&Private::hasVolatileQualifier);
3198       addProperty("trailingReturnType",  this,&Private::trailingReturnType);
3199       addProperty("extraTypeChars",      this,&Private::extraTypeChars);
3200       addProperty("templateDecls",       this,&Private::templateDecls);
3201       addProperty("labels",              this,&Private::labels);
3202       addProperty("enumBaseType",        this,&Private::enumBaseType);
3203       addProperty("enumValues",          this,&Private::enumValues);
3204       addProperty("paramDocs",           this,&Private::paramDocs);
3205       addProperty("reimplements",        this,&Private::reimplements);
3206       addProperty("implements",          this,&Private::implements);
3207       addProperty("reimplementedBy",     this,&Private::reimplementedBy);
3208       addProperty("implementedBy",       this,&Private::implementedBy);
3209       addProperty("examples",            this,&Private::examples);
3210       addProperty("typeConstraints",     this,&Private::typeConstraints);
3211       addProperty("functionQualifier",   this,&Private::functionQualifier);
3212       addProperty("sourceRefs",          this,&Private::sourceRefs);
3213       addProperty("sourceRefBys",        this,&Private::sourceRefBys);
3214       addProperty("hasSources",          this,&Private::hasSources);
3215       addProperty("sourceCode",          this,&Private::sourceCode);
3216       addProperty("hasCallGraph",        this,&Private::hasCallGraph);
3217       addProperty("callGraph",           this,&Private::callGraph);
3218       addProperty("hasCallerGraph",      this,&Private::hasCallerGraph);
3219       addProperty("callerGraph",         this,&Private::callerGraph);
3220       addProperty("fieldType",           this,&Private::fieldType);
3221
3222       m_cache.propertyAttrs.reset(TemplateList::alloc());
3223       if (md && md->isProperty())
3224       {
3225         if (md->isGettable())           m_cache.propertyAttrs->append("get");
3226         if (md->isPrivateGettable())    m_cache.propertyAttrs->append("private get");
3227         if (md->isProtectedGettable())  m_cache.propertyAttrs->append("protected get");
3228         if (md->isSettable())           m_cache.propertyAttrs->append("set");
3229         if (md->isPrivateSettable())    m_cache.propertyAttrs->append("private set");
3230         if (md->isProtectedSettable())  m_cache.propertyAttrs->append("protected set");
3231       }
3232       m_cache.eventAttrs.reset(TemplateList::alloc());
3233       if (md && md->isEvent())
3234       {
3235         if (md->isAddable())   m_cache.eventAttrs->append("add");
3236         if (md->isRemovable()) m_cache.eventAttrs->append("remove");
3237         if (md->isRaisable())  m_cache.eventAttrs->append("raise");
3238       }
3239     }
3240     virtual ~Private() {}
3241     TemplateVariant fieldType() const
3242     {
3243       return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->fieldType());
3244     }
3245     TemplateVariant declType() const
3246     {
3247       return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->getDeclType());
3248     }
3249     TemplateVariant declArgs() const
3250     {
3251       return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->argsString());
3252     }
3253     TemplateVariant exception() const
3254     {
3255       return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->excpString());
3256     }
3257     TemplateVariant bitfields() const
3258     {
3259       return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->bitfieldString());
3260     }
3261     TemplateVariant isStatic() const
3262     {
3263       return m_memberDef->isStatic();
3264     }
3265     TemplateVariant isObjCMethod() const
3266     {
3267       return m_memberDef->isObjCMethod();
3268     }
3269     TemplateVariant isObjCProperty() const
3270     {
3271       return m_memberDef->isObjCProperty();
3272     }
3273     TemplateVariant isImplementation() const
3274     {
3275       return m_memberDef->isImplementation();
3276     }
3277     TemplateVariant isSignal() const
3278     {
3279       return m_memberDef->isSignal();
3280     }
3281     TemplateVariant isSlot() const
3282     {
3283       return m_memberDef->isSlot();
3284     }
3285     TemplateVariant isTypedef() const
3286     {
3287       return m_memberDef->isTypedef();
3288     }
3289     TemplateVariant isFunction() const
3290     {
3291       return m_memberDef->isFunction();
3292     }
3293     TemplateVariant isFunctionPtr() const
3294     {
3295       return m_memberDef->isFunctionPtr();
3296     }
3297     TemplateVariant isFriend() const
3298     {
3299       return m_memberDef->isFriend();
3300     }
3301     TemplateVariant isForeign() const
3302     {
3303       return m_memberDef->isForeign();
3304     }
3305     TemplateVariant isEvent() const
3306     {
3307       return m_memberDef->isEvent();
3308     }
3309     TemplateVariant isInline() const
3310     {
3311       return m_memberDef->isInline();
3312     }
3313     TemplateVariant isExplicit() const
3314     {
3315       return m_memberDef->isExplicit();
3316     }
3317     TemplateVariant isMutable() const
3318     {
3319       return m_memberDef->isMutable();
3320     }
3321     TemplateVariant isGettable() const
3322     {
3323       return m_memberDef->isGettable();
3324     }
3325     TemplateVariant isPrivateGettable() const
3326     {
3327       return m_memberDef->isPrivateGettable();
3328     }
3329     TemplateVariant isProtectedGettable() const
3330     {
3331       return m_memberDef->isProtectedGettable();
3332     }
3333     TemplateVariant isSettable() const
3334     {
3335       return m_memberDef->isSettable();
3336     }
3337     TemplateVariant isPrivateSettable() const
3338     {
3339       return m_memberDef->isPrivateSettable();
3340     }
3341     TemplateVariant isProtectedSettable() const
3342     {
3343       return m_memberDef->isProtectedSettable();
3344     }
3345     TemplateVariant isReadable() const
3346     {
3347       return m_memberDef->isReadable();
3348     }
3349     TemplateVariant isWritable() const
3350     {
3351       return m_memberDef->isWritable();
3352     }
3353     TemplateVariant isAddable() const
3354     {
3355       return m_memberDef->isAddable();
3356     }
3357     TemplateVariant isRemovable() const
3358     {
3359       return m_memberDef->isRemovable();
3360     }
3361     TemplateVariant isRaisable() const
3362     {
3363       return m_memberDef->isRaisable();
3364     }
3365     TemplateVariant isFinal() const
3366     {
3367       return m_memberDef->isFinal();
3368     }
3369     TemplateVariant isAbstract() const
3370     {
3371       return m_memberDef->isAbstract();
3372     }
3373     TemplateVariant isOverride() const
3374     {
3375       return m_memberDef->isOverride();
3376     }
3377     TemplateVariant isInitonly() const
3378     {
3379       return m_memberDef->isInitonly();
3380     }
3381     TemplateVariant isOptional() const
3382     {
3383       return m_memberDef->isOptional();
3384     }
3385     TemplateVariant isRequired() const
3386     {
3387       return m_memberDef->isRequired();
3388     }
3389     TemplateVariant isNonAtomic() const
3390     {
3391       return m_memberDef->isNonAtomic();
3392     }
3393     TemplateVariant isCopy() const
3394     {
3395       return m_memberDef->isCopy();
3396     }
3397     TemplateVariant isAssign() const
3398     {
3399       return m_memberDef->isAssign();
3400     }
3401     TemplateVariant isRetain() const
3402     {
3403       return m_memberDef->isRetain();
3404     }
3405     TemplateVariant isWeak() const
3406     {
3407       return m_memberDef->isWeak();
3408     }
3409     TemplateVariant isStrong() const
3410     {
3411       return m_memberDef->isStrong();
3412     }
3413     TemplateVariant isUnretained() const
3414     {
3415       return m_memberDef->isUnretained();
3416     }
3417     TemplateVariant isNew() const
3418     {
3419       return m_memberDef->isNew();
3420     }
3421     TemplateVariant isSealed() const
3422     {
3423       return m_memberDef->isSealed();
3424     }
3425     TemplateVariant isExternal() const
3426     {
3427       return m_memberDef->isExternal();
3428     }
3429     TemplateVariant isAlias() const
3430     {
3431       return m_memberDef->isAlias();
3432     }
3433     TemplateVariant isDefault() const
3434     {
3435       return m_memberDef->isDefault();
3436     }
3437     TemplateVariant isDelete() const
3438     {
3439       return m_memberDef->isDelete();
3440     }
3441     TemplateVariant isNoExcept() const
3442     {
3443       return m_memberDef->isNoExcept();
3444     }
3445     TemplateVariant isAttribute() const
3446     {
3447       return m_memberDef->isAttribute();
3448     }
3449     TemplateVariant isUNOProperty() const
3450     {
3451       return m_memberDef->isUNOProperty();
3452     }
3453     TemplateVariant isReadonly() const
3454     {
3455       return m_memberDef->isReadonly();
3456     }
3457     TemplateVariant isBound() const
3458     {
3459       return m_memberDef->isBound();
3460     }
3461     TemplateVariant isConstrained() const
3462     {
3463       return m_memberDef->isConstrained();
3464     }
3465     TemplateVariant isTransient() const
3466     {
3467       return m_memberDef->isTransient();
3468     }
3469     TemplateVariant isMaybeVoid() const
3470     {
3471       return m_memberDef->isMaybeVoid();
3472     }
3473     TemplateVariant isMaybeDefault() const
3474     {
3475       return m_memberDef->isMaybeDefault();
3476     }
3477     TemplateVariant isMaybeAmbiguous() const
3478     {
3479       return m_memberDef->isMaybeAmbiguous();
3480     }
3481     TemplateVariant isPublished() const
3482     {
3483       return m_memberDef->isPublished();
3484     }
3485     TemplateVariant isTemplateSpecialization() const
3486     {
3487       return m_memberDef->isTemplateSpecialization();
3488     }
3489     TemplateVariant isProperty() const
3490     {
3491       return m_memberDef->isProperty();
3492     }
3493     TemplateVariant isEnumValue() const
3494     {
3495       return m_memberDef->isEnumValue();
3496     }
3497     TemplateVariant isVariable() const
3498     {
3499       return m_memberDef->isVariable();
3500     }
3501     TemplateVariant isEnumeration() const
3502     {
3503       return m_memberDef->isEnumerate();
3504     }
3505     TemplateVariant hasDetails() const
3506     {
3507       return m_memberDef->isDetailedSectionLinkable();
3508     }
3509     TemplateVariant initializer() const
3510     {
3511       return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->initializer());
3512     }
3513     TemplateVariant initializerAsCode() const
3514     {
3515       if (!m_cache.initializerParsed)
3516       {
3517         QCString scopeName;
3518         if (m_memberDef->getClassDef())
3519         {
3520           scopeName = m_memberDef->getClassDef()->name();
3521         }
3522         else if (m_memberDef->getNamespaceDef())
3523         {
3524           scopeName = m_memberDef->getNamespaceDef()->name();
3525         }
3526         m_cache.initializer = parseCode(m_memberDef,scopeName,relPathAsString(),
3527                                         m_memberDef->initializer());
3528         m_cache.initializerParsed = TRUE;
3529       }
3530       return m_cache.initializer;
3531     }
3532     TemplateVariant isDefine() const
3533     {
3534       return m_memberDef->isDefine();
3535     }
3536     TemplateVariant isAnonymous() const
3537     {
3538       QCString name = m_memberDef->name();
3539       return !name.isEmpty() && name.at(0)=='@';
3540     }
3541     TemplateVariant anonymousType() const
3542     {
3543       if (!m_cache.anonymousType)
3544       {
3545         ClassDef *cd = m_memberDef->getClassDefOfAnonymousType();
3546         if (cd)
3547         {
3548           m_cache.anonymousType.reset(ClassContext::alloc(cd));
3549         }
3550       }
3551       if (m_cache.anonymousType)
3552       {
3553         return m_cache.anonymousType.get();
3554       }
3555       else
3556       {
3557         return FALSE;
3558       }
3559     }
3560     TemplateVariant anonymousMember() const
3561     {
3562       if (!m_cache.anonymousMember)
3563       {
3564         MemberDef *md = m_memberDef->fromAnonymousMember();
3565         if (md)
3566         {
3567           m_cache.anonymousMember.reset(MemberContext::alloc(md));
3568         }
3569       }
3570       if (m_cache.anonymousMember)
3571       {
3572         return m_cache.anonymousMember.get();
3573       }
3574       else
3575       {
3576         return FALSE;
3577       }
3578     }
3579     TemplateVariant isRelated() const
3580     {
3581       return m_memberDef->isRelated();
3582     }
3583     TemplateVariant enumBaseType() const
3584     {
3585       return m_memberDef->enumBaseType();
3586     }
3587     TemplateVariant hasOneLineInitializer() const
3588     {
3589       return m_memberDef->hasOneLineInitializer();
3590     }
3591     TemplateVariant hasMultiLineInitializer() const
3592     {
3593       return m_memberDef->hasMultiLineInitializer();
3594     }
3595     TemplateVariant enumValues() const
3596     {
3597       if (!m_cache.enumValues)
3598       {
3599         MemberList *ml = m_memberDef->enumFieldList();
3600         if (ml)
3601         {
3602           m_cache.enumValues.reset(MemberListContext::alloc(ml));
3603         }
3604         else
3605         {
3606           m_cache.enumValues.reset(MemberListContext::alloc());
3607         }
3608       }
3609       return m_cache.enumValues.get();
3610     }
3611     TemplateVariant templateArgs() const
3612     {
3613       if (!m_cache.templateArgs && m_memberDef->templateArguments())
3614       {
3615         m_cache.templateArgs.reset(ArgumentListContext::alloc(m_memberDef->templateArguments(),m_memberDef,relPathAsString()));
3616       }
3617       if (m_cache.templateArgs)
3618       {
3619         return m_cache.templateArgs.get();
3620       }
3621       else
3622       {
3623         return TemplateVariant(FALSE);
3624       }
3625     }
3626     TemplateVariant templateAlias() const
3627     {
3628       if (m_memberDef->isAlias())
3629       {
3630         return createLinkedText(m_memberDef,relPathAsString(),
3631                                 QCString(" = ")+m_memberDef->typeString());
3632       }
3633       return "";
3634     }
3635     TemplateVariant propertyAttrs() const
3636     {
3637       return m_cache.propertyAttrs.get();
3638     }
3639     TemplateVariant eventAttrs() const
3640     {
3641       return m_cache.eventAttrs.get();
3642     }
3643     TemplateVariant getClass() const
3644     {
3645       if (!m_cache.classDef && m_memberDef->getClassDef())
3646       {
3647         m_cache.classDef.reset(ClassContext::alloc(m_memberDef->getClassDef()));
3648       }
3649       if (m_cache.classDef)
3650       {
3651         return m_cache.classDef.get();
3652       }
3653       else
3654       {
3655         return TemplateVariant(FALSE);
3656       }
3657     }
3658     TemplateVariant getFile() const
3659     {
3660       if (!m_cache.fileDef && m_memberDef->getFileDef())
3661       {
3662         m_cache.fileDef.reset(FileContext::alloc(m_memberDef->getFileDef()));
3663       }
3664       if (m_cache.fileDef)
3665       {
3666         return m_cache.fileDef.get();
3667       }
3668       else
3669       {
3670         return TemplateVariant(FALSE);
3671       }
3672     }
3673     TemplateVariant getNamespace() const
3674     {
3675       if (!m_cache.namespaceDef && m_memberDef->getNamespaceDef())
3676       {
3677         m_cache.namespaceDef.reset(NamespaceContext::alloc(m_memberDef->getNamespaceDef()));
3678       }
3679       if (m_cache.namespaceDef)
3680       {
3681         return m_cache.namespaceDef.get();
3682       }
3683       else
3684       {
3685         return TemplateVariant(FALSE);
3686       }
3687     }
3688     TemplateVariant definition() const
3689     {
3690       return createLinkedText(m_memberDef,relPathAsString(),
3691                               m_memberDef->displayDefinition());
3692     }
3693     ArgumentList *getDefArgList() const
3694     {
3695       return (m_memberDef->isDocsForDefinition()) ?
3696               m_memberDef->argumentList() : m_memberDef->declArgumentList();
3697     }
3698     TemplateVariant parameters() const
3699     {
3700       if (!m_cache.arguments)
3701       {
3702         ArgumentList *defArgList = getDefArgList();
3703         if (defArgList && !m_memberDef->isProperty())
3704         {
3705           m_cache.arguments.reset(ArgumentListContext::alloc(defArgList,m_memberDef,relPathAsString()));
3706         }
3707         else
3708         {
3709           m_cache.arguments.reset(ArgumentListContext::alloc());
3710         }
3711       }
3712       return m_cache.arguments.get();
3713     }
3714     TemplateVariant hasParameterList() const
3715     {
3716       return getDefArgList()!=0;
3717     }
3718     TemplateVariant hasConstQualifier() const
3719     {
3720       ArgumentList *al = getDefArgList();
3721       return al ? al->constSpecifier : FALSE;
3722     }
3723     TemplateVariant hasVolatileQualifier() const
3724     {
3725       ArgumentList *al = getDefArgList();
3726       return al ? al->volatileSpecifier : FALSE;
3727     }
3728     TemplateVariant trailingReturnType() const
3729     {
3730       ArgumentList *al = getDefArgList();
3731       if (al && !al->trailingReturnType.isEmpty())
3732       {
3733         return createLinkedText(m_memberDef,relPathAsString(),
3734                                 al->trailingReturnType);
3735       }
3736       else
3737       {
3738         return "";
3739       }
3740     }
3741     TemplateVariant extraTypeChars() const
3742     {
3743       return m_memberDef->extraTypeChars();
3744     }
3745     void addTemplateDecls(TemplateList *tl) const
3746     {
3747       ClassDef *cd=m_memberDef->getClassDef();
3748       if (m_memberDef->definitionTemplateParameterLists())
3749       {
3750         QListIterator<ArgumentList> ali(*m_memberDef->definitionTemplateParameterLists());
3751         ArgumentList *tal;
3752         for (ali.toFirst();(tal=ali.current());++ali)
3753         {
3754           if (tal->count()>0)
3755           {
3756             ArgumentListContext *al = ArgumentListContext::alloc(tal,m_memberDef,relPathAsString());
3757             tl->append(al);
3758           }
3759         }
3760       }
3761       else
3762       {
3763         if (cd && !m_memberDef->isRelated() && !m_memberDef->isTemplateSpecialization())
3764         {
3765           QList<ArgumentList> tempParamLists;
3766           cd->getTemplateParameterLists(tempParamLists);
3767           //printf("#tempParamLists=%d\n",tempParamLists.count());
3768           QListIterator<ArgumentList> ali(tempParamLists);
3769           ArgumentList *tal;
3770           for (ali.toFirst();(tal=ali.current());++ali)
3771           {
3772             if (tal->count()>0)
3773             {
3774               ArgumentListContext *al = ArgumentListContext::alloc(tal,m_memberDef,relPathAsString());
3775               tl->append(al);
3776             }
3777           }
3778         }
3779         if (m_memberDef->templateArguments()) // function template prefix
3780         {
3781           ArgumentListContext *al = ArgumentListContext::alloc(
3782               m_memberDef->templateArguments(),m_memberDef,relPathAsString());
3783           tl->append(al);
3784         }
3785       }
3786     }
3787     TemplateVariant templateDecls() const
3788     {
3789       if (!m_cache.templateDecls)
3790       {
3791         TemplateList *tl = TemplateList::alloc();
3792         addTemplateDecls(tl);
3793         m_cache.templateDecls.reset(tl);
3794       }
3795       return m_cache.templateDecls.get();
3796     }
3797     TemplateVariant labels() const
3798     {
3799       if (!m_cache.labels)
3800       {
3801         QStrList sl;
3802         m_memberDef->getLabels(sl,m_memberDef->getOuterScope());
3803         TemplateList *tl = TemplateList::alloc();
3804         if (sl.count()>0)
3805         {
3806           QStrListIterator it(sl);
3807           for (;it.current();++it)
3808           {
3809             tl->append(*it);
3810           }
3811         }
3812         m_cache.labels.reset(tl);
3813       }
3814       return m_cache.labels.get();
3815     }
3816     TemplateVariant paramDocs() const
3817     {
3818       if (!m_cache.paramDocs)
3819       {
3820         if (m_memberDef->argumentList() && m_memberDef->argumentList()->hasDocumentation())
3821         {
3822           QCString paramDocs;
3823           ArgumentListIterator ali(*m_memberDef->argumentList());
3824           Argument *a;
3825           // convert the parameter documentation into a list of @param commands
3826           for (ali.toFirst();(a=ali.current());++ali)
3827           {
3828             if (a->hasDocumentation())
3829             {
3830               QCString direction = extractDirection(a->docs);
3831               paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
3832             }
3833           }
3834           m_cache.paramDocs.reset(new TemplateVariant(parseDoc(m_memberDef,
3835                                            m_memberDef->docFile(),m_memberDef->docLine(),
3836                                            relPathAsString(),paramDocs,FALSE)));
3837         }
3838         else
3839         {
3840           m_cache.paramDocs.reset(new TemplateVariant(""));
3841         }
3842       }
3843       return *m_cache.paramDocs;
3844     }
3845     TemplateVariant implements() const
3846     {
3847       if (!m_cache.implements)
3848       {
3849         MemberDef *md = m_memberDef->reimplements();
3850         m_cache.implements.reset(TemplateList::alloc());
3851         if (md)
3852         {
3853           ClassDef *cd = md->getClassDef();
3854           if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface))
3855           {
3856             MemberContext *mc = MemberContext::alloc(md);
3857             m_cache.implements->append(mc);
3858           }
3859         }
3860       }
3861       return m_cache.implements.get();
3862     }
3863     TemplateVariant reimplements() const
3864     {
3865       if (!m_cache.reimplements)
3866       {
3867         MemberDef *md = m_memberDef->reimplements();
3868         m_cache.reimplements.reset(TemplateList::alloc());
3869         if (md)
3870         {
3871           ClassDef *cd = md->getClassDef();
3872           if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface)
3873           {
3874             MemberContext *mc = MemberContext::alloc(md);
3875             m_cache.reimplements->append(mc);
3876           }
3877         }
3878       }
3879       return m_cache.reimplements.get();
3880     }
3881     TemplateVariant implementedBy() const
3882     {
3883       if (!m_cache.implementedBy)
3884       {
3885         MemberList *ml = m_memberDef->reimplementedBy();
3886         m_cache.implementedBy.reset(TemplateList::alloc());
3887         if (ml)
3888         {
3889           MemberListIterator mli(*ml);
3890           MemberDef *md=0;
3891           for (mli.toFirst();(md=mli.current());++mli)
3892           {
3893             ClassDef *cd = md->getClassDef();
3894             if (cd && (md->virtualness()==Pure || cd->compoundType()==ClassDef::Interface))
3895             {
3896               MemberContext *mc = new MemberContext(md);
3897               m_cache.implementedBy->append(mc);
3898             }
3899           }
3900         }
3901       }
3902       return m_cache.implementedBy.get();
3903     }
3904     TemplateVariant reimplementedBy() const
3905     {
3906       if (!m_cache.reimplementedBy)
3907       {
3908         m_cache.reimplementedBy.reset(TemplateList::alloc());
3909         MemberList *ml = m_memberDef->reimplementedBy();
3910         if (ml)
3911         {
3912           MemberListIterator mli(*ml);
3913           MemberDef *md=0;
3914           for (mli.toFirst();(md=mli.current());++mli)
3915           {
3916             ClassDef *cd = md->getClassDef();
3917             if (cd && md->virtualness()!=Pure && cd->compoundType()!=ClassDef::Interface)
3918             {
3919               MemberContext *mc = new MemberContext(md);
3920               m_cache.reimplementedBy->append(mc);
3921             }
3922           }
3923         }
3924       }
3925       return m_cache.reimplementedBy.get();
3926     }
3927     void addExamples(TemplateList *list) const
3928     {
3929       if (m_memberDef->hasExamples())
3930       {
3931         ExampleSDict::Iterator it(*m_memberDef->getExamples());
3932         Example *ex;
3933         for (it.toFirst();(ex=it.current());++it)
3934         {
3935           TemplateStruct *s = TemplateStruct::alloc();
3936           s->set("text",ex->name);
3937           s->set("isLinkable",TRUE);
3938           s->set("anchor",ex->anchor);
3939           s->set("fileName",ex->file);
3940           list->append(s);
3941         }
3942       }
3943     }
3944     TemplateVariant examples() const
3945     {
3946       if (!m_cache.examples)
3947       {
3948         TemplateList *exampleList = TemplateList::alloc();
3949         addExamples(exampleList);
3950         m_cache.examples.reset(exampleList);
3951       }
3952       return m_cache.examples.get();
3953     }
3954     TemplateVariant typeConstraints() const
3955     {
3956       if (!m_cache.typeConstraints && m_memberDef->typeConstraints())
3957       {
3958         m_cache.typeConstraints.reset(ArgumentListContext::alloc(m_memberDef->typeConstraints(),m_memberDef,relPathAsString()));
3959       }
3960       else
3961       {
3962         m_cache.typeConstraints.reset(ArgumentListContext::alloc());
3963       }
3964       return m_cache.typeConstraints.get();
3965     }
3966     TemplateVariant functionQualifier() const
3967     {
3968       if (!m_memberDef->isObjCMethod() &&
3969           (m_memberDef->isFunction()  || m_memberDef->isSlot() ||
3970            m_memberDef->isPrototype() || m_memberDef->isSignal()
3971           )
3972          )
3973       {
3974         return "()";
3975       }
3976       else
3977       {
3978         return "";
3979       }
3980     }
3981     TemplateVariant sourceRefs() const
3982     {
3983       if (!m_cache.sourceRefs)
3984       {
3985         m_cache.sourceRefs.reset(MemberListContext::alloc(m_memberDef->getReferencesMembers(),TRUE));
3986       }
3987       return m_cache.sourceRefs.get();
3988     }
3989     TemplateVariant sourceRefBys() const
3990     {
3991       if (!m_cache.sourceRefBys)
3992       {
3993         m_cache.sourceRefBys.reset(MemberListContext::alloc(m_memberDef->getReferencedByMembers(),TRUE));
3994       }
3995       return m_cache.sourceRefBys.get();
3996     }
3997     TemplateVariant hasSources() const
3998     {
3999       return TemplateVariant(m_memberDef->hasSources());
4000     }
4001     TemplateVariant sourceCode() const
4002     {
4003       if (!m_cache.sourceCodeParsed)
4004       {
4005         QCString codeFragment;
4006         FileDef *fd   = m_memberDef->getBodyDef();
4007         int startLine = m_memberDef->getStartBodyLine();
4008         int endLine   = m_memberDef->getEndBodyLine();
4009         if (fd && readCodeFragment(fd->absFilePath(),
4010               startLine,endLine,codeFragment)
4011            )
4012         {
4013           QCString scopeName;
4014           if (m_memberDef->getClassDef())
4015           {
4016             scopeName = m_memberDef->getClassDef()->name();
4017           }
4018           else if (m_memberDef->getNamespaceDef())
4019           {
4020             scopeName = m_memberDef->getNamespaceDef()->name();
4021           }
4022           m_cache.sourceCode = parseCode(m_memberDef,scopeName,relPathAsString(),codeFragment,startLine,endLine,TRUE);
4023           m_cache.sourceCodeParsed = TRUE;
4024         }
4025       }
4026       return m_cache.sourceCode;
4027     }
4028     DotCallGraph *getCallGraph() const
4029     {
4030       if (!m_cache.callGraph)
4031       {
4032         m_cache.callGraph.reset(new DotCallGraph(m_memberDef,FALSE));
4033       }
4034       return m_cache.callGraph.get();
4035     }
4036     TemplateVariant hasCallGraph() const
4037     {
4038       static bool haveDot = Config_getBool("HAVE_DOT");
4039       static bool callGraph = Config_getBool("CALL_GRAPH");
4040       if ((callGraph || m_memberDef->hasCallGraph()) && haveDot &&
4041           (m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal()))
4042       {
4043         DotCallGraph *cg = getCallGraph();
4044         return !cg->isTooBig() && !cg->isTrivial();
4045       }
4046       return TemplateVariant(FALSE);
4047     }
4048     TemplateVariant callGraph() const
4049     {
4050       if (hasCallGraph().toBool())
4051       {
4052         DotCallGraph *cg = getCallGraph();
4053         QGString result;
4054         FTextStream t(&result);
4055         cg->writeGraph(t,GOF_BITMAP,EOF_Html,
4056             g_globals.outputDir,
4057             g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension,
4058             relPathAsString(),TRUE,g_globals.dynSectionId
4059             );
4060         g_globals.dynSectionId++;
4061         return TemplateVariant(result.data(),TRUE);
4062       }
4063       else
4064       {
4065         return TemplateVariant("");
4066       }
4067     }
4068     DotCallGraph *getCallerGraph() const
4069     {
4070       if (!m_cache.callerGraph)
4071       {
4072         m_cache.callerGraph.reset(new DotCallGraph(m_memberDef,TRUE));
4073       }
4074       return m_cache.callerGraph.get();
4075     }
4076     TemplateVariant hasCallerGraph() const
4077     {
4078       static bool haveDot = Config_getBool("HAVE_DOT");
4079       static bool callerGraph = Config_getBool("CALLER_GRAPH");
4080       if ((callerGraph || m_memberDef->hasCallerGraph()) && haveDot &&
4081           (m_memberDef->isFunction() || m_memberDef->isSlot() || m_memberDef->isSignal()))
4082       {
4083         DotCallGraph *cg = getCallerGraph();
4084         return !cg->isTooBig() && !cg->isTrivial();
4085       }
4086       return TemplateVariant(FALSE);
4087     }
4088     TemplateVariant callerGraph() const
4089     {
4090       if (hasCallerGraph().toBool())
4091       {
4092         DotCallGraph *cg = getCallerGraph();
4093         QGString result;
4094         FTextStream t(&result);
4095         cg->writeGraph(t,GOF_BITMAP,EOF_Html,
4096             g_globals.outputDir,
4097             g_globals.outputDir+portable_pathSeparator()+m_memberDef->getOutputFileBase()+Doxygen::htmlFileExtension,
4098             relPathAsString(),TRUE,g_globals.dynSectionId
4099             );
4100         g_globals.dynSectionId++;
4101         return TemplateVariant(result.data(),TRUE);
4102       }
4103       else
4104       {
4105         return TemplateVariant("");
4106       }
4107     }
4108   private:
4109     MemberDef *m_memberDef;
4110     struct Cachable
4111     {
4112       Cachable() : initializerParsed(FALSE), sourceCodeParsed(FALSE)
4113       {
4114       }
4115       SharedPtr<ArgumentListContext> templateArgs;
4116       SharedPtr<ArgumentListContext> arguments;
4117       SharedPtr<MemberListContext>   enumValues;
4118       SharedPtr<FileContext>         fileDef;
4119       SharedPtr<NamespaceContext>    namespaceDef;
4120       SharedPtr<ClassContext>        classDef;
4121       SharedPtr<ClassContext>        anonymousType;
4122       SharedPtr<TemplateList>        templateDecls;
4123       ScopedPtr<TemplateVariant>     paramDocs;
4124       SharedPtr<TemplateList>        implements;
4125       SharedPtr<TemplateList>        reimplements;
4126       SharedPtr<TemplateList>        implementedBy;
4127       SharedPtr<MemberListContext>   sourceRefs;
4128       SharedPtr<MemberListContext>   sourceRefBys;
4129       ScopedPtr<DotCallGraph>        callGraph;
4130       ScopedPtr<DotCallGraph>        callerGraph;
4131       SharedPtr<MemberContext>       anonymousMember;
4132       SharedPtr<TemplateList>        reimplementedBy;
4133       SharedPtr<TemplateList>        labels;
4134       TemplateVariant                initializer;
4135       bool                           initializerParsed;
4136       TemplateVariant                sourceCode;
4137       bool                           sourceCodeParsed;
4138       SharedPtr<TemplateList>        examples;
4139       SharedPtr<TemplateList>        exampleList;
4140       SharedPtr<ArgumentListContext> typeConstraints;
4141       SharedPtr<TemplateList>        propertyAttrs;
4142       SharedPtr<TemplateList>        eventAttrs;
4143     };
4144     mutable Cachable m_cache;
4145 };
4146 //%% }
4147
4148 MemberContext::MemberContext(MemberDef *md) : RefCountedContext("MemberContext")
4149 {
4150   p = new Private(md);
4151 }
4152
4153 MemberContext::~MemberContext()
4154 {
4155   delete p;
4156 }
4157
4158 TemplateVariant MemberContext::get(const char *n) const
4159 {
4160   return p->get(n);
4161 }
4162
4163
4164 //------------------------------------------------------------------------
4165
4166 //%% struct Module(Symbol): group information
4167 //%% {
4168 class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
4169 {
4170   public:
4171     Private(GroupDef *gd) : DefinitionContext<ModuleContext::Private>(gd) , m_groupDef(gd)
4172     {
4173       addProperty("title",                     this,&Private::title);
4174       addProperty("highlight",                 this,&Private::highlight);
4175       addProperty("subhighlight",              this,&Private::subHighlight);
4176       addProperty("hasGroupGraph",             this,&Private::hasGroupGraph);
4177       addProperty("groupGraph",                this,&Private::groupGraph);
4178       addProperty("hasDetails",                this,&Private::hasDetails);
4179       addProperty("modules",                   this,&Private::modules);
4180       addProperty("dirs",                      this,&Private::dirs);
4181       addProperty("files",                     this,&Private::files);
4182       addProperty("namespaces",                this,&Private::namespaces);
4183       addProperty("classes",                   this,&Private::classes);
4184       addProperty("constantgroups",            this,&Private::constantgroups);
4185       addProperty("examples",                  this,&Private::examples);
4186       addProperty("macros",                    this,&Private::macros);
4187       addProperty("typedefs",                  this,&Private::typedefs);
4188       addProperty("enums",                     this,&Private::enums);
4189       addProperty("enumvalues",                this,&Private::enumValues);
4190       addProperty("functions",                 this,&Private::functions);
4191       addProperty("variables",                 this,&Private::variables);
4192       addProperty("signals",                   this,&Private::signals);
4193       addProperty("publicSlots",               this,&Private::publicSlots);
4194       addProperty("protectedSlots",            this,&Private::protectedSlots);
4195       addProperty("privateSlots",              this,&Private::privateSlots);
4196       addProperty("events",                    this,&Private::events);
4197       addProperty("properties",                this,&Private::properties);
4198       addProperty("friends",                   this,&Private::friends);
4199       addProperty("memberGroups",              this,&Private::memberGroups);
4200       addProperty("detailedMacros",            this,&Private::detailedMacros);
4201       addProperty("detailedTypedefs",          this,&Private::detailedTypedefs);
4202       addProperty("detailedEnums",             this,&Private::detailedEnums);
4203       addProperty("detailedEnumValues",        this,&Private::detailedEnumValues);
4204       addProperty("detailedFunctions",         this,&Private::detailedFunctions);
4205       addProperty("detailedVariables",         this,&Private::detailedVariables);
4206       addProperty("detailedSignals",           this,&Private::detailedSignals);
4207       addProperty("detailedPublicSlots",       this,&Private::detailedPublicSlots);
4208       addProperty("detailedProtectedSlots",    this,&Private::detailedProtectedSlots);
4209       addProperty("detailedPrivateSlots",      this,&Private::detailedPrivateSlots);
4210       addProperty("detailedEvents",            this,&Private::detailedEvents);
4211       addProperty("detailedProperties",        this,&Private::detailedProperties);
4212       addProperty("detailedFriends",           this,&Private::detailedFriends);
4213       addProperty("inlineClasses",             this,&Private::inlineClasses);
4214       addProperty("compoundType",              this,&Private::compoundType);
4215     }
4216     virtual ~Private() {}
4217     TemplateVariant title() const
4218     {
4219       return TemplateVariant(m_groupDef->groupTitle());
4220     }
4221     TemplateVariant highlight() const
4222     {
4223       return TemplateVariant("modules");
4224     }
4225     TemplateVariant subHighlight() const
4226     {
4227       return TemplateVariant("");
4228     }
4229     DotGroupCollaboration *getGroupGraph() const
4230     {
4231       if (!m_cache.groupGraph)
4232       {
4233         m_cache.groupGraph.reset(new DotGroupCollaboration(m_groupDef));
4234       }
4235       return m_cache.groupGraph.get();
4236     }
4237     TemplateVariant hasGroupGraph() const
4238     {
4239       bool result=FALSE;
4240       static bool haveDot     = Config_getBool("HAVE_DOT");
4241       static bool groupGraphs = Config_getBool("GROUP_GRAPHS");
4242       if (haveDot && groupGraphs)
4243       {
4244         DotGroupCollaboration *graph = getGroupGraph();
4245         result = !graph->isTrivial();
4246       }
4247       return result;
4248     }
4249     TemplateVariant groupGraph() const
4250     {
4251       QGString result;
4252       static bool haveDot     = Config_getBool("HAVE_DOT");
4253       static bool groupGraphs = Config_getBool("GROUP_GRAPHS");
4254       if (haveDot && groupGraphs)
4255       {
4256         DotGroupCollaboration *graph = getGroupGraph();
4257         FTextStream t(&result);
4258         graph->writeGraph(t,GOF_BITMAP,
4259                           EOF_Html,
4260                           g_globals.outputDir,
4261                           g_globals.outputDir+portable_pathSeparator()+m_groupDef->getOutputFileBase()+Doxygen::htmlFileExtension,
4262                           relPathAsString(),
4263                           TRUE,
4264                           g_globals.dynSectionId);
4265       }
4266       g_globals.dynSectionId++;
4267       return TemplateVariant(result.data(),TRUE);
4268     }
4269     TemplateVariant hasDetails() const
4270     {
4271       return m_groupDef->hasDetailedDescription();
4272     }
4273     TemplateVariant modules() const
4274     {
4275       if (!m_cache.modules)
4276       {
4277         TemplateList *moduleList = TemplateList::alloc();
4278         if (m_groupDef->getSubGroups())
4279         {
4280           GroupListIterator gli(*m_groupDef->getSubGroups());
4281           GroupDef *gd;
4282           for (gli.toFirst();(gd=gli.current());++gli)
4283           {
4284             if (gd->isVisible())
4285             {
4286               moduleList->append(ModuleContext::alloc(gd));
4287             }
4288           }
4289         }
4290         m_cache.modules.reset(moduleList);
4291       }
4292       return m_cache.modules.get();
4293     }
4294     TemplateVariant examples() const
4295     {
4296       if (!m_cache.examples)
4297       {
4298         TemplateList *exampleList = TemplateList::alloc();
4299         if (m_groupDef->getExamples())
4300         {
4301           PageSDict::Iterator eli(*m_groupDef->getExamples());
4302           PageDef *ex;
4303           for (eli.toFirst();(ex=eli.current());++eli)
4304           {
4305             exampleList->append(PageContext::alloc(ex));
4306           }
4307         }
4308         m_cache.examples.reset(exampleList);
4309       }
4310       return m_cache.examples.get();
4311     }
4312     TemplateVariant pages() const
4313     {
4314       if (!m_cache.pages)
4315       {
4316         TemplateList *pageList = TemplateList::alloc();
4317         if (m_groupDef->getExamples())
4318         {
4319           PageSDict::Iterator eli(*m_groupDef->getPages());
4320           PageDef *ex;
4321           for (eli.toFirst();(ex=eli.current());++eli)
4322           {
4323             pageList->append(PageContext::alloc(ex));
4324           }
4325         }
4326         m_cache.pages.reset(pageList);
4327       }
4328       return m_cache.pages.get();
4329     }
4330     TemplateVariant dirs() const
4331     {
4332       if (!m_cache.dirs)
4333       {
4334         TemplateList *dirList = TemplateList::alloc();
4335         if (m_groupDef->getDirs())
4336         {
4337           QListIterator<DirDef> it(*m_groupDef->getDirs());
4338           DirDef *dd;
4339           for (it.toFirst();(dd=it.current());++it)
4340           {
4341             dirList->append(DirContext::alloc(dd));
4342           }
4343         }
4344         m_cache.dirs.reset(dirList);
4345       }
4346       return m_cache.dirs.get();
4347     }
4348     TemplateVariant files() const
4349     {
4350       if (!m_cache.files)
4351       {
4352         TemplateList *fileList = TemplateList::alloc();
4353         if (m_groupDef->getFiles())
4354         {
4355           QListIterator<FileDef> it(*m_groupDef->getFiles());
4356           FileDef *fd;
4357           for (it.toFirst();(fd=it.current());++it)
4358           {
4359             fileList->append(FileContext::alloc(fd));
4360           }
4361         }
4362         m_cache.files.reset(fileList);
4363       }
4364       return m_cache.files.get();
4365     }
4366     TemplateVariant classes() const
4367     {
4368       if (!m_cache.classes)
4369       {
4370         TemplateList *classList = TemplateList::alloc();
4371         if (m_groupDef->getClasses())
4372         {
4373           ClassSDict::Iterator sdi(*m_groupDef->getClasses());
4374           ClassDef *cd;
4375           for (sdi.toFirst();(cd=sdi.current());++sdi)
4376           {
4377             if (cd->visibleInParentsDeclList())
4378             {
4379               classList->append(ClassContext::alloc(cd));
4380             }
4381           }
4382         }
4383         m_cache.classes.reset(classList);
4384       }
4385       return m_cache.classes.get();
4386     }
4387     TemplateVariant namespaces() const
4388     {
4389       if (!m_cache.namespaces)
4390       {
4391         TemplateList *namespaceList = TemplateList::alloc();
4392         if (m_groupDef->getNamespaces())
4393         {
4394           NamespaceSDict::Iterator sdi(*m_groupDef->getNamespaces());
4395           NamespaceDef *nd;
4396           for (sdi.toFirst();(nd=sdi.current());++sdi)
4397           {
4398             if (nd->isLinkable() && !nd->isConstantGroup())
4399             {
4400               namespaceList->append(NamespaceContext::alloc(nd));
4401             }
4402           }
4403         }
4404         m_cache.namespaces.reset(namespaceList);
4405       }
4406       return m_cache.namespaces.get();
4407     }
4408     TemplateVariant constantgroups() const
4409     {
4410       if (!m_cache.constantgroups)
4411       {
4412         TemplateList *namespaceList = TemplateList::alloc();
4413         if (m_groupDef->getNamespaces())
4414         {
4415           NamespaceSDict::Iterator sdi(*m_groupDef->getNamespaces());
4416           NamespaceDef *nd;
4417           for (sdi.toFirst();(nd=sdi.current());++sdi)
4418           {
4419             if (nd->isLinkable() && nd->isConstantGroup())
4420             {
4421               namespaceList->append(NamespaceContext::alloc(nd));
4422             }
4423           }
4424         }
4425         m_cache.constantgroups.reset(namespaceList);
4426       }
4427       return m_cache.constantgroups.get();
4428     }
4429
4430     TemplateVariant getMemberList(SharedPtr<MemberListInfoContext> &list,
4431                                   MemberListType type,const char *title,bool detailed=FALSE) const
4432     {
4433       if (!list)
4434       {
4435         MemberList *ml = m_groupDef->getMemberList(type);
4436         if (ml)
4437         {
4438           list.reset(MemberListInfoContext::alloc(m_groupDef,relPathAsString(),ml,title,detailed));
4439         }
4440       }
4441       if (list)
4442       {
4443         return list.get();
4444       }
4445       else
4446       {
4447         return TemplateVariant(FALSE);
4448       }
4449     }
4450     TemplateVariant macros() const
4451     {
4452       return getMemberList(m_cache.macros,MemberListType_decDefineMembers,theTranslator->trDefines());
4453     }
4454     TemplateVariant typedefs() const
4455     {
4456       return getMemberList(m_cache.typedefs,MemberListType_decTypedefMembers,theTranslator->trTypedefs());
4457     }
4458     TemplateVariant enums() const
4459     {
4460       return getMemberList(m_cache.enums,MemberListType_decEnumMembers,theTranslator->trEnumerations());
4461     }
4462     TemplateVariant enumValues() const
4463     {
4464       return getMemberList(m_cache.enums,MemberListType_decEnumValMembers,theTranslator->trEnumerationValues());
4465     }
4466     TemplateVariant functions() const
4467     {
4468       QCString title = theTranslator->trFunctions();
4469       SrcLangExt lang = m_groupDef->getLanguage();
4470       if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprograms();
4471       else if (lang==SrcLangExt_VHDL) title=VhdlDocGen::trFunctionAndProc();
4472       return getMemberList(m_cache.functions,MemberListType_decFuncMembers,title);
4473     }
4474     TemplateVariant variables() const
4475     {
4476       return getMemberList(m_cache.variables,MemberListType_decVarMembers,theTranslator->trVariables());
4477     }
4478     TemplateVariant signals() const
4479     {
4480       return getMemberList(m_cache.signals,MemberListType_signals,theTranslator->trSignals());
4481     }
4482     TemplateVariant publicSlots() const
4483     {
4484       return getMemberList(m_cache.publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots());
4485     }
4486     TemplateVariant protectedSlots() const
4487     {
4488       return getMemberList(m_cache.protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots());
4489     }
4490     TemplateVariant privateSlots() const
4491     {
4492       return getMemberList(m_cache.privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots());
4493     }
4494     TemplateVariant events() const
4495     {
4496       return getMemberList(m_cache.events,MemberListType_events,theTranslator->trEvents());
4497     }
4498     TemplateVariant properties() const
4499     {
4500       return getMemberList(m_cache.properties,MemberListType_properties,theTranslator->trProperties());
4501     }
4502     TemplateVariant friends() const
4503     {
4504       return getMemberList(m_cache.friends,MemberListType_friends,theTranslator->trFriends());
4505     }
4506     TemplateVariant memberGroups() const
4507     {
4508       if (!m_cache.memberGroups)
4509       {
4510         if (m_groupDef->getMemberGroupSDict())
4511         {
4512           m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_groupDef,relPathAsString(),m_groupDef->getMemberGroupSDict(),m_groupDef->subGrouping()));
4513         }
4514         else
4515         {
4516           m_cache.memberGroups.reset(MemberGroupListContext::alloc());
4517         }
4518       }
4519       return m_cache.memberGroups.get();
4520     }
4521     TemplateVariant detailedMacros() const
4522     {
4523       return getMemberList(m_cache.detailedMacros,MemberListType_docDefineMembers,theTranslator->trDefineDocumentation());
4524     }
4525     TemplateVariant detailedTypedefs() const
4526     {
4527       return getMemberList(m_cache.detailedTypedefs,MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation());
4528     }
4529     TemplateVariant detailedEnums() const
4530     {
4531       return getMemberList(m_cache.detailedEnums,MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation());
4532     }
4533     TemplateVariant detailedEnumValues() const
4534     {
4535       return getMemberList(m_cache.detailedEnumValues,MemberListType_docEnumValMembers,theTranslator->trEnumerationValueDocumentation());
4536     }
4537     TemplateVariant detailedFunctions() const
4538     {
4539       QCString title = theTranslator->trFunctionDocumentation();
4540       SrcLangExt lang = m_groupDef->getLanguage();
4541       if (lang==SrcLangExt_Fortran) title=theTranslator->trSubprogramDocumentation();
4542       return getMemberList(m_cache.detailedFunctions,MemberListType_docFuncMembers,title);
4543     }
4544     TemplateVariant detailedVariables() const
4545     {
4546       return getMemberList(m_cache.detailedVariables,MemberListType_docVarMembers,theTranslator->trVariableDocumentation());
4547     }
4548     TemplateVariant detailedSignals() const
4549     {
4550       return getMemberList(m_cache.detailedSignals,MemberListType_docSignalMembers,theTranslator->trSignals());
4551     }
4552     TemplateVariant detailedPublicSlots() const
4553     {
4554       return getMemberList(m_cache.detailedPublicSlots,MemberListType_docPubSlotMembers,theTranslator->trPublicSlots());
4555     }
4556     TemplateVariant detailedProtectedSlots() const
4557     {
4558       return getMemberList(m_cache.detailedProtectedSlots,MemberListType_docProSlotMembers,theTranslator->trProtectedSlots());
4559     }
4560     TemplateVariant detailedPrivateSlots() const
4561     {
4562       return getMemberList(m_cache.detailedPrivateSlots,MemberListType_docPriSlotMembers,theTranslator->trPrivateSlots());
4563     }
4564     TemplateVariant detailedEvents() const
4565     {
4566       return getMemberList(m_cache.detailedEvents,MemberListType_docEventMembers,theTranslator->trEventDocumentation(),TRUE);
4567     }
4568     TemplateVariant detailedProperties() const
4569     {
4570       return getMemberList(m_cache.detailedProperties,MemberListType_docPropMembers,theTranslator->trPropertyDocumentation(),TRUE);
4571     }
4572     TemplateVariant detailedFriends() const
4573     {
4574       return getMemberList(m_cache.detailedFriends,MemberListType_docFriendMembers,theTranslator->trFriends(),TRUE);
4575     }
4576     TemplateVariant inlineClasses() const
4577     {
4578       if (!m_cache.inlineClasses)
4579       {
4580         TemplateList *classList = TemplateList::alloc();
4581         if (m_groupDef->getClasses())
4582         {
4583           ClassSDict::Iterator sdi(*m_groupDef->getClasses());
4584           ClassDef *cd;
4585           for (sdi.toFirst();(cd=sdi.current());++sdi)
4586           {
4587             if (cd->name().find('@')==-1 &&
4588                 cd->isLinkableInProject() &&
4589                 cd->isEmbeddedInOuterScope() &&
4590                 cd->partOfGroups()==0)
4591             {
4592               classList->append(ClassContext::alloc(cd));
4593             }
4594           }
4595         }
4596         m_cache.inlineClasses.reset(classList);
4597       }
4598       return m_cache.inlineClasses.get();
4599     }
4600     TemplateVariant compoundType() const
4601     {
4602       return "module"; //theTranslator->trGroup(FALSE,TRUE);
4603     }
4604   private:
4605     GroupDef *m_groupDef;
4606     struct Cachable
4607     {
4608       SharedPtr<TemplateList>               modules;
4609       SharedPtr<TemplateList>               dirs;
4610       SharedPtr<TemplateList>               files;
4611       SharedPtr<TemplateList>               classes;
4612       SharedPtr<TemplateList>               namespaces;
4613       SharedPtr<TemplateList>               constantgroups;
4614       SharedPtr<TemplateList>               examples;
4615       SharedPtr<TemplateList>               pages;
4616       SharedPtr<MemberListInfoContext>      macros;
4617       SharedPtr<MemberListInfoContext>      typedefs;
4618       SharedPtr<MemberListInfoContext>      enums;
4619       SharedPtr<MemberListInfoContext>      enumValues;
4620       SharedPtr<MemberListInfoContext>      functions;
4621       SharedPtr<MemberListInfoContext>      variables;
4622       SharedPtr<MemberListInfoContext>      signals;
4623       SharedPtr<MemberListInfoContext>      publicSlots;
4624       SharedPtr<MemberListInfoContext>      protectedSlots;
4625       SharedPtr<MemberListInfoContext>      privateSlots;
4626       SharedPtr<MemberListInfoContext>      events;
4627       SharedPtr<MemberListInfoContext>      properties;
4628       SharedPtr<MemberListInfoContext>      friends;
4629       SharedPtr<MemberGroupListContext>     memberGroups;
4630       SharedPtr<MemberListInfoContext>      detailedMacros;
4631       SharedPtr<MemberListInfoContext>      detailedTypedefs;
4632       SharedPtr<MemberListInfoContext>      detailedEnums;
4633       SharedPtr<MemberListInfoContext>      detailedEnumValues;
4634       SharedPtr<MemberListInfoContext>      detailedFunctions;
4635       SharedPtr<MemberListInfoContext>      detailedVariables;
4636       SharedPtr<MemberListInfoContext>      detailedSignals;
4637       SharedPtr<MemberListInfoContext>      detailedPublicSlots;
4638       SharedPtr<MemberListInfoContext>      detailedProtectedSlots;
4639       SharedPtr<MemberListInfoContext>      detailedPrivateSlots;
4640       SharedPtr<MemberListInfoContext>      detailedEvents;
4641       SharedPtr<MemberListInfoContext>      detailedProperties;
4642       SharedPtr<MemberListInfoContext>      detailedFriends;
4643       SharedPtr<TemplateList>               inlineClasses;
4644       ScopedPtr<DotGroupCollaboration>      groupGraph;
4645     };
4646     mutable Cachable m_cache;
4647 };
4648 //%% }
4649
4650 ModuleContext::ModuleContext(GroupDef *gd) : RefCountedContext("ModuleContext")
4651 {
4652   p = new Private(gd);
4653 }
4654
4655 ModuleContext::~ModuleContext()
4656 {
4657   delete p;
4658 }
4659
4660 TemplateVariant ModuleContext::get(const char *n) const
4661 {
4662   return p->get(n);
4663 }
4664
4665 //------------------------------------------------------------------------
4666
4667 //%% list ClassList[Class] : list of classes
4668 class ClassListContext::Private : public GenericNodeListContext
4669 {
4670   public:
4671     void addClasses(const ClassSDict &classSDict)
4672     {
4673       ClassSDict::Iterator cli(classSDict);
4674       ClassDef *cd;
4675       for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
4676       {
4677         if (cd->getLanguage()==SrcLangExt_VHDL &&
4678             ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
4679              (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
4680            ) // no architecture
4681         {
4682           continue;
4683         }
4684         if (cd->isLinkableInProject() && cd->templateMaster()==0)
4685         {
4686           append(ClassContext::alloc(cd));
4687         }
4688       }
4689     }
4690 };
4691
4692 ClassListContext::ClassListContext() : RefCountedContext("ClassListContext")
4693 {
4694   p = new Private;
4695   p->addClasses(*Doxygen::classSDict);
4696   p->addClasses(*Doxygen::hiddenClasses);
4697 }
4698
4699 ClassListContext::~ClassListContext()
4700 {
4701   delete p;
4702 }
4703
4704 // TemplateListIntf
4705 int ClassListContext::count() const
4706 {
4707   return p->count();
4708 }
4709
4710 TemplateVariant ClassListContext::at(int index) const
4711 {
4712   return p->at(index);
4713 }
4714
4715 TemplateListIntf::ConstIterator *ClassListContext::createIterator() const
4716 {
4717   return p->createIterator();
4718 }
4719
4720 //------------------------------------------------------------------------
4721
4722 //%% list ClassIndex[Class] : list of classes
4723 class ClassIndexContext::Private : public PropertyMapper
4724 {
4725   public:
4726     Private()
4727     {
4728       addProperty("list",        this,&Private::list);
4729       addProperty("fileName",    this,&Private::fileName);
4730       addProperty("relPath",     this,&Private::relPath);
4731       addProperty("highlight",   this,&Private::highlight);
4732       addProperty("subhighlight",this,&Private::subhighlight);
4733       addProperty("title",       this,&Private::title);
4734     }
4735     TemplateVariant list() const
4736     {
4737       if (!m_cache.classes)
4738       {
4739         TemplateList *classList = TemplateList::alloc();
4740         if (Doxygen::classSDict)
4741         {
4742           ClassSDict::Iterator cli(*Doxygen::classSDict);
4743           ClassDef *cd;
4744           for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
4745           {
4746             if (cd->getLanguage()==SrcLangExt_VHDL &&
4747                 ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
4748                  (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
4749                ) // no architecture
4750             {
4751               continue;
4752             }
4753             if (cd->isLinkableInProject() && cd->templateMaster()==0)
4754             {
4755               classList->append(ClassContext::alloc(cd));
4756             }
4757           }
4758         }
4759         m_cache.classes.reset(classList);
4760       }
4761       return m_cache.classes.get();
4762     }
4763     TemplateVariant fileName() const
4764     {
4765       return "classes";
4766     }
4767     TemplateVariant relPath() const
4768     {
4769       return "";
4770     }
4771     TemplateVariant highlight() const
4772     {
4773       return "classes";
4774     }
4775     TemplateVariant subhighlight() const
4776     {
4777       return "classindex";
4778     }
4779     TemplateVariant title() const
4780     {
4781       static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
4782       static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
4783       if (fortranOpt)
4784       {
4785         return theTranslator->trDataTypes();
4786       }
4787       else if (vhdlOpt)
4788       {
4789         return VhdlDocGen::trDesignUnits();
4790       }
4791       else
4792       {
4793         return theTranslator->trCompoundIndex();
4794       }
4795     }
4796   private:
4797     struct Cachable
4798     {
4799       SharedPtr<TemplateList> classes;
4800     };
4801     mutable Cachable m_cache;
4802 };
4803
4804 ClassIndexContext::ClassIndexContext() : RefCountedContext("ClassIndexContext")
4805 {
4806   p = new Private;
4807   //p->addClasses(*Doxygen::hiddenClasses);
4808 }
4809
4810 ClassIndexContext::~ClassIndexContext()
4811 {
4812   delete p;
4813 }
4814
4815 // TemplateStructIntf
4816 TemplateVariant ClassIndexContext::get(const char *n) const
4817 {
4818   return p->get(n);
4819 }
4820
4821 //------------------------------------------------------------------------
4822
4823 //%% struct ClassInheritanceNode: node in inheritance tree
4824 //%% {
4825 class ClassInheritanceNodeContext::Private : public PropertyMapper
4826 {
4827   public:
4828     Private(ClassDef *cd) : m_classDef(cd)
4829     {
4830       //%% bool is_leaf_node: true if this node does not have any children
4831       addProperty("is_leaf_node",this,&Private::isLeafNode);
4832       //%% ClassInheritance children: list of nested classes/namespaces
4833       addProperty("children",this,&Private::children);
4834       //%% Class class: class info
4835       addProperty("class",this,&Private::getClass);
4836     }
4837     void addChildren(const BaseClassList *bcl,bool hideSuper)
4838     {
4839       if (bcl==0) return;
4840       BaseClassListIterator bcli(*bcl);
4841       BaseClassDef *bcd;
4842       for (bcli.toFirst() ; (bcd=bcli.current()) ; ++bcli)
4843       {
4844         ClassDef *cd=bcd->classDef;
4845         if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
4846         {
4847           continue;
4848         }
4849
4850         bool b;
4851         if (cd->getLanguage()==SrcLangExt_VHDL)
4852         {
4853           b=hasVisibleRoot(cd->subClasses());
4854         }
4855         else
4856         {
4857           b=hasVisibleRoot(cd->baseClasses());
4858         }
4859
4860         if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
4861         {
4862           bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
4863           ClassInheritanceNodeContext *tnc = new ClassInheritanceNodeContext(cd);
4864           m_children.append(tnc);
4865           if (hasChildren)
4866           {
4867             //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
4868             bool wasVisited=cd->visited;
4869             cd->visited=TRUE;
4870             if (cd->getLanguage()==SrcLangExt_VHDL)
4871             {
4872               tnc->addChildren(cd->baseClasses(),wasVisited);
4873             }
4874             else
4875             {
4876               tnc->addChildren(cd->subClasses(),wasVisited);
4877             }
4878           }
4879         }
4880       }
4881     }
4882     TemplateVariant isLeafNode() const
4883     {
4884       return m_children.isEmpty();
4885     }
4886     TemplateVariant children() const
4887     {
4888       return TemplateVariant(&m_children);
4889     }
4890     TemplateVariant getClass() const
4891     {
4892       if (!m_cache.classContext)
4893       {
4894         m_cache.classContext.reset(ClassContext::alloc(m_classDef));
4895       }
4896       return m_cache.classContext.get();
4897     }
4898   private:
4899     ClassDef *m_classDef;
4900     GenericNodeListContext m_children;
4901     struct Cachable
4902     {
4903       SharedPtr<ClassContext> classContext;
4904     };
4905     mutable Cachable m_cache;
4906 };
4907 //%% }
4908
4909 ClassInheritanceNodeContext::ClassInheritanceNodeContext(ClassDef *cd) : RefCountedContext("ClassInheritanceNodeContext")
4910 {
4911   p = new Private(cd);
4912 }
4913
4914 ClassInheritanceNodeContext::~ClassInheritanceNodeContext()
4915 {
4916   delete p;
4917 }
4918
4919 TemplateVariant ClassInheritanceNodeContext::get(const char *n) const
4920 {
4921   return p->get(n);
4922 }
4923
4924 void ClassInheritanceNodeContext::addChildren(const BaseClassList *bcl,bool hideSuper)
4925 {
4926   p->addChildren(bcl,hideSuper);
4927 }
4928
4929 //------------------------------------------------------------------------
4930
4931 //%% list ClassInheritance[ClassInheritanceNode]: list of classes
4932 class ClassInheritanceContext::Private : public GenericNodeListContext
4933 {
4934   public:
4935     void addClasses(const ClassSDict &classSDict)
4936     {
4937       ClassSDict::Iterator cli(classSDict);
4938       ClassDef *cd;
4939       for (cli.toFirst();(cd=cli.current());++cli)
4940       {
4941         bool b;
4942         if (cd->getLanguage()==SrcLangExt_VHDL)
4943         {
4944           if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
4945           {
4946             continue;
4947           }
4948           b=!hasVisibleRoot(cd->subClasses());
4949         }
4950         else
4951         {
4952           b=!hasVisibleRoot(cd->baseClasses());
4953         }
4954         if (b)
4955         {
4956           if (cd->isVisibleInHierarchy()) // should it be visible
4957           {
4958             // new root level class
4959             ClassInheritanceNodeContext *tnc = ClassInheritanceNodeContext::alloc(cd);
4960             append(tnc);
4961             bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
4962             if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren)
4963             {
4964               tnc->addChildren(cd->baseClasses(),cd->visited);
4965               cd->visited=TRUE;
4966             }
4967             else if (hasChildren)
4968             {
4969               tnc->addChildren(cd->subClasses(),cd->visited);
4970               cd->visited=TRUE;
4971             }
4972           }
4973         }
4974       }
4975     }
4976 };
4977
4978 ClassInheritanceContext::ClassInheritanceContext() : RefCountedContext("ClassInheritanceContext")
4979 {
4980   p = new Private;
4981   initClassHierarchy(Doxygen::classSDict);
4982   initClassHierarchy(Doxygen::hiddenClasses);
4983   p->addClasses(*Doxygen::classSDict);
4984   p->addClasses(*Doxygen::hiddenClasses);
4985 }
4986
4987 ClassInheritanceContext::~ClassInheritanceContext()
4988 {
4989   delete p;
4990 }
4991
4992 // TemplateListIntf
4993 int ClassInheritanceContext::count() const
4994 {
4995   return (int)p->count();
4996 }
4997
4998 TemplateVariant ClassInheritanceContext::at(int index) const
4999 {
5000   TemplateVariant result;
5001   if (index>=0 && index<count())
5002   {
5003     result = p->at(index);
5004   }
5005   return result;
5006 }
5007
5008 TemplateListIntf::ConstIterator *ClassInheritanceContext::createIterator() const
5009 {
5010   return p->createIterator();
5011 }
5012
5013 //------------------------------------------------------------------------
5014
5015 //%% struct ClassHierarchy: inheritance tree
5016 //%% {
5017 class ClassHierarchyContext::Private : public PropertyMapper
5018 {
5019   public:
5020     TemplateVariant tree() const
5021     {
5022       if (!m_cache.classTree)
5023       {
5024         m_cache.classTree.reset(ClassInheritanceContext::alloc());
5025       }
5026       return m_cache.classTree.get();
5027     }
5028     TemplateVariant fileName() const
5029     {
5030       return "hierarchy";
5031     }
5032     TemplateVariant relPath() const
5033     {
5034       return "";
5035     }
5036     TemplateVariant highlight() const
5037     {
5038       return "classes";
5039     }
5040     TemplateVariant subhighlight() const
5041     {
5042       return "classhierarchy";
5043     }
5044     TemplateVariant title() const
5045     {
5046       static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
5047       if (vhdlOpt)
5048       {
5049         return VhdlDocGen::trDesignUnitHierarchy();
5050       }
5051       else
5052       {
5053         return theTranslator->trClassHierarchy();
5054       }
5055     }
5056     Private()
5057     {
5058       //%% ClassInheritance tree
5059       addProperty("tree",this,&Private::tree);
5060       addProperty("fileName",this,&Private::fileName);
5061       addProperty("relPath",this,&Private::relPath);
5062       addProperty("highlight",this,&Private::highlight);
5063       addProperty("subhighlight",this,&Private::subhighlight);
5064       addProperty("title",this,&Private::title);
5065     }
5066   private:
5067     struct Cachable
5068     {
5069       SharedPtr<ClassInheritanceContext> classTree;
5070     };
5071     mutable Cachable m_cache;
5072 };
5073 //%% }
5074
5075 ClassHierarchyContext::ClassHierarchyContext() : RefCountedContext("ClassHierarchyContext")
5076 {
5077   p = new Private;
5078 }
5079
5080 ClassHierarchyContext::~ClassHierarchyContext()
5081 {
5082   delete p;
5083 }
5084
5085 TemplateVariant ClassHierarchyContext::get(const char *name) const
5086 {
5087   return p->get(name);
5088 }
5089
5090 //------------------------------------------------------------------------
5091
5092 //%% struct NestingNode: node is a nesting relation tree
5093 //%% {
5094 class NestingNodeContext::Private : public PropertyMapper
5095 {
5096   public:
5097     Private(const NestingNodeContext *parent,const NestingNodeContext *thisNode,
5098         Definition *d,int index,int level,bool addCls)
5099       : m_parent(parent), m_def(d), m_level(level), m_index(index)
5100     {
5101       m_children.reset(NestingContext::alloc(thisNode,level+1));
5102       //%% bool is_leaf_node: true if this node does not have any children
5103       addProperty("is_leaf_node",this,&Private::isLeafNode);
5104       //%% Nesting children: list of nested classes/namespaces
5105       addProperty("children",this,&Private::children);
5106       //%% [optional] Class class: class info (if this node represents a class)
5107       addProperty("class",this,&Private::getClass);
5108       //%% [optional] Namespace namespace: namespace info (if this node represents a namespace)
5109       addProperty("namespace",this,&Private::getNamespace);
5110       //%% [optional] File file: file info (if this node represents a file)
5111       addProperty("file",this,&Private::getFile);
5112       //%% [optional] Dir dir: directory info (if this node represents a directory)
5113       addProperty("dir",this,&Private::getDir);
5114       //%% [optional] Page page: page info (if this node represents a page)
5115       addProperty("page",this,&Private::getPage);
5116       //%% [optional] Module module: module info (if this node represents a module)
5117       addProperty("module",this,&Private::getModule);
5118       //%% int id
5119       addProperty("id",this,&Private::id);
5120       //%% string level
5121       addProperty("level",this,&Private::level);
5122       //%% string name
5123       addProperty("name",this,&Private::name);
5124       //%% string brief
5125       addProperty("brief",this,&Private::brief);
5126       //%% bool isLinkable
5127       addProperty("isLinkable",this,&Private::isLinkable);
5128       addProperty("anchor",this,&Private::anchor);
5129       addProperty("fileName",this,&Private::fileName);
5130
5131       addNamespaces(addCls);
5132       addClasses();
5133       addDirFiles();
5134       addPages();
5135       addModules();
5136     }
5137     TemplateVariant isLeafNode() const
5138     {
5139       return m_children->count()==0;
5140     }
5141     TemplateVariant children() const
5142     {
5143       return m_children.get();
5144     }
5145     TemplateVariant getClass() const
5146     {
5147       if (!m_cache.classContext && m_def->definitionType()==Definition::TypeClass)
5148       {
5149         m_cache.classContext.reset(ClassContext::alloc((ClassDef*)m_def));
5150       }
5151       if (m_cache.classContext)
5152       {
5153         return m_cache.classContext.get();
5154       }
5155       else
5156       {
5157         return TemplateVariant(FALSE);
5158       }
5159     }
5160     TemplateVariant getNamespace() const
5161     {
5162       if (!m_cache.namespaceContext && m_def->definitionType()==Definition::TypeNamespace)
5163       {
5164         m_cache.namespaceContext.reset(NamespaceContext::alloc((NamespaceDef*)m_def));
5165       }
5166       if (m_cache.namespaceContext)
5167       {
5168         return m_cache.namespaceContext.get();
5169       }
5170       else
5171       {
5172         return TemplateVariant(FALSE);
5173       }
5174     }
5175     TemplateVariant getDir() const
5176     {
5177       if (!m_cache.dirContext && m_def->definitionType()==Definition::TypeDir)
5178       {
5179         m_cache.dirContext.reset(DirContext::alloc((DirDef*)m_def));
5180       }
5181       if (m_cache.dirContext)
5182       {
5183         return m_cache.dirContext.get();
5184       }
5185       else
5186       {
5187         return TemplateVariant(FALSE);
5188       }
5189     }
5190     TemplateVariant getFile() const
5191     {
5192       if (!m_cache.fileContext && m_def->definitionType()==Definition::TypeFile)
5193       {
5194         m_cache.fileContext.reset(FileContext::alloc((FileDef*)m_def));
5195       }
5196       if (m_cache.fileContext)
5197       {
5198         return m_cache.fileContext.get();
5199       }
5200       else
5201       {
5202         return TemplateVariant(FALSE);
5203       }
5204     }
5205     TemplateVariant getPage() const
5206     {
5207       if (!m_cache.pageContext && m_def->definitionType()==Definition::TypePage)
5208       {
5209         m_cache.pageContext.reset(PageContext::alloc((PageDef*)m_def));
5210       }
5211       if (m_cache.pageContext)
5212       {
5213         return m_cache.pageContext.get();
5214       }
5215       else
5216       {
5217         return TemplateVariant(FALSE);
5218       }
5219     }
5220     TemplateVariant getModule() const
5221     {
5222       if (!m_cache.moduleContext && m_def->definitionType()==Definition::TypeGroup)
5223       {
5224         m_cache.moduleContext.reset(ModuleContext::alloc((GroupDef*)m_def));
5225       }
5226       if (m_cache.moduleContext)
5227       {
5228         return m_cache.moduleContext.get();
5229       }
5230       else
5231       {
5232         return TemplateVariant(FALSE);
5233       }
5234     }
5235     TemplateVariant level() const
5236     {
5237       return m_level;
5238     }
5239     TemplateVariant id() const
5240     {
5241       QCString result;
5242       if (m_parent) result=m_parent->id();
5243       result+=QCString().setNum(m_index)+"_";
5244       return result;
5245     }
5246     TemplateVariant name() const
5247     {
5248       return m_def->displayName(FALSE);
5249     }
5250     QCString relPathAsString() const
5251     {
5252       static bool createSubdirs = Config_getBool("CREATE_SUBDIRS");
5253       return createSubdirs ? QCString("../../") : QCString("");
5254     }
5255     TemplateVariant brief() const
5256     {
5257       if (!m_cache.brief)
5258       {
5259         if (m_def->hasBriefDescription())
5260         {
5261           m_cache.brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(),
5262                               "",m_def->briefDescription(),TRUE)));
5263         }
5264         else
5265         {
5266           m_cache.brief.reset(new TemplateVariant(""));
5267         }
5268       }
5269       return *m_cache.brief;
5270     }
5271     TemplateVariant isLinkable() const
5272     {
5273       return m_def->isLinkable();
5274     }
5275     TemplateVariant anchor() const
5276     {
5277       return m_def->anchor();
5278     }
5279     TemplateVariant fileName() const
5280     {
5281       return m_def->getOutputFileBase();
5282     }
5283
5284     void addClasses()
5285     {
5286       ClassDef *cd = m_def->definitionType()==Definition::TypeClass ? (ClassDef*)m_def : 0;
5287       if (cd && cd->getClassSDict())
5288       {
5289         m_children->addClasses(*cd->getClassSDict(),FALSE);
5290       }
5291     }
5292     void addNamespaces(bool addClasses)
5293     {
5294       NamespaceDef *nd = m_def->definitionType()==Definition::TypeNamespace ? (NamespaceDef*)m_def : 0;
5295       if (nd && nd->getNamespaceSDict())
5296       {
5297         m_children->addNamespaces(*nd->getNamespaceSDict(),FALSE,addClasses);
5298       }
5299       if (addClasses && nd && nd->getClassSDict())
5300       {
5301         m_children->addClasses(*nd->getClassSDict(),FALSE);
5302       }
5303     }
5304     void addDirFiles()
5305     {
5306       DirDef *dd = m_def->definitionType()==Definition::TypeDir ? (DirDef*)m_def : 0;
5307       if (dd)
5308       {
5309         m_children->addDirs(dd->subDirs());
5310         if (dd && dd->getFiles())
5311         {
5312           m_children->addFiles(*dd->getFiles());
5313         }
5314       }
5315     }
5316     void addPages()
5317     {
5318       PageDef *pd = m_def->definitionType()==Definition::TypePage ? (PageDef*)m_def : 0;
5319       if (pd && pd->getSubPages())
5320       {
5321         m_children->addPages(*pd->getSubPages(),FALSE);
5322       }
5323     }
5324     void addModules()
5325     {
5326       GroupDef *gd = m_def->definitionType()==Definition::TypeGroup ? (GroupDef*)m_def : 0;
5327       if (gd && gd->getSubGroups())
5328       {
5329         m_children->addModules(*gd->getSubGroups());
5330       }
5331     }
5332   private:
5333     const NestingNodeContext *m_parent;
5334     Definition *m_def;
5335     SharedPtr<NestingContext> m_children;
5336     int m_level;
5337     int m_index;
5338     struct Cachable
5339     {
5340       SharedPtr<ClassContext>     classContext;
5341       SharedPtr<NamespaceContext> namespaceContext;
5342       SharedPtr<DirContext>       dirContext;
5343       SharedPtr<FileContext>      fileContext;
5344       SharedPtr<PageContext>      pageContext;
5345       SharedPtr<ModuleContext>    moduleContext;
5346       ScopedPtr<TemplateVariant>  brief;
5347     };
5348     mutable Cachable m_cache;
5349 };
5350 //%% }
5351
5352 NestingNodeContext::NestingNodeContext(const NestingNodeContext *parent,
5353                                        Definition *d,int index,int level,bool addClass) : RefCountedContext("NestingNodeContext")
5354 {
5355   p = new Private(parent,this,d,index,level,addClass);
5356 }
5357
5358 NestingNodeContext::~NestingNodeContext()
5359 {
5360   delete p;
5361 }
5362
5363 TemplateVariant NestingNodeContext::get(const char *n) const
5364 {
5365   return p->get(n);
5366 }
5367
5368 QCString NestingNodeContext::id() const
5369 {
5370   return p->id().toString();
5371 }
5372
5373 //------------------------------------------------------------------------
5374
5375 //%% list Nesting[NestingNode]: namespace and class nesting relations
5376 class NestingContext::Private : public GenericNodeListContext
5377 {
5378   public:
5379     Private(const NestingNodeContext *parent,int level)
5380       : m_parent(parent), m_level(level), m_index(0) {}
5381
5382     void addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses)
5383     {
5384       NamespaceSDict::Iterator nli(nsDict);
5385       NamespaceDef *nd;
5386       for (nli.toFirst();(nd=nli.current());++nli)
5387       {
5388         if (nd->localName().find('@')==-1 &&
5389             (!rootOnly || nd->getOuterScope()==Doxygen::globalScope))
5390         {
5391           bool hasChildren = namespaceHasVisibleChild(nd,addClasses);
5392           bool isLinkable  = nd->isLinkableInProject();
5393           if (isLinkable || hasChildren)
5394           {
5395             NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,nd,m_index,m_level,addClasses);
5396             append(nnc);
5397             m_index++;
5398           }
5399         }
5400       }
5401     }
5402     void addClasses(const ClassSDict &clDict,bool rootOnly)
5403     {
5404       ClassSDict::Iterator cli(clDict);
5405       ClassDef *cd;
5406       for (;(cd=cli.current());++cli)
5407       {
5408         if (cd->getLanguage()==SrcLangExt_VHDL)
5409         {
5410           if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
5411               (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS
5412              )// no architecture
5413           {
5414             continue;
5415           }
5416         }
5417         if (!rootOnly ||
5418             cd->getOuterScope()==0 ||
5419             cd->getOuterScope()==Doxygen::globalScope
5420            )
5421         {
5422           if (classVisibleInIndex(cd) && cd->templateMaster()==0)
5423           {
5424             NestingNodeContext *nnc = NestingNodeContext::alloc(m_parent,cd,m_index,m_level,TRUE);
5425             append(nnc);
5426             m_index++;
5427           }
5428         }
5429       }
5430     }
5431     void addDirs(const DirSDict &dirDict)
5432     {
5433       SDict<DirDef>::Iterator dli(dirDict);
5434       DirDef *dd;
5435       for (dli.toFirst();(dd=dli.current());++dli)
5436       {
5437         if (dd->getOuterScope()==Doxygen::globalScope)
5438         {
5439           append(NestingNodeContext::alloc(m_parent,dd,m_index,m_level,FALSE));
5440           m_index++;
5441         }
5442       }
5443     }
5444     void addDirs(const DirList &dirList)
5445     {
5446       QListIterator<DirDef> li(dirList);
5447       DirDef *dd;
5448       for (li.toFirst();(dd=li.current());++li)
5449       {
5450         append(NestingNodeContext::alloc(m_parent,dd,m_index,m_level,FALSE));
5451         m_index++;
5452       }
5453     }
5454     void addFiles(const FileNameList &fnList)
5455     {
5456       FileNameListIterator fnli(fnList);
5457       FileName *fn;
5458       for (fnli.toFirst();(fn=fnli.current());++fnli)
5459       {
5460         FileNameIterator fni(*fn);
5461         FileDef *fd;
5462         for (;(fd=fni.current());++fni)
5463         {
5464           if (fd->getDirDef()==0) // top level file
5465           {
5466             append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE));
5467             m_index++;
5468           }
5469         }
5470       }
5471     }
5472     void addFiles(const FileList &fList)
5473     {
5474       QListIterator<FileDef> li(fList);
5475       FileDef *fd;
5476       for (li.toFirst();(fd=li.current());++li)
5477       {
5478         append(NestingNodeContext::alloc(m_parent,fd,m_index,m_level,FALSE));
5479         m_index++;
5480       }
5481     }
5482     void addPages(const PageSDict &pages,bool rootOnly)
5483     {
5484       SDict<PageDef>::Iterator pli(pages);
5485       PageDef *pd;
5486       for (pli.toFirst();(pd=pli.current());++pli)
5487       {
5488         if (!rootOnly ||
5489             pd->getOuterScope()==0 ||
5490             pd->getOuterScope()->definitionType()!=Definition::TypePage)
5491         {
5492           append(NestingNodeContext::alloc(m_parent,pd,m_index,m_level,FALSE));
5493           m_index++;
5494         }
5495       }
5496     }
5497     void addModules(const GroupSDict &groups)
5498     {
5499       GroupSDict::Iterator gli(groups);
5500       GroupDef *gd;
5501       for (gli.toFirst();(gd=gli.current());++gli)
5502       {
5503         static bool externalGroups = Config_getBool("EXTERNAL_GROUPS");
5504         if (!gd->isASubGroup() && gd->isVisible() &&
5505              (!gd->isReference() || externalGroups)
5506            )
5507         {
5508           append(NestingNodeContext::alloc(m_parent,gd,m_index,m_level,FALSE));
5509           m_index++;
5510         }
5511       }
5512     }
5513     void addModules(const GroupList &list)
5514     {
5515       GroupListIterator gli(list);
5516       GroupDef *gd;
5517       for (gli.toFirst();(gd=gli.current());++gli)
5518       {
5519         if (gd->isVisible())
5520         {
5521           append(NestingNodeContext::alloc(m_parent,gd,m_index,m_level,FALSE));
5522           m_index++;
5523         }
5524       }
5525     }
5526   private:
5527     const NestingNodeContext *m_parent;
5528     int m_level;
5529     int m_index;
5530 };
5531
5532 NestingContext::NestingContext(const NestingNodeContext *parent,int level) : RefCountedContext("NestingContext")
5533 {
5534   p = new Private(parent,level);
5535 }
5536
5537 NestingContext::~NestingContext()
5538 {
5539   delete p;
5540 }
5541
5542 // TemplateListIntf
5543 int NestingContext::count() const
5544 {
5545   return p->count();
5546 }
5547
5548 TemplateVariant NestingContext::at(int index) const
5549 {
5550   return p->at(index);
5551 }
5552
5553 TemplateListIntf::ConstIterator *NestingContext::createIterator() const
5554 {
5555   return p->createIterator();
5556 }
5557
5558 void NestingContext::addClasses(const ClassSDict &clDict,bool rootOnly)
5559 {
5560   p->addClasses(clDict,rootOnly);
5561 }
5562
5563 void NestingContext::addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses)
5564 {
5565   p->addNamespaces(nsDict,rootOnly,addClasses);
5566 }
5567
5568 void NestingContext::addDirs(const DirSDict &dirs)
5569 {
5570   p->addDirs(dirs);
5571 }
5572
5573 void NestingContext::addDirs(const DirList &dirs)
5574 {
5575   p->addDirs(dirs);
5576 }
5577
5578 void NestingContext::addFiles(const FileNameList &files)
5579 {
5580   p->addFiles(files);
5581 }
5582
5583 void NestingContext::addFiles(const FileList &files)
5584 {
5585   p->addFiles(files);
5586 }
5587
5588 void NestingContext::addPages(const PageSDict &pages,bool rootOnly)
5589 {
5590   p->addPages(pages,rootOnly);
5591 }
5592
5593 void NestingContext::addModules(const GroupSDict &modules)
5594 {
5595   p->addModules(modules);
5596 }
5597
5598 void NestingContext::addModules(const GroupList &modules)
5599 {
5600   p->addModules(modules);
5601 }
5602
5603 //------------------------------------------------------------------------
5604
5605 static int computeMaxDepth(const TemplateListIntf *list)
5606 {
5607   int maxDepth=0;
5608   if (list)
5609   {
5610     TemplateListIntf::ConstIterator *it = list->createIterator();
5611     TemplateVariant v;
5612     for (it->toFirst();it->current(v);it->toNext())
5613     {
5614       const TemplateStructIntf *s = v.toStruct();
5615       TemplateVariant child = s->get("children");
5616       int d = computeMaxDepth(child.toList())+1;
5617       if (d>maxDepth) maxDepth=d;
5618     }
5619     delete it;
5620   }
5621   return maxDepth;
5622 }
5623
5624 static int computeNumNodesAtLevel(const TemplateStructIntf *s,int level,int maxLevel)
5625 {
5626   int num=0;
5627   if (level<maxLevel)
5628   {
5629     num++;
5630     TemplateVariant child = s->get("children");
5631     if (child.toList())
5632     {
5633       TemplateListIntf::ConstIterator *it = child.toList()->createIterator();
5634       TemplateVariant v;
5635       for (it->toFirst();it->current(v);it->toNext())
5636       {
5637         num+=computeNumNodesAtLevel(v.toStruct(),level+1,maxLevel);
5638       }
5639       delete it;
5640     }
5641   }
5642   return num;
5643 }
5644
5645 static int computePreferredDepth(const TemplateListIntf *list,int maxDepth)
5646 {
5647   int preferredNumEntries = Config_getInt("HTML_INDEX_NUM_ENTRIES");
5648   int preferredDepth=1;
5649   if (preferredNumEntries>0)
5650   {
5651     int depth = maxDepth;
5652     for (int i=1;i<=depth;i++)
5653     {
5654       int num=0;
5655       TemplateListIntf::ConstIterator *it = list->createIterator();
5656       TemplateVariant v;
5657       for (it->toFirst();it->current(v);it->toNext())
5658       {
5659         num+=computeNumNodesAtLevel(v.toStruct(),0,i);
5660       }
5661       delete it;
5662       if (num<=preferredNumEntries)
5663       {
5664         preferredDepth=i;
5665       }
5666       else
5667       {
5668         break;
5669       }
5670     }
5671   }
5672   return preferredDepth;
5673 }
5674
5675
5676 //%% struct ClassTree: Class nesting relations
5677 //%% {
5678 class ClassTreeContext::Private : public PropertyMapper
5679 {
5680   public:
5681     Private()
5682     {
5683       m_classTree.reset(NestingContext::alloc(0,0));
5684       if (Doxygen::namespaceSDict)
5685       {
5686         m_classTree->addNamespaces(*Doxygen::namespaceSDict,TRUE,TRUE);
5687       }
5688       if (Doxygen::classSDict)
5689       {
5690         m_classTree->addClasses(*Doxygen::classSDict,TRUE);
5691       }
5692       //%% Nesting tree
5693       addProperty("tree",this,&Private::tree);
5694       addProperty("fileName",this,&Private::fileName);
5695       addProperty("relPath",this,&Private::relPath);
5696       addProperty("highlight",this,&Private::highlight);
5697       addProperty("subhighlight",this,&Private::subhighlight);
5698       addProperty("title",this,&Private::title);
5699       addProperty("preferredDepth",this,&Private::preferredDepth);
5700       addProperty("maxDepth",this,&Private::maxDepth);
5701     }
5702     TemplateVariant tree() const
5703     {
5704       return m_classTree.get();
5705     }
5706     TemplateVariant fileName() const
5707     {
5708       return "annotated";
5709     }
5710     TemplateVariant relPath() const
5711     {
5712       return "";
5713     }
5714     TemplateVariant highlight() const
5715     {
5716       return "classes";
5717     }
5718     TemplateVariant subhighlight() const
5719     {
5720       return "classlist";
5721     }
5722     TemplateVariant title() const
5723     {
5724       static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
5725       static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
5726       if (fortranOpt)
5727       {
5728         return theTranslator->trCompoundListFortran();
5729       }
5730       else if (vhdlOpt)
5731       {
5732         return VhdlDocGen::trDesignUnitList();
5733       }
5734       else
5735       {
5736         return theTranslator->trClasses();
5737       }
5738     }
5739     TemplateVariant maxDepth() const
5740     {
5741       if (!m_cache.maxDepthComputed)
5742       {
5743         m_cache.maxDepth = computeMaxDepth(m_classTree.get());
5744         m_cache.maxDepthComputed=TRUE;
5745       }
5746       return m_cache.maxDepth;
5747     }
5748     TemplateVariant preferredDepth() const
5749     {
5750       if (!m_cache.preferredDepthComputed)
5751       {
5752         m_cache.preferredDepth = computePreferredDepth(m_classTree.get(),maxDepth().toInt());
5753         m_cache.preferredDepthComputed=TRUE;
5754       }
5755       return m_cache.preferredDepth;
5756     }
5757   private:
5758     SharedPtr<NestingContext> m_classTree;
5759     struct Cachable
5760     {
5761       Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
5762       int   maxDepth;
5763       bool  maxDepthComputed;
5764       int   preferredDepth;
5765       bool  preferredDepthComputed;
5766     };
5767     mutable Cachable m_cache;
5768 };
5769 //%% }
5770
5771 ClassTreeContext::ClassTreeContext() : RefCountedContext("ClassTreeContext")
5772 {
5773   p = new Private;
5774 }
5775
5776 ClassTreeContext::~ClassTreeContext()
5777 {
5778   delete p;
5779 }
5780
5781 TemplateVariant ClassTreeContext::get(const char *name) const
5782 {
5783   return p->get(name);
5784 }
5785
5786 //------------------------------------------------------------------------
5787
5788 //%% list NamespaceList[Namespace] : list of namespaces
5789 class NamespaceListContext::Private : public GenericNodeListContext
5790 {
5791   public:
5792     void addNamespaces(const NamespaceSDict &nsDict)
5793     {
5794       NamespaceSDict::Iterator nli(nsDict);
5795       NamespaceDef *nd;
5796       for (nli.toFirst();(nd=nli.current());++nli)
5797       {
5798         if (nd->isLinkableInProject())
5799         {
5800           append(NamespaceContext::alloc(nd));
5801         }
5802       }
5803     }
5804 };
5805
5806 NamespaceListContext::NamespaceListContext() : RefCountedContext("NamespaceListContext")
5807 {
5808   p = new Private;
5809   p->addNamespaces(*Doxygen::namespaceSDict);
5810 }
5811
5812 NamespaceListContext::~NamespaceListContext()
5813 {
5814   delete p;
5815 }
5816
5817 // TemplateListIntf
5818 int NamespaceListContext::count() const
5819 {
5820   return p->count();
5821 }
5822
5823 TemplateVariant NamespaceListContext::at(int index) const
5824 {
5825   return p->at(index);
5826 }
5827
5828 TemplateListIntf::ConstIterator *NamespaceListContext::createIterator() const
5829 {
5830   return p->createIterator();
5831 }
5832
5833 //------------------------------------------------------------------------
5834
5835 //%% struct NamespaceTree: tree of nested namespace
5836 //%% {
5837 class NamespaceTreeContext::Private : public PropertyMapper
5838 {
5839   public:
5840     Private()
5841     {
5842       m_namespaceTree.reset(NestingContext::alloc(0,0));
5843       if (Doxygen::namespaceSDict)
5844       {
5845         m_namespaceTree->addNamespaces(*Doxygen::namespaceSDict,TRUE,FALSE);
5846       }
5847       //%% Nesting tree
5848       addProperty("tree",this,&Private::tree);
5849       addProperty("fileName",this,&Private::fileName);
5850       addProperty("relPath",this,&Private::relPath);
5851       addProperty("highlight",this,&Private::highlight);
5852       addProperty("subhighlight",this,&Private::subhighlight);
5853       addProperty("title",this,&Private::title);
5854       addProperty("preferredDepth",this,&Private::preferredDepth);
5855       addProperty("maxDepth",this,&Private::maxDepth);
5856     }
5857     TemplateVariant tree() const
5858     {
5859       return m_namespaceTree.get();
5860     }
5861     TemplateVariant fileName() const
5862     {
5863       return "namespaces";
5864     }
5865     TemplateVariant relPath() const
5866     {
5867       return "";
5868     }
5869     TemplateVariant highlight() const
5870     {
5871       return "namespaces";
5872     }
5873     TemplateVariant subhighlight() const
5874     {
5875       return "namespacelist";
5876     }
5877     TemplateVariant title() const
5878     {
5879       static bool javaOpt    = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
5880       static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
5881       static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
5882       if (javaOpt || vhdlOpt)
5883       {
5884         return theTranslator->trPackages();
5885       }
5886       else if (fortranOpt)
5887       {
5888         return theTranslator->trModulesList();
5889       }
5890       else
5891       {
5892         return theTranslator->trNamespaceList();
5893       }
5894     }
5895     TemplateVariant maxDepth() const
5896     {
5897       if (!m_cache.maxDepthComputed)
5898       {
5899         m_cache.maxDepth = computeMaxDepth(m_namespaceTree.get());
5900         m_cache.maxDepthComputed=TRUE;
5901       }
5902       return m_cache.maxDepth;
5903     }
5904     TemplateVariant preferredDepth() const
5905     {
5906       if (!m_cache.preferredDepthComputed)
5907       {
5908         m_cache.preferredDepth = computePreferredDepth(m_namespaceTree.get(),maxDepth().toInt());
5909         m_cache.preferredDepthComputed=TRUE;
5910       }
5911       return m_cache.preferredDepth;
5912     }
5913   private:
5914     SharedPtr<NestingContext> m_namespaceTree;
5915     struct Cachable
5916     {
5917       Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
5918       int   maxDepth;
5919       bool  maxDepthComputed;
5920       int   preferredDepth;
5921       bool  preferredDepthComputed;
5922     };
5923     mutable Cachable m_cache;
5924 };
5925 //%% }
5926
5927 NamespaceTreeContext::NamespaceTreeContext() : RefCountedContext("NamespaceTreeContext")
5928 {
5929   p = new Private;
5930 }
5931
5932 NamespaceTreeContext::~NamespaceTreeContext()
5933 {
5934   delete p;
5935 }
5936
5937 TemplateVariant NamespaceTreeContext::get(const char *name) const
5938 {
5939   return p->get(name);
5940 }
5941
5942 //------------------------------------------------------------------------
5943
5944 //%% list FileList[File] : list of files
5945 class FileListContext::Private : public GenericNodeListContext
5946 {
5947   public:
5948     void addFiles(const FileNameList &fnList)
5949     {
5950       // TODO: if FULL_PATH_NAMES is enabled, the ordering should be dir+file
5951       FileNameListIterator fnli(fnList);
5952       FileName *fn;
5953       for (fnli.toFirst();(fn=fnli.current());++fnli)
5954       {
5955         FileNameIterator fni(*fn);
5956         FileDef *fd;
5957         for (fni.toFirst();(fd=fni.current());++fni)
5958         {
5959           bool doc = fd->isLinkableInProject();
5960           bool src = fd->generateSourceFile();
5961           bool nameOk = !fd->isDocumentationFile();
5962           if (nameOk && (doc || src) && !fd->isReference())
5963           {
5964             append(FileContext::alloc(fd));
5965           }
5966         }
5967       }
5968     }
5969 };
5970
5971 FileListContext::FileListContext() : RefCountedContext("FileListContext")
5972 {
5973   p = new Private;
5974   if (Doxygen::inputNameList) p->addFiles(*Doxygen::inputNameList);
5975 }
5976
5977 FileListContext::~FileListContext()
5978 {
5979   delete p;
5980 }
5981
5982 // TemplateListIntf
5983 int FileListContext::count() const
5984 {
5985   return p->count();
5986 }
5987
5988 TemplateVariant FileListContext::at(int index) const
5989 {
5990   return p->at(index);
5991 }
5992
5993 TemplateListIntf::ConstIterator *FileListContext::createIterator() const
5994 {
5995   return p->createIterator();
5996 }
5997
5998 //------------------------------------------------------------------------
5999
6000 //%% list DirList[Dir] : list of files
6001 class DirListContext::Private : public GenericNodeListContext
6002 {
6003   public:
6004     Private()
6005     {
6006       DirDef *dir;
6007       DirSDict::Iterator sdi(*Doxygen::directories);
6008       for (sdi.toFirst();(dir=sdi.current());++sdi)
6009       {
6010         append(DirContext::alloc(dir));
6011       }
6012     }
6013 };
6014
6015 DirListContext::DirListContext() : RefCountedContext("DirListContext")
6016 {
6017   p = new Private;
6018 }
6019
6020 DirListContext::~DirListContext()
6021 {
6022   delete p;
6023 }
6024
6025 // TemplateListIntf
6026 int DirListContext::count() const
6027 {
6028   return p->count();
6029 }
6030
6031 TemplateVariant DirListContext::at(int index) const
6032 {
6033   return p->at(index);
6034 }
6035
6036 TemplateListIntf::ConstIterator *DirListContext::createIterator() const
6037 {
6038   return p->createIterator();
6039 }
6040
6041
6042 //------------------------------------------------------------------------
6043
6044 //%% list UsedFiles[File] : list of files
6045 class UsedFilesContext::Private : public GenericNodeListContext
6046 {
6047   public:
6048     void addFile(FileDef *fd)
6049     {
6050       append(FileContext::alloc(fd));
6051     }
6052 };
6053
6054 UsedFilesContext::UsedFilesContext(ClassDef *cd) : RefCountedContext("UsedFilesContext")
6055 {
6056   p = new Private;
6057   if (cd)
6058   {
6059     QListIterator<FileDef> li(cd->usedFiles());
6060     FileDef *fd;
6061     for (li.toFirst();(fd=li.current());++li)
6062     {
6063       p->addFile(fd);
6064     }
6065   }
6066 }
6067
6068 UsedFilesContext::~UsedFilesContext()
6069 {
6070   delete p;
6071 }
6072
6073 // TemplateListIntf
6074 int UsedFilesContext::count() const
6075 {
6076   return p->count();
6077 }
6078
6079 TemplateVariant UsedFilesContext::at(int index) const
6080 {
6081   return p->at(index);
6082 }
6083
6084 TemplateListIntf::ConstIterator *UsedFilesContext::createIterator() const
6085 {
6086   return p->createIterator();
6087 }
6088
6089 void UsedFilesContext::addFile(FileDef *fd)
6090 {
6091   p->addFile(fd);
6092 }
6093
6094 //------------------------------------------------------------------------
6095
6096 //%% struct FileTree: tree of directories and files
6097 //%% {
6098 class FileTreeContext::Private : public PropertyMapper
6099 {
6100   public:
6101     Private()
6102     {
6103       // Add dirs tree
6104       m_dirFileTree.reset(NestingContext::alloc(0,0));
6105       if (Doxygen::directories)
6106       {
6107         m_dirFileTree->addDirs(*Doxygen::directories);
6108       }
6109       if (Doxygen::inputNameList)
6110       {
6111         m_dirFileTree->addFiles(*Doxygen::inputNameList);
6112       }
6113       //%% DirFile tree:
6114       addProperty("tree",this,&Private::tree);
6115       addProperty("fileName",this,&Private::fileName);
6116       addProperty("relPath",this,&Private::relPath);
6117       addProperty("highlight",this,&Private::highlight);
6118       addProperty("subhighlight",this,&Private::subhighlight);
6119       addProperty("title",this,&Private::title);
6120       addProperty("preferredDepth",this,&Private::preferredDepth);
6121       addProperty("maxDepth",this,&Private::maxDepth);
6122     }
6123     TemplateVariant tree() const
6124     {
6125       return m_dirFileTree.get();
6126     }
6127     TemplateVariant fileName() const
6128     {
6129       return "files";
6130     }
6131     TemplateVariant relPath() const
6132     {
6133       return "";
6134     }
6135     TemplateVariant highlight() const
6136     {
6137       return "files";
6138     }
6139     TemplateVariant subhighlight() const
6140     {
6141       return "filelist";
6142     }
6143     TemplateVariant title() const
6144     {
6145       return theTranslator->trFileList();
6146     }
6147     TemplateVariant maxDepth() const
6148     {
6149       if (!m_cache.maxDepthComputed)
6150       {
6151         m_cache.maxDepth = computeMaxDepth(m_dirFileTree.get());
6152         m_cache.maxDepthComputed=TRUE;
6153       }
6154       return m_cache.maxDepth;
6155     }
6156     TemplateVariant preferredDepth() const
6157     {
6158       if (!m_cache.preferredDepthComputed)
6159       {
6160         m_cache.preferredDepth = computePreferredDepth(m_dirFileTree.get(),maxDepth().toInt());
6161         m_cache.preferredDepthComputed=TRUE;
6162       }
6163       return m_cache.preferredDepth;
6164     }
6165   private:
6166     SharedPtr<NestingContext> m_dirFileTree;
6167     struct Cachable
6168     {
6169       Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
6170       int   maxDepth;
6171       bool  maxDepthComputed;
6172       int   preferredDepth;
6173       bool  preferredDepthComputed;
6174     };
6175     mutable Cachable m_cache;
6176 };
6177 //%% }
6178
6179 FileTreeContext::FileTreeContext() : RefCountedContext("FileTreeContext")
6180 {
6181   p = new Private;
6182 }
6183
6184 FileTreeContext::~FileTreeContext()
6185 {
6186   delete p;
6187 }
6188
6189 TemplateVariant FileTreeContext::get(const char *name) const
6190 {
6191   return p->get(name);
6192 }
6193
6194 //------------------------------------------------------------------------
6195
6196 //%% struct PageTree: tree of related pages
6197 //%% {
6198 class PageTreeContext::Private : public PropertyMapper
6199 {
6200   public:
6201     Private()
6202     {
6203       m_pageTree.reset(NestingContext::alloc(0,0));
6204       // Add pages
6205       if (Doxygen::pageSDict)
6206       {
6207         m_pageTree->addPages(*Doxygen::pageSDict,TRUE);
6208       }
6209
6210       //%% PageNodeList tree:
6211       addProperty("tree",this,&Private::tree);
6212       addProperty("fileName",this,&Private::fileName);
6213       addProperty("relPath",this,&Private::relPath);
6214       addProperty("highlight",this,&Private::highlight);
6215       addProperty("subhighlight",this,&Private::subhighlight);
6216       addProperty("title",this,&Private::title);
6217       addProperty("preferredDepth",this,&Private::preferredDepth);
6218       addProperty("maxDepth",this,&Private::maxDepth);
6219     }
6220     TemplateVariant tree() const
6221     {
6222       return m_pageTree.get();
6223     }
6224     TemplateVariant fileName() const
6225     {
6226       return "pages";
6227     }
6228     TemplateVariant relPath() const
6229     {
6230       return "";
6231     }
6232     TemplateVariant highlight() const
6233     {
6234       return "pages";
6235     }
6236     TemplateVariant subhighlight() const
6237     {
6238       return "";
6239     }
6240     TemplateVariant title() const
6241     {
6242       return theTranslator->trRelatedPages();
6243     }
6244     TemplateVariant maxDepth() const
6245     {
6246       if (!m_cache.maxDepthComputed)
6247       {
6248         m_cache.maxDepth = computeMaxDepth(m_pageTree.get());
6249         m_cache.maxDepthComputed=TRUE;
6250       }
6251       return m_cache.maxDepth;
6252     }
6253     TemplateVariant preferredDepth() const
6254     {
6255       if (!m_cache.preferredDepthComputed)
6256       {
6257         m_cache.preferredDepth = computePreferredDepth(m_pageTree.get(),maxDepth().toInt());
6258         m_cache.preferredDepthComputed=TRUE;
6259       }
6260       return m_cache.preferredDepth;
6261     }
6262   private:
6263     SharedPtr<NestingContext> m_pageTree;
6264     struct Cachable
6265     {
6266       Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
6267       int   maxDepth;
6268       bool  maxDepthComputed;
6269       int   preferredDepth;
6270       bool  preferredDepthComputed;
6271     };
6272     mutable Cachable m_cache;
6273 };
6274 //%% }
6275
6276 PageTreeContext::PageTreeContext() : RefCountedContext("PageTreeContext")
6277 {
6278   p = new Private;
6279 }
6280
6281 PageTreeContext::~PageTreeContext()
6282 {
6283   delete p;
6284 }
6285
6286 TemplateVariant PageTreeContext::get(const char *name) const
6287 {
6288   return p->get(name);
6289 }
6290
6291 //------------------------------------------------------------------------
6292
6293 //%% list PageList[Page]: list of pages
6294 class PageListContext::Private : public GenericNodeListContext
6295 {
6296   public:
6297     void addPages(const PageSDict &pages)
6298     {
6299       PageSDict::Iterator pdi(pages);
6300       PageDef *pd=0;
6301       for (pdi.toFirst();(pd=pdi.current());++pdi)
6302       {
6303         if (!pd->getGroupDef() && !pd->isReference())
6304         {
6305           append(PageContext::alloc(pd));
6306         }
6307       }
6308     }
6309 };
6310
6311 PageListContext::PageListContext(const PageSDict *pages) : RefCountedContext("PageListContext")
6312 {
6313   p = new Private;
6314   if (pages) p->addPages(*pages);
6315 }
6316
6317 PageListContext::~PageListContext()
6318 {
6319   delete p;
6320 }
6321
6322 // TemplateListIntf
6323 int PageListContext::count() const
6324 {
6325   return p->count();
6326 }
6327
6328 TemplateVariant PageListContext::at(int index) const
6329 {
6330   return p->at(index);
6331 }
6332
6333 TemplateListIntf::ConstIterator *PageListContext::createIterator() const
6334 {
6335   return p->createIterator();
6336 }
6337
6338 //------------------------------------------------------------------------
6339
6340 //%% list ModuleList[ModuleNode]: list of directories and/or files
6341 class ModuleListContext::Private : public GenericNodeListContext
6342 {
6343   public:
6344     void addModules()
6345     {
6346       GroupSDict::Iterator gli(*Doxygen::groupSDict);
6347       GroupDef *gd;
6348       for (gli.toFirst();(gd=gli.current());++gli)
6349       {
6350         if (!gd->isReference())
6351         {
6352           append(ModuleContext::alloc(gd));
6353         }
6354       }
6355     }
6356 };
6357
6358 ModuleListContext::ModuleListContext() : RefCountedContext("ModuleListContext")
6359 {
6360   p = new Private;
6361   p->addModules();
6362 }
6363
6364 ModuleListContext::~ModuleListContext()
6365 {
6366   delete p;
6367 }
6368
6369 // TemplateListIntf
6370 int ModuleListContext::count() const
6371 {
6372   return p->count();
6373 }
6374
6375 TemplateVariant ModuleListContext::at(int index) const
6376 {
6377   return p->at(index);
6378 }
6379
6380 TemplateListIntf::ConstIterator *ModuleListContext::createIterator() const
6381 {
6382   return p->createIterator();
6383 }
6384
6385 //------------------------------------------------------------------------
6386
6387 //%% struct ModuleTree: tree of modules
6388 //%% {
6389 class ModuleTreeContext::Private : public PropertyMapper
6390 {
6391   public:
6392     Private()
6393     {
6394       m_moduleTree.reset(NestingContext::alloc(0,0));
6395       // Add modules
6396       if (Doxygen::groupSDict)
6397       {
6398         m_moduleTree->addModules(*Doxygen::groupSDict);
6399       }
6400
6401       //%% ModuleList tree:
6402       addProperty("tree",this,&Private::tree);
6403       addProperty("fileName",this,&Private::fileName);
6404       addProperty("relPath",this,&Private::relPath);
6405       addProperty("highlight",this,&Private::highlight);
6406       addProperty("subhighlight",this,&Private::subhighlight);
6407       addProperty("title",this,&Private::title);
6408       addProperty("preferredDepth",this,&Private::preferredDepth);
6409       addProperty("maxDepth",this,&Private::maxDepth);
6410     }
6411     TemplateVariant tree() const
6412     {
6413       return m_moduleTree.get();
6414     }
6415     TemplateVariant fileName() const
6416     {
6417       return "modules";
6418     }
6419     TemplateVariant relPath() const
6420     {
6421       return "";
6422     }
6423     TemplateVariant highlight() const
6424     {
6425       return "modules";
6426     }
6427     TemplateVariant subhighlight() const
6428     {
6429       return "";
6430     }
6431     TemplateVariant title() const
6432     {
6433       return theTranslator->trModules();
6434     }
6435     TemplateVariant maxDepth() const
6436     {
6437       if (!m_cache.maxDepthComputed)
6438       {
6439         m_cache.maxDepth = computeMaxDepth(m_moduleTree.get());
6440         m_cache.maxDepthComputed=TRUE;
6441       }
6442       return m_cache.maxDepth;
6443     }
6444     TemplateVariant preferredDepth() const
6445     {
6446       if (!m_cache.preferredDepthComputed)
6447       {
6448         m_cache.preferredDepth = computePreferredDepth(m_moduleTree.get(),maxDepth().toInt());
6449         m_cache.preferredDepthComputed=TRUE;
6450       }
6451       return m_cache.preferredDepth;
6452     }
6453   private:
6454     SharedPtr<NestingContext> m_moduleTree;
6455     struct Cachable
6456     {
6457       Cachable() : maxDepthComputed(FALSE), preferredDepthComputed(FALSE) {}
6458       int   maxDepth;
6459       bool  maxDepthComputed;
6460       int   preferredDepth;
6461       bool  preferredDepthComputed;
6462     };
6463     mutable Cachable m_cache;
6464 };
6465 //%% }
6466
6467 ModuleTreeContext::ModuleTreeContext() : RefCountedContext("ModuleTreeContext")
6468 {
6469   p = new Private;
6470 }
6471
6472 ModuleTreeContext::~ModuleTreeContext()
6473 {
6474   delete p;
6475 }
6476
6477 TemplateVariant ModuleTreeContext::get(const char *name) const
6478 {
6479   return p->get(name);
6480 }
6481
6482 //------------------------------------------------------------------------
6483
6484 //%% struct NavPathElem: list of examples page
6485 //%% {
6486 class NavPathElemContext::Private : public PropertyMapper
6487 {
6488   public:
6489     Private(Definition *def) : m_def(def)
6490     {
6491       addProperty("isLinkable",this,&Private::isLinkable);
6492       addProperty("fileName",this,&Private::fileName);
6493       addProperty("anchor",this,&Private::anchor);
6494       addProperty("text",this,&Private::text);
6495     }
6496     TemplateVariant isLinkable() const
6497     {
6498       return m_def->isLinkable();
6499     }
6500     TemplateVariant anchor() const
6501     {
6502       return m_def->anchor();
6503     }
6504     TemplateVariant fileName() const
6505     {
6506       return m_def->getOutputFileBase();
6507     }
6508     TemplateVariant text() const
6509     {
6510       Definition::DefType type = m_def->definitionType();
6511       QCString text = m_def->localName();
6512       if (type==Definition::TypeGroup)
6513       {
6514         text = ((const GroupDef*)m_def)->groupTitle();
6515       }
6516       else if (type==Definition::TypePage && !(((const PageDef*)m_def)->title().isEmpty()))
6517       {
6518         text = ((const PageDef*)m_def)->title();
6519       }
6520       else if (type==Definition::TypeClass)
6521       {
6522         if (text.right(2)=="-p")
6523         {
6524           text = text.left(text.length()-2);
6525         }
6526       }
6527       return text;
6528     }
6529   private:
6530     Definition *m_def;
6531 };
6532 //%% }
6533
6534 NavPathElemContext::NavPathElemContext(Definition *def) : RefCountedContext("NavPathElemContext")
6535 {
6536   p = new Private(def);
6537 }
6538
6539 NavPathElemContext::~NavPathElemContext()
6540 {
6541   delete p;
6542 }
6543
6544 TemplateVariant NavPathElemContext::get(const char *name) const
6545 {
6546   return p->get(name);
6547 }
6548
6549
6550 //------------------------------------------------------------------------
6551
6552 //%% struct ExampleList: list of examples page
6553 //%% {
6554 class ExampleListContext::Private : public PropertyMapper
6555 {
6556   public:
6557     TemplateVariant items() const
6558     {
6559       return m_pageList.get();
6560     }
6561     TemplateVariant fileName() const
6562     {
6563       return "examples";
6564     }
6565     TemplateVariant relPath() const
6566     {
6567       return "";
6568     }
6569     TemplateVariant highlight() const
6570     {
6571       return "examples";
6572     }
6573     TemplateVariant subhighlight() const
6574     {
6575       return "";
6576     }
6577     TemplateVariant title() const
6578     {
6579       return theTranslator->trExamples();
6580     }
6581     Private()
6582     {
6583       m_pageList.reset(PageListContext::alloc(Doxygen::exampleSDict));
6584
6585       addProperty("items",this,&Private::items);
6586       addProperty("fileName",this,&Private::fileName);
6587       addProperty("relPath",this,&Private::relPath);
6588       addProperty("highlight",this,&Private::highlight);
6589       addProperty("subhighlight",this,&Private::subhighlight);
6590       addProperty("title",this,&Private::title);
6591     }
6592   private:
6593     SharedPtr<PageListContext> m_pageList;
6594 };
6595 //%% }
6596
6597 ExampleListContext::ExampleListContext() : RefCountedContext("ExampleListContext")
6598 {
6599   p = new Private;
6600 }
6601
6602 ExampleListContext::~ExampleListContext()
6603 {
6604   delete p;
6605 }
6606
6607 TemplateVariant ExampleListContext::get(const char *name) const
6608 {
6609   return p->get(name);
6610 }
6611
6612 //------------------------------------------------------------------------
6613
6614 //%% struct GlobalsIndex: list of examples page
6615 //%% {
6616 class GlobalsIndexContext::Private : public PropertyMapper
6617 {
6618   public:
6619     Private()
6620     {
6621       addProperty("all",         this,&Private::all);
6622       addProperty("functions",   this,&Private::functions);
6623       addProperty("variables",   this,&Private::variables);
6624       addProperty("typedefs",    this,&Private::typedefs);
6625       addProperty("enums",       this,&Private::enums);
6626       addProperty("enumValues",  this,&Private::enumValues);
6627       addProperty("macros",      this,&Private::macros);
6628       addProperty("properties",  this,&Private::properties);
6629       addProperty("events",      this,&Private::events);
6630       addProperty("related",     this,&Private::related);
6631       addProperty("fileName",    this,&Private::fileName);
6632       addProperty("relPath",     this,&Private::relPath);
6633       addProperty("highlight",   this,&Private::highlight);
6634       addProperty("subhighlight",this,&Private::subhighlight);
6635       addProperty("title",       this,&Private::title);
6636     }
6637     typedef bool (MemberDef::*MemberFunc)() const;
6638     TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
6639     {
6640       if (!listRef)
6641       {
6642         TemplateList *list = TemplateList::alloc();
6643         MemberName *mn;
6644         MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
6645         for (fnli.toFirst();(mn=fnli.current());++fnli)
6646         {
6647           MemberDef *md;
6648           MemberNameIterator mni(*mn);
6649           for (mni.toFirst();(md=mni.current());++mni)
6650           {
6651             FileDef *fd=md->getFileDef();
6652             if (fd && fd->isLinkableInProject() &&
6653                 !md->name().isEmpty() && !md->getNamespaceDef() && md->isLinkableInProject())
6654             {
6655               if (filter==0 || (md->*filter)())
6656               {
6657                 list->append(MemberContext::alloc(md));
6658               }
6659             }
6660           }
6661         }
6662         listRef.reset(list);
6663       }
6664       return listRef.get();
6665     }
6666     TemplateVariant all() const
6667     {
6668       return getMembersFiltered(m_cache.all,0);
6669     }
6670     TemplateVariant functions() const
6671     {
6672       return getMembersFiltered(m_cache.functions,&MemberDef::isFunction);
6673     }
6674     TemplateVariant variables() const
6675     {
6676       return getMembersFiltered(m_cache.variables,&MemberDef::isVariable);
6677     }
6678     TemplateVariant typedefs() const
6679     {
6680       return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef);
6681     }
6682     TemplateVariant enums() const
6683     {
6684       return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate);
6685     }
6686     TemplateVariant enumValues() const
6687     {
6688       return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue);
6689     }
6690     TemplateVariant macros() const
6691     {
6692       return getMembersFiltered(m_cache.macros,&MemberDef::isDefine);
6693     }
6694     TemplateVariant properties() const
6695     {
6696       return FALSE;
6697     }
6698     TemplateVariant events() const
6699     {
6700       return FALSE;
6701     }
6702     TemplateVariant related() const
6703     {
6704       return FALSE;
6705     }
6706     TemplateVariant fileName() const
6707     {
6708       return "globals";
6709     }
6710     TemplateVariant relPath() const
6711     {
6712       return "";
6713     }
6714     TemplateVariant highlight() const
6715     {
6716       return "files";
6717     }
6718     TemplateVariant subhighlight() const
6719     {
6720       return "filemembers";
6721     }
6722     TemplateVariant title() const
6723     {
6724       return theTranslator->trFileMembers();
6725     }
6726   private:
6727     struct Cachable
6728     {
6729       Cachable() {}
6730       SharedPtr<TemplateList> all;
6731       SharedPtr<TemplateList> functions;
6732       SharedPtr<TemplateList> variables;
6733       SharedPtr<TemplateList> typedefs;
6734       SharedPtr<TemplateList> enums;
6735       SharedPtr<TemplateList> enumValues;
6736       SharedPtr<TemplateList> macros;
6737     };
6738     mutable Cachable m_cache;
6739 };
6740 //%% }
6741
6742 GlobalsIndexContext::GlobalsIndexContext() : RefCountedContext("GlobalsIndexContext")
6743 {
6744   p = new Private;
6745 }
6746
6747 GlobalsIndexContext::~GlobalsIndexContext()
6748 {
6749   delete p;
6750 }
6751
6752 TemplateVariant GlobalsIndexContext::get(const char *name) const
6753 {
6754   return p->get(name);
6755 }
6756
6757 //------------------------------------------------------------------------
6758
6759 //%% struct ClassMembersIndex: list of examples page
6760 //%% {
6761 class ClassMembersIndexContext::Private : public PropertyMapper
6762 {
6763   public:
6764     Private()
6765     {
6766       addProperty("all",         this,&Private::all);
6767       addProperty("functions",   this,&Private::functions);
6768       addProperty("variables",   this,&Private::variables);
6769       addProperty("typedefs",    this,&Private::typedefs);
6770       addProperty("enums",       this,&Private::enums);
6771       addProperty("enumValues",  this,&Private::enumValues);
6772       addProperty("macros",      this,&Private::macros);
6773       addProperty("properties",  this,&Private::properties);
6774       addProperty("events",      this,&Private::events);
6775       addProperty("related",     this,&Private::related);
6776       addProperty("fileName",    this,&Private::fileName);
6777       addProperty("relPath",     this,&Private::relPath);
6778       addProperty("highlight",   this,&Private::highlight);
6779       addProperty("subhighlight",this,&Private::subhighlight);
6780       addProperty("title",       this,&Private::title);
6781     }
6782     typedef bool (MemberDef::*MemberFunc)() const;
6783     TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
6784     {
6785       if (!listRef)
6786       {
6787         TemplateList *list = TemplateList::alloc();
6788         MemberName *mn;
6789         MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
6790         for (mnli.toFirst();(mn=mnli.current());++mnli)
6791         {
6792           MemberDef *md;
6793           MemberNameIterator mni(*mn);
6794           for (mni.toFirst();(md=mni.current());++mni)
6795           {
6796             ClassDef *cd = md->getClassDef();
6797             if (cd && cd->isLinkableInProject() && cd->templateMaster()==0 &&
6798                 md->isLinkableInProject() && !md->name().isEmpty())
6799             {
6800               if (filter==0 || (md->*filter)())
6801               {
6802                 list->append(MemberContext::alloc(md));
6803               }
6804             }
6805           }
6806         }
6807         listRef.reset(list);
6808       }
6809       return listRef.get();
6810     }
6811     TemplateVariant all() const
6812     {
6813       return getMembersFiltered(m_cache.all,&MemberDef::isNotFriend);
6814     }
6815     TemplateVariant functions() const
6816     {
6817       return getMembersFiltered(m_cache.functions,&MemberDef::isFunctionOrSignalSlot);
6818     }
6819     TemplateVariant variables() const
6820     {
6821       return getMembersFiltered(m_cache.variables,&MemberDef::isVariable);
6822     }
6823     TemplateVariant typedefs() const
6824     {
6825       return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef);
6826     }
6827     TemplateVariant enums() const
6828     {
6829       return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate);
6830     }
6831     TemplateVariant enumValues() const
6832     {
6833       return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue);
6834     }
6835     TemplateVariant macros() const
6836     {
6837       return FALSE;
6838     }
6839     TemplateVariant properties() const
6840     {
6841       return getMembersFiltered(m_cache.properties,&MemberDef::isProperty);
6842     }
6843     TemplateVariant events() const
6844     {
6845       return getMembersFiltered(m_cache.events,&MemberDef::isEvent);
6846     }
6847     TemplateVariant related() const
6848     {
6849       return getMembersFiltered(m_cache.related,&MemberDef::isRelated);
6850     }
6851     TemplateVariant fileName() const
6852     {
6853       return "functions";
6854     }
6855     TemplateVariant relPath() const
6856     {
6857       return "";
6858     }
6859     TemplateVariant highlight() const
6860     {
6861       return "classes";
6862     }
6863     TemplateVariant subhighlight() const
6864     {
6865       return "classmembers";
6866     }
6867     TemplateVariant title() const
6868     {
6869       return theTranslator->trCompoundMembers();
6870     }
6871   private:
6872     struct Cachable
6873     {
6874       Cachable() {}
6875       SharedPtr<TemplateList> all;
6876       SharedPtr<TemplateList> functions;
6877       SharedPtr<TemplateList> variables;
6878       SharedPtr<TemplateList> typedefs;
6879       SharedPtr<TemplateList> enums;
6880       SharedPtr<TemplateList> enumValues;
6881       SharedPtr<TemplateList> properties;
6882       SharedPtr<TemplateList> events;
6883       SharedPtr<TemplateList> related;
6884     };
6885     mutable Cachable m_cache;
6886 };
6887 //%% }
6888
6889 ClassMembersIndexContext::ClassMembersIndexContext() : RefCountedContext("ClassMembersIndexContext")
6890 {
6891   p = new Private;
6892 }
6893
6894 ClassMembersIndexContext::~ClassMembersIndexContext()
6895 {
6896   delete p;
6897 }
6898
6899 TemplateVariant ClassMembersIndexContext::get(const char *name) const
6900 {
6901   return p->get(name);
6902 }
6903
6904 //------------------------------------------------------------------------
6905
6906 //%% struct NamespaceMembersIndex: list of examples page
6907 //%% {
6908 class NamespaceMembersIndexContext::Private : public PropertyMapper
6909 {
6910   public:
6911     Private()
6912     {
6913       addProperty("all",         this,&Private::all);
6914       addProperty("functions",   this,&Private::functions);
6915       addProperty("variables",   this,&Private::variables);
6916       addProperty("typedefs",    this,&Private::typedefs);
6917       addProperty("enums",       this,&Private::enums);
6918       addProperty("enumValues",  this,&Private::enumValues);
6919       addProperty("macros",      this,&Private::macros);
6920       addProperty("properties",  this,&Private::properties);
6921       addProperty("events",      this,&Private::events);
6922       addProperty("related",     this,&Private::related);
6923       addProperty("fileName",    this,&Private::fileName);
6924       addProperty("relPath",     this,&Private::relPath);
6925       addProperty("highlight",   this,&Private::highlight);
6926       addProperty("subhighlight",this,&Private::subhighlight);
6927       addProperty("title",       this,&Private::title);
6928     }
6929     typedef bool (MemberDef::*MemberFunc)() const;
6930     TemplateVariant getMembersFiltered(SharedPtr<TemplateList> &listRef,MemberFunc filter) const
6931     {
6932       if (!listRef)
6933       {
6934         TemplateList *list = TemplateList::alloc();
6935         MemberName *mn;
6936         MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
6937         for (fnli.toFirst();(mn=fnli.current());++fnli)
6938         {
6939           MemberDef *md;
6940           MemberNameIterator mni(*mn);
6941           for (mni.toFirst();(md=mni.current());++mni)
6942           {
6943             NamespaceDef *nd=md->getNamespaceDef();
6944             if (nd && nd->isLinkableInProject() &&
6945                 !md->name().isEmpty() && md->isLinkableInProject())
6946             {
6947               if (filter==0 || (md->*filter)())
6948               {
6949                 list->append(MemberContext::alloc(md));
6950               }
6951             }
6952           }
6953         }
6954         listRef.reset(list);
6955       }
6956       return listRef.get();
6957     }
6958     TemplateVariant all() const
6959     {
6960       return getMembersFiltered(m_cache.all,0);
6961     }
6962     TemplateVariant functions() const
6963     {
6964       return getMembersFiltered(m_cache.functions,&MemberDef::isFunction);
6965     }
6966     TemplateVariant variables() const
6967     {
6968       return getMembersFiltered(m_cache.variables,&MemberDef::isVariable);
6969     }
6970     TemplateVariant typedefs() const
6971     {
6972       return getMembersFiltered(m_cache.typedefs,&MemberDef::isTypedef);
6973     }
6974     TemplateVariant enums() const
6975     {
6976       return getMembersFiltered(m_cache.enums,&MemberDef::isEnumerate);
6977     }
6978     TemplateVariant enumValues() const
6979     {
6980       return getMembersFiltered(m_cache.enumValues,&MemberDef::isEnumValue);
6981     }
6982     TemplateVariant macros() const
6983     {
6984       return FALSE;
6985     }
6986     TemplateVariant properties() const
6987     {
6988       return FALSE;
6989     }
6990     TemplateVariant events() const
6991     {
6992       return FALSE;
6993     }
6994     TemplateVariant related() const
6995     {
6996       return FALSE;
6997     }
6998     TemplateVariant fileName() const
6999     {
7000       return "namespacemembers";
7001     }
7002     TemplateVariant relPath() const
7003     {
7004       return "";
7005     }
7006     TemplateVariant highlight() const
7007     {
7008       return "namespaces";
7009     }
7010     TemplateVariant subhighlight() const
7011     {
7012       return "namespacemembers";
7013     }
7014     TemplateVariant title() const
7015     {
7016       return theTranslator->trNamespaceMembers();
7017     }
7018   private:
7019     struct Cachable
7020     {
7021       Cachable() {}
7022       SharedPtr<TemplateList> all;
7023       SharedPtr<TemplateList> functions;
7024       SharedPtr<TemplateList> variables;
7025       SharedPtr<TemplateList> typedefs;
7026       SharedPtr<TemplateList> enums;
7027       SharedPtr<TemplateList> enumValues;
7028     };
7029     mutable Cachable m_cache;
7030 };
7031 //%% }
7032
7033 NamespaceMembersIndexContext::NamespaceMembersIndexContext() : RefCountedContext("NamespaceMembersIndexContext")
7034 {
7035   p = new Private;
7036 }
7037
7038 NamespaceMembersIndexContext::~NamespaceMembersIndexContext()
7039 {
7040   delete p;
7041 }
7042
7043 TemplateVariant NamespaceMembersIndexContext::get(const char *name) const
7044 {
7045   return p->get(name);
7046 }
7047
7048
7049 //------------------------------------------------------------------------
7050
7051 //%% struct InheritanceNode: a class in the inheritance list
7052 //%% {
7053 class InheritanceNodeContext::Private : public PropertyMapper
7054 {
7055   public:
7056     Private(ClassDef *cd,const QCString &name) : m_classDef(cd), m_name(name)
7057     {
7058       addProperty("class",this,&Private::getClass);
7059       addProperty("name",this,&Private::name);
7060     }
7061     TemplateVariant getClass() const
7062     {
7063       if (!m_classContext)
7064       {
7065         m_classContext.reset(ClassContext::alloc(m_classDef));
7066       }
7067       return m_classContext.get();
7068     }
7069     TemplateVariant name() const
7070     {
7071       return m_name;
7072     }
7073   private:
7074     ClassDef *m_classDef;
7075     mutable SharedPtr<ClassContext> m_classContext;
7076     QCString m_name;
7077 };
7078 //%% }
7079
7080 InheritanceNodeContext::InheritanceNodeContext(ClassDef *cd,const QCString &name) : RefCountedContext("InheritanceNodeContext")
7081 {
7082   p = new Private(cd,name);
7083 }
7084
7085 InheritanceNodeContext::~InheritanceNodeContext()
7086 {
7087   delete p;
7088 }
7089
7090 TemplateVariant InheritanceNodeContext::get(const char *name) const
7091 {
7092   return p->get(name);
7093 }
7094
7095 //------------------------------------------------------------------------
7096
7097 //%% list InheritanceList[InheritanceNode] : list of inherited classes
7098 class InheritanceListContext::Private : public GenericNodeListContext
7099 {
7100   public:
7101     void addClass(ClassDef *cd,const QCString &name)
7102     {
7103       append(InheritanceNodeContext::alloc(cd,name));
7104     }
7105 };
7106
7107 InheritanceListContext::InheritanceListContext(const BaseClassList *list, bool baseClasses) : RefCountedContext("InheritanceListContext")
7108 {
7109   p = new Private;
7110   if (list)
7111   {
7112     BaseClassListIterator li(*list);
7113     BaseClassDef *bcd;
7114     for (li.toFirst();(bcd=li.current());++li)
7115     {
7116       ClassDef *cd=bcd->classDef;
7117       QCString name;
7118       if (baseClasses)
7119       {
7120         name = insertTemplateSpecifierInScope(
7121                      cd->displayName(),bcd->templSpecifiers);
7122       }
7123       else
7124       {
7125         name = cd->displayName();
7126       }
7127       //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses);
7128       p->addClass(cd,name);
7129     }
7130   }
7131 }
7132
7133 InheritanceListContext::~InheritanceListContext()
7134 {
7135   delete p;
7136 }
7137
7138 // TemplateListIntf
7139 int InheritanceListContext::count() const
7140 {
7141   return p->count();
7142 }
7143
7144 TemplateVariant InheritanceListContext::at(int index) const
7145 {
7146   return p->at(index);
7147 }
7148
7149 TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const
7150 {
7151   return p->createIterator();
7152 }
7153
7154 //------------------------------------------------------------------------
7155
7156 //%% list MemberList[Member] : list of inherited classes
7157 class MemberListContext::Private : public GenericNodeListContext
7158 {
7159   public:
7160     void addMember(MemberDef *md)
7161     {
7162       append(MemberContext::alloc(md));
7163     }
7164 };
7165
7166 MemberListContext::MemberListContext() : RefCountedContext("MemberListContext")
7167 {
7168   p = new Private;
7169 }
7170
7171 MemberListContext::MemberListContext(const MemberList *list) : RefCountedContext("MemberListContext")
7172 {
7173   p = new Private;
7174   if (list)
7175   {
7176     bool details = list->listType()&MemberListType_detailedLists;
7177     MemberListIterator mli(*list);
7178     MemberDef *md;
7179     for (mli.toFirst();(md=mli.current());++mli)
7180     {
7181       if ((md->isBriefSectionVisible() && !details) ||
7182           (md->isDetailedSectionLinkable() && details)
7183          )
7184       {
7185         p->addMember(md);
7186       }
7187     }
7188   }
7189 }
7190
7191 MemberListContext::MemberListContext(MemberSDict *list,bool doSort) : RefCountedContext("MemberListContext")
7192 {
7193   p = new Private;
7194   if (list)
7195   {
7196     if (doSort)
7197     {
7198       list->sort();
7199     }
7200     MemberSDict::Iterator it(*list);
7201     MemberDef *md;
7202     for (it.toFirst();(md=it.current());++it)
7203     {
7204       p->addMember(md);
7205     }
7206   }
7207 }
7208
7209 MemberListContext::~MemberListContext()
7210 {
7211   delete p;
7212 }
7213
7214 // TemplateListIntf
7215 int MemberListContext::count() const
7216 {
7217   return p->count();
7218 }
7219
7220 TemplateVariant MemberListContext::at(int index) const
7221 {
7222   return p->at(index);
7223 }
7224
7225 TemplateListIntf::ConstIterator *MemberListContext::createIterator() const
7226 {
7227   return p->createIterator();
7228 }
7229
7230 //------------------------------------------------------------------------
7231
7232 //%% struct MemberInfo: member information
7233 //%% {
7234 class MemberInfoContext::Private : public PropertyMapper
7235 {
7236   public:
7237     Private(const MemberInfo *mi) : m_memberInfo(mi)
7238     {
7239       //%% string protection
7240       addProperty("protection",this,&Private::protection);
7241       //%% string virtualness
7242       addProperty("virtualness",this,&Private::virtualness);
7243       //%% string ambiguityScope
7244       addProperty("ambiguityScope",this,&Private::ambiguityScope);
7245       //%% Member member
7246       addProperty("member",this,&Private::member);
7247     }
7248     TemplateVariant protection() const
7249     {
7250       switch (m_memberInfo->prot)
7251       {
7252         case ::Public:    return "public";
7253         case ::Protected: return "protected";
7254         case ::Private:   return "private";
7255         case ::Package:   return "package";
7256       }
7257       return "";
7258     }
7259     TemplateVariant virtualness() const
7260     {
7261       switch (m_memberInfo->virt)
7262       {
7263         case ::Normal:   return "normal";
7264         case ::Virtual:  return "virtual";
7265         case ::Pure:     return "pure";
7266       }
7267       return "";
7268     }
7269     TemplateVariant ambiguityScope() const
7270     {
7271       return m_memberInfo->ambiguityResolutionScope;
7272     }
7273     TemplateVariant member() const
7274     {
7275       if (!m_member && m_memberInfo->memberDef)
7276       {
7277         m_member.reset(MemberContext::alloc(m_memberInfo->memberDef));
7278       }
7279       if (m_member)
7280       {
7281         return m_member.get();
7282       }
7283       else
7284       {
7285         return TemplateVariant(FALSE);
7286       }
7287     }
7288   private:
7289     const MemberInfo *m_memberInfo;
7290     mutable SharedPtr<MemberContext> m_member;
7291 };
7292 //%% }
7293
7294 MemberInfoContext::MemberInfoContext(const MemberInfo *mi) : RefCountedContext("MemberInfoContext")
7295 {
7296   p = new Private(mi);
7297 }
7298
7299 MemberInfoContext::~MemberInfoContext()
7300 {
7301   delete p;
7302 }
7303
7304 TemplateVariant MemberInfoContext::get(const char *name) const
7305 {
7306   return p->get(name);
7307 }
7308
7309
7310 //------------------------------------------------------------------------
7311
7312 //%% list AllMembersList[MemberList] : list of inherited classes
7313 class AllMembersListContext::Private : public GenericNodeListContext
7314 {
7315   public:
7316     Private(const MemberNameInfoSDict *ml)
7317     {
7318       if (ml)
7319       {
7320         static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
7321         MemberNameInfoSDict::Iterator mnii(*ml);
7322         MemberNameInfo *mni;
7323         for (mnii.toFirst();(mni=mnii.current());++mnii)
7324         {
7325           MemberNameInfoIterator mnii2(*mni);
7326           MemberInfo *mi;
7327           for (mnii2.toFirst();(mi=mnii2.current());++mnii2)
7328           {
7329             MemberDef *md=mi->memberDef;
7330             ClassDef  *cd=md->getClassDef();
7331             if (cd && !md->name().isEmpty() && md->name()[0]!='@')
7332             {
7333               if ((cd->isLinkable() && md->isLinkable()) ||
7334                   (!cd->isArtificial() && !hideUndocMembers &&
7335                    (protectionLevelVisible(md->protection()) || md->isFriend())
7336                   )
7337                  )
7338               {
7339                 append(MemberInfoContext::alloc(mi));
7340               }
7341             }
7342           }
7343         }
7344       }
7345     }
7346 };
7347
7348 AllMembersListContext::AllMembersListContext() : RefCountedContext("AllMembersListContext")
7349 {
7350   p = new Private(0);
7351 }
7352
7353 AllMembersListContext::AllMembersListContext(const MemberNameInfoSDict *ml) : RefCountedContext("AllMembersListContext")
7354 {
7355   p = new Private(ml);
7356 }
7357
7358 AllMembersListContext::~AllMembersListContext()
7359 {
7360   delete p;
7361 }
7362
7363 // TemplateListIntf
7364 int AllMembersListContext::count() const
7365 {
7366   return p->count();
7367 }
7368
7369 TemplateVariant AllMembersListContext::at(int index) const
7370 {
7371   return p->at(index);
7372 }
7373
7374 TemplateListIntf::ConstIterator *AllMembersListContext::createIterator() const
7375 {
7376   return p->createIterator();
7377 }
7378
7379 //------------------------------------------------------------------------
7380
7381 //%% struct MemberGroupInfo: member group information
7382 //%% {
7383 class MemberGroupInfoContext::Private : public PropertyMapper
7384 {
7385   public:
7386     Private(Definition *def,const QCString &relPath,const MemberGroup *mg) :
7387       m_def(def),
7388       m_relPath(relPath),
7389       m_memberGroup(mg)
7390     {
7391       addProperty("members",      this,&Private::members);
7392       addProperty("title",        this,&Private::groupTitle);
7393       addProperty("subtitle",     this,&Private::groupSubtitle);
7394       addProperty("anchor",       this,&Private::groupAnchor);
7395       addProperty("memberGroups", this,&Private::memberGroups);
7396       addProperty("docs",         this,&Private::docs);
7397       addProperty("inherited",    this,&Private::inherited);
7398     }
7399     TemplateVariant members() const
7400     {
7401       if (!m_cache.memberListContext)
7402       {
7403         m_cache.memberListContext.reset(MemberListContext::alloc(m_memberGroup->members()));
7404       }
7405       return m_cache.memberListContext.get();
7406     }
7407     TemplateVariant groupTitle() const
7408     {
7409       return m_memberGroup->header();
7410     }
7411     TemplateVariant groupSubtitle() const
7412     {
7413       return "";
7414     }
7415     TemplateVariant groupAnchor() const
7416     {
7417       return m_memberGroup->anchor();
7418     }
7419     TemplateVariant memberGroups() const
7420     {
7421       if (!m_cache.memberGroups)
7422       {
7423         m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_def,m_relPath,0));
7424       }
7425       return m_cache.memberGroups.get();
7426     }
7427     TemplateVariant docs() const
7428     {
7429       if (!m_cache.docs)
7430       {
7431         QCString docs = m_memberGroup->documentation();
7432         if (!docs.isEmpty())
7433         {
7434           m_cache.docs.reset(new TemplateVariant(
7435                            parseDoc(m_def,"[@name docs]",-1, // TODO store file & line
7436                                     m_relPath,
7437                                     m_memberGroup->documentation()+"\n",FALSE)));
7438         }
7439         else
7440         {
7441           m_cache.docs.reset(new TemplateVariant(""));
7442         }
7443       }
7444       return *m_cache.docs;
7445     }
7446     TemplateVariant inherited() const
7447     {
7448       return FALSE;
7449     }
7450   private:
7451     Definition *m_def;
7452     QCString m_relPath;
7453     const MemberGroup *m_memberGroup;
7454     struct Cachable
7455     {
7456       SharedPtr<MemberListContext>      memberListContext;
7457       SharedPtr<MemberGroupListContext> memberGroups;
7458       ScopedPtr<TemplateVariant>        docs;
7459     };
7460     mutable Cachable m_cache;
7461 };
7462 //%% }
7463
7464 MemberGroupInfoContext::MemberGroupInfoContext(Definition *def,
7465        const QCString &relPath,const MemberGroup *mg) : RefCountedContext("MemberGroupInfoContext")
7466 {
7467   p = new Private(def,relPath,mg);
7468 }
7469
7470 MemberGroupInfoContext::~MemberGroupInfoContext()
7471 {
7472   delete p;
7473 }
7474
7475 TemplateVariant MemberGroupInfoContext::get(const char *name) const
7476 {
7477   return p->get(name);
7478 }
7479
7480 //------------------------------------------------------------------------
7481
7482 //%% list MemberGroupList[MemberGroupInfo] : list of member groups
7483 class MemberGroupListContext::Private : public GenericNodeListContext
7484 {
7485   public:
7486     void addMemberGroup(Definition *def,const QCString &relPath,const MemberGroup *mg)
7487     {
7488       append(MemberGroupInfoContext::alloc(def,relPath,mg));
7489     }
7490 };
7491
7492 MemberGroupListContext::MemberGroupListContext() : RefCountedContext("MemberGroupListContext")
7493 {
7494   p = new Private;
7495 }
7496
7497 MemberGroupListContext::MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupList *list) : RefCountedContext("MemberGroupListContext")
7498 {
7499   p = new Private;
7500   if (list)
7501   {
7502     MemberGroupListIterator mgli(*list);
7503     MemberGroup *mg;
7504     for (;(mg=mgli.current());++mgli)
7505     {
7506       p->addMemberGroup(def,relPath,mg);
7507     }
7508   }
7509 }
7510
7511 MemberGroupListContext::MemberGroupListContext(Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping) : RefCountedContext("MemberGroupListContext")
7512 {
7513   p = new Private;
7514   if (dict)
7515   {
7516     MemberGroupSDict::Iterator di(*dict);
7517     const MemberGroup *mg;
7518     for (di.toFirst();(mg=di.current());++di)
7519     {
7520       if (!mg->allMembersInSameSection() || !subGrouping)
7521       {
7522         p->addMemberGroup(def,relPath,mg);
7523       }
7524     }
7525   }
7526 }
7527
7528 MemberGroupListContext::~MemberGroupListContext()
7529 {
7530   delete p;
7531 }
7532
7533 // TemplateListIntf
7534 int MemberGroupListContext::count() const
7535 {
7536   return p->count();
7537 }
7538
7539 TemplateVariant MemberGroupListContext::at(int index) const
7540 {
7541   return p->at(index);
7542 }
7543
7544 TemplateListIntf::ConstIterator *MemberGroupListContext::createIterator() const
7545 {
7546   return p->createIterator();
7547 }
7548
7549
7550 //------------------------------------------------------------------------
7551
7552 //%% struct MemberListInfo: member list information
7553 //%% {
7554 class MemberListInfoContext::Private : public PropertyMapper
7555 {
7556   public:
7557     Private(Definition *def,const QCString &relPath,const MemberList *ml,const QCString &title,const QCString &subtitle) :
7558       m_def(def),
7559       m_memberList(ml),
7560       m_relPath(relPath),
7561       m_title(title),
7562       m_subtitle(subtitle)
7563     {
7564       addProperty("members",      this,&Private::members);
7565       addProperty("title",        this,&Private::title);
7566       addProperty("subtitle",     this,&Private::subtitle);
7567       addProperty("anchor",       this,&Private::anchor);
7568       addProperty("memberGroups", this,&Private::memberGroups);
7569       addProperty("inherited",    this,&Private::inherited);
7570     }
7571     TemplateVariant members() const
7572     {
7573       if (!m_cache.memberListContext)
7574       {
7575         m_cache.memberListContext.reset(MemberListContext::alloc(m_memberList));
7576       }
7577       return m_cache.memberListContext.get();
7578     }
7579     TemplateVariant title() const
7580     {
7581       return m_title;
7582     }
7583     TemplateVariant subtitle() const
7584     {
7585       return m_subtitle;
7586     }
7587     TemplateVariant anchor() const
7588     {
7589       return MemberList::listTypeAsString(m_memberList->listType());
7590     }
7591     TemplateVariant memberGroups() const
7592     {
7593       if (!m_cache.memberGroups)
7594       {
7595         m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_def,m_relPath,m_memberList->getMemberGroupList()));
7596       }
7597       return m_cache.memberGroups.get();
7598     }
7599     TemplateVariant inherited() const
7600     {
7601       if (!m_cache.inherited && (m_memberList->listType()&MemberListType_detailedLists)==0 &&
7602           m_def->definitionType()==Definition::TypeClass)
7603       {
7604         InheritedMemberInfoListContext *ctx = InheritedMemberInfoListContext::alloc();
7605         ctx->addMemberList((ClassDef*)m_def,m_memberList->listType(),m_title,FALSE);
7606         m_cache.inherited.reset(ctx);
7607       }
7608       if (m_cache.inherited)
7609       {
7610         return m_cache.inherited.get();
7611       }
7612       else
7613       {
7614         return TemplateVariant(FALSE);
7615       }
7616     }
7617   private:
7618     Definition *m_def;
7619     const MemberList *m_memberList;
7620     QCString m_relPath;
7621     QCString m_title;
7622     QCString m_subtitle;
7623     struct Cachable
7624     {
7625       SharedPtr<MemberListContext> memberListContext;
7626       SharedPtr<MemberGroupListContext> memberGroups;
7627       SharedPtr<InheritedMemberInfoListContext> inherited;
7628     };
7629     mutable Cachable m_cache;
7630 };
7631 //%% }
7632
7633 MemberListInfoContext::MemberListInfoContext(
7634            Definition *def,const QCString &relPath,const MemberList *ml,
7635            const QCString &title,const QCString &subtitle) : RefCountedContext("MemberListInfoContext")
7636 {
7637   p = new Private(def,relPath,ml,title,subtitle);
7638 }
7639
7640 MemberListInfoContext::~MemberListInfoContext()
7641 {
7642   delete p;
7643 }
7644
7645 TemplateVariant MemberListInfoContext::get(const char *name) const
7646 {
7647   return p->get(name);
7648 }
7649
7650 //------------------------------------------------------------------------
7651
7652 //%% struct InheritedMemberInfo: inherited member information
7653 //%% {
7654 class InheritedMemberInfoContext::Private : public PropertyMapper
7655 {
7656   public:
7657     Private(ClassDef *cd,MemberList *ml,const QCString &title)
7658       : m_class(cd), m_memberList(ml), m_title(title)
7659     {
7660       addProperty("class",         this,&Private::getClass);
7661       addProperty("title",         this,&Private::title);
7662       addProperty("members",       this,&Private::members);
7663       addProperty("id",            this,&Private::id);
7664       addProperty("inheritedFrom", this,&Private::inheritedFrom);
7665     }
7666     virtual ~Private()
7667     {
7668       delete m_memberList;
7669     }
7670     TemplateVariant getClass() const
7671     {
7672       if (!m_classCtx)
7673       {
7674         m_classCtx.reset(ClassContext::alloc(m_class));
7675       }
7676       return m_classCtx.get();
7677     }
7678     TemplateVariant title() const
7679     {
7680       return m_title;
7681     }
7682     TemplateVariant members() const
7683     {
7684       if (!m_memberListCtx)
7685       {
7686         m_memberListCtx.reset(MemberListContext::alloc(m_memberList));
7687       }
7688       return m_memberListCtx.get();
7689     }
7690     TemplateVariant id() const
7691     {
7692       return substitute(MemberList::listTypeAsString(m_memberList->listType()),"-","_")+"_"+
7693                         stripPath(m_class->getOutputFileBase());
7694     }
7695     TemplateVariant inheritedFrom() const
7696     {
7697       if (!m_inheritedFrom)
7698       {
7699         m_inheritedFrom.reset(TemplateList::alloc());
7700         m_inheritedFrom->append(title());
7701         m_inheritedFrom->append(getClass());
7702       }
7703       return m_inheritedFrom.get();
7704     }
7705
7706   private:
7707     ClassDef *  m_class;
7708     MemberList *m_memberList;
7709     QCString    m_title;
7710     mutable SharedPtr<ClassContext> m_classCtx;
7711     mutable SharedPtr<MemberListContext> m_memberListCtx;
7712     mutable SharedPtr<TemplateList> m_inheritedFrom;
7713 };
7714 //%% }
7715
7716 InheritedMemberInfoContext::InheritedMemberInfoContext(ClassDef *cd,MemberList *ml,
7717                                                        const QCString &title) : RefCountedContext("InheritedMemberInfoContext")
7718 {
7719   p = new Private(cd,ml,title);
7720 }
7721
7722 InheritedMemberInfoContext::~InheritedMemberInfoContext()
7723 {
7724   delete p;
7725 }
7726
7727 TemplateVariant InheritedMemberInfoContext::get(const char *name) const
7728 {
7729   return p->get(name);
7730 }
7731
7732 //------------------------------------------------------------------------
7733
7734 //%% list InheritedMemberList[InheritedMemberInfo] : list of inherited classes
7735 class InheritedMemberInfoListContext::Private : public GenericNodeListContext
7736 {
7737   public:
7738     void addMemberList(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList)
7739     {
7740       if (ml)
7741       {
7742         MemberListIterator li(*ml);
7743         MemberDef *md;
7744         for (li.toFirst();(md=li.current());++li)
7745         {
7746           if (md->isBriefSectionVisible() && !md->isReimplementedBy(inheritedFrom))
7747           {
7748             combinedList->append(md);
7749           }
7750         }
7751       }
7752     }
7753     void addMemberListIncludingGrouped(ClassDef *inheritedFrom,MemberList *ml,MemberList *combinedList)
7754     {
7755       if (ml)
7756       {
7757         addMemberList(inheritedFrom,ml,combinedList);
7758         if (ml->getMemberGroupList())
7759         {
7760           MemberGroupListIterator mgli(*ml->getMemberGroupList());
7761           MemberGroup *mg;
7762           for (mgli.toFirst();(mg=mgli.current());++mgli)
7763           {
7764             addMemberList(inheritedFrom,mg->members(),combinedList);
7765           }
7766         }
7767       }
7768     }
7769     void addMemberGroupsOfClass(ClassDef *inheritedFrom,
7770                                 ClassDef *cd,MemberListType lt,MemberList *combinedList)
7771     {
7772       if (cd->getMemberGroupSDict())
7773       {
7774         MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
7775         MemberGroup *mg;
7776         for (;(mg=mgli.current());++mgli)
7777         {
7778           if (mg->members() && (!mg->allMembersInSameSection() || !cd->subGrouping())) // group is in its own section
7779           {
7780             MemberListIterator li(*mg->members());
7781             MemberDef *md;
7782             for (li.toFirst();(md=li.current());++li)
7783             {
7784               if (lt==md->getSectionList(mg->parent())->listType() &&
7785                   !md->isReimplementedBy(inheritedFrom) &&
7786                   md->isBriefSectionVisible())
7787               {
7788                 combinedList->append(md);
7789               }
7790             }
7791           }
7792         }
7793       }
7794     }
7795     void addInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt,
7796                              MemberListType lt1,int lt2,const QCString &title,bool additionalList)
7797     {
7798       int count = cd->countMembersIncludingGrouped(lt1,inheritedFrom,additionalList);
7799       if (lt2!=-1) count += cd->countMembersIncludingGrouped((MemberListType)lt2,inheritedFrom,additionalList);
7800       if (count>0)
7801       {
7802         MemberList *ml  = cd->getMemberList(lt1);
7803         MemberList *ml2 = lt2!=-1 ? cd->getMemberList((MemberListType)lt2) : 0;
7804         MemberList *combinedList = new MemberList(lt);
7805         addMemberListIncludingGrouped(inheritedFrom,ml,combinedList);
7806         addMemberListIncludingGrouped(inheritedFrom,ml2,combinedList);
7807         addMemberGroupsOfClass(inheritedFrom,cd,lt,combinedList);
7808         if (lt2!=-1) addMemberGroupsOfClass(inheritedFrom,cd,(MemberListType)lt2,combinedList);
7809         append(InheritedMemberInfoContext::alloc(cd,combinedList,title));
7810       }
7811     }
7812     void findInheritedMembers(ClassDef *inheritedFrom,ClassDef *cd,MemberListType lt,
7813                               int lt2, const QCString &title,bool additionalList,
7814                               QPtrDict<void> *visitedClasses)
7815     {
7816       if (cd->baseClasses())
7817       {
7818         BaseClassListIterator it(*cd->baseClasses());
7819         BaseClassDef *ibcd;
7820         for (it.toFirst();(ibcd=it.current());++it)
7821         {
7822           ClassDef *icd=ibcd->classDef;
7823           if (icd->isLinkable())
7824           {
7825             int lt1,lt3;
7826             convertProtectionLevel(lt,ibcd->prot,&lt1,&lt3);
7827             if (lt2==-1 && lt3!=-1)
7828             {
7829               lt2=lt3;
7830             }
7831             if (visitedClasses->find(icd)==0)
7832             {
7833               visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
7834               if (lt1!=-1)
7835               {
7836                 // add member info for members of cd with list type lt
7837                 addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList);
7838                 // recurse down the inheritance tree
7839                 findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses);
7840               }
7841             }
7842           }
7843         }
7844       }
7845     }
7846 };
7847
7848 InheritedMemberInfoListContext::InheritedMemberInfoListContext() : RefCountedContext("InheritedMemberInfoListContext")
7849 {
7850   p = new Private;
7851 }
7852
7853 void InheritedMemberInfoListContext::addMemberList(
7854     ClassDef *cd,MemberListType lt,const QCString &title,bool additionalList)
7855 {
7856   QPtrDict<void> visited(17);
7857   bool memberInSection = cd->countMembersIncludingGrouped(lt,cd,FALSE)>0;
7858   bool show = (additionalList && !memberInSection) || // inherited member to show in the additional inherited members list
7859               (!additionalList && memberInSection);   // inherited member to show in a member list of the class
7860   //printf("%s:%s show=%d\n",cd->name().data(),MemberList::listTypeAsString(lt).data(),show);
7861   if (show)
7862   {
7863     p->findInheritedMembers(cd,cd,lt,-1,title,additionalList,&visited);
7864   }
7865 }
7866
7867 InheritedMemberInfoListContext::~InheritedMemberInfoListContext()
7868 {
7869   delete p;
7870 }
7871
7872 // TemplateListIntf
7873 int InheritedMemberInfoListContext::count() const
7874 {
7875   return p->count();
7876 }
7877
7878 TemplateVariant InheritedMemberInfoListContext::at(int index) const
7879 {
7880   return p->at(index);
7881 }
7882
7883 TemplateListIntf::ConstIterator *InheritedMemberInfoListContext::createIterator() const
7884 {
7885   return p->createIterator();
7886 }
7887
7888 //------------------------------------------------------------------------
7889
7890 //%% struct Argument: parameter information
7891 //%% {
7892 class ArgumentContext::Private : public PropertyMapper
7893 {
7894   public:
7895     Private(const Argument *arg,Definition *def,const QCString &relPath) :
7896       m_argument(arg), m_def(def), m_relPath(relPath)
7897     {
7898       addProperty("type",     this,&Private::type);
7899       addProperty("name",     this,&Private::name);
7900       addProperty("defVal",   this,&Private::defVal);
7901       addProperty("docs",     this,&Private::docs);
7902       addProperty("attrib",   this,&Private::attrib);
7903       addProperty("array",    this,&Private::array);
7904       addProperty("namePart", this,&Private::namePart);
7905     }
7906     TemplateVariant type() const
7907     {
7908       return createLinkedText(m_def,m_relPath,m_argument->type);
7909     }
7910     TemplateVariant attrib() const
7911     {
7912       return m_argument->attrib;
7913     }
7914     TemplateVariant name() const
7915     {
7916       return m_argument->name;
7917     }
7918     TemplateVariant defVal() const
7919     {
7920       return createLinkedText(m_def,m_relPath,m_argument->defval);
7921     }
7922     TemplateVariant array() const
7923     {
7924       return m_argument->array;
7925     }
7926     TemplateVariant docs() const
7927     {
7928       if (!m_cache.docs && m_def)
7929       {
7930         if (!m_argument->docs.isEmpty())
7931         {
7932           m_cache.docs.reset(new TemplateVariant(
7933                              parseDoc(m_def,m_def->docFile(),m_def->docLine(),
7934                              m_relPath,m_argument->docs,TRUE)));
7935         }
7936         else
7937         {
7938           m_cache.docs.reset(new TemplateVariant(""));
7939         }
7940       }
7941       return *m_cache.docs;
7942     }
7943     TemplateVariant namePart() const
7944     {
7945       QCString result = m_argument->attrib;
7946       int l = result.length();
7947       if (l>2 && result.at(0)=='[' && result.at(l-1)==']')
7948       {
7949         result = result.mid(1,l-2);
7950         if (result!=",") result+=":"; // for normal keywords add colon
7951       }
7952       return result;
7953     }
7954   private:
7955     const Argument *m_argument;
7956     Definition *m_def;
7957     QCString m_relPath;
7958     struct Cachable
7959     {
7960       ScopedPtr<TemplateVariant> docs;
7961     };
7962     mutable Cachable m_cache;
7963 };
7964 //%% }
7965
7966 ArgumentContext::ArgumentContext(const Argument *al,Definition *def,const QCString &relPath) : RefCountedContext("ArgumentContext")
7967 {
7968   p = new Private(al,def,relPath);
7969 }
7970
7971 ArgumentContext::~ArgumentContext()
7972 {
7973   delete p;
7974 }
7975
7976 TemplateVariant ArgumentContext::get(const char *name) const
7977 {
7978   return p->get(name);
7979 }
7980
7981 //------------------------------------------------------------------------
7982
7983 //%% list ArgumentList[Argument] : list of inherited classes
7984 class ArgumentListContext::Private : public GenericNodeListContext
7985 {
7986   public:
7987     void addArgument(const Argument *arg,Definition *def,const QCString &relPath)
7988     {
7989       append(ArgumentContext::alloc(arg,def,relPath));
7990     }
7991 };
7992
7993 ArgumentListContext::ArgumentListContext() : RefCountedContext("ArgumentListContext")
7994 {
7995   p = new Private;
7996 }
7997
7998 ArgumentListContext::ArgumentListContext(const ArgumentList *list,
7999                         Definition *def,const QCString &relPath) : RefCountedContext("ArgumentListContext")
8000 {
8001   p = new Private;
8002   if (list)
8003   {
8004     ArgumentListIterator ali(*list);
8005     const Argument *arg;
8006     for (ali.toFirst();(arg=ali.current());++ali)
8007     {
8008       p->addArgument(arg,def,relPath);
8009     }
8010   }
8011 }
8012
8013 ArgumentListContext::~ArgumentListContext()
8014 {
8015   delete p;
8016 }
8017
8018 // TemplateListIntf
8019 int ArgumentListContext::count() const
8020 {
8021   return p->count();
8022 }
8023
8024 TemplateVariant ArgumentListContext::at(int index) const
8025 {
8026   return p->at(index);
8027 }
8028
8029 TemplateListIntf::ConstIterator *ArgumentListContext::createIterator() const
8030 {
8031   return p->createIterator();
8032 }
8033
8034 //------------------------------------------------------------------------
8035
8036 class HtmlEscaper : public TemplateEscapeIntf
8037 {
8038   public:
8039     QCString escape(const QCString &s)
8040     {
8041       return convertToHtml(s,TRUE);
8042     }
8043 };
8044
8045 //------------------------------------------------------------------------
8046
8047 class HtmlSpaceless : public TemplateSpacelessIntf
8048 {
8049   public:
8050     HtmlSpaceless() { reset(); }
8051     void reset()
8052     {
8053       m_insideTag = FALSE;
8054       m_insideString = '\0';
8055       m_removeSpaces = TRUE;
8056     }
8057     QCString remove(const QCString &s)
8058     {
8059       QGString result;
8060       const char *p = s.data();
8061       char c;
8062       while ((c=*p++))
8063       {
8064         switch(c)
8065         {
8066           case '<': // start of a tag
8067             if (!m_insideString) m_insideTag=TRUE,m_removeSpaces=FALSE;
8068             result+=c;
8069             break;
8070           case '>': // end of a tag
8071             if (!m_insideString) m_insideTag=FALSE,m_removeSpaces=TRUE;
8072             result+=c;
8073             break;
8074           case '\\': // escaped character in a string
8075             result+=c;
8076             if (m_insideString && *p) result+=*p++;
8077             break;
8078           case '"': case '\'':
8079             if (m_insideTag)
8080             {
8081               if (m_insideString==c) // end of string
8082               {
8083                 m_insideString='\0';
8084               }
8085               else // start of string
8086               {
8087                 m_insideString=c;
8088               }
8089             }
8090             result+=c;
8091             break;
8092           case ' ': case '\t': case '\n': // whitespace
8093             if (!m_insideTag) // outside tags strip consecutive whitespace
8094             {
8095               m_removeSpaces=TRUE;
8096             }
8097             else
8098             {
8099               result+=' ';
8100             }
8101             break;
8102           default:
8103             //if (m_removeSpaces) result+=' ';
8104             result+=c;
8105             m_removeSpaces=FALSE;
8106             break;
8107         }
8108       }
8109       result+='\0';
8110       //printf("HtmlSpaceless::remove({%s})={%s} m_insideTag=%d m_insideString=%d removeSpaces=%d\n",s.data(),result.data(),
8111       //    m_insideTag,m_insideString,m_removeSpaces);
8112       return result.data();
8113     }
8114   private:
8115     bool m_insideTag;
8116     char m_insideString;
8117     bool m_removeSpaces;
8118 };
8119
8120 //------------------------------------------------------------------------
8121
8122 #if DEBUG_REF
8123 int RefCountedContext::s_totalCount;
8124 #endif
8125
8126 void generateOutputViaTemplate()
8127 {
8128   {
8129     TemplateEngine e;
8130     TemplateContext *ctx = e.createContext();
8131     if (ctx)
8132     {
8133       SharedPtr<DoxygenContext>               doxygen              (DoxygenContext::alloc());
8134       SharedPtr<ConfigContext>                config               (ConfigContext::alloc());
8135       SharedPtr<TranslateContext>             tr                   (TranslateContext::alloc());
8136       SharedPtr<ClassListContext>             classList            (ClassListContext::alloc());
8137       SharedPtr<ClassIndexContext>            classIndex           (ClassIndexContext::alloc());
8138       SharedPtr<ClassTreeContext>             classTree            (ClassTreeContext::alloc());
8139       SharedPtr<ClassHierarchyContext>        classHierarchy       (ClassHierarchyContext::alloc());
8140       SharedPtr<NamespaceListContext>         namespaceList        (NamespaceListContext::alloc());
8141       SharedPtr<NamespaceTreeContext>         namespaceTree        (NamespaceTreeContext::alloc());
8142       SharedPtr<DirListContext>               dirList              (DirListContext::alloc());
8143       SharedPtr<FileListContext>              fileList             (FileListContext::alloc());
8144       SharedPtr<FileTreeContext>              fileTree             (FileTreeContext::alloc());
8145       SharedPtr<PageTreeContext>              pageTree             (PageTreeContext::alloc());
8146       SharedPtr<PageListContext>              pageList             (PageListContext::alloc(Doxygen::pageSDict));
8147       SharedPtr<ExampleListContext>           exampleList          (ExampleListContext::alloc());
8148       SharedPtr<ModuleTreeContext>            moduleTree           (ModuleTreeContext::alloc());
8149       SharedPtr<ModuleListContext>            moduleList           (ModuleListContext::alloc());
8150       SharedPtr<PageContext>                  mainPage             (PageContext::alloc(Doxygen::mainPage,TRUE));
8151       SharedPtr<GlobalsIndexContext>          globalsIndex         (GlobalsIndexContext::alloc());
8152       SharedPtr<ClassMembersIndexContext>     classMembersIndex    (ClassMembersIndexContext::alloc());
8153       SharedPtr<NamespaceMembersIndexContext> namespaceMembersIndex(NamespaceMembersIndexContext::alloc());
8154
8155       //%% Doxygen doxygen:
8156       ctx->set("doxygen",doxygen.get());
8157       //%% Translator tr:
8158       ctx->set("tr",tr.get());
8159       //%% Config config:
8160       ctx->set("config",config.get());
8161       //%% ClassList classList:
8162       ctx->set("classList",classList.get()); // not used for standard HTML
8163       //%% ClassTree classTree:
8164       ctx->set("classTree",classTree.get());
8165       //%% ClassIndex classIndex:
8166       ctx->set("classIndex",classIndex.get());
8167       //%% ClassHierarchy classHierarchy:
8168       ctx->set("classHierarchy",classHierarchy.get());
8169       //%% NamespaceList namespaceList:
8170       ctx->set("namespaceList",namespaceList.get());
8171       //%% NamespaceTree namespaceTree:
8172       ctx->set("namespaceTree",namespaceTree.get());
8173       //%% FileList fileList:
8174       ctx->set("fileList",fileList.get());
8175       //%% FileTree fileTree:
8176       ctx->set("fileTree",fileTree.get());
8177       //%% PageList pageList
8178       ctx->set("pageList",pageList.get());
8179       //%% PageTree pageTree
8180       ctx->set("pageTree",pageTree.get());
8181       //%% ExampleList exampleList
8182       ctx->set("exampleList",exampleList.get());
8183       //%% ModuleTree moduleTree
8184       ctx->set("moduleTree",moduleTree.get());
8185       //%% ModuleList moduleList
8186       ctx->set("moduleList",moduleList.get());
8187       //%% DirList dirList
8188       ctx->set("dirList",dirList.get());
8189       //%% Page mainPage
8190       ctx->set("mainPage",mainPage.get());
8191       //%% GlobalsIndex globalsIndex:
8192       ctx->set("globalsIndex",globalsIndex.get());
8193       //%% ClassMembersIndex classMembersIndex:
8194       ctx->set("classMembersIndex",classMembersIndex.get());
8195       //%% NamespaceMembersIndex namespaceMembersIndex:
8196       ctx->set("namespaceMembersIndex",namespaceMembersIndex.get());
8197
8198       // render HTML output
8199       Template *tpl = e.loadByName("htmllayout.tpl",1);
8200       if (tpl)
8201       {
8202         g_globals.outputFormat = ContextGlobals::Html;
8203         g_globals.dynSectionId = 0;
8204         g_globals.outputDir    = Config_getString("HTML_OUTPUT");
8205         QDir dir(g_globals.outputDir);
8206         createSubDirs(dir);
8207         HtmlEscaper htmlEsc;
8208         ctx->setEscapeIntf(Config_getString("HTML_FILE_EXTENSION"),&htmlEsc);
8209         HtmlSpaceless spl;
8210         ctx->setSpacelessIntf(&spl);
8211         ctx->setOutputDirectory(g_globals.outputDir);
8212         FTextStream ts;
8213         tpl->render(ts,ctx);
8214         e.unload(tpl);
8215       }
8216
8217       // TODO: render other outputs
8218
8219       e.destroyContext(ctx);
8220     }
8221   }
8222 #if DEBUG_REF // should be 0, i.e. all objects are deleted
8223   printf("==== total ref count %d\n",RefCountedContext::s_totalCount);
8224 #endif
8225 }
8226