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;
+ }
}