summaryrefslogtreecommitdiffstats
path: root/src/index.cpp
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-12-20 13:37:39 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-12-21 12:54:18 (GMT)
commit59372719ef31d7a76e2cfb64ab4628a315ccaf3a (patch)
treeb1aea66c40069d150439a08368d57517835e505c /src/index.cpp
parent2dcbf7b29510a99168b1ab3f7d67d21a28a70eaf (diff)
downloadDoxygen-59372719ef31d7a76e2cfb64ab4628a315ccaf3a.zip
Doxygen-59372719ef31d7a76e2cfb64ab4628a315ccaf3a.tar.gz
Doxygen-59372719ef31d7a76e2cfb64ab4628a315ccaf3a.tar.bz2
Refactoring: modernize class index
Diffstat (limited to 'src/index.cpp')
-rw-r--r--src/index.cpp427
1 files changed, 130 insertions, 297 deletions
diff --git a/src/index.cpp b/src/index.cpp
index 82430ef..259dd9f 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -177,74 +177,41 @@ const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
static void startQuickIndexList(OutputList &ol,bool letterTabs=FALSE)
{
- bool fancyTabs = TRUE;
- if (fancyTabs)
+ if (letterTabs)
{
- if (letterTabs)
- {
- ol.writeString(" <div id=\"navrow4\" class=\"tabs3\">\n");
- }
- else
- {
- ol.writeString(" <div id=\"navrow3\" class=\"tabs2\">\n");
- }
- ol.writeString(" <ul class=\"tablist\">\n");
+ ol.writeString(" <div id=\"navrow4\" class=\"tabs3\">\n");
}
else
{
- ol.writeString(" <div class=\"qindex\">");
+ ol.writeString(" <div id=\"navrow3\" class=\"tabs2\">\n");
}
+ ol.writeString(" <ul class=\"tablist\">\n");
}
static void endQuickIndexList(OutputList &ol)
{
- bool fancyTabs = TRUE;
- if (fancyTabs)
- {
- ol.writeString(" </ul>\n");
- }
+ ol.writeString(" </ul>\n");
ol.writeString(" </div>\n");
}
static void startQuickIndexItem(OutputList &ol,const char *l,
bool hl,bool compact,bool &first)
{
- bool fancyTabs = TRUE;
- if (!first && compact && !fancyTabs) ol.writeString(" | ");
first=FALSE;
- if (fancyTabs)
- {
- ol.writeString(" <li");
- if (hl) ol.writeString(" class=\"current\"");
- ol.writeString("><a ");
- }
- else
- {
- if (!compact) ol.writeString("<li>");
- if (hl && compact)
- {
- ol.writeString("<a class=\"qindexHL\" ");
- }
- else
- {
- ol.writeString("<a class=\"qindex\" ");
- }
- }
+ ol.writeString(" <li");
+ if (hl) ol.writeString(" class=\"current\"");
+ ol.writeString("><a ");
ol.writeString("href=\"");
ol.writeString(l);
ol.writeString("\">");
- if (fancyTabs)
- {
- ol.writeString("<span>");
- }
+ ol.writeString("<span>");
}
static void endQuickIndexItem(OutputList &ol)
{
- bool fancyTabs=TRUE;
- if (fancyTabs) ol.writeString("</span>");
+ ol.writeString("</span>");
ol.writeString("</a>");
- if (fancyTabs) ol.writeString("</li>\n");
+ ol.writeString("</li>\n");
}
// don't make this static as it is called from a template function and some
@@ -2041,6 +2008,29 @@ static QCString letterToString(uint letter)
return QString(QChar(letter)).utf8();
}
+static QCString letterToLabel(const char *startLetter)
+{
+ const char *p = startLetter;
+ if (startLetter==0 || *startLetter==0) return "";
+ char c = *p;
+ QCString result;
+ if (isId1(c))
+ {
+ result+=c;
+ }
+ else
+ {
+ result="0x";
+ const char hex[]="0123456789abcdef";
+ while ((c=*p++))
+ {
+ result+=hex[((unsigned char)c)>>4];
+ result+=hex[((unsigned char)c)&0xf];
+ }
+ }
+ return result;
+}
+
static QCString letterToLabel(uint startLetter)
{
char s[11]; // max 0x12345678 + '\0'
@@ -2078,87 +2068,31 @@ static QCString letterToLabel(uint startLetter)
return s;
}
-//----------------------------------------------------------------------------
-/** Special class list where sorting takes IGNORE_PREFIX into account. */
-class PrefixIgnoreClassList : public ClassList
-{
- public:
- typedef const ClassDef ElementType;
- PrefixIgnoreClassList(uint letter) : m_letter(letter) {}
- uint letter() const { return m_letter; }
- private:
- virtual int compareValue(const ClassDef *c1, const ClassDef *c2) const
- {
- QCString n1 = c1->className();
- QCString n2 = c2->className();
- return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
- }
- uint m_letter;
-};
+//----------------------------------------------------------------------------
/** Class representing a cell in the alphabetical class index. */
class AlphaIndexTableCell
{
public:
- AlphaIndexTableCell(int row,int col,uint letter,const ClassDef *cd) :
+ AlphaIndexTableCell(int row,int col,const std::string &letter,const ClassDef *cd) :
m_letter(letter), m_class(cd), m_row(row), m_col(col)
- { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-',
- // cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>");
+ {
}
const ClassDef *classDef() const { return m_class; }
- uint letter() const { return m_letter; }
- int row() const { return m_row; }
- int column() const { return m_col; }
+ std::string letter() const { return m_letter; }
+ int row() const { return m_row; }
+ int column() const { return m_col; }
private:
- uint m_letter;
+ std::string m_letter;
const ClassDef *m_class;
int m_row;
int m_col;
};
-/** Class representing a row in the alphabetical class index. */
-class AlphaIndexTableRows : public QList<AlphaIndexTableCell>
-{
- public:
- AlphaIndexTableRows() { setAutoDelete(TRUE); }
-};
-
-/** Iterator for the cells in a row of the alphabetical class index. */
-class AlphaIndexTableRowsIterator : public QListIterator<AlphaIndexTableCell>
-{
- public:
- AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list_) :
- QListIterator<AlphaIndexTableCell>(list_) {}
-};
-
-/** Class representing the columns in the alphabetical class index. */
-class AlphaIndexTableColumns : public QList<AlphaIndexTableRows>
-{
- public:
- AlphaIndexTableColumns() { setAutoDelete(TRUE); }
-};
-
-class UsedIndexLetters : public SIntDict<uint>
-{
- public:
- UsedIndexLetters() : SIntDict<uint>(257) { setAutoDelete(TRUE); }
- void add(uint letter)
- {
- uint *v = find(letter);
- if (v==0)
- {
- append(letter,new uint(letter));
- }
- }
- private:
- int compareValues( const uint *p1, const uint *p2) const
- {
- return (int)*p1 - (int)*p2; // subtracting is done by int not uint.
- }
-};
+using UsedIndexLetters = std::set<std::string>;
// write an alphabetical index of all class with a header for each letter
static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct, int annotatedCount)
@@ -2169,8 +2103,6 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct
UsedIndexLetters indexLettersUsed;
// first count the number of headers
- uint startLetter=0;
- int headerItems=0;
for (const auto &cd : *Doxygen::classLinkedMap)
{
if (sliceOpt && cd->compoundType() != ct)
@@ -2182,49 +2114,35 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct
int index = getPrefixIndex(cd->className());
//printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
- startLetter=getUtf8CodeToLower(cd->className(),index);
- indexLettersUsed.add(startLetter);
+ char charStr[MAX_UTF8_CHAR_SIZE];
+ if (getUtf8Char(cd->className().data()+index,charStr,CaseModifier::ToUpper)>0)
+ // get the first UTF8 character (after the part that should be ignored)
+ {
+ indexLettersUsed.insert(charStr);
+ }
}
}
- indexLettersUsed.sort();
// write quick link index (row of letters)
QCString alphaLinks = "<div class=\"qindex\">";
- SIntDict<uint>::Iterator it(indexLettersUsed);
- uint *pLetter;
- for (it.toFirst();(pLetter=it.current());++it)
- {
- if (headerItems) alphaLinks += "&#160;|&#160;";
- headerItems++;
- QCString li = letterToLabel(*pLetter);
- QCString ls = letterToString(*pLetter);
+ bool first=true;
+ for (const auto &letter : indexLettersUsed)
+ {
+ if (!first) alphaLinks += "&#160;|&#160;";
+ first=false;
+ QCString li = letterToLabel(letter.c_str());
alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" +
li + "\">" +
- ls + "</a>";
+ letter + "</a>";
}
alphaLinks += "</div>\n";
ol.writeString(alphaLinks);
-
- // the number of columns in the table
- const int columns = Config_getInt(COLS_IN_ALPHA_INDEX);
-
- int i,j;
- int totalItems = headerItems*2 + annotatedCount; // number of items in the table (headers span 2 items)
- int rows = (totalItems + columns - 1)/columns; // number of rows in the table
-
- //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n",
- // headerItems,totalItems,columns,rows,itemsInLastRow);
-
- // Keep a list of classes for each starting letter
- LetterToIndexMap<PrefixIgnoreClassList> classesByLetter;
- AlphaIndexTableColumns tableColumns;
+ std::map<std::string, std::vector<const ClassDef*> > classesByLetter;
// fill the columns with the class list (row elements in each column,
// expect for the columns with number >= itemsInLastRow, which get one
// item less.
- //int icount=0;
- startLetter=0;
for (const auto &cd : *Doxygen::classLinkedMap)
{
if (sliceOpt && cd->compoundType() != ct)
@@ -2235,185 +2153,100 @@ static void writeAlphabeticalClassList(OutputList &ol, ClassDef::CompoundType ct
if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
int index = getPrefixIndex(cd->className());
- startLetter=getUtf8CodeToLower(cd->className(),index);
- // Do some sorting again, since the classes are sorted by name with
- // prefix, which should be ignored really.
- if (cd->getLanguage()==SrcLangExt_VHDL)
+ char charStr[MAX_UTF8_CHAR_SIZE];
+ if (getUtf8Char(cd->className().data()+index,charStr,CaseModifier::ToUpper)>0)
+ // get the first UTF8 character (after the part that should be ignored)
{
- if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture
+ auto it = classesByLetter.find(charStr);
+ if (it!=classesByLetter.end()) // add class to the existing list
{
- classesByLetter.append(startLetter,cd.get());
+ it->second.push_back(cd.get());
+ }
+ else // new entry
+ {
+ classesByLetter.insert(
+ std::make_pair(std::string(charStr),
+ std::vector<const ClassDef*>({ cd.get() })));
}
}
- else
- {
- classesByLetter.append(startLetter,cd.get());
- }
- }
- }
-
- #define NEXT_ROW() \
- do \
- { \
- if (row>maxRows) maxRows=row; \
- if (row>=rows && col<columns) \
- { \
- col++; \
- row=0; \
- tableRows = new AlphaIndexTableRows; \
- tableColumns.append(tableRows); \
- } \
- } \
- while(0) \
-
- AlphaIndexTableRows *tableRows = new AlphaIndexTableRows;
- tableColumns.append(tableRows);
- int col=0,row=0,maxRows=0;
- PrefixIgnoreClassList *cl;
- SIntDict<PrefixIgnoreClassList>::Iterator lit(classesByLetter);
- for (lit.toFirst();(cl=lit.current());++lit)
- {
- uint l = cl->letter();
- // add special header cell
- tableRows->append(new AlphaIndexTableCell(row,col,l,(ClassDef*)0x8));
- row++;
- tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8));
- row++;
- ClassListIterator cit(*cl);
- cit.toFirst();
- ClassDef *cd = cit.current();
- ++cit;
- tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
- row++;
- NEXT_ROW();
- for (;(cd=cit.current()); ++cit)
- {
- // add normal cell
- tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
- row++;
- NEXT_ROW();
}
}
- // create row iterators for each column
- AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns];
- for (i=0;i<columns;i++)
+ // sort the class lists per letter while ignoring the prefix
+ for (auto &kv : classesByLetter)
{
- if (i<(int)tableColumns.count())
- {
- colIterators[i] = new AlphaIndexTableRowsIterator(*tableColumns.at(i));
- }
- else // empty column
- {
- colIterators[i] = 0;
- }
+ std::sort(kv.second.begin(), kv.second.end(),
+ [](const auto &c1,const auto &c2)
+ {
+ QCString n1 = c1->className();
+ QCString n2 = c2->className();
+ return qstricmp(n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2))<0;
+ });
}
- ol.writeString("<table class=\"classindex\">\n");
// generate table
- for (i=0;i<=maxRows;i++) // foreach table row
- {
- //printf("writing row %d\n",i);
- //ol.nextTableRow();
- ol.writeString("<tr>");
- // the last column may contain less items then the others
- //int colsInRow = (i<rows-1) ? columns : itemsInLastRow;
- //printf("row [%d]\n",i);
- bool cellCont = false;
- for (j=0;j<columns;j++) // foreach table column
- {
- if (colIterators[j])
+ if (!classesByLetter.empty())
+ {
+ ol.writeString("<div class=\"classindex\">\n");
+ int counter=0;
+ for (const auto &cl : classesByLetter)
+ {
+ QCString parity = (counter++%2)==0 ? "even" : "odd";
+ ol.writeString("<dl class=\"classindex " + parity + "\">\n");
+
+ // write character heading
+ ol.writeString("<dt class=\"alphachar\">");
+ QCString s = letterToLabel(cl.first.c_str());
+ ol.writeString("<a name=\"letter_");
+ ol.writeString(s);
+ ol.writeString("\">");
+ ol.writeString(cl.first.c_str());
+ ol.writeString("</a>");
+ ol.writeString("</dt>\n");
+
+ // write class links
+ for (const auto &cd : cl.second)
{
- AlphaIndexTableCell *cell = colIterators[j]->current();
- if (cell)
+ ol.writeString("<dd>");
+ QCString namesp,cname;
+ extractNamespaceName(cd->name(),cname,namesp);
+ QCString nsDispName;
+ SrcLangExt lang = cd->getLanguage();
+ QCString sep = getLanguageSpecificSeparator(lang);
+ if (sep!="::")
{
- if (cell->row()==i)
- {
- if (cell->letter()!=0)
- {
- cellCont = true;
- QCString s = letterToLabel(cell->letter());
- ol.writeString("<td rowspan=\"2\" valign=\"bottom\">");
- ol.writeString("<a name=\"letter_");
- ol.writeString(s);
- ol.writeString("\"></a>");
- ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
- "<tr>"
- "<td><div class=\"ah\">&#160;&#160;");
- ol.writeString(letterToString(cell->letter()));
- ol.writeString( "&#160;&#160;</div>"
- "</td>"
- "</tr>"
- "</table>\n");
- }
- else if (cell->classDef()!=(ClassDef*)0x8)
- {
- cellCont = true;
- const ClassDef *cd = cell->classDef();
- ol.writeString("<td valign=\"top\">");
- QCString namesp,cname;
- //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName();
- //QCString cname=cd->className();
- extractNamespaceName(cd->name(),cname,namesp);
- QCString nsDispName;
- SrcLangExt lang = cd->getLanguage();
- QCString sep = getLanguageSpecificSeparator(lang);
- if (sep!="::")
- {
- nsDispName=substitute(namesp,"::",sep);
- cname=substitute(cname,"::",sep);
- }
- else
- {
- nsDispName=namesp;
- }
-
- ol.writeObjectLink(cd->getReference(),
- cd->getOutputFileBase(),cd->anchor(),cname);
- if (!namesp.isEmpty())
- {
- ol.docify(" (");
- NamespaceDef *nd = getResolvedNamespace(namesp);
- if (nd && nd->isLinkable())
- {
- ol.writeObjectLink(nd->getReference(),
- nd->getOutputFileBase(),0,nsDispName);
- }
- else
- {
- ol.docify(nsDispName);
- }
- ol.docify(")");
- }
- ol.writeNonBreakableSpace(3);
- }
- ++(*colIterators[j]);
- if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8)
- {
- ol.writeString("</td>\n");
- }
- }
+ nsDispName=substitute(namesp,"::",sep);
+ cname=substitute(cname,"::",sep);
}
else
{
- cellCont = true;
- ol.writeString("<td></td>");
+ nsDispName=namesp;
}
- }
- }
- if (!cellCont) ol.writeString("<td></td>"); // we need at least one cell in case of xhtml
- ol.writeString("</tr>\n");
- }
- ol.writeString("</table>\n");
- ol.writeString(alphaLinks);
+ ol.writeObjectLink(cd->getReference(),
+ cd->getOutputFileBase(),cd->anchor(),cname);
+ if (!namesp.isEmpty())
+ {
+ ol.writeString(" (");
+ NamespaceDef *nd = getResolvedNamespace(namesp);
+ if (nd && nd->isLinkable())
+ {
+ ol.writeObjectLink(nd->getReference(),
+ nd->getOutputFileBase(),0,nsDispName);
+ }
+ else
+ {
+ ol.docify(nsDispName);
+ }
+ ol.writeString(")");
+ }
+ ol.writeString("</dd>");
+ }
- // release the temporary memory
- for (i=0;i<columns;i++)
- {
- delete colIterators[i];
+ ol.writeString("</dl>\n");
+ }
+ ol.writeString("</div>\n");
}
- delete[] colIterators;
}
//----------------------------------------------------------------------------