#include "context.h" #include "config.h" #include "index.h" #include "classlist.h" #include "doxygen.h" #include "namespacedef.h" #include "filedef.h" #include "pagedef.h" #include "groupdef.h" #include "util.h" #include "version.h" #include "language.h" #include "message.h" #include "vhdldocgen.h" #include "filename.h" #include "dirdef.h" #include "docparser.h" #include "htmlgen.h" #include "htmldocvisitor.h" #include "dot.h" #include "diagram.h" struct ContextGlobals { enum OutputFormat { Html, LateX, Rtf, ManPage, DocBook, Xml, TagFile }; int dynSectionId; QCString outputDir; OutputFormat outputFormat; } g_globals; /** @brief Scoped smart pointer */ template class ScopedPtr { private: T *m_ptr; ScopedPtr(const ScopedPtr &); ScopedPtr &operator=(const ScopedPtr &); void operator==(const ScopedPtr &) const; void operator!=(const ScopedPtr &) const; public: typedef T Type; explicit ScopedPtr(T *p=0) : m_ptr(p) {} ~ScopedPtr() { delete m_ptr; }; T &operator*() const { return *m_ptr; } T *operator->() const { return m_ptr; } T *get() const { return m_ptr; } operator bool() const { return m_ptr!=0; } void reset(T *p=0) { if (p!=m_ptr) { delete m_ptr; m_ptr = p; } } }; // iterator support template class GenericConstIterator : public TemplateListIntf::ConstIterator { public: GenericConstIterator(const QList &list) : m_it(list) { } virtual ~GenericConstIterator() {} void toFirst() { m_it.toFirst(); } void toLast() { m_it.toLast(); } void toNext() { if (m_it.current()) ++m_it; } void toPrev() { if (m_it.current()) --m_it; } bool current(TemplateVariant &v) const { if (m_it.current()) { v = m_it.current(); return TRUE; } else { v = TemplateVariant(); return FALSE; } } private: QListIterator m_it; }; //------------------------------------------------------------------------ // standard list implementation template class GenericNodeListContext : public TemplateListIntf { public: GenericNodeListContext() { m_children.setAutoDelete(TRUE); } // TemplateListIntf methods int count() const { return (int)m_children.count(); } TemplateVariant at(int index) const { TemplateVariant result; if (index>=0 && index(m_children); } void append(T *ctn) { m_children.append(ctn); } bool isEmpty() const { return m_children.isEmpty(); } private: mutable QList m_children; }; //------------------------------------------------------------------------ /** @brief Helper class to map a property name to a handler member function */ class PropertyMapper { private: struct PropertyFuncIntf { virtual ~PropertyFuncIntf() {} virtual TemplateVariant operator()() const = 0; }; template struct PropertyFunc : public PropertyFuncIntf { typedef TemplateVariant (T::*Handler)() const; PropertyFunc(const T *o,Handler h) : obj(o), handler(h) {} TemplateVariant operator()() const { return (obj->*handler)(); } const T *obj; Handler handler; }; public: PropertyMapper() { m_map.setAutoDelete(TRUE); } /** Add a property to the map * @param[in] name The name of the property to add. * @param[in] obj The object handling access to the property. * @param[in] handle The method to call when the property is accessed. */ template void addProperty(const char *name,const T* obj, typename PropertyFunc::Handler handle) { m_map.insert(name,new PropertyFunc(obj,handle)); } /** Gets the value of a property. * @param[in] name The name of the property. * @returns A variant representing the properties value or an * invalid variant if it was not found. */ TemplateVariant get(const char *name) const { //printf("PropertyMapper::get(%s)\n",name); TemplateVariant result; PropertyFuncIntf *func = m_map.find(name); if (func) { result = (*func)(); } return result; } private: QDict m_map; }; //------------------------------------------------------------------------ //%% struct Config : configuration options //%% { class ConfigContext::Private { public: Private() { cachedLists.setAutoDelete(TRUE); } TemplateVariant fetchList(const QCString &name,const QStrList *list) { TemplateList *tlist = cachedLists.find(name); if (tlist==0) { tlist = new TemplateList; cachedLists.insert(name,tlist); QStrListIterator li(*list); char *s; for (li.toFirst();(s=li.current());++li) { tlist->append(s); } } return tlist; } private: QDict cachedLists; }; //%% } ConfigContext::ConfigContext() { p = new Private; } ConfigContext::~ConfigContext() { delete p; } TemplateVariant ConfigContext::get(const char *name) const { TemplateVariant result; if (name) { ConfigOption *option = Config::instance()->get(name); if (option) { switch (option->kind()) { case ConfigOption::O_Bool: return TemplateVariant(*((ConfigBool*)option)->valueRef()); case ConfigOption::O_Int: return TemplateVariant(*((ConfigInt*)option)->valueRef()); case ConfigOption::O_Enum: return TemplateVariant(*((ConfigEnum*)option)->valueRef()); case ConfigOption::O_String: return TemplateVariant(*((ConfigString*)option)->valueRef()); case ConfigOption::O_List: return p->fetchList(name,((ConfigList*)option)->valueRef()); break; default: break; } } } return result; } //------------------------------------------------------------------------ //%% struct Doxygen: global information //%% { class DoxygenContext::Private : public PropertyMapper { public: TemplateVariant version() const { return versionString; } TemplateVariant date() const { return TemplateVariant(dateToString(TRUE)); } Private() { //%% string version addProperty("version",this,&Private::version); //makeProperty(this,&Private::version)); //%% string date addProperty("date", this,&Private::date); } }; //%% } DoxygenContext::DoxygenContext() { p = new Private; } DoxygenContext::~DoxygenContext() { delete p; } TemplateVariant DoxygenContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Translator: translation methods //%% { class TranslateContext::Private : public PropertyMapper { public: static TemplateVariant generatedAtFunc(const void *obj,const QValueList &args) { return ((TranslateContext::Private*)obj)->generatedAt(args); } static TemplateVariant inheritanceDiagramForFunc(const void *obj,const QValueList &args) { return ((TranslateContext::Private*)obj)->inheritanceDiagramFor(args); } static TemplateVariant inheritsListFunc(const void *obj,const QValueList &args) { return ((TranslateContext::Private*)obj)->inheritsList(args); } static TemplateVariant inheritedByListFunc(const void *obj,const QValueList &args) { return ((TranslateContext::Private*)obj)->inheritedByList(args); } static TemplateVariant collaborationDiagramForFunc(const void *obj,const QValueList &args) { return ((TranslateContext::Private*)obj)->collaborationDiagramFor(args); } TemplateVariant generatedAt(const QValueList &args) const { if (args.count()==2) { return theTranslator->trGeneratedAt(args[0].toString(),args[1].toString()); } else { err("tr.generateAt should take two parameters, got %d!\n",args.count()); } return TemplateVariant(); } TemplateVariant inheritanceDiagramFor(const QValueList &args) const { if (args.count()==1) { return theTranslator->trClassDiagram(args[0].toString()); } else { err("tr.inheritanceDiagramFor should take one parameter, got %d!\n",args.count()); } return TemplateVariant(); } TemplateVariant collaborationDiagramFor(const QValueList &args) const { if (args.count()==1) { return theTranslator->trCollaborationDiagram(args[0].toString()); } else { err("tr.collaborationDiagramFor should take one parameter, got %d!\n",args.count()); } return TemplateVariant(); } TemplateVariant inheritsList(const QValueList &args) const { if (args.count()==1) { return theTranslator->trInheritsList(args[0].toInt()); } else { err("tr.inheritsList should take one integer parameter, got %d!\n",args.count()); } return TemplateVariant(); } QCString inheritedByList(const QValueList &args) const { if (args.count()==1) { return theTranslator->trInheritedByList(args[0].toInt()); } else { err("tr.inheritedByList should take one integer parameter, got %d!\n",args.count()); } return QCString(); } TemplateVariant generatedBy() const { return theTranslator->trGeneratedBy(); } TemplateVariant generatedAt() const { return TemplateVariant(this,&Private::generatedAtFunc); } TemplateVariant inheritanceDiagramFor() const { return TemplateVariant(this,&Private::inheritanceDiagramForFunc); } TemplateVariant collaborationDiagramFor() const { return TemplateVariant(this,&Private::collaborationDiagramForFunc); } TemplateVariant search() const { return theTranslator->trSearch(); } TemplateVariant mainPage() const { return theTranslator->trMainPage(); } TemplateVariant classes() const { return theTranslator->trClasses(); } TemplateVariant classList() const { return theTranslator->trCompoundList(); } TemplateVariant classIndex() const { return theTranslator->trCompoundIndex(); } TemplateVariant classHierarchy() const { return theTranslator->trClassHierarchy(); } TemplateVariant classMembers() const { return theTranslator->trCompoundMembers(); } TemplateVariant modules() const { return theTranslator->trModules(); } TemplateVariant namespaces() const { if (m_javaOpt || m_vhdlOpt) { return theTranslator->trPackages(); } else if (m_fortranOpt) { return theTranslator->trModules(); } else { return theTranslator->trNamespaces(); } } TemplateVariant files() const { return theTranslator->trFile(TRUE,FALSE); } TemplateVariant pages() const { return theTranslator->trRelatedPages(); } TemplateVariant examples() const { return theTranslator->trExamples(); } TemplateVariant namespaceList() const { if (m_javaOpt || m_vhdlOpt) { return theTranslator->trPackages(); } else if (m_fortranOpt) { return theTranslator->trModulesList(); } else { return theTranslator->trNamespaceList(); } } TemplateVariant namespaceMembers() const { if (m_javaOpt || m_vhdlOpt) { return theTranslator->trPackageMembers(); } else if (m_fortranOpt) { return theTranslator->trModulesMembers(); } else { return theTranslator->trNamespaceMembers(); } } TemplateVariant fileList() const { return theTranslator->trFileList(); } TemplateVariant fileMembers() const { return theTranslator->trFileMembers(); } TemplateVariant relatedPagesDesc() const { return theTranslator->trRelatedPagesDescription(); } TemplateVariant more() const { return theTranslator->trMore(); } TemplateVariant detailedDesc() const { return theTranslator->trDetailedDescription(); } TemplateVariant inheritsList() const { return TemplateVariant(this,&Private::inheritsListFunc); } TemplateVariant inheritedByList() const { return TemplateVariant(this,&Private::inheritedByListFunc); } Private() { //%% string generatedBy addProperty("generatedby", this,&Private::generatedBy); //%% string generatedAt addProperty("generatedAt", this,&Private::generatedAt); //%% string search addProperty("search", this,&Private::search); //%% string mainPage addProperty("mainPage", this,&Private::mainPage); //%% string classes addProperty("classes", this,&Private::classes); //%% string classList addProperty("classList", this,&Private::classList); //%% string classIndex addProperty("classIndex", this,&Private::classIndex); //%% string classHierarchy addProperty("classHierarchy", this,&Private::classHierarchy); //%% string classMembers addProperty("classMembers", this,&Private::classMembers); //%% string modules addProperty("modules", this,&Private::modules); //%% string namespaces addProperty("namespaces", this,&Private::namespaces); //%% string files addProperty("files", this,&Private::files); //%% string pages addProperty("pages", this,&Private::pages); //%% string examples addProperty("examples", this,&Private::examples); //%% string namespaceList addProperty("namespaceList", this,&Private::namespaceList); //%% string namespaceMembers addProperty("namespaceMembers", this,&Private::namespaceMembers); //%% srting fileList addProperty("fileList", this,&Private::fileList); //%% string fileMembers addProperty("fileMembers", this,&Private::fileMembers); //%% string relatedPagesDescripiton addProperty("relatedPagesDesc", this,&Private::relatedPagesDesc); //%% string more addProperty("more", this,&Private::more); //%% string detailedDescription addProperty("detailedDesc", this,&Private::detailedDesc); //%% string inheritanceDiagramFor addProperty("inheritanceDiagramFor", this,&Private::inheritanceDiagramFor); //%% string collaborationDiagramFor addProperty("collaborationDiagramFor", this,&Private::collaborationDiagramFor); //%% string inheritsList addProperty("inheritsList", this,&Private::inheritsList); //%% string inheritedByList addProperty("inheritedByList", this,&Private::inheritedByList); m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); m_vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); } private: bool m_javaOpt; bool m_fortranOpt; bool m_vhdlOpt; }; //%% } TranslateContext::TranslateContext() { p = new Private; } TranslateContext::~TranslateContext() { delete p; } TemplateVariant TranslateContext::get(const char *n) const { return p->get(n); } static TemplateVariant parseDoc(Definition *def,const QCString &file,int line, const QCString &relPath,const QCString &docStr,bool isBrief) { TemplateVariant result; DocRoot *root = validatingParseDoc(file,line,def,0,docStr,TRUE,FALSE,0,isBrief,FALSE); QGString docs; { FTextStream ts(&docs); // TODO: support other generators HtmlCodeGenerator codeGen(ts,relPath); HtmlDocVisitor visitor(ts,codeGen,def); root->accept(&visitor); } bool isEmpty = root->isEmpty(); if (isEmpty) result = ""; else result = TemplateVariant(docs,TRUE); delete root; return result; } //------------------------------------------------------------------------ //%% struct Symbol: shared info for all symbols //%% { template class DefinitionContext : public PropertyMapper { public: DefinitionContext(Definition *d) : m_def(d) { //%% string name: the name of the symbol addProperty("name",this,&DefinitionContext::name); //%% string bareName: the bare name of the symbol with scope info addProperty("bareName",this,&DefinitionContext::bareName); //%% string relPath: the relative path to the root of the output (CREATE_SUBDIRS) addProperty("relPath",this,&DefinitionContext::relPath); //%% string fileName: the file name of the output file associated with the symbol (without extension) addProperty("fileName",this,&DefinitionContext::fileName); //%% string anchor: anchor within the page addProperty("anchor",this,&DefinitionContext::anchor); //%% string details: the detailed documentation for this symbol addProperty("details",this,&DefinitionContext::details); //%% string brief: the brief description for this symbol addProperty("brief",this,&DefinitionContext::brief); //%% string sourceFileName: the file name of the source file (without extension) addProperty("sourceFileName",this,&DefinitionContext::sourceFileName); //%% bool isLinkable: can the symbol be linked to? addProperty("isLinkable",this,&DefinitionContext::isLinkable); //%% bool isLinkableInProject: can the symbol be linked within this project? addProperty("isLinkableInProject",this,&DefinitionContext::isLinkableInProject); //%% int dynSectionId: identifier that can be used for collapsable sections addProperty("dynSectionId",this,&DefinitionContext::dynSectionId); //%% string language: the programming language in which the symbol is written addProperty("language",this,&DefinitionContext::language); } TemplateVariant fileName() const { return m_def->getOutputFileBase(); } TemplateVariant anchor() const { return m_def->anchor(); } TemplateVariant sourceFileName() const { return m_def->getSourceFileBase(); } TemplateVariant isLinkable() const { return m_def->isLinkable(); } TemplateVariant isLinkableInProject() const { return m_def->isLinkableInProject(); } TemplateVariant name() const { return m_def->displayName(TRUE); } TemplateVariant bareName() const { return m_def->displayName(FALSE); } QCString relPathAsString() const { static bool createSubdirs = Config_getBool("CREATE_SUBDIRS"); return createSubdirs ? QCString("../../") : QCString(""); } TemplateVariant relPath() const { return relPathAsString(); } TemplateVariant details() const { if (!m_details) { m_details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(), relPathAsString(),m_def->documentation(),FALSE))); } return *m_details; } TemplateVariant brief() const { if (!m_brief) { if (m_def->hasBriefDescription()) { m_brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(), relPathAsString(),m_def->briefDescription(),TRUE))); } else { m_brief.reset(new TemplateVariant("")); } } return *m_brief; } TemplateVariant dynSectionId() const { return g_globals.dynSectionId; } TemplateVariant language() const { SrcLangExt lang = m_def->getLanguage(); QCString result = "unknown"; switch (lang) { case SrcLangExt_Unknown: break; case SrcLangExt_IDL: result="idl"; break; case SrcLangExt_Java: result="java"; break; case SrcLangExt_CSharp: result="csharp"; break; case SrcLangExt_D: result="d"; break; case SrcLangExt_PHP: result="php"; break; case SrcLangExt_ObjC: result="objc"; break; case SrcLangExt_Cpp: result="cpp"; break; case SrcLangExt_JS: result="js"; break; case SrcLangExt_Python: result="python"; break; case SrcLangExt_Fortran: result="fortran"; break; case SrcLangExt_VHDL: result="vhdl"; break; case SrcLangExt_XML: result="xml"; break; case SrcLangExt_Tcl: result="tcl"; break; case SrcLangExt_Markdown: result="markdown"; break; } return result; } private: Definition *m_def; mutable ScopedPtr m_details; mutable ScopedPtr m_brief; }; //%% } //------------------------------------------------------------------------ //%% struct IncludeInfo: include file information //%% { class IncludeInfoContext::Private : public PropertyMapper { public: Private(IncludeInfo *info,SrcLangExt lang) : m_info(info), m_fileContext(info && info->fileDef ? info->fileDef : 0), m_lang(lang) { if (m_info) { addProperty("file",this,&Private::file); addProperty("name",this,&Private::name); addProperty("isImport",this,&Private::isImport); addProperty("isLocal",this,&Private::isLocal); } } TemplateVariant isLocal() const { bool isIDLorJava = m_lang==SrcLangExt_IDL || m_lang==SrcLangExt_Java; return m_info->local || isIDLorJava; } TemplateVariant isImport() const { return m_info->imported; } TemplateVariant file() const { if (m_info->fileDef) { return &m_fileContext; } else { return FALSE; } } TemplateVariant name() const { return m_info->includeName; } private: IncludeInfo *m_info; FileContext m_fileContext; SrcLangExt m_lang; }; IncludeInfoContext::IncludeInfoContext(IncludeInfo *info,SrcLangExt lang) { p = new Private(info,lang); } IncludeInfoContext::~IncludeInfoContext() { delete p; } TemplateVariant IncludeInfoContext::get(const char *n) const { return p->get(n); } //%% } //------------------------------------------------------------------------ //%% struct Class(Symbol): class information //%% { class ClassContext::Private : public DefinitionContext { public: Private(ClassDef *cd) : DefinitionContext(cd) , m_classDef(cd), m_usedFiles(cd), m_includeInfo(cd ? cd->includeInfo() : 0, cd ? cd->getLanguage() : SrcLangExt_Unknown) { addProperty("title", this,&Private::title); addProperty("highlight", this,&Private::highlight); addProperty("subhighlight", this,&Private::subHighlight); addProperty("hasDetails", this,&Private::hasDetails); addProperty("generatedFromFiles", this,&Private::generatedFromFiles); addProperty("usedFiles", this,&Private::usedFiles); addProperty("hasInheritanceDiagram", this,&Private::hasInheritanceDiagram); addProperty("inheritanceDiagram", this,&Private::inheritanceDiagram); addProperty("hasCollaborationDiagram", this,&Private::hasCollaborationDiagram); addProperty("collaborationDiagram", this,&Private::collaborationDiagram); addProperty("includeInfo", this,&Private::includeInfo); addProperty("includeStatement", this,&Private::includeStatement); addProperty("inherits", this,&Private::inherits); addProperty("inheritedBy", this,&Private::inheritedBy); addProperty("unoIDLServices", this,&Private::unoIDLServices); addProperty("unoIDLInterfaces", this,&Private::unoIDLInterfaces); addProperty("signals", this,&Private::signals); addProperty("publicTypes", this,&Private::publicTypes); addProperty("publicMethods", this,&Private::publicMethods); addProperty("publicStaticMethods", this,&Private::publicStaticMethods); addProperty("publicAttributes", this,&Private::publicAttributes); addProperty("publicStaticAttributes", this,&Private::publicStaticAttributes); addProperty("publicSlots", this,&Private::publicSlots); addProperty("protectedTypes", this,&Private::protectedTypes); addProperty("protectedMethods", this,&Private::protectedMethods); addProperty("protectedStaticMethods", this,&Private::protectedStaticMethods); addProperty("protectedAttributes", this,&Private::protectedAttributes); addProperty("protectedStaticAttributes", this,&Private::protectedStaticAttributes); addProperty("protectedSlots", this,&Private::protectedSlots); addProperty("privateTypes", this,&Private::privateTypes); addProperty("privateMethods", this,&Private::privateMethods); addProperty("privateStaticMethods", this,&Private::privateStaticMethods); addProperty("privateAttributes", this,&Private::privateAttributes); addProperty("privateStaticAttributes", this,&Private::privateStaticAttributes); addProperty("privateSlots", this,&Private::privateSlots); addProperty("packageTypes", this,&Private::packageTypes); addProperty("packageMethods", this,&Private::packageMethods); addProperty("packageStaticMethods", this,&Private::packageStaticMethods); addProperty("packageAttributes", this,&Private::packageAttributes); addProperty("packageStaticAttributes", this,&Private::packageStaticAttributes); addProperty("properties", this,&Private::properties); addProperty("events", this,&Private::events); addProperty("friends", this,&Private::friends); addProperty("related", this,&Private::related); addProperty("nestedClasses", this,&Private::nestedClasses); addProperty("compoundType", this,&Private::compoundType); addProperty("templateDecls", this,&Private::templateDecls); } TemplateVariant title() const { return TemplateVariant(m_classDef->title()); } TemplateVariant highlight() const { return TemplateVariant("classes"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } TemplateVariant hasDetails() const { return m_classDef->hasDetailedDescription(); } TemplateVariant generatedFromFiles() const { return m_classDef->generatedFromFiles(); } TemplateVariant usedFiles() const { return TemplateVariant(&m_usedFiles); } DotClassGraph *getClassGraph() const { if (!m_cache.classGraph) { m_cache.classGraph.reset(new DotClassGraph(m_classDef,DotNode::Inheritance)); } return m_cache.classGraph.get(); } int numInheritanceNodes() const { if (m_cache.inheritanceNodes==-1) { m_cache.inheritanceNodes=m_classDef->countInheritanceNodes(); } return m_cache.inheritanceNodes>0; } TemplateVariant hasInheritanceDiagram() const { bool result=FALSE; static bool haveDot = Config_getBool("HAVE_DOT"); static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS"); static bool classGraph = Config_getBool("CLASS_GRAPH"); if (haveDot && (classDiagrams || classGraph)) { DotClassGraph *cg = getClassGraph(); result = !cg->isTrivial() && !cg->isTooBig(); } else if (classDiagrams) { result = numInheritanceNodes()>0; } return result; } TemplateVariant inheritanceDiagram() const { QGString result; static bool haveDot = Config_getBool("HAVE_DOT"); static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS"); static bool classGraph = Config_getBool("CLASS_GRAPH"); if (haveDot && (classDiagrams || classGraph)) { DotClassGraph *cg = getClassGraph(); FTextStream t(&result); cg->writeGraph(t,BITMAP, g_globals.outputDir, m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } else if (classDiagrams) { ClassDiagram d(m_classDef); FTextStream t(&result); QCString name = convertToHtml(m_classDef->displayName()); t << "
" << endl; t << "getOutputFileBase(); t << ".png\" usemap=\"#" << name << "_map\" alt=\"\"/>" << endl; t << "" << endl; d.writeImage(t,g_globals.outputDir, relPathAsString(), m_classDef->getOutputFileBase()); t << "
"; } g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } DotClassGraph *getCollaborationGraph() const { if (!m_cache.collaborationGraph) { m_cache.collaborationGraph.reset(new DotClassGraph(m_classDef,DotNode::Collaboration)); } return m_cache.collaborationGraph.get(); } TemplateVariant hasCollaborationDiagram() const { static bool haveDot = Config_getBool("HAVE_DOT"); return haveDot && !getCollaborationGraph()->isTrivial(); } TemplateVariant collaborationDiagram() const { static bool haveDot = Config_getBool("HAVE_DOT"); QGString result; if (haveDot) { DotClassGraph *cg = getCollaborationGraph(); FTextStream t(&result); cg->writeGraph(t,BITMAP, g_globals.outputDir, m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension, relPathAsString(),TRUE,TRUE,g_globals.dynSectionId ); } g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } TemplateVariant includeInfo() const { if (m_classDef->includeInfo()) { return TemplateVariant(&m_includeInfo); } else { return TemplateVariant(FALSE); } } TemplateVariant includeStatement() const { return m_classDef->includeStatement(); } TemplateVariant inherits() const { if (!m_cache.inheritsList) { m_cache.inheritsList.reset(new InheritanceListContext(m_classDef->baseClasses(),TRUE)); } return m_cache.inheritsList.get(); } TemplateVariant inheritedBy() const { if (!m_cache.inheritedByList) { m_cache.inheritedByList.reset(new InheritanceListContext(m_classDef->subClasses(),FALSE)); } return m_cache.inheritedByList.get(); } TemplateVariant getMemberList(ScopedPtr &list, MemberListType type,const char *title) const { if (!list) { MemberList *ml = m_classDef->getMemberList(type); if (ml) { list.reset(new MemberListInfoContext(ml,title)); } } if (list) { return list.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant unoIDLServices() const { return getMemberList(m_cache.unoIDLServices,MemberListType_services,theTranslator->trServices()); } TemplateVariant unoIDLInterfaces() const { return getMemberList(m_cache.unoIDLInterfaces,MemberListType_interfaces,theTranslator->trInterfaces()); } TemplateVariant signals() const { return getMemberList(m_cache.signals,MemberListType_signals,theTranslator->trSignals()); } TemplateVariant publicTypes() const { return getMemberList(m_cache.publicTypes,MemberListType_pubTypes,theTranslator->trPublicTypes()); } TemplateVariant publicMethods() const { return getMemberList(m_cache.publicMethods,MemberListType_pubMethods, m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods() : theTranslator->trPublicMembers()); } TemplateVariant publicStaticMethods() const { return getMemberList(m_cache.publicStaticMethods,MemberListType_pubStaticMethods, m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods() : theTranslator->trStaticPublicMembers()); } TemplateVariant publicAttributes() const { return getMemberList(m_cache.publicAttributes,MemberListType_pubAttribs,theTranslator->trPublicAttribs()); } TemplateVariant publicStaticAttributes() const { return getMemberList(m_cache.publicStaticAttributes,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs()); } TemplateVariant publicSlots() const { return getMemberList(m_cache.publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots()); } TemplateVariant protectedTypes() const { return getMemberList(m_cache.protectedTypes,MemberListType_proTypes,theTranslator->trProtectedTypes()); } TemplateVariant protectedMethods() const { return getMemberList(m_cache.protectedMethods,MemberListType_proMethods,theTranslator->trProtectedMembers()); } TemplateVariant protectedStaticMethods() const { return getMemberList(m_cache.protectedStaticMethods,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers()); } TemplateVariant protectedAttributes() const { return getMemberList(m_cache.protectedAttributes,MemberListType_proAttribs,theTranslator->trProtectedAttribs()); } TemplateVariant protectedStaticAttributes() const { return getMemberList(m_cache.protectedStaticAttributes,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs()); } TemplateVariant protectedSlots() const { return getMemberList(m_cache.protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots()); } TemplateVariant privateTypes() const { return getMemberList(m_cache.privateTypes,MemberListType_priTypes,theTranslator->trPrivateTypes()); } TemplateVariant privateSlots() const { return getMemberList(m_cache.privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots()); } TemplateVariant privateMethods() const { return getMemberList(m_cache.privateMethods,MemberListType_priMethods,theTranslator->trPrivateMembers()); } TemplateVariant privateStaticMethods() const { return getMemberList(m_cache.privateStaticMethods,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers()); } TemplateVariant privateAttributes() const { return getMemberList(m_cache.privateAttributes,MemberListType_priAttribs,theTranslator->trPrivateAttribs()); } TemplateVariant privateStaticAttributes() const { return getMemberList(m_cache.privateStaticAttributes,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs()); } TemplateVariant packageTypes() const { return getMemberList(m_cache.packageTypes,MemberListType_pacTypes,theTranslator->trPackageTypes()); } TemplateVariant packageMethods() const { return getMemberList(m_cache.packageMethods,MemberListType_pacMethods,theTranslator->trPackageMembers()); } TemplateVariant packageStaticMethods() const { return getMemberList(m_cache.packageStaticMethods,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()); } TemplateVariant packageAttributes() const { return getMemberList(m_cache.packageAttributes,MemberListType_pacAttribs,theTranslator->trPackageAttribs()); } TemplateVariant packageStaticAttributes() const { return getMemberList(m_cache.packageStaticAttributes,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs()); } TemplateVariant properties() const { return getMemberList(m_cache.properties,MemberListType_properties,theTranslator->trProperties()); } TemplateVariant events() const { return getMemberList(m_cache.events,MemberListType_events,theTranslator->trEvents()); } TemplateVariant friends() const { return getMemberList(m_cache.events,MemberListType_friends,theTranslator->trFriends()); } TemplateVariant related() const { return getMemberList(m_cache.events,MemberListType_related,theTranslator->trRelatedFunctions()); } TemplateVariant nestedClasses() const { static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE"); static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES"); static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES"); if (!m_cache.nestedClasses) { if (m_classDef->getClassSDict()) { NestedClassListContext *classList = new NestedClassListContext; ClassSDict::Iterator sdi(*m_classDef->getClassSDict()); ClassDef *cd; for (sdi.toFirst();(cd=sdi.current());++sdi) { bool linkable = cd->isLinkable(); if (cd->name().find('@')==-1 && !cd->isExtension() && (cd->protection()!=::Private || extractPrivate) && (linkable || (!hideUndocClasses && (!cd->isLocal() || extractLocalClasses))) ) { classList->append(cd); } } m_cache.nestedClasses.reset(classList); } } if (m_cache.nestedClasses) { return m_cache.nestedClasses.get(); } else { return TemplateVariant(FALSE); } } TemplateVariant compoundType() const { return m_classDef->compoundTypeString(); } void addTemplateDecls(Definition *d,TemplateList *tl) const { if (d->definitionType()==Definition::TypeClass) { Definition *parent = d->getOuterScope(); if (parent) { addTemplateDecls(parent,tl); } ClassDef *cd=(ClassDef *)d; if (cd->templateArguments()) { ArgumentListContext *al = new ArgumentListContext(cd->templateArguments()); // since a TemplateVariant does take ownership of the object, we add it // a separate list just to be able to delete it and avoid a memory leak m_cache.templateArgList.append(al); tl->append(al); } } } TemplateVariant templateDecls() const { if (!m_cache.templateDecls) { TemplateList *tl = new TemplateList; addTemplateDecls(m_classDef,tl); m_cache.templateDecls.reset(tl); } if (m_cache.templateDecls) { return m_cache.templateDecls.get(); } else { return TemplateVariant(FALSE); } } private: ClassDef *m_classDef; UsedFilesContext m_usedFiles; IncludeInfoContext m_includeInfo; struct Cachable { Cachable() : inheritanceNodes(-1) { templateArgList.setAutoDelete(TRUE); } ScopedPtr inheritsList; ScopedPtr inheritedByList; ScopedPtr classGraph; ScopedPtr collaborationGraph; ScopedPtr nestedClasses; ScopedPtr publicTypes; ScopedPtr publicMethods; ScopedPtr publicStaticMethods; ScopedPtr publicAttributes; ScopedPtr publicStaticAttributes; ScopedPtr publicSlots; ScopedPtr protectedTypes; ScopedPtr protectedMethods; ScopedPtr protectedStaticMethods; ScopedPtr protectedAttributes; ScopedPtr protectedStaticAttributes; ScopedPtr protectedSlots; ScopedPtr privateTypes; ScopedPtr privateMethods; ScopedPtr privateStaticMethods; ScopedPtr privateAttributes; ScopedPtr privateStaticAttributes; ScopedPtr privateSlots; ScopedPtr packageTypes; ScopedPtr packageMethods; ScopedPtr packageStaticMethods; ScopedPtr packageAttributes; ScopedPtr packageStaticAttributes; ScopedPtr unoIDLServices; ScopedPtr unoIDLInterfaces; ScopedPtr signals; ScopedPtr properties; ScopedPtr events; ScopedPtr friends; ScopedPtr related; ScopedPtr templateDecls; int inheritanceNodes; QList templateArgList; }; mutable Cachable m_cache; }; //%% } ClassContext::ClassContext(ClassDef *cd) { //printf("ClassContext::ClassContext(%s)\n",cd?cd->name().data():""); p = new Private(cd); } ClassContext::~ClassContext() { delete p; } TemplateVariant ClassContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Namespace(Symbol): namespace information //%% { class NamespaceContext::Private : public DefinitionContext { public: Private(NamespaceDef *nd) : DefinitionContext(nd) , m_namespaceDef(nd) { addProperty("title",this,&Private::title); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subHighlight); } TemplateVariant title() const { return TemplateVariant(m_namespaceDef->title()); } TemplateVariant highlight() const { return TemplateVariant("namespaces"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } private: NamespaceDef *m_namespaceDef; }; //%% } NamespaceContext::NamespaceContext(NamespaceDef *nd) { p = new Private(nd); } NamespaceContext::~NamespaceContext() { delete p; } TemplateVariant NamespaceContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct File(Symbol): file information //%% { class FileContext::Private : public DefinitionContext { public: Private(FileDef *fd) : DefinitionContext(fd) , m_fileDef(fd) { addProperty("title",this,&Private::title); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subHighlight); addProperty("versionInfo",this,&Private::versionInfo); } TemplateVariant title() const { return m_fileDef->title(); } TemplateVariant highlight() const { return TemplateVariant("files"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } TemplateVariant versionInfo() const { return m_fileDef->getVersion(); } private: FileDef *m_fileDef; }; //%% } FileContext::FileContext(FileDef *fd) { p = new Private(fd); } FileContext::~FileContext() { delete p; } TemplateVariant FileContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Dir(Symbol): directory information //%% { class DirContext::Private : public DefinitionContext { public: Private(DirDef *dd) : DefinitionContext(dd) , m_dirDef(dd) { addProperty("title",this,&Private::title); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subHighlight); addProperty("dirName",this,&Private::dirName); } TemplateVariant title() const { return TemplateVariant(m_dirDef->shortTitle()); } TemplateVariant highlight() const { return TemplateVariant("files"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } TemplateVariant dirName() const { return TemplateVariant(m_dirDef->shortName()); } private: DirDef *m_dirDef; }; //%% } DirContext::DirContext(DirDef *fd) { p = new Private(fd); } DirContext::~DirContext() { delete p; } TemplateVariant DirContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Page(Symbol): page information //%% { class PageContext::Private : public DefinitionContext { public: Private(PageDef *pd) : DefinitionContext(pd) , m_pageDef(pd) { addProperty("title",this,&Private::title); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subHighlight); } TemplateVariant title() const { return TemplateVariant(m_pageDef->title()); } TemplateVariant highlight() const { return TemplateVariant("pages"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } private: PageDef *m_pageDef; }; //%% } PageContext::PageContext(PageDef *pd) { p = new Private(pd); } PageContext::~PageContext() { delete p; } TemplateVariant PageContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ class TextGeneratorHtml : public TextGeneratorIntf { public: TextGeneratorHtml(FTextStream &ts,const QCString &relPath) : m_ts(ts), m_relPath(relPath) {} void writeString(const char *s,bool keepSpaces) const { if (s==0) return; //printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces); if (keepSpaces) { const char *p=s; char c; while ((c=*p++)) { switch(c) { case '<': m_ts << "<"; break; case '>': m_ts << ">"; break; case '\'': m_ts << "'"; break; case '"': m_ts << """; break; case '&': m_ts << "&"; break; case ' ': m_ts << " "; break; } } } else { m_ts << convertToHtml(s); } } void writeBreak(int indent) const { m_ts << "
"; for (int i=0;i"; m_ts << convertToHtml(name); m_ts << ""; } private: FTextStream &m_ts; QCString m_relPath; }; class TextGeneratorFactory { public: static TextGeneratorFactory *instance() { static TextGeneratorFactory *instance = 0; if (instance==0) instance = new TextGeneratorFactory; return instance; } TextGeneratorIntf *create(FTextStream &ts,const QCString &relPath) { switch (g_globals.outputFormat) { case ContextGlobals::Html: return new TextGeneratorHtml(ts,relPath); break; default: break; } return 0; } private: TextGeneratorFactory() {} virtual ~TextGeneratorFactory() {} }; TemplateVariant createLinkedText(Definition *def,const QCString &relPath,const QCString &text) { QGString s; FTextStream ts(&s); TextGeneratorIntf *tg = TextGeneratorFactory::instance()->create(ts,relPath); if (tg) { linkifyText(*tg,def->getOuterScope(),def->getBodyDef(),def,text); return TemplateVariant(s.data(),TRUE); } else { return text; } } //%% struct Member(Symbol): member information //%% { class MemberContext::Private : public DefinitionContext { public: Private(MemberDef *md) : DefinitionContext(md) , m_memberDef(md) { addProperty("declType", this,&Private::declType); addProperty("declArgs", this,&Private::declArgs); addProperty("isStatic", this,&Private::isStatic); addProperty("isObjCMethod", this,&Private::isObjCMethod); addProperty("isObjCProperty", this,&Private::isObjCProperty); addProperty("isImplementation", this,&Private::isImplementation); addProperty("isEvent", this,&Private::isEvent); addProperty("isProperty", this,&Private::isProperty); addProperty("hasDetails", this,&Private::hasDetails); addProperty("exception", this,&Private::exception); addProperty("bitfields", this,&Private::bitfields); addProperty("initializer", this,&Private::initializer); addProperty("oneLineInitializer",this,&Private::oneLineInitializer); addProperty("templateArgs", this,&Private::templateArgs); addProperty("templateAlias", this,&Private::templateAlias); addProperty("propertyAttrs", this,&Private::propertyAttrs); addProperty("eventAttrs", this,&Private::eventAttrs); if (md && md->isProperty()) { if (md->isGettable()) m_propertyAttrs.append("get"); if (md->isSettable()) m_propertyAttrs.append("set"); } if (md && md->isEvent()) { if (md->isAddable()) m_eventAttrs.append("add"); if (md->isRemovable()) m_eventAttrs.append("remove"); if (md->isRaisable()) m_eventAttrs.append("raise"); } } TemplateVariant declType() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->getDeclType()); } TemplateVariant declArgs() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->argsString()); } TemplateVariant exception() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->excpString()); } TemplateVariant bitfields() const { return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->bitfieldString()); } TemplateVariant isStatic() const { return m_memberDef->isStatic(); } TemplateVariant isObjCMethod() const { return m_memberDef->isObjCMethod(); } TemplateVariant isObjCProperty() const { return m_memberDef->isObjCProperty(); } TemplateVariant isImplementation() const { return m_memberDef->isImplementation(); } TemplateVariant isEvent() const { return m_memberDef->isEvent(); } TemplateVariant isProperty() const { return m_memberDef->isProperty(); } TemplateVariant hasDetails() const { return m_memberDef->isDetailedSectionLinkable(); } TemplateVariant initializer() const { return m_memberDef->initializer(); } TemplateVariant oneLineInitializer() const { return m_memberDef->hasOneLineInitializer(); } TemplateVariant templateArgs() const { if (!m_templateArgs) { m_templateArgs.reset(new ArgumentListContext(m_memberDef->templateArguments())); } return m_templateArgs.get(); } TemplateVariant templateAlias() const { if (m_memberDef->isAlias()) { return createLinkedText(m_memberDef,relPathAsString(), QCString(" = ")+m_memberDef->typeString()); } return ""; } TemplateVariant propertyAttrs() const { return &m_propertyAttrs; } TemplateVariant eventAttrs() const { return &m_eventAttrs; } private: MemberDef *m_memberDef; mutable ScopedPtr m_templateArgs; TemplateList m_propertyAttrs; TemplateList m_eventAttrs; }; //%% } MemberContext::MemberContext(MemberDef *md) { p = new Private(md); } MemberContext::~MemberContext() { delete p; } TemplateVariant MemberContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% struct Module(Symbol): group information //%% { class ModuleContext::Private : public DefinitionContext { public: Private(GroupDef *gd) : DefinitionContext(gd) , m_groupDef(gd) { addProperty("title",this,&Private::title); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subHighlight); } TemplateVariant title() const { return TemplateVariant(m_groupDef->groupTitle()); } TemplateVariant highlight() const { return TemplateVariant("modules"); } TemplateVariant subHighlight() const { return TemplateVariant(""); } private: GroupDef *m_groupDef; }; //%% } ModuleContext::ModuleContext(GroupDef *gd) { p = new Private(gd); } ModuleContext::~ModuleContext() { delete p; } TemplateVariant ModuleContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% list NestedClassList[Class] : list of nested classes class NestedClassListContext::Private : public GenericNodeListContext { }; NestedClassListContext::NestedClassListContext() { p = new Private; } NestedClassListContext::~NestedClassListContext() { delete p; } // TemplateListIntf int NestedClassListContext::count() const { return p->count(); } TemplateVariant NestedClassListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *NestedClassListContext::createIterator() const { return p->createIterator(); } void NestedClassListContext::append(ClassDef *cd) { if (cd) { p->append(new ClassContext(cd)); } } //------------------------------------------------------------------------ //%% list ClassList[Class] : list of classes class ClassListContext::Private : public GenericNodeListContext { public: void addClasses(const ClassSDict &classSDict) { ClassSDict::Iterator cli(classSDict); ClassDef *cd; for (cli.toFirst() ; (cd=cli.current()) ; ++cli ) { if (cd->getLanguage()==SrcLangExt_VHDL && ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) ) // no architecture { continue; } if (cd->isLinkableInProject() && cd->templateMaster()==0) { append(new ClassContext(cd)); } } } }; ClassListContext::ClassListContext() { p = new Private; p->addClasses(*Doxygen::classSDict); p->addClasses(*Doxygen::hiddenClasses); } ClassListContext::~ClassListContext() { delete p; } // TemplateListIntf int ClassListContext::count() const { return p->count(); } TemplateVariant ClassListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *ClassListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct ClassInheritanceNode: node in inheritance tree //%% { class ClassInheritanceNodeContext::Private : public PropertyMapper { public: Private(ClassDef *cd) : m_classContext(cd) { //%% bool is_leaf_node: true if this node does not have any children addProperty("is_leaf_node",this,&Private::isLeafNode); //%% ClassInheritance children: list of nested classes/namespaces addProperty("children",this,&Private::children); //%% Class class: class info addProperty("class",this,&Private::getClass); } void addChildren(const BaseClassList *bcl,bool hideSuper) { if (bcl==0) return; BaseClassListIterator bcli(*bcl); BaseClassDef *bcd; for (bcli.toFirst() ; (bcd=bcli.current()) ; ++bcli) { ClassDef *cd=bcd->classDef; if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; } bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { b=hasVisibleRoot(cd->subClasses()); } else { b=hasVisibleRoot(cd->baseClasses()); } if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses())) { bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd); ClassInheritanceNodeContext *tnc = new ClassInheritanceNodeContext(cd); m_children.append(tnc); if (hasChildren) { //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited); bool wasVisited=cd->visited; cd->visited=TRUE; if (cd->getLanguage()==SrcLangExt_VHDL) { tnc->addChildren(cd->baseClasses(),wasVisited); } else { tnc->addChildren(cd->subClasses(),wasVisited); } } } } } TemplateVariant isLeafNode() const { return m_children.isEmpty(); } TemplateVariant children() const { return TemplateVariant(&m_children); } TemplateVariant getClass() const { return TemplateVariant(&m_classContext); } private: GenericNodeListContext m_children; ClassContext m_classContext; }; //%% } ClassInheritanceNodeContext::ClassInheritanceNodeContext(ClassDef *cd) { p = new Private(cd); } ClassInheritanceNodeContext::~ClassInheritanceNodeContext() { delete p; } TemplateVariant ClassInheritanceNodeContext::get(const char *n) const { return p->get(n); } void ClassInheritanceNodeContext::addChildren(const BaseClassList *bcl,bool hideSuper) { p->addChildren(bcl,hideSuper); } //------------------------------------------------------------------------ //%% list ClassInheritance[ClassInheritanceNode]: list of classes class ClassInheritanceContext::Private : public GenericNodeListContext { public: void addClasses(const ClassSDict &classSDict) { ClassSDict::Iterator cli(classSDict); ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { if (!(VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS) { continue; } b=!hasVisibleRoot(cd->subClasses()); } else { b=!hasVisibleRoot(cd->baseClasses()); } if (b) { if (cd->isVisibleInHierarchy()) // should it be visible { // new root level class ClassInheritanceNodeContext *tnc = new ClassInheritanceNodeContext(cd); append(tnc); bool hasChildren = !cd->visited && classHasVisibleChildren(cd); if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren) { tnc->addChildren(cd->baseClasses(),cd->visited); cd->visited=TRUE; } else if (hasChildren) { tnc->addChildren(cd->subClasses(),cd->visited); cd->visited=TRUE; } } } } } }; ClassInheritanceContext::ClassInheritanceContext() { p = new Private; initClassHierarchy(Doxygen::classSDict); initClassHierarchy(Doxygen::hiddenClasses); p->addClasses(*Doxygen::classSDict); p->addClasses(*Doxygen::hiddenClasses); } ClassInheritanceContext::~ClassInheritanceContext() { delete p; } // TemplateListIntf int ClassInheritanceContext::count() const { return (int)p->count(); } TemplateVariant ClassInheritanceContext::at(int index) const { TemplateVariant result; if (index>=0 && indexat(index); } return result; } TemplateListIntf::ConstIterator *ClassInheritanceContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct ClassHierarchy: inheritance tree //%% { class ClassHierarchyContext::Private : public PropertyMapper { public: TemplateVariant tree() const { return TemplateVariant(&m_classTree); } TemplateVariant fileName() const { return "hierarchy"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "classes"; } TemplateVariant subhighlight() const { return "classhierarchy"; } TemplateVariant title() const { static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); if (vhdlOpt) { return VhdlDocGen::trDesignUnitHierarchy(); } else { return theTranslator->trClassHierarchy(); } } Private() { //%% ClassInheritance tree addProperty("tree",this,&Private::tree); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: ClassInheritanceContext m_classTree; }; //%% } ClassHierarchyContext::ClassHierarchyContext() { p = new Private; } ClassHierarchyContext::~ClassHierarchyContext() { delete p; } TemplateVariant ClassHierarchyContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct NestingNode: node is a nesting relation tree //%% { class NestingNodeContext::Private : public PropertyMapper { public: Private(Definition *d,bool addCls) : m_def(d), m_classContext(m_def->definitionType()==Definition::TypeClass?(ClassDef*)d:0), m_namespaceContext(m_def->definitionType()==Definition::TypeNamespace?(NamespaceDef*)d:0) { //%% bool is_leaf_node: true if this node does not have any children addProperty("is_leaf_node",this,&Private::isLeafNode); //%% Nesting children: list of nested classes/namespaces addProperty("children",this,&Private::children); //%% [optional] Class class: class info (if this node represents a class) addProperty("class",this,&Private::getClass); //%% [optional] Namespace namespace: namespace info (if this node represents a namespace) addProperty("namespace",this,&Private::getNamespace); addNamespaces(addCls); addClasses(); } TemplateVariant isLeafNode() const { return m_children.count()==0; } TemplateVariant children() const { return TemplateVariant(&m_children); } TemplateVariant getClass() const { if (m_def->definitionType()==Definition::TypeClass) { return TemplateVariant(&m_classContext); } else { return TemplateVariant(FALSE); } } TemplateVariant getNamespace() const { if (m_def->definitionType()==Definition::TypeNamespace) { return TemplateVariant(&m_namespaceContext); } else { return TemplateVariant(FALSE); } } void addClasses() { ClassDef *cd = m_def->definitionType()==Definition::TypeClass ? (ClassDef*)m_def : 0; if (cd && cd->getClassSDict()) { m_children.addClasses(*cd->getClassSDict(),FALSE); } } void addNamespaces(bool addClasses) { NamespaceDef *nd = m_def->definitionType()==Definition::TypeNamespace ? (NamespaceDef*)m_def : 0; if (nd && nd->getNamespaceSDict()) { m_children.addNamespaces(*nd->getNamespaceSDict(),FALSE,addClasses); } if (addClasses && nd && nd->getClassSDict()) { m_children.addClasses(*nd->getClassSDict(),FALSE); } } Definition *m_def; private: NestingContext m_children; ClassContext m_classContext; NamespaceContext m_namespaceContext; }; //%% } NestingNodeContext::NestingNodeContext(Definition *d,bool addClass) { p = new Private(d,addClass); } NestingNodeContext::~NestingNodeContext() { delete p; } TemplateVariant NestingNodeContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% list Nesting[NestingNode]: namespace and class nesting relations class NestingContext::Private : public GenericNodeListContext { public: void addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses) { NamespaceSDict::Iterator nli(nsDict); NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (nd->localName().find('@')==-1 && (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { bool hasChildren = namespaceHasVisibleChild(nd,addClasses); bool isLinkable = nd->isLinkableInProject(); if (isLinkable || hasChildren) { NestingNodeContext *nnc = new NestingNodeContext(nd,addClasses); append(nnc); } } } } void addClasses(const ClassSDict &clDict,bool rootOnly) { ClassSDict::Iterator cli(clDict); ClassDef *cd; for (;(cd=cli.current());++cli) { if (cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS )// no architecture { continue; } } if (!rootOnly || cd->getOuterScope()==0 || cd->getOuterScope()==Doxygen::globalScope ) { if (classVisibleInIndex(cd) && cd->templateMaster()==0) { NestingNodeContext *nnc = new NestingNodeContext(cd,TRUE); append(nnc); } } } } }; NestingContext::NestingContext() { p = new Private; } NestingContext::~NestingContext() { delete p; } // TemplateListIntf int NestingContext::count() const { return p->count(); } TemplateVariant NestingContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *NestingContext::createIterator() const { return p->createIterator(); } void NestingContext::addClasses(const ClassSDict &clDict,bool rootOnly) { p->addClasses(clDict,rootOnly); } void NestingContext::addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bool addClasses) { p->addNamespaces(nsDict,rootOnly,addClasses); } //------------------------------------------------------------------------ //%% struct ClassTree: Class nesting relations //%% { class ClassTreeContext::Private : public PropertyMapper { public: TemplateVariant tree() const { return TemplateVariant(&m_classTree); } TemplateVariant fileName() const { return "annotated"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "classes"; } TemplateVariant subhighlight() const { return "classlist"; } TemplateVariant title() const { static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); if (fortranOpt) { return theTranslator->trCompoundListFortran(); } else if (vhdlOpt) { return VhdlDocGen::trDesignUnitList(); } else { return theTranslator->trClasses(); } } Private() { if (Doxygen::namespaceSDict) { m_classTree.addNamespaces(*Doxygen::namespaceSDict,TRUE,TRUE); } if (Doxygen::classSDict) { m_classTree.addClasses(*Doxygen::classSDict,TRUE); } //%% Nesting tree addProperty("tree",this,&Private::tree); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: NestingContext m_classTree; }; //%% } ClassTreeContext::ClassTreeContext() { p = new Private; } ClassTreeContext::~ClassTreeContext() { delete p; } TemplateVariant ClassTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list NamespaceList[Namespace] : list of namespaces class NamespaceListContext::Private : public GenericNodeListContext { public: void addNamespaces(const NamespaceSDict &nsDict) { NamespaceSDict::Iterator nli(nsDict); NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (nd->isLinkableInProject()) { append(new NamespaceContext(nd)); } } } }; NamespaceListContext::NamespaceListContext() { p = new Private; p->addNamespaces(*Doxygen::namespaceSDict); } NamespaceListContext::~NamespaceListContext() { delete p; } // TemplateListIntf int NamespaceListContext::count() const { return p->count(); } TemplateVariant NamespaceListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *NamespaceListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct NamespaceTree: tree of nested namespace //%% { class NamespaceTreeContext::Private : public PropertyMapper { public: TemplateVariant tree() const { return TemplateVariant(&m_namespaceTree); } TemplateVariant fileName() const { return "namespaces"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "namespaces"; } TemplateVariant subhighlight() const { return "namespacelist"; } TemplateVariant title() const { static bool javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); if (javaOpt || vhdlOpt) { return theTranslator->trPackages(); } else if (fortranOpt) { return theTranslator->trModulesList(); } else { return theTranslator->trNamespaceList(); } } Private() { if (Doxygen::namespaceSDict) { m_namespaceTree.addNamespaces(*Doxygen::namespaceSDict,TRUE,FALSE); } //%% Nesting tree addProperty("tree",this,&Private::tree); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: NestingContext m_namespaceTree; }; //%% } NamespaceTreeContext::NamespaceTreeContext() { p = new Private; } NamespaceTreeContext::~NamespaceTreeContext() { delete p; } TemplateVariant NamespaceTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list FileList[File] : list of files class FileListContext::Private : public GenericNodeListContext { public: void addFiles(const FileNameList &fnList) { // TODO: if FULL_PATH_NAMES is enabled, the ordering should be dir+file FileNameListIterator fnli(fnList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); FileDef *fd; for (fni.toFirst();(fd=fni.current());++fni) { bool doc = fd->isLinkableInProject(); bool src = fd->generateSourceFile(); bool nameOk = !fd->isDocumentationFile(); if (nameOk && (doc || src) && !fd->isReference()) { append(new FileContext(fd)); } } } } }; FileListContext::FileListContext() { p = new Private; if (Doxygen::inputNameList) p->addFiles(*Doxygen::inputNameList); } FileListContext::~FileListContext() { delete p; } // TemplateListIntf int FileListContext::count() const { return p->count(); } TemplateVariant FileListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *FileListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list UsedFiles[File] : list of files class UsedFilesContext::Private : public GenericNodeListContext { public: void addFile(FileDef *fd) { append(new FileContext(fd)); } }; UsedFilesContext::UsedFilesContext(ClassDef *cd) { p = new Private; if (cd) { QListIterator li(cd->usedFiles()); FileDef *fd; for (li.toFirst();(fd=li.current());++li) { p->addFile(fd); } } } UsedFilesContext::~UsedFilesContext() { delete p; } // TemplateListIntf int UsedFilesContext::count() const { return p->count(); } TemplateVariant UsedFilesContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *UsedFilesContext::createIterator() const { return p->createIterator(); } void UsedFilesContext::addFile(FileDef *fd) { p->addFile(fd); } //------------------------------------------------------------------------ //%% struct DirFileNode: node is a directory hierarchy //%% { class DirFileNodeContext::Private : public PropertyMapper { public: Private(Definition *d) : m_def(d), m_dirContext (m_def->definitionType()==Definition::TypeDir ? (DirDef*)d : 0), m_fileContext(m_def->definitionType()==Definition::TypeFile ? (FileDef*)d : 0) { //%% bool is_leaf_node: true if this node does not have any children addProperty("is_leaf_node",this,&Private::isLeafNode); //%% DirFile children: list of nested classes/namespaces addProperty("children",this,&Private::children); //%% [optional] Dir dir: directory info (if this node represents a directory) addProperty("dir",this,&Private::getDir); //%% [optional] File file: file info (if this node represents a file) addProperty("file",this,&Private::getFile); addDirFiles(); } TemplateVariant isLeafNode() const { return m_children.count()==0; } TemplateVariant children() const { return TemplateVariant(&m_children); } TemplateVariant getDir() const { if (m_def->definitionType()==Definition::TypeDir) { return TemplateVariant(&m_dirContext); } else { return TemplateVariant(FALSE); } } TemplateVariant getFile() const { if (m_def->definitionType()==Definition::TypeFile) { return TemplateVariant(&m_fileContext); } else { return TemplateVariant(FALSE); } } void addDirFiles() { DirDef *dd = m_def->definitionType()==Definition::TypeDir ? (DirDef*)m_def : 0; if (dd) { m_children.addDirs(dd->subDirs()); if (dd && dd->getFiles()) { m_children.addFiles(*dd->getFiles()); } } } private: Definition *m_def; DirFileContext m_children; DirContext m_dirContext; FileContext m_fileContext; }; //%% } DirFileNodeContext::DirFileNodeContext(Definition *d) { p = new Private(d); } DirFileNodeContext::~DirFileNodeContext() { delete p; } TemplateVariant DirFileNodeContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% list DirFile[DirFileNode]: list of directories and/or files class DirFileContext::Private : public GenericNodeListContext { public: void addDirs(const DirSDict &dirDict) { SDict::Iterator dli(dirDict); DirDef *dd; for (dli.toFirst();(dd=dli.current());++dli) { if (dd->getOuterScope()==Doxygen::globalScope) { append(new DirFileNodeContext(dd)); } } } void addDirs(const DirList &dirList) { QListIterator li(dirList); DirDef *dd; for (li.toFirst();(dd=li.current());++li) { append(new DirFileNodeContext(dd)); } } void addFiles(const FileNameList &fnList) { FileNameListIterator fnli(fnList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); FileDef *fd; for (;(fd=fni.current());++fni) { if (fd->getDirDef()==0) // top level file { append(new DirFileNodeContext(fd)); } } } } void addFiles(const FileList &fList) { QListIterator li(fList); FileDef *fd; for (li.toFirst();(fd=li.current());++li) { append(new DirFileNodeContext(fd)); } } }; DirFileContext::DirFileContext() { p = new Private; } DirFileContext::~DirFileContext() { delete p; } // TemplateListIntf int DirFileContext::count() const { return p->count(); } TemplateVariant DirFileContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *DirFileContext::createIterator() const { return p->createIterator(); } void DirFileContext::addDirs(const DirSDict &dirs) { p->addDirs(dirs); } void DirFileContext::addDirs(const DirList &dirs) { p->addDirs(dirs); } void DirFileContext::addFiles(const FileNameList &files) { p->addFiles(files); } void DirFileContext::addFiles(const FileList &files) { p->addFiles(files); } //------------------------------------------------------------------------ //%% struct FileTree: tree of directories and files //%% { class FileTreeContext::Private : public PropertyMapper { public: TemplateVariant tree() const { return TemplateVariant(&m_dirFileTree); } TemplateVariant fileName() const { return "files"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "files"; } TemplateVariant subhighlight() const { return "filelist"; } TemplateVariant title() const { return theTranslator->trFileList(); } Private() { // Add dirs tree if (Doxygen::directories) { m_dirFileTree.addDirs(*Doxygen::directories); } if (Doxygen::inputNameList) { m_dirFileTree.addFiles(*Doxygen::inputNameList); } //%% DirFile tree: addProperty("tree",this,&Private::tree); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: DirFileContext m_dirFileTree; }; //%% } FileTreeContext::FileTreeContext() { p = new Private; } FileTreeContext::~FileTreeContext() { delete p; } TemplateVariant FileTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct PageNode: node is a directory hierarchy //%% { class PageNodeContext::Private : public PropertyMapper { public: Private(PageDef *pd) : m_pageDef(pd), m_pageContext(pd) { //%% bool is_leaf_node: true if this node does not have any children addProperty("is_leaf_node",this,&Private::isLeafNode); //%% PageList children: list of nested classes/namespaces addProperty("children",this,&Private::children); //%% Page page: page info addProperty("page",this,&Private::getPage); addPages(); } TemplateVariant isLeafNode() const { return m_children.count()==0; } TemplateVariant children() const { return TemplateVariant(&m_children); } TemplateVariant getPage() const { return TemplateVariant(&m_pageContext); } void addPages() { if (m_pageDef->getSubPages()) { m_children.addPages(*m_pageDef->getSubPages(),FALSE); } } private: PageDef *m_pageDef; PageNodeListContext m_children; PageContext m_pageContext; }; //%% } PageNodeContext::PageNodeContext(PageDef *pd) { p = new Private(pd); } PageNodeContext::~PageNodeContext() { delete p; } TemplateVariant PageNodeContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% list PageList[PageNode]: list of directories and/or files class PageNodeListContext::Private : public GenericNodeListContext { public: void addPages(const PageSDict &pages,bool rootOnly) { SDict::Iterator pli(pages); PageDef *pd; for (pli.toFirst();(pd=pli.current());++pli) { if (!rootOnly || pd->getOuterScope()==0 || pd->getOuterScope()->definitionType()!=Definition::TypePage) { append(new PageNodeContext(pd)); } } } }; PageNodeListContext::PageNodeListContext() { p = new Private; } PageNodeListContext::~PageNodeListContext() { delete p; } // TemplateListIntf int PageNodeListContext::count() const { return p->count(); } TemplateVariant PageNodeListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *PageNodeListContext::createIterator() const { return p->createIterator(); } void PageNodeListContext::addPages(const PageSDict &pages,bool rootOnly) { p->addPages(pages,rootOnly); } //------------------------------------------------------------------------ //%% struct PageTree: tree of related pages //%% { class PageTreeContext::Private : public PropertyMapper { public: TemplateVariant tree() const { return TemplateVariant(&m_pageList); } TemplateVariant fileName() const { return "pages"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "pages"; } TemplateVariant subhighlight() const { return ""; } TemplateVariant title() const { return theTranslator->trRelatedPages(); } Private() { // Add pages if (Doxygen::pageSDict) { m_pageList.addPages(*Doxygen::pageSDict,TRUE); } //%% PageNodeList tree: addProperty("tree",this,&Private::tree); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: PageNodeListContext m_pageList; }; //%% } PageTreeContext::PageTreeContext() { p = new Private; } PageTreeContext::~PageTreeContext() { delete p; } TemplateVariant PageTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct PageList: list of related pages //%% { class PageListContext::Private : public PropertyMapper { public: TemplateVariant items() const { return TemplateVariant(&m_pageList); } TemplateVariant fileName() const { return "pages"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "pages"; } TemplateVariant subhighlight() const { return ""; } TemplateVariant title() const { return theTranslator->trRelatedPages(); } Private() { // Add pages PageSDict::Iterator pdi(*Doxygen::pageSDict); PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { if (!pd->getGroupDef() && !pd->isReference()) { m_pageList.append(new PageContext(pd)); } } //%% list[Page] items: addProperty("items",this,&Private::items); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: GenericNodeListContext m_pageList; }; //%% } PageListContext::PageListContext() { p = new Private; } PageListContext::~PageListContext() { delete p; } TemplateVariant PageListContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct ModuleNode: node is a directory hierarchy //%% { class ModuleNodeContext::Private : public PropertyMapper { public: Private(GroupDef *gd) : m_groupDef(gd), m_moduleContext(gd) { //%% bool is_leaf_node: true if this node does not have any children addProperty("is_leaf_node",this,&Private::isLeafNode); //%% ModuleList children: list of submodules addProperty("children",this,&Private::children); //%% Module module: module info addProperty("module",this,&Private::getModule); addModules(); } TemplateVariant isLeafNode() const { return m_children.count()==0; } TemplateVariant children() const { return TemplateVariant(&m_children); } TemplateVariant getModule() const { return TemplateVariant(&m_moduleContext); } void addModules() { if (m_groupDef->getSubGroups()) { m_children.addModules(*m_groupDef->getSubGroups()); } } private: GroupDef *m_groupDef; ModuleListContext m_children; ModuleContext m_moduleContext; }; //%% } ModuleNodeContext::ModuleNodeContext(GroupDef *gd) { p = new Private(gd); } ModuleNodeContext::~ModuleNodeContext() { delete p; } TemplateVariant ModuleNodeContext::get(const char *n) const { return p->get(n); } //------------------------------------------------------------------------ //%% list ModuleList[ModuleNode]: list of directories and/or files class ModuleListContext::Private : public GenericNodeListContext { public: void addModules(const GroupSDict &modules) { static bool externalGroups = Config_getBool("EXTERNAL_GROUPS"); GroupSDict::Iterator gli(modules); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { if (!gd->isASubGroup() && gd->isVisible() && (!gd->isReference() || externalGroups)) { append(new ModuleNodeContext(gd)); } } } void addModules(const GroupList &list) { QListIterator gli(list); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { append(new ModuleNodeContext(gd)); } } }; ModuleListContext::ModuleListContext() { p = new Private; } ModuleListContext::~ModuleListContext() { delete p; } // TemplateListIntf int ModuleListContext::count() const { return p->count(); } TemplateVariant ModuleListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *ModuleListContext::createIterator() const { return p->createIterator(); } void ModuleListContext::addModules(const GroupSDict &modules) { p->addModules(modules); } void ModuleListContext::addModules(const GroupList &modules) { p->addModules(modules); } //------------------------------------------------------------------------ //%% struct ModuleTree: tree of modules //%% { class ModuleTreeContext::Private : public PropertyMapper { public: TemplateVariant tree() const { return TemplateVariant(&m_moduleList); } TemplateVariant fileName() const { return "modules"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "modules"; } TemplateVariant subhighlight() const { return ""; } TemplateVariant title() const { return theTranslator->trModules(); } Private() { // Add modules if (Doxygen::groupSDict) { m_moduleList.addModules(*Doxygen::groupSDict); } //%% ModuleList tree: addProperty("tree",this,&Private::tree); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: ModuleListContext m_moduleList; }; //%% } ModuleTreeContext::ModuleTreeContext() { p = new Private; } ModuleTreeContext::~ModuleTreeContext() { delete p; } TemplateVariant ModuleTreeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct ExampleList: list of examples page //%% { class ExampleListContext::Private : public PropertyMapper { public: TemplateVariant items() const { return TemplateVariant(&m_pageList); } TemplateVariant fileName() const { return "examples"; } TemplateVariant relPath() const { return ""; } TemplateVariant highlight() const { return "examples"; } TemplateVariant subhighlight() const { return ""; } TemplateVariant title() const { return theTranslator->trExamples(); } Private() { // Add pages if (Doxygen::exampleSDict) { m_pageList.addPages(*Doxygen::exampleSDict,FALSE); } //%% PageNodeList items: addProperty("items",this,&Private::items); addProperty("fileName",this,&Private::fileName); addProperty("relPath",this,&Private::relPath); addProperty("highlight",this,&Private::highlight); addProperty("subhighlight",this,&Private::subhighlight); addProperty("title",this,&Private::title); } private: PageNodeListContext m_pageList; }; //%% } ExampleListContext::ExampleListContext() { p = new Private; } ExampleListContext::~ExampleListContext() { delete p; } TemplateVariant ExampleListContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct InheritanceNode: a class in the inheritance list //%% { class InheritanceNodeContext::Private : public PropertyMapper { public: Private(ClassDef *cd,const QCString &name) : m_classContext(cd), m_name(name) { addProperty("class",this,&Private::getClass); addProperty("name",this,&Private::name); } TemplateVariant getClass() const { return &m_classContext; } TemplateVariant name() const { return m_name; } private: ClassContext m_classContext; QCString m_name; }; //%% } InheritanceNodeContext::InheritanceNodeContext(ClassDef *cd,const QCString &name) { p = new Private(cd,name); } InheritanceNodeContext::~InheritanceNodeContext() { delete p; } TemplateVariant InheritanceNodeContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list InheritanceList[InheritanceNode] : list of inherited classes class InheritanceListContext::Private : public GenericNodeListContext { public: void addClass(ClassDef *cd,const QCString &name) { append(new InheritanceNodeContext(cd,name)); } }; InheritanceListContext::InheritanceListContext(const BaseClassList *list, bool baseClasses) { p = new Private; if (list) { BaseClassListIterator li(*list); BaseClassDef *bcd; for (li.toFirst();(bcd=li.current());++li) { ClassDef *cd=bcd->classDef; QCString name; if (baseClasses) { name = insertTemplateSpecifierInScope( cd->displayName(),bcd->templSpecifiers); } else { name = cd->displayName(); } //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses); p->addClass(cd,name); } } } InheritanceListContext::~InheritanceListContext() { delete p; } // TemplateListIntf int InheritanceListContext::count() const { return p->count(); } TemplateVariant InheritanceListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% list MemberList[Member] : list of inherited classes class MemberListContext::Private : public GenericNodeListContext { public: void addMember(MemberDef *md) { append(new MemberContext(md)); } }; MemberListContext::MemberListContext(const MemberList *list) { p = new Private; if (list) { MemberListIterator mli(*list); MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { if (md->isBriefSectionVisible()) { p->addMember(md); } } } } MemberListContext::~MemberListContext() { delete p; } // TemplateListIntf int MemberListContext::count() const { return p->count(); } TemplateVariant MemberListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *MemberListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ //%% struct MemberListInfo: member list information //%% { class MemberListInfoContext::Private : public PropertyMapper { public: Private(const MemberList *ml,const QCString &title,const QCString &subtitle) : m_memberListContext(ml), m_memberList(ml), m_title(title), m_subtitle(subtitle) { addProperty("members", this,&Private::members); addProperty("title", this,&Private::title); addProperty("subtitle",this,&Private::subtitle); addProperty("anchor", this,&Private::anchor); // TODO: member groups } TemplateVariant members() const { return &m_memberListContext; } TemplateVariant title() const { return m_title; } TemplateVariant subtitle() const { return m_subtitle; } TemplateVariant anchor() const { return m_memberList->listTypeAsString(m_memberList->listType()); } private: MemberListContext m_memberListContext; const MemberList *m_memberList; QCString m_title; QCString m_subtitle; }; //%% } MemberListInfoContext::MemberListInfoContext(const MemberList *ml, const QCString &title,const QCString &subtitle) { p = new Private(ml,title,subtitle); } MemberListInfoContext::~MemberListInfoContext() { delete p; } TemplateVariant MemberListInfoContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% struct Argument: member list information //%% { class ArgumentContext::Private : public PropertyMapper { public: Private(const Argument *arg) : m_argument(arg) { addProperty("type", this,&Private::type); addProperty("name", this,&Private::name); addProperty("defVal",this,&Private::defVal); } TemplateVariant type() const { return m_argument->type; } TemplateVariant name() const { return m_argument->name; } TemplateVariant defVal() const { return m_argument->defval; } private: const Argument *m_argument; }; //%% } ArgumentContext::ArgumentContext(const Argument *al) { p = new Private(al); } ArgumentContext::~ArgumentContext() { delete p; } TemplateVariant ArgumentContext::get(const char *name) const { return p->get(name); } //------------------------------------------------------------------------ //%% list ArgumentList[Argument] : list of inherited classes class ArgumentListContext::Private : public GenericNodeListContext { public: void addArgument(const Argument *arg) { append(new ArgumentContext(arg)); } }; ArgumentListContext::ArgumentListContext(const ArgumentList *list) { p = new Private; if (list) { ArgumentListIterator ali(*list); const Argument *arg; for (ali.toFirst();(arg=ali.current());++ali) { p->addArgument(arg); } } } ArgumentListContext::~ArgumentListContext() { delete p; } // TemplateListIntf int ArgumentListContext::count() const { return p->count(); } TemplateVariant ArgumentListContext::at(int index) const { return p->at(index); } TemplateListIntf::ConstIterator *ArgumentListContext::createIterator() const { return p->createIterator(); } //------------------------------------------------------------------------ class HtmlEscaper : public TemplateEscapeIntf { public: QCString escape(const QCString &s) { return convertToHtml(s,TRUE); } }; //------------------------------------------------------------------------ class HtmlSpaceless : public TemplateSpacelessIntf { public: HtmlSpaceless() : m_insideTag(FALSE), m_insideString('\0'), m_removeSpaces(TRUE) {} QCString remove(const QCString &s) { QGString result; const char *p = s.data(); char c; while ((c=*p++)) { switch(c) { case '<': // start of a tag if (!m_insideString) m_insideTag=TRUE,m_removeSpaces=FALSE; result+=c; break; case '>': // end of a tag if (!m_insideString) m_insideTag=FALSE,m_removeSpaces=TRUE; result+=c; break; case '\\': // escaped character in a string result+=c; if (m_insideString && *p) result+=*p++; break; case '"': case '\'': if (m_insideTag) { if (m_insideString==c) // end of string { m_insideString='\0'; } else // start of string { m_insideString=c; } } result+=c; break; case ' ': case '\t': case '\n': // whitespace if (!m_removeSpaces) { result+=' '; } if (!m_insideTag) // outside tags strip consecutive whitespace { m_removeSpaces=TRUE; } break; default: result+=c; m_removeSpaces=FALSE; break; } } result+='\0'; //printf("HtmlSpaceless::remove('%s')='%s' m_insideTag=%d m_insideString=%d removeSpaces=%d\n",s.data(),result.data(), // m_insideTag,m_insideString,m_removeSpaces); return result.data(); } private: bool m_insideTag; char m_insideString; bool m_removeSpaces; }; //------------------------------------------------------------------------ void generateOutputViaTemplate() { TemplateEngine e; TemplateContext *ctx = e.createContext(); if (ctx) { DoxygenContext doxygen; ConfigContext config; TranslateContext tr; ClassListContext classList; ClassTreeContext classTree; ClassHierarchyContext classHierarchy; NamespaceListContext namespaceList; NamespaceTreeContext namespaceTree; FileListContext fileList; FileTreeContext fileTree; PageTreeContext pageTree; PageListContext pageList; ModuleTreeContext moduleTree; ExampleListContext exampleList; //%% Doxygen doxygen: ctx->set("doxygen",&doxygen); //%% Translator tr: ctx->set("tr",&tr); //%% Config config: ctx->set("config",&config); //%% ClassList classList: ctx->set("classList",&classList); // not used for standard HTML //%% ClassTree classTree: ctx->set("classTree",&classTree); // classIndex //%% ClassHierarchy classHierarchy: ctx->set("classHierarchy",&classHierarchy); //%% NamespaceList namespaceList: ctx->set("namespaceList",&namespaceList); //%% NamespaceTree namespaceTree: ctx->set("namespaceTree",&namespaceTree); //%% FileList fileList: ctx->set("fileList",&fileList); //%% FileTree fileTree: ctx->set("fileTree",&fileTree); //%% PageList pageList ctx->set("pageList",&pageList); //%% PageTree pageTree ctx->set("pageTree",&pageTree); //%% ModuleTree moduleTree ctx->set("moduleTree",&moduleTree); //%% ExampleList exampleList ctx->set("exampleList",&exampleList); // render HTML output Template *tpl = e.loadByName("htmllayout.tpl"); if (tpl) { g_globals.outputFormat = ContextGlobals::Html; g_globals.dynSectionId = 0; g_globals.outputDir = Config_getString("HTML_OUTPUT"); HtmlEscaper esc; ctx->setEscapeIntf(&esc); HtmlSpaceless spl; ctx->setSpacelessIntf(&spl); ctx->setOutputDirectory(g_globals.outputDir); FTextStream ts; tpl->render(ts,ctx); } // TODO: render other outputs } }