From edd056308d04d6f445a48e05105d4d9a0ece80a0 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Tue, 6 May 2014 21:28:15 +0200 Subject: Added flatten, listsort and paginate filters --- src/template.cpp | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/src/template.cpp b/src/template.cpp index 64d3523..e882930 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "sortdict.h" #include "ftextstream.h" @@ -806,6 +807,184 @@ class FilterDefault //-------------------------------------------------------------------- +/** @brief The implementation of the "flatten" filter */ +class FilterFlatten +{ + public: + static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &) + { + if (!v.isValid() || v.type()!=TemplateVariant::List) + { + return v; + } + else + { + TemplateList *list = TemplateList::alloc(); + flatten(v.toList(),list); + return TemplateVariant(list); + } + } + + private: + static void flatten(TemplateListIntf *tree,TemplateList *list) + { + TemplateListIntf::ConstIterator *it = tree->createIterator(); + TemplateVariant item; + for (it->toFirst();(it->current(item));it->toNext()) + { + TemplateStructIntf *s = item.toStruct(); + if (s) + { + list->append(item); + // if s has "children" then recurse into the children + TemplateVariant children = s->get("children"); + if (children.isValid() && children.type()==TemplateVariant::List) + { + flatten(children.toList(),list); + } + } + else + { + list->append(item); + } + } + delete it; + } +}; + +//-------------------------------------------------------------------- + +/** @brief The implementation of the "listsort" filter */ +class FilterListSort +{ + 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; + for (sit.toFirst();(elem=sit.current());++sit) + { + result->append(elem->value); + } + return result; + } + return v; + } + + private: + static QCString determineSortKey(TemplateStructIntf *s,const QCString &arg) + { + int i,p=0; + QCString result; + while ((i=arg.find("{{",p))!=-1) + { + result+=arg.mid(p,i-p); + int j=arg.find("}}",i+2); + if (j!=-1) + { + QCString var = arg.mid(i+2,j-i-2); + TemplateVariant val=s->get(var); + //printf("found argument %s value=%s\n",var.data(),val.toString().data()); + result+=val.toString(); + p=j+2; + } + else + { + p=i+1; + } + } + result+=arg.right(arg.length()-p); + return result; + } +}; + +//-------------------------------------------------------------------- + +/** @brief The implementation of the "listsort" filter */ +class FilterPaginate +{ + public: + static TemplateVariant apply(const TemplateVariant &v,const TemplateVariant &args) + { + if (v.isValid() && v.type()==TemplateVariant::List && + args.isValid() && args.type()==TemplateVariant::Integer) + { + int pageSize = args.toInt(); + TemplateListIntf *list = v.toList(); + TemplateList *result = TemplateList::alloc(); + TemplateListIntf::ConstIterator *it = list->createIterator(); + TemplateVariant item; + TemplateList *pageList=0; + int i = 0; + for (it->toFirst();(it->current(item));it->toNext()) + { + if (pageList==0) + { + pageList = TemplateList::alloc(); + result->append(pageList); + } + pageList->append(item); + i++; + if (i==pageSize) // page is full start a new one + { + pageList=0; + i=0; + } + } + delete it; + return result; + } + else // wrong arguments + { + return v; + } + } +}; + +//-------------------------------------------------------------------- + /** @brief The implementation of the "default" filter */ class FilterStripPath { @@ -926,8 +1105,11 @@ static TemplateFilterFactory::AutoRegister fAdd("add"); static TemplateFilterFactory::AutoRegister fAppend("append"); static TemplateFilterFactory::AutoRegister fLength("length"); static TemplateFilterFactory::AutoRegister fNoWrap("nowrap"); +static TemplateFilterFactory::AutoRegister fFlatten("flatten"); static TemplateFilterFactory::AutoRegister fDefault("default"); static TemplateFilterFactory::AutoRegister fPrepend("prepend"); +static TemplateFilterFactory::AutoRegister fListSort("listsort"); +static TemplateFilterFactory::AutoRegister fPaginate("paginate"); static TemplateFilterFactory::AutoRegister fStripPath("stripPath"); static TemplateFilterFactory::AutoRegister fDivisibleBy("divisibleby"); -- cgit v0.12