diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index db3c9130b..ae21ad9c6 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -456,6 +456,21 @@ namespace NLGUI return _DL.back(); } + // OL + class HTMLOListElement { + public: + HTMLOListElement(int start, std::string type) + : Value(start),Type(type), First(true) + { } + + std::string getListMarkerText() const; + public: + sint32 Value; + std::string Type; + bool First; + }; + std::vector _OL; + // A mode std::vector _A; inline bool getA() const diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index dbe947839..4c851285b 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -1721,6 +1721,29 @@ namespace NLGUI flushString (); getParagraph()->setFirstViewIndent(LIIndent); } + else if (!_OL.empty()) + { + if (_OL.back().First) + { + _OL.back().First = false; + newParagraph(ULBeginSpace); + } + else + { + newParagraph(LIBeginSpace); + } + + // OL list index can be overridden by
  • attribute + if (present[HTML_LI_VALUE] && value[HTML_LI_VALUE]) + fromString(value[HTML_LI_VALUE], _OL.back().Value); + + ucstring str; + str.fromUtf8(_OL.back().getListMarkerText() + ". "); + addString(str); + flushString(); + getParagraph()->setFirstViewIndent(LIIndent); + _OL.back().Value++; + } break; case HTML_P: newParagraph(PBeginSpace); @@ -1994,6 +2017,21 @@ namespace NLGUI getParagraph()->setFirstViewIndent(indent); } break; + case HTML_OL: + { + sint32 start = 1; + std::string type("1"); + + if (present[HTML_OL_START] && value[HTML_OL_START]) + fromString(value[HTML_OL_START], start); + if (present[HTML_OL_TYPE] && value[HTML_OL_TYPE]) + type = value[HTML_OL_TYPE]; + + _OL.push_back(HTMLOListElement(start, type)); + _Indent += ULIndent; + endParagraph(); + } + break; } } } @@ -2114,6 +2152,15 @@ namespace NLGUI _Localize = false; } break; + case HTML_OL: + if (!_OL.empty()) + { + _Indent -= ULIndent; + _Indent = std::max(_Indent, (uint)0); + endParagraph(); + popIfNotEmpty(_OL); + } + break; case HTML_UL: if (getUL()) { @@ -3938,6 +3985,7 @@ namespace NLGUI _DT = false; _UL.clear(); _DL.clear(); + _OL.clear(); _A.clear(); _Link.clear(); _LinkTitle.clear(); @@ -5414,5 +5462,85 @@ namespace NLGUI return 0; } + // *************************************************************************** + std::string CGroupHTML::HTMLOListElement::getListMarkerText() const + { + std::string ret; + sint32 number = Value; + bool upper = false; + + if (Type == "a" || Type == "A") + { + // @see toAlphabeticOrNumeric in WebKit + static const char lower[26] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + static const char upper[26] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; + uint size = 26; + if (number < 1) + { + ret = toString(number); + } + else + { + const char* digits = (Type == "A" ? upper : lower); + while(number > 0) + { + --number; + ret.insert(ret.begin(), digits[number % size]); + number /= size; + } + } + } + else if (Type == "i" || Type == "I") + { + // @see toRoman in WebKit + static const char lower[7] = {'i', 'v', 'x', 'l', 'c', 'd', 'm'}; + static const char upper[7] = {'I', 'V', 'X', 'L', 'C', 'D', 'M'}; + + if (number < 1 || number > 3999) + { + ret = toString(number); + } + else + { + const char* digits = (Type == "I" ? upper : lower); + uint8 i, d=0; + do { + uint32 num = number % 10; + if (num % 5 < 4){ + for (i = num % 5; i > 0; i--) + { + ret.insert(ret.begin(), digits[d]); + } + } + if (num >= 4 && num <= 8) + { + ret.insert(ret.begin(), digits[d + 1]); + } + if (num == 9) + { + ret.insert(ret.begin(), digits[d + 2]); + } + if (num % 5 == 4) + { + ret.insert(ret.begin(), digits[d]); + } + number /= 10; + d += 2; + } while (number > 0); + if (Type == "I") + { + ret = toUpper(ret); + } + } + } + else + { + ret = toString(Value); + } + + return ret; + } }