From 064992b0c901661b49de24ce1a1d9a06e9957a93 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sun, 6 Jul 2014 10:06:00 +0200 Subject: Added groupby filter and some more context info --- Doxyfile | 2 +- src/context.cpp | 91 ++++++++++++++++++++++++++++++++++++--- src/template.cpp | 128 ++++++++++++++++++++++++++++++++++++++++++------------- src/template.h | 2 + 4 files changed, 187 insertions(+), 36 deletions(-) diff --git a/Doxyfile b/Doxyfile index 3b175c4..bc30271 100644 --- a/Doxyfile +++ b/Doxyfile @@ -173,7 +173,7 @@ QHP_SECT_FILTER_ATTRS = QHG_LOCATION = GENERATE_ECLIPSEHELP = NO ECLIPSE_DOC_ID = org.doxygen.Project -DISABLE_INDEX = YES +DISABLE_INDEX = NO GENERATE_TREEVIEW = YES ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 diff --git a/src/context.cpp b/src/context.cpp index f432ed0..cd44e1b 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -804,6 +804,46 @@ class TranslateContext::Private : public PropertyMapper { return theTranslator->trDirectories(); } + TemplateVariant all() const + { + return theTranslator->trAll(); + } + TemplateVariant functions() const + { + static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); + static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL"); + return fortranOpt ? theTranslator->trSubprograms() : + vhdlOpt ? VhdlDocGen::trFunctionAndProc() : + theTranslator->trFunctions(); + } + TemplateVariant variables() const + { + return theTranslator->trVariables(); + } + TemplateVariant typedefs() const + { + return theTranslator->trTypedefs(); + } + TemplateVariant enums() const + { + return theTranslator->trEnumerations(); + } + TemplateVariant properties() const + { + return theTranslator->trProperties(); + } + TemplateVariant events() const + { + return theTranslator->trEvents(); + } + TemplateVariant related() const + { + return theTranslator->trRelatedFunctions(); + } + TemplateVariant macros() const + { + return theTranslator->trDefines(); + } Private() { //%% string generatedBy @@ -878,8 +918,6 @@ class TranslateContext::Private : public PropertyMapper addProperty("defineValue", this,&Private::defineValue); //%% string initialValue addProperty("initialValue", this,&Private::initialValue); - //%% string enumerationValues - addProperty("enumerationValues", this,&Private::enumerationValues); //%% markerstring implements addProperty("implements", this,&Private::implements); //%% markerstring reimplements @@ -922,6 +960,26 @@ class TranslateContext::Private : public PropertyMapper addProperty("directories", this,&Private::directories); //%% string moduleDescript addProperty("modulesDescription", this,&Private::modulesDescription); + //%% string all + addProperty("all", this,&Private::all); + //%% string functions + addProperty("functions", this,&Private::functions); + //%% string variables + addProperty("variables", this,&Private::variables); + //%% string typedefs + addProperty("typedefs", this,&Private::typedefs); + //%% string enums + addProperty("enums", this,&Private::enums); + //%% string enumValues + addProperty("enumValues", this,&Private::enumerationValues); + //%% string properties + addProperty("properties", this,&Private::properties); + //%% string events + addProperty("events", this,&Private::events); + //%% string related + addProperty("related", this,&Private::related); + //%% string macros + addProperty("macros", this,&Private::macros); m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); @@ -3072,6 +3130,7 @@ class MemberContext::Private : public DefinitionContext addProperty("propertyAttrs", this,&Private::propertyAttrs); addProperty("eventAttrs", this,&Private::eventAttrs); addProperty("class", this,&Private::getClass); + addProperty("file", this,&Private::getFile); addProperty("definition", this,&Private::definition); addProperty("parameters", this,&Private::parameters); addProperty("hasParameterList", this,&Private::hasParameterList); @@ -3536,6 +3595,21 @@ class MemberContext::Private : public DefinitionContext return TemplateVariant(FALSE); } } + TemplateVariant getFile() const + { + if (!m_cache.fileDef && m_memberDef->getFileDef()) + { + m_cache.fileDef.reset(FileContext::alloc(m_memberDef->getFileDef())); + } + if (m_cache.fileDef) + { + return m_cache.fileDef.get(); + } + else + { + return TemplateVariant(FALSE); + } + } TemplateVariant definition() const { return createLinkedText(m_memberDef,relPathAsString(), @@ -3966,6 +4040,7 @@ class MemberContext::Private : public DefinitionContext SharedPtr templateArgs; SharedPtr arguments; SharedPtr enumValues; + SharedPtr fileDef; SharedPtr classDef; SharedPtr anonymousType; SharedPtr templateDecls; @@ -6521,7 +6596,7 @@ class GlobalsIndexContext::Private : public PropertyMapper } TemplateVariant subhighlight() const { - return "globals"; + return "filemembers"; } TemplateVariant title() const { @@ -7826,7 +7901,13 @@ class HtmlEscaper : public TemplateEscapeIntf class HtmlSpaceless : public TemplateSpacelessIntf { public: - HtmlSpaceless() : m_insideTag(FALSE), m_insideString('\0'), m_removeSpaces(TRUE) {} + HtmlSpaceless() { reset(); } + void reset() + { + m_insideTag = FALSE; + m_insideString = '\0'; + m_removeSpaces = TRUE; + } QCString remove(const QCString &s) { QGString result; @@ -7880,7 +7961,7 @@ class HtmlSpaceless : public TemplateSpacelessIntf } } result+='\0'; - //printf("HtmlSpaceless::remove('%s')='%s' m_insideTag=%d m_insideString=%d removeSpaces=%d\n",s.data(),result.data(), + //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(); } diff --git a/src/template.cpp b/src/template.cpp index af012e9..9070b98 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -702,7 +702,9 @@ class TemplateContextImpl : public TemplateContext QCString outputDirectory() const { return m_outputDir; } TemplateEscapeIntf *escapeIntf() const { return m_activeEscapeIntf; } TemplateSpacelessIntf *spacelessIntf() const { return m_spacelessIntf; } - void enableSpaceless(bool b) { m_spacelessEnabled=b; } + void enableSpaceless(bool b) { if (b && !m_spacelessEnabled) m_spacelessIntf->reset(); + m_spacelessEnabled=b; + } bool spacelessEnabled() const { return m_spacelessEnabled && m_spacelessIntf; } void warn(const char *fileName,int line,const char *fmt,...) const; @@ -993,6 +995,83 @@ class FilterListSort //-------------------------------------------------------------------- +/** @brief The implementation of the "groupBy" filter */ +class FilterGroupBy +{ + struct ListElem + { + ListElem(const QCString &k,const TemplateVariant &v) : key(k), value(v) {} + QCString key; + TemplateVariant value; + }; + class SortList : public QList + { + public: + SortList() { setAutoDelete(TRUE); } + private: + int compareValues(const ListElem *item1,const ListElem *item2) const + { + return qstrcmp(item1->key,item2->key); + } + }; + public: + static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args) + { + if (v.type()==TemplateVariant::List && args.type()==TemplateVariant::String) + { + //printf("FilterListSort::apply: v=%s args=%s\n",v.toString().data(),args.toString().data()); + TemplateListIntf::ConstIterator *it = v.toList()->createIterator(); + + TemplateVariant item; + TemplateList *result = TemplateList::alloc(); + + // create list of items based on v using the data in args as a sort key + SortList sortList; + for (it->toFirst();(it->current(item));it->toNext()) + { + TemplateStructIntf *s = item.toStruct(); + if (s) + { + QCString sortKey = determineSortKey(s,args.toString()); + sortList.append(new ListElem(sortKey,item)); + //printf("sortKey=%s\n",sortKey.data()); + } + } + delete it; + + // sort the list + sortList.sort(); + + // add sorted items to the result list + QListIterator sit(sortList); + ListElem *elem; + TemplateList *groupList=0; + QCString prevKey; + for (sit.toFirst();(elem=sit.current());++sit) + { + if (groupList==0 || elem->key!=prevKey) + { + groupList = TemplateList::alloc(); + result->append(groupList); + prevKey = elem->key; + } + groupList->append(elem->value); + } + return result; + } + return v; + } + + private: + static QCString determineSortKey(TemplateStructIntf *s,const QCString &attribName) + { + TemplateVariant v = s->get(attribName); + return v.toString(); + } +}; + +//-------------------------------------------------------------------- + /** @brief The implementation of the "paginate" filter */ class FilterPaginate { @@ -1053,7 +1132,7 @@ class FilterAlphaIndex private: int compareValues(const ListElem *item1,const ListElem *item2) const { - return item2->key-item1->key; + return item1->key-item2->key; } }; static QCString keyToLetter(uint startLetter) @@ -1065,7 +1144,7 @@ class FilterAlphaIndex char s[10]; if (startLetter>0x20 && startLetter<=0x7f) // printable ASCII character { - s[0]=(char)startLetter; + s[0]=tolower((char)startLetter); s[1]=0; } else @@ -1283,6 +1362,7 @@ static TemplateFilterFactory::AutoRegister fNoWrap("nowrap"); static TemplateFilterFactory::AutoRegister fFlatten("flatten"); static TemplateFilterFactory::AutoRegister fDefault("default"); static TemplateFilterFactory::AutoRegister fPrepend("prepend"); +static TemplateFilterFactory::AutoRegister fGroupBy("groupBy"); static TemplateFilterFactory::AutoRegister fListSort("listsort"); static TemplateFilterFactory::AutoRegister fPaginate("paginate"); static TemplateFilterFactory::AutoRegister fStripPath("stripPath"); @@ -3706,7 +3786,7 @@ class TemplateNodeWith : public TemplateNodeCreator } else { - parser->warn(parser->templateName(),line,"invalid argument '%s' for with tag",arg.data()); + parser->warn(parser->templateName(),line,"invalid argument '%s' for 'with' tag",arg.data()); } ++it; } @@ -3813,47 +3893,35 @@ class TemplateNodeSet : public TemplateNodeCreator }; public: TemplateNodeSet(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data) - : TemplateNodeCreator(parser,parent,line) + : TemplateNodeCreator(parser,parent,line), m_mapping(0) { TRACE(("{TemplateNodeSet(%s)\n",data.data())); - m_args.setAutoDelete(TRUE); ExpressionParser expParser(parser,line); - QValueList args = split(data," "); - QValueListIterator it = args.begin(); - while (it!=args.end()) + // data format: name=expression + int j=data.find('='); + ExprAst *expr = 0; + if (j>0 && (expr = expParser.parse(data.mid(j+1)))) { - QCString arg = *it; - int j=arg.find('='); - if (j>0) - { - ExprAst *expr = expParser.parse(arg.mid(j+1)); - if (expr) - { - m_args.append(new Mapping(arg.left(j),expr)); - } - } - else - { - parser->warn(parser->templateName(),line,"invalid argument '%s' for with tag",arg.data()); - } - ++it; + m_mapping = new Mapping(data.left(j),expr); } TRACE(("}TemplateNodeSet(%s)\n",data.data())); } + ~TemplateNodeSet() + { + delete m_mapping; + } void render(FTextStream &, TemplateContext *c) { TemplateContextImpl *ci = dynamic_cast(c); ci->setLocation(m_templateName,m_line); - QListIterator it(m_args); - Mapping *mapping; - for (it.toFirst();(mapping=it.current());++it) + if (m_mapping) { - TemplateVariant value = mapping->value->resolve(c); - ci->set(mapping->name,value); + TemplateVariant value = m_mapping->value->resolve(c); + ci->set(m_mapping->name,value); } } private: - QList m_args; + Mapping *m_mapping; }; //---------------------------------------------------------- diff --git a/src/template.h b/src/template.h index 7994216..ef9792c 100644 --- a/src/template.h +++ b/src/template.h @@ -406,6 +406,8 @@ class TemplateSpacelessIntf public: /** Returns the \a input after removing redundant whitespace */ virtual QCString remove(const QCString &input) = 0; + /** Reset filter state */ + virtual void reset() = 0; }; //------------------------------------------------------------------------ -- cgit v0.12